Browse Source

Import V3 source

Caleb Porzio 3 năm trước cách đây
mục cha
commit
b46c41fa24
100 tập tin đã thay đổi với 32418 bổ sung28514 xóa
  1. 4 3
      .gitignore
  2. 0 960
      README.ar.md
  3. 0 806
      README.ckb.md
  4. 0 795
      README.de.md
  5. 0 752
      README.es.md
  6. 0 1061
      README.fa.md
  7. 0 793
      README.fr.md
  8. 0 802
      README.id.md
  9. 0 551
      README.ja.md
  10. 0 783
      README.ko.md
  11. 29 797
      README.md
  12. 0 796
      README.no.md
  13. 0 789
      README.pt.md
  14. 0 787
      README.ru.md
  15. 0 792
      README.tr.md
  16. 0 783
      README.zh-CN.md
  17. 0 750
      README.zh-TW.md
  18. 0 13
      babel.config.js
  19. 1579 0
      benchmarks/giant.html
  20. 22142 0
      benchmarks/init.html
  21. 201 0
      benchmarks/loop.html
  22. 17 0
      benchmarks/memory.html
  23. 65 0
      benchmarks/mutation_observer.html
  24. 11 0
      cypress.json
  25. 0 8042
      dist/alpine-ie11.js
  26. 0 1956
      dist/alpine.js
  27. 0 116
      examples/card-game.html
  28. 0 507
      examples/index.html
  29. 0 97
      examples/tags.html
  30. 10 0
      index.html
  31. 0 10
      inject-version-readme.js
  32. 4 185
      jest.config.js
  33. 4380 4746
      package-lock.json
  34. 17 42
      package.json
  35. 7 0
      packages/alpinejs/builds/cdn.js
  36. 3 0
      packages/alpinejs/builds/module.js
  37. 12 0
      packages/alpinejs/package.json
  38. 40 0
      packages/alpinejs/src/alpine.js
  39. 63 0
      packages/alpinejs/src/clone.js
  40. 10 0
      packages/alpinejs/src/datas.js
  41. 164 0
      packages/alpinejs/src/directives.js
  42. 14 0
      packages/alpinejs/src/directives/index.js
  43. 43 0
      packages/alpinejs/src/directives/x-bind.js
  44. 5 0
      packages/alpinejs/src/directives/x-cloak.js
  45. 43 0
      packages/alpinejs/src/directives/x-data.js
  46. 4 0
      packages/alpinejs/src/directives/x-effect.js
  47. 249 0
      packages/alpinejs/src/directives/x-for.js
  48. 30 0
      packages/alpinejs/src/directives/x-if.js
  49. 17 0
      packages/alpinejs/src/directives/x-ignore.js
  50. 8 0
      packages/alpinejs/src/directives/x-init.js
  51. 105 0
      packages/alpinejs/src/directives/x-model.js
  52. 16 0
      packages/alpinejs/src/directives/x-on.js
  53. 16 0
      packages/alpinejs/src/directives/x-ref.js
  54. 46 0
      packages/alpinejs/src/directives/x-show.js
  55. 15 0
      packages/alpinejs/src/directives/x-text.js
  56. 311 0
      packages/alpinejs/src/directives/x-transition.js
  57. 121 0
      packages/alpinejs/src/evaluator.js
  58. 74 0
      packages/alpinejs/src/index.js
  59. 77 0
      packages/alpinejs/src/interceptor.js
  60. 79 0
      packages/alpinejs/src/lifecycle.js
  61. 20 0
      packages/alpinejs/src/magics.js
  62. 4 0
      packages/alpinejs/src/magics/$dispatch.js
  63. 3 0
      packages/alpinejs/src/magics/$el.js
  64. 4 0
      packages/alpinejs/src/magics/$nextTick.js
  65. 4 0
      packages/alpinejs/src/magics/$refs.js
  66. 4 0
      packages/alpinejs/src/magics/$store.js
  67. 23 0
      packages/alpinejs/src/magics/$watch.js
  68. 6 0
      packages/alpinejs/src/magics/index.js
  69. 177 0
      packages/alpinejs/src/mutation.js
  70. 24 0
      packages/alpinejs/src/nextTick.js
  71. 5 0
      packages/alpinejs/src/plugin.js
  72. 44 0
      packages/alpinejs/src/reactivity.js
  73. 33 0
      packages/alpinejs/src/scheduler.js
  74. 70 0
      packages/alpinejs/src/scope.js
  75. 20 0
      packages/alpinejs/src/store.js
  76. 129 0
      packages/alpinejs/src/utils/bind.js
  77. 56 0
      packages/alpinejs/src/utils/classes.js
  78. 12 0
      packages/alpinejs/src/utils/dispatch.js
  79. 174 0
      packages/alpinejs/src/utils/on.js
  80. 14 0
      packages/alpinejs/src/utils/once.js
  81. 38 0
      packages/alpinejs/src/utils/styles.js
  82. 38 0
      packages/alpinejs/src/utils/walk.js
  83. 4 0
      packages/alpinejs/src/utils/warn.js
  84. 7 0
      packages/csp/builds/cdn.js
  85. 3 0
      packages/csp/builds/module.js
  86. 12 0
      packages/csp/package.json
  87. 37 0
      packages/csp/src/index.js
  88. 7 0
      packages/docs/package.json
  89. 5 0
      packages/docs/src/en/advanced.md
  90. 40 0
      packages/docs/src/en/advanced/async.md
  91. 72 0
      packages/docs/src/en/advanced/csp.md
  92. 360 0
      packages/docs/src/en/advanced/extending.md
  93. 101 0
      packages/docs/src/en/advanced/reactivity.md
  94. 326 0
      packages/docs/src/en/alpine-101.md
  95. 7 0
      packages/docs/src/en/directives.md
  96. 189 0
      packages/docs/src/en/directives/bind.md
  97. 38 0
      packages/docs/src/en/directives/cloak.md
  98. 170 0
      packages/docs/src/en/directives/data.md
  99. 20 0
      packages/docs/src/en/directives/effect.md
  100. 87 0
      packages/docs/src/en/directives/for.md

+ 4 - 3
.gitignore

@@ -1,3 +1,4 @@
-/node_modules/
-SCRATCH.md
-COMMIT_MSG.aim.txt
+node_modules
+scratch.md
+package-lock.json
+dist/

+ 0 - 960
README.ar.md

@@ -1,960 +0,0 @@
-<div dir="rtl">
-
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-توفر لك Alpine.js بنية تفاعلية (تصريحية) مثل أُطر العمل الشهيرة Vue و React بكُلفة وجهد أقل بكثير.
-
-يمكنك الإحتفاظ بـ DOM والاستمرار في استخدامه، وإضافة الدّوال والوظائف له عند الحاجة.
-
-يشبه إلى حد ما [Tailwind](https://tailwindcss.com/) ولكن في الجافاسكربت.
-
-> ملاحظة: نشير إلى أن بُنية Alpine.js شبية جداً بـ [Vue](https://vuejs.org/) (أو [Angular](https://angularjs.org/)). أنا ممتن لهذه الأُطر بما قدموه في تطوير الويب.
-
-#### ملاحظة:
-
-يمكنك قراءة التوثيق بتنسيق أفضل "RTL" من الرابط التالي ([AlpineJs بالعربية](https://alpinejs.abdelhadi.org/#/)).
-
-## التوثيق بلغات أخرى
-
-| Language | Link for documentation |
-| --- | --- |
-| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
-| German | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanese | [**日本語ドキュメント**](./README.ja.md) |
-| Portuguese | [**Documentação em Português**](./README.pt.md) |
-| Russian | [**Документация на русском**](./README.ru.md) |
-| Spanish | [**Documentación en Español**](./README.es.md) |
-| Turkish | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| Français | [**Documentation en Français**](./README.fr.md) |
-
-## التركيب
-
-**باستعمال CDN:** أضف السطر البرمجي التالي في نهاية `<head>`. 
-
-<div dir="ltr">
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-</div>
-
-
-سيقوم Alpine.js بتهيئة نفسه، سهلة أليس كذلك!
-
-في بيئات التطوير، نوصي باستعمال إصدار محدّد كما في الرابط، لتجنب حدوث مشاكل غير متوقعة أو تصادمها مع الإصدارات الحديثة. على سبيل المثال، لاستخدام الإصدار الأخير (2.8.2) يمكنك كتابة:
-
-<div dir="ltr">
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-</div>
-
-
-**باستعمال NPM:** قم بتنصيب الحزمة من NPM.
-
-<div dir="ltr">
-
-```js
-npm i alpinejs
-```
-
-</div>
-
-
-قم باستدعائها وتضمينها في مشروعك.
-
-<div dir="ltr">
-
-```js
-import 'alpinejs'
-```
-
-</div>
-
-
-**لدعم نسخة المتصفّح IE11** يرجى استعمال السُطور البرمجية التالية بدلاً عن السابق.
-
-<div dir="ltr">
-
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-    
-</div>
-
-لو تُلاحظ في السطور أعلاه كتبنا [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) ، تسمح هذه الأنماط للمتصفحات الحديثة بتحميل مجموعة الوحدات بشكل تلقائي، بينما ستقوم IE11 والمتصفحات القديمة الأخرى تبحميل وحدات IE11 تلقائياً. 
-
-## طريقة الاستخدام
-
-القائمة المنسدلة (Dropdown) والنوافذ (Modal)
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">فتح القائمة</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        محتوى القائمة
-    </ul>
-</div>
-```
-
-</div>
-
-
-*علامات التبويب (Tabs)*
-
-<div dir="ltr">
-
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">النافذة Foo</div>
-    <div x-show="tab === 'bar'">النافذة Bar</div>
-</div>
-```
-
-</div>
-
-
-يمكنك أيضاً استخدامه في أماكن أخرى: 
-
-*التحضير المُسبق (Pre-fetching) لمُحتوى HTML.*
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >إظهار القائمة</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        جارٍ التحميل ...
-    </div>
-</div>
-```
-
-</div>
-
-
-## الشرح
-
-هناك إجمالي 14 موجّهاً مُتاحا:
-
-| الموجّه | الوصف |
-| --: | --: |
-| [`x-data`](#x-data) | إعلان أو تعريف حقل (Scope) جديد للمكوّن. |
-| [`x-init`](#x-init) | ينفّذ تعليمات برمجية عند تشغيل إحدى المكوّنات. |
-| [`x-show`](#x-show) | إظهار أو إزالة العناصر بناء على التعبيرات المنطقية <span dir="ltr">`display: none;`</span> صحيحة أو خاطئة. |
-| [`x-bind`](#x-bind) | يضبط قيمة السّمة (attribute) على حسب نتائج تعليمات الجافاسكربت. |
-| [`x-on`](#x-on) | يربط المُنصِت للأحداث (event listener) بالعنصر، يتم تنفيذ تعليمات الجافاسكربت عند التفاعل معه. |
-| [`x-model`](#x-model) | يضيف اتصالا للبيانات ثنائي الإتجاه "two-way data binding" حيث أن القيم الذي يُدخلها المستخدم تتم مزامنتها مع قيمة بيانات العنصر للمكوّن. |
-| [`x-text`](#x-text) | يعمل بشكل مشابه لـ `x-bind`، ولكنه يقوم بتحديث النص المضمن `innerText` داخل العنصر. |
-| [`x-html`](#x-html) | يعمل بشكل مشابه لـ `x-bind`، ولكنه يقوم بتحديث النص المضمن `innerText` داخل العنصر. |
-| [`x-ref`](#x-ref) | طريقة سهلة لاسترجاع عنصر داخل DOM موجود خارج المكوّن الخاص بك. |
-| [`x-if`](#x-if) | إزالة عنصر تماماً من الـDOM. يجب استخدامه داخل وَسم `<template>` |
-| [`x-for`](#x-for) | ينشئ فروع DOM جديدة لكل عنصر من عناصر المصفوفة. يجب استخدامه داخل وَسم `<template>` |
-| [`x-transition`](#x-transition) | توجيه لعمل تأثيرات انتقالية في مراحل مختلفة على الأصناف (Classes) |
-| [`x-spread`](#x-spread) | يسمح لك بربط الكائنات التي تحتوي على توجيهات Alpine بالعناصر، لتحسين إمكانية إعادة استخدامه بشكل أفضل. |
-| [`x-cloak`](#x-cloak) | تتم إزالة هذه السمة عند تهيئة Alpine. مفيد لإخفاء DOM المُهيأ مسبقًا. |
-
-و 6 خصائص سحرية:
-
-| الخصائص السحرية | الوصف |
-| --: | --: |
-| <span dir="ltr">[`$el`](#el)</span> | ترجع فرع DOM الخاص بالمكوّن الأساسي (root component). |
-| <span dir="ltr">[`$refs`](#refs)</span> | يسترجع عناصر DOM المميّزة بـ `x-ref` داخل المكوّن. |
-| <span dir="ltr">[`$event`](#event)</span> | يرجع كائن الحدث "Event"  الأصلي داخل المُنصت لأحداث المستخدم. |
-| <span dir="ltr">[`$dispatch`](#dispatch)</span> | ينشئ حدثاً مخصصا `CustomEvent` ويرسله داخلياً باستخدام `.dispatchEvent()`. |
-| <span dir="ltr">[`$nextTick`](#nexttick)</span> | بعد معالجة Alpine لتحديث DOM يتم تنفيذ تعليمات برمجية. |
-| <span dir="ltr">[`$watch`](#watch)</span> | يقوم باستدعاء callback تم تحديده مسبقاً عندما يتم تعديل خاصية المُراقب "watched" |
-
-## الرعاة
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**هل تريد عرض شعارك هنا؟ [راسلني على تويتر](https://twitter.com/calebporzio)**
-
-## مشاريع المجتمع
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### الموجّهات
-
----
-
-### `x-data`
-
-**المثال:** <span dir="ltr">`<div x-data="{ foo: 'bar' }">...</div>`</span>
-
-**البُنية:** <span dir="ltr">`<div x-data="[object literal]">...</div>`</span>
-
-تعرّف `x-data` حقل/نطاق جديد للمكوّن، يخبر Alpine بتهيئة المكوّن الجديد بكائن البيانات المعرّف والمحدّد مسبقاً.
-
-مشابه لخاصية `data` في المكونّات في إطار Vue.
-
-**استخراج التعابير المنطقية للمكوّن**
-
-يمكنك من استخراج مصدر البيانات والتعاملات ذات الصّلة إلى دوال قابلة لإعادة الاستخدام. 
-
-<div dir="ltr">
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">فتح</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // القائمة المنسدلة
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> لمستخدمي مجمّع الوحدات (bundler): يرجى ملاحظة أن الدوال التي يصل إليها Alpine.js في النطاق العام (window). فلاستخدام x-data يجب أن تصرّحها إلى `window`. على سبيل المثال <span dir="ltr">`window.dropdown = function () {}`</span> (لأنه في Webpack ،Rollup ،Parcel وما إلى ذلك، الدّوال التي تكتبتها تكون بشكل افتراضي ضِمن نطاق الوحدة "module" وليس في نطاق الصفحة `window`).
-
-يمكنك أيضاً دمج عدة كائنات متعددة معاً باستخدام محلّل الكائنات (object destructuring).
-
-<div dir="ltr">
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
-</div>
-
-
----
-
-### `x-init`
-**المثال:** <span dir="ltr">`<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`</span>
-
-**البُنية:** <span dir="ltr">`<div x-data="..." x-init="[expression]"></div>`</span>
-
-ينفّذ `x-init` تعليمات برمجية عند تشغيل وتهيئة إحدى المكوّنات.
-
-إذا أردت تنفيذ التعليمات البرمجية بعد أن يجري Alpine تحديثه على الـDOM (مُماثل لـ <span dir="ltr">`mounted()`</span> في Vue.js) يمكنك إرجاع callback من `x-init` وسيتم تشغيله بعدها:
-
-<span dir="ltr"> `x-init="() => { // يمكننا الوصول إلى DOM بعد تهيئته // }"` </span>
-
----
-
-### `x-show`
-**المثال:** <span dir="ltr">`<div x-show="open"></div>`</span>
-
-**البُنية:** <span dir="ltr">`<div x-show="[expression]"></div>`</span>
-
-تمكّننا `x-show` من إظهار أو إزالة العناصر بناء على التعبيرات المنطقية <span dir="ltr">`display: none;`</span> صحيحة أو خاطئة.
-
-**x-show.transition**
-
-`x-show.transition` عبارة عن واجهة "API" يمكنها تحسين `x-show` وجعله أكثر جمالية باستخدام تأثيرات CSS transitions.
-
-<div dir="ltr">
-
-```html
-<div x-show.transition="open">
-    يتم عمل تأثير بصري بالظهور "in" و الاختفاء "out"
-</div>
-```
-
-</div>
-
-
-| التوجيهات | الوصف |
-| ---: | ---: |
-| `x-show.transition` | يتلاشى ويتقلص بمرور الوقت (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms). |
-| `x-show.transition.in` | تأثير انتقالي "in" فقط. |
-| `x-show.transition.out` | تأثير خارجي "out" فقط. |
-| `x-show.transition.opacity` | تأثير التلاشي فقط. |
-| `x-show.transition.scale` | تأثير على الحجم فقط. |
-| `x-show.transition.scale.75` | ضبط قيمة الحجم `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | يضبط قيمة الانتقال الأولي "in" إلى 200 مللي ثانية. تأخذ قيمة الانتقال النهائي "out" نصف القيمة المحددة (في هذه الحالة 100 مللي ثانية). |
-| `x-show.transition.origin.top.right` | تنسيق التحولات CSS transform الأصلية `transform-origin: top right` |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | تأثيرات على فترات مختلفة "in" و "out". |
-
-
-> ملاحظة: يمكنك دمج جميع التأثيرات مع بعضها البعض (على الرغم من أنها غريبة ربما): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> ملاحظة: سينتظر `x-show` إلى حين أن تنتهني جميع التأثيرات، إذا كنت تريد تجاهلها، أضف المعدّل <span dir="ltr">`.immediate`</span>
-
-<div dir="ltr">
-
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
-
-</div>
-
----
-
-### `x-bind`
-
-> ملاحظة: يمكنك اختصار الكتابة باستعمال النقطتين ":" مثل <span dir="ltr">`:type="..."`</span>
-
-**المثال:** <span dir="ltr">`<input x-bind:type="inputType">`</span>
-
-**البُنية:** <span dir="ltr">`<input x-bind:[attribute]="[expression]">`</span>
-
-يضبط قيمة السّمة (attribute) على حسب نتائج تعليمات الجافاسكربت. ويمكن لهذه التعليمات أن تصل إلى جميع بيانات المكوّن. ويتم تحديثه في كل مرة يتم فيها تحديث بياناته.
-
-> ملاحظة: يتم تحديث ارتباطات السمات (binding) فقط إذا تم تحديث قيّمها. يكتشف Alpine تلقائيًا هذه القيم والتحديثات ثم يحسّنها.
-
-**استخدام `x-bind` لـ class attributes**
-
-يتصرف `x-bind` بشكل مختلف قليلاً عند تحديد الصنف (class attribute).
-
-بالنسبة للأصناف (classes) قم بتمرير كائن يكون مفتاحه هو اسم الفئة، وقيَمُ هذه الأزواج عبارة عن تعبيرات منطقية تحدّد ما إذا كان يتم تطبيق الصنف على العنصر أم لا.
-
-مثال:
-<span dir="ltr">`<div x-bind:class="{ 'hidden': foo }"></div>`</span>
-
-في هذا المثال يتم تطبيق الصنف "hidden" فقط عندما تكون قيمة foo صحيحة `true`.
-
-**`x-bind` للسمات المنطقية (boolean attributes)**
-
-يدعم `x-bind` المتغيرات بالإضافة إلى تعبيرات الجافاسكربت في حالة إذا كانت تُرجع قيمة منطقية صحيحة أو خاطئة (`true` أو `false`).
-
-مثال:
-<div dir="ltr">
-```html
-<!-- العبارة: -->
-<button x-bind:disabled="myVar">إضغطني</button>
-
-<!-- إذا myVar == true: -->
-<button disabled="disabled">اضغطني</button>
-
-<!-- في حال myVar == false:  -->
-<button>اضغطني</button>
-```
-</div>
-
-هنا تتم إضافة السمة `disabled` أو إزالتها بناءً على قيمة المتغيّر `myVar`.
-
-تدعم كذلك Alpine سمات منطقية مختلفة  HTML specification مثل:  `disabled`,`readonly`,`required`,`checked`,`hidden`,`selected`,`open` وغيرها.
-
-المُعدّل .camel
-مثال: <svg x-bind:view-box.camel="viewBox">
-
-يقوم المعدّل بضبط وربط حالة الأحرف بصيغة camel case لاسم السمة. في المثال أعلاه، تم ربط قيمة viewBox بِسِمة viewBox (بدلاً من view-box).
-
----
-
-### `x-on`
-
-> ملاحظة: يمكنك اختصار الكتابة باستعمال النقطتين ":" مثل <span dir="ltr">`@click="..."`</span>
-
-**المثال:** <span dir="ltr">`<button x-on:click="foo = 'bar'"></button>`</span>
-
-**البُنية:** <span dir="ltr">`<button x-on:[event]="[expression]"></button>`</span>
-
-يقوم x-on بإرفاق المُنصت للأحداث (event listener). عندما يتم حدث (event) من قِبل المستخدم يتم تنفيذ تعليمات الجافاسكربت المحددة.
-
-يتم تحديث السِمات الأخرى للعنصر المرتبطة بمصدر البيانات هذا بمجرد تعديل البيانات الموجودة في التعليمات البرمجية.
-
-> ملاحظة: اختياريًا، يمكن أيضًا تحديد اسم دالة الجافاسكربت.
-
-**المثال:** <span dir="ltr">`<button x-on:click="myFunction"></button>`</span>
-
-هذه تكافئ: <span dir="ltr">`<button x-on:click="myFunction($event)"></button>`</span>
-
-**المُعدّل `keydown`**
-
-**المثال:** <span dir="ltr">`<input type="text" x-on:keydown.escape="open = false">`</span>
-
-يمكنك الإستجابة لأحداث معينة عند ضغط المستخدم في لوحة المفاتيح باستخدام المعدّلات `x-on:keydown`. يرجى ملاحظة أن هذا المُعدّل يستخدم صيغة kebab-case لتسمية قيم `Event.key`.
-
-أمثلة: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> يمكننا كذلك الإستجابة لأزرار لوحة المفاتيح الأساسية مثل <span dir="ltr">`x-on:keydown.cmd.enter="foo"`</span>
-
-**المُعدّل <span dir="ltr">`.away`</span>**
-
-**المثال:** <span dir="ltr">`<div x-on:click.away="showModal = false"></div>`</span>
-
-لا يتم تنفيذ تعبير Event Handler إلا إذا لم يتم تشغيل الحدث بواسطة العنصر نفسه (أو مكوناته الفرعية).
-
-هذا مفيد لإخفاء القوائم المنسدلة والنوافذ عندما يضغط المستخدم في مكان آخر.
-
-**المُعدّل <span dir="ltr">`.prevent`</span>**
-**المثال:** <span dir="ltr">`<input type="checkbox" x-on:click.prevent>`</span>
-
-تؤدي إضافة <span dir="ltr">`.prevent`</span> داخل مستمع الحدث إلى استدعاء منع `preventDefault` في الحدث الذي سيتم تنفيذه. في المثال أعلاه، هذا يعني أن مربع الاختيار لن يتم تحديده بالفعل عندما ينقر المستخدم عليه.
-
-**المُعدّل <span dir="ltr">`.stop`</span>**
-**المثال::** <span dir="ltr">`<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`</span>
-
-إضافة <span dir="ltr">`.stop`</span> إلى المنصت للأحداث يستدعي `stopPropagation.` في المثال أعلاه، يعني أن الحدث "click" لن ينتقل إلى  `<div>` الخارجي. بمعنى آخر، عندما ينقر المستخدم على الزر، لا يتم تعريف `foo` على أنه `bar`.
-
-**المُعدّل <span dir="ltr">`.self`</span>**
-**المثال:** <span dir="ltr">`<div x-on:click.self="foo = 'bar'"><button></button></div>`</span>
-
-إضافة .self إلى المنصت للأحداث يأدي إلى تشغيل الحدث فقط إذا كان <span dir="ltr">`$event.target`</span> هو نفس العنصر. في المثال أعلاه، يعني أنه عند النقر على الزر "button" لن يتم تشغيل الحدث.
-
-**المُعدّل <span dir="ltr">`.window`</span>**
-**المثال:** <span dir="ltr">`<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`</span>
-
-إضافة <span dir="ltr">`.window`</span> إلى منصت الأحداث، سيقوم بتثبيت منصت للأحداث على نافذة المتصفّح كله `window` بدلاً من DOM الذي قمت بتصريحه أو تحديده. هذا مفيد لك في حال أردت ضبط أحد المكوّنات وتغييرها على حسب حجم (أبعاد) المتصفّح. في المثال أعلاه سيتم إغلاق النافذة أو القائمة المنسدلة إذا تجاوزت أبعاد المتصفح 768 بكسل، خلاف ذلك نُبقيه على حالته.
-
->ملاحظة: يمكنك أيضًا استخدام معدّل `.document` لإرفاق المنصت بدلا من `window`.
-
-**المُعدّل <span dir="ltr">`.once`</span>**
-**المثال:** <span dir="ltr">`<button x-on:mouseenter.once="fetchSomething()"></button>`</span>
-
-تعني إضافة المعدّل <span dir="ltr">`.once`</span> إلى المنصت للحدث أن المنصت (listener) يعمل مرة واحدة فقط. هذا مفيد للمهام التي تريد القيام بها مرة واحدة فقط، مثل الجلب الجزئي لشفرات HTML أو ما شابه.
-
-**المُعدّل <span dir="ltr">`.passive`</span>**
-**المثال:** <span dir="ltr">`<button x-on:mousedown.passive="interactive = true"></button>`</span>
-
-إذا أضفنا <span dir="ltr">`.passive`</span> إلى المنصت للحدث، فإن هذا الرمز المميز سيعطل وظيفة `preventDefault()` ولن تعمل على أي حدث يتم تنفيذه. يمكن أن يساعدك أحياناً في تحسين أداء التمرير (scroll) على الأجهزة التي تعمل باللمس.
-
-**المُعدّل <span dir="ltr">`.debounce`</span>**
-**المثال:** <span dir="ltr">`<input x-on:input.debounce="fetchSomething()">`</span>
-
-يتيح لك تحديد <span dir="ltr">`.debounce`</span> وقت تنفيذ الأحداث، لن يعمل معالج الأحداث (event handler) فقط إذا مرت فترة زمنية معينة منذ آخر حدث، عندما يكون المعالج جاهزاً للتنفيذ سيتم تنفيذ آخر استدعاء للمعالج.
-
-مهلة الإنتظار "wait" الإفتراضية هي 250 مللي ثانية.
-
-إذا أردت تخصيص مهلة الإنتظار يمكنك استخدام الطريقة التالية:
-
-<div dir="ltr">
-
-```html
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-</div>
-
-
-**المُعدّل <span dir="ltr">`.camel`</span>**
-**المثال:** <span dir="ltr">`<input x-on:event-name.camel="doSomething()">`</span>
-
-يقوم المنصت للأحداث بالإنصات إلى الأحداث التي تحمل حالة أحرف بصيغة camelCase. في هذا المثال سيتم تنفيذها للعناصر التي تحمل اسم `eventName`.
-
----
-
-### `x-model`
-**المثال:** <span dir="ltr">`<input type="text" x-model="foo">`</span>
-
-**البُنية:** <span dir="ltr">`<input type="text" x-model="[data item]">`</span>
-
-يضيف `x-model` ربط بيانات ثنائي الإتجاه "two-way data binding" (أي أن ربط البيانات يكون في كلا الطرفين). بمعنى آخر، أن قيمة العنصر تتم مزامنتها مع قيمة بيانات عنصر المكوّن.
-
-> يكتشف `x-model` تلقائياً التغييرات التي تطرأ على العناصر التالية:  text inputs ،checkboxes ،radio buttons ،textareas ،selects ،multiple selects.
-> يمكنك فهم كيف يعمل ذلك في الخفاء في "سيناريوهات" إطار عمل [Vue](https://vuejs.org/v2/guide/forms.html).
-
-**المُعدّل <span dir="ltr">`.number`</span>**
-**المثال:** <span dir="ltr">`<input x-model.number="age">`</span>
-
-يقوم <span dir="ltr">`.number`</span> بتحويل القيمة المدخلة عبر `<input>` إلى رقم. في حال تعذّر تحليل القيمة المدخلة لرقم فعلاً سيُرجع القيمة الأصلية المدخلة.
-
-**المُعدّل <span dir="ltr">`.debounce`</span>**
-**المثال:** <span dir="ltr">`<input x-model.debounce="search">`</span>
-
-يتيح لك تحديد <span dir="ltr">`.debounce`</span> وقت تنفيذ الأحداث، لن يعمل معالج الأحداث (event handler) فقط إذا مرت فترة زمنية معينة منذ آخر حدث، عندما يكون المعالج جاهزاً للتنفيذ سيتم تنفيذ آخر استدعاء للمعالج.
-
-مهلة الإنتظار "wait" الإفتراضية هي 250 مللي ثانية.
-
-إذا أردت تخصيص مهلة الإنتظار يمكنك استخدام الطريقة التالية:
-
-<div dir="ltr">
-
-```html
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
-</div>
-
----
-
-### `x-text`
-**المثال:** <span dir="ltr">`<span x-text="foo"></span>`</span>
-
-**البُنية:** <span dir="ltr">`<span x-text="[expression]"`</span>
-
-يعمل بشكل مشابه لـ `x-bind`، ولكنه يقوم بتحديث النص المضمن `innerText` داخل العنصر.  
-
----
-
-### `x-html`
-**المثال:** <span dir="ltr">`<span x-html="foo"></span>`</span>
-
-**البُنية:** <span dir="ltr">`<span x-html="[expression]"`</span>
-
-يعمل بشكل مشابه لـ `x-bind`، ولكنه يقوم بتحديث شفرة HTML المضمنة `innerText` داخل العنصر. 
-
-> :warning: **في هذه الحالة نوصي بكتابة محتوى (شفرات نظيفة) ولا تسمح بمُدخلات المُستخدم (user-provided)** :warning:
->
-> يمكن أن يؤدي عرض HTML على المتصفّح من جهات خارجية أن توقع موقعك بثغرات [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting).
-
----
-
-### `x-ref`
-**المثال:** <span dir="ltr">`<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`</span>
-
-**البُنية:** <span dir="ltr">`<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`</span>
-
-توفر `x-ref` طريقة مفيدة لجلب عناصر DOM خارج المكون الخاص بك، عندما تقوم بتعيين `x-ref` للعنصر، سيكون متاحاً لجميع معالجات الأحداث داخل الكائن عن طريق استدعاء `$refs`. 
-
-يوفر ذلك بديلا مفيدا في حال كان يجب استخدام الأمر `document.querySelector` في كثير من الأحيان للإشارة إلى العناصر.
-
-> يمكنك أيضا ربط القيم المتغيّرة (الديناميكية) بـ <span dir="ltr">`<span :x-ref="item.id"></span>`</span>.
-
----
-
-### `x-if`
-**المثال:** <span dir="ltr">`<template x-if="true"><div>Some Element</div></template>`</span>
-
-**البُنية:** <span dir="ltr">`<template x-if="[expression]"><div>Some Element</div></template>`</span>
-
-إذا كانت وظيفة `x-show` (كما شرحناها سابقاً) غير كافية، فيمكن استخدام `x-if` بدلاً من ذلك لإزالة عنصر بالكامل من DOM.
-
-نظرًا لأن Alpine لا يحتوي على DOM افتراضي، يجب استخدام `x-if` مع الوسم `<template></template>`. بحيث يسمح لـ Alpine  بالبقاء مستقرًا والوصول إلى DOM الحقيقي.
-
-> ملاحظة: عند استخدام `x-if`، يجب أن يكون هناك عنصر جذر واحد (element root) على الأقل داخل `<template></template>`
-
-> ملاحظة: عند استخدام template في svg، ستحتاج إلى إضافة [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) الذي يجب تنفيذه قبل تهيئة Alpine.js. 
-
----
-
-### `x-for`
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> ملاحظة: الـ`:key` مفتاح اختياري، ومع ذلك، نوصى به.
-</div>
-
-
-> ملاحظة: هذا `:key` مفتاح اختياري ، ومع ذلك، نوصى به وبشدة.
-
-يُعدّ `x-for` مناسباً للحالات التي يلزم فيها إنشاء عقدة DOM جديدة لكل عنصر داخل المصفوفة. مشابه لـ `v-for` في Vue، ولكن الاختلاف الوحيد هو أنه يجب وضعه في وسم `template` بدلاً من عنصر DOM عادي.
-
-إذا كنت ترغب في الوصول إلى الفهرس الحالي (current index) للتكرار، فاستخدم الصيغة التالية:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- يمكنك أيضًا الرجوع إلى "index" داخل التكرار إذا لزم الأمر. -->
-    <div x-text="index"></div>
-</template>
-```
-
-إذا كنت ترغب في الوصول إلى تكرار مصفوفة كائن (array object)، فاستخدم الصيغة التالية:
-
-<div dir="ltr">
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- يمكنك أيضًا الرجوع إلى "collection" في التكرار متى احتجت إلى ذلك. -->
-    <!-- العنصر الحالي. -->
-    <div x-text="item"></div>
-    <!--نفس العنصر المذكور أعلاه. -->
-    <div x-text="collection[index]"></div>
-    <!-- العنصر السابق. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-</div>
-
-> ملاحظة: عند استخدام `x-for`، يجب أن يكون هناك عنصر جذر واحد (element root) على الأقل داخل `template`.
-
-> ملاحظة: عند استخدام template في svg، ستحتاج إلى إضافة [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) الذي يجب تنفيذه قبل تهيئة Alpine.js. 
-
-#### تداخل `x-for`
-يمكنك عمل حلقات تكرار داخل حلقات x-for ولكن يجب أن نلّف كل حلقة في عنصر. مثلا:
-
-<div dir="ltr">
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-</div>
-
-
-#### التكرار داخل مجال:
-
-يدعم Alpine صيغة `i in n`، حيث يمثّل n عدداً صحيحاً مما يسمح لك بعمل تكرار على مجال معين من العناصر.
-
-<div dir="ltr">
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
-</div>
-
----
-
-### `x-transition`
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-</div>
-<div dir="ltr">
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-</div>
-
-> المثال أعلاه يستخدم تنسيقات [Tailwind CSS](https://tailwindcss.com/)
-
-يوفر Alpine ستة تأثيرات انتقالية مختلفة لتطبيق الفئات (Classes) على مراحل مختلفة من انتقال العنصر، بين الحالات "hidden" و "shown". تعمل هذه التوجيهات مع كل من x-show و x-if.
-
-تعمل هذه تمامًا مثل توجيهات التأثير بـ VueJS، باستثناء أن لها أسماء مختلفة وأكثر منطقية:
-
-| التوجيه | الوصف |
-| ---: | ---: |
-| <span dir="ltr">`:enter`</span> | يتم تطبيقه طوال مرحلة الدخول. |
-| <span dir="ltr">`:enter-start`</span> | تتم إضافته قبل إدراج العنصر وإزالة الإطار (frame) بعد إدراج العنصر. |
-| <span dir="ltr">`:enter-end`</span> | تمت إضافة إطار (frame) واحد بعد إدراج العنصر (في نفس الوقت تتم إزالة `enter-start`) ، تتم إزالته عند انتهاء التأثير/التحريك. |
-| <span dir="ltr">`:leave`</span> | تُطبق طوال مرحلة الخروج. |
-| <span dir="ltr">`:leave-start`</span> | يُضاف مباشرة عند بدء انتهاء التأثير، وإزالته بعد إطار واحد. |
-| <span dir="ltr">`:leave-end`</span> | تمت إضافة إطار بعد تشغيل "انتهاء التأثير" (في نفس الوقت الذي تتم فيه إزالة `leave-start`) ، وتتم إزالته عند انتهاء التأثير/التحريك. |
-
----
-
-### `x-spread`
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">فتح القائمة المنسدلة</button>
-
-    <span x-spread="dialogue">محتوى القائمة</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-</div>
-
-
-يتيح `x-spread` نقل ربط الكائنات التي تحتوي على توجيهات Alpine لعنصر ما، إلى كائن يمكن إعادة استخدامه.
-
-مفاتيح الكائن (object keys) عبارة عن توجيهات (يمكن أن يكون أي توجيهات بما في ذلك المُعدّلات) والقيم عبارة عن عمليات callback يتم تنفيذ قيمها بواسطة Alpine.
-
-> ملاحظة: هناك بعض الأشياء التي يجب مراعاتها في `x-spread`:
-> - الحالة الخاصة الوحيدة لـ spread هي استخدامه مع `x-for`. عند تطبيقه على التوجيه `x-for`، يجب إرجاع تعليمات نصيّة عادية بواسطة callback.  مثال span dir="ltr">`['x-for']() { return 'item in items' }`</span>
-> - `x-data` و  `x-init` لا يمكن استخدامهما داخل كائن "spread".
-
----
-
-### `x-cloak`
-**المثال:** <span dir="ltr">`<div x-data="{}" x-cloak></div>`</span>
-
-تتم إزالة سمة `x-cloak` من العنصر أثناء تهيئة Alpine. يساعد هذا في إخفاء DOM المهيأ مسبقاً. لكي يعمل هذا عليك بإضافة التعليمات التالية:
-
-<div dir="ltr">
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-</div>
-
-
-### الخصائص السحرية
-
-> باستثناء <span dir="ltr">$el</span>، **لا يمكن استخدام الخصائص السحرية ضمن x-data** في حال لم تتم تهيئة المكوّن بعد.
-
----
-
-### <span dir="ltr">`$el`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">استبدلني بـ "foo"</button>
-</div>
-```
-
-</div>
-
-
-<span dir="ltr">`$el`</span> خاصية سحرية للوصول إلى فرع DOM الأساسي.
-
-### <span dir="ltr">`$refs`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-</div>
-
-
-يسترجع عناصر DOM المميّزة بـ `x-ref` داخل المكوّن، مفيدًا عندما تحتاج عناصر DOM إلى التعديل يدويًا.
-
----
-
-### <span dir="ltr">`$event`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-يرجع كائن الحدث "Event"  الأصلي داخل المُنصت لأحداث المستخدم.
-</div>
-
-> ملاحظة: خاصية $event متاحة فقط في تعليمات DOM.
-
-إذا أردت تمرير $event داخل دوال الجافاسكربت فيمكنك تمريرها مباشرة.
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### <span dir="ltr">`$dispatch`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!--عند النقر عليه، يقوم console.log بطباعة "bar" -->
-</div>
-```
-
-</div>
-
-
-<span dir="ltr">`$dispatch`</span> هي طريقة مختصرة لإنشاء أحداث مخصصة `CustomEvent` وإرسالها داخلياً باستخدام <span dir="ltr">`.dispatchEvent()`</span> هناك العديد من حالات الاستخدام التي يكون فيها إرسال البيانات بين المكونات من خلال أحداث يحددها المستخدم خيارًا جيداً. هنا يمكنك العثور على [مزيد من المعلومات](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) حول نظام CustomEvent الأساسي في المتصفحات.
-
-<div dir="ltr">
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- عندما يتم النقر فوق الزر `x-model` يتلقط حدث "input" الناشئ ويقوم بتحديث foo إلى"baz ". -->
-    </span>
-</div>
-```
-
-</div>
-
-
-**ملاحظة حول انتشار الحدث** (**Event Propagation**)
-
-إذا كنت ترغب في توقيف الأحداث التي يتم تشغيلها بواسطة عقد HTML داخل نفس التسلسل الهرمي المتداخل (يعني `div` داخل `div` وهكذا)، فيجب عليك استخدام المُعدِّل <span dir="ltr">`.window`</span>.
-
-مثال:
-
-<div dir="ltr">
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> ملاحظة: المثال أعلاه لن يعمل بشكل جيّد. لأنه إذا تم تشغيل الحدث المخصص، فسيتم انتشار "تشغيله" في العناصر الرئيسة المشتركة بـ div.
-</div>
-
-**Dispatching to Components**
-
-يمكن أيضًا استخدام الطريقة الموضحة أعلاه لتمكين الاتصال بين المكونات:
-
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!--عندما تنقر سيطبع console.log "Hello World!". -->
-```
-
-</div>
-
-
-يمكنك أيضا استخدام <span dir="ltr">`$dispatch()`</span> لبدء تحديث البيانات من روابط `x-model`. على سبيل المثال:
-
-<div dir="ltr">
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- بعد النقر على عنصر `<button>` ، سيعترض `x-model` حدث "input" ويحدّث foo بـ "bar" -->
-    </span>
-</div>
-```
-
-</div>
-
-> ملاحظ: خاصية <span dir="ltr">`$dispatch`</span> متاحة فقط ضمن تعليمات DOM.
-
-إذا أردت تمرير <span dir="ltr">`$dispatch`</span> داخل دوال الجافاسكربت فيمكنك تمريرها مباشرة.
-
-<span dir="ltr">`<button x-on:click="myFunction($dispatch)"></button>`</span>
-
----
-
-### <span dir="ltr">`$nextTick`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-</div>
-
-
-<span dir="ltr">`$nextTick`</span> هي خاصية تعني أن التعليمات لا يتم تنفيذها إلا بعد أن يقوم Alpine بتنفيذ تحديثات DOM التفاعلية. هذا مفيد إذا كنت لا تريد التفاعل مع DOM حتى يتم إجراء جميع تحديثات للبيانات.
-
----
-
-### <span dir="ltr">`$watch`</span>
-**المثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-تمكّنك <span dir="ltr">`$watch`</span> في المثال أعلاه من تفعيل `open` عند الضغط على الزر "button"، يقوم callback بتنفيذ `console.log` وطباعة القيمة الجديدة.
-
-## الحماية
-إذا وجدت ثغرة أمنية، يُرجى إرسال بريد إلكتروني إلى: [calebporzio@gmail.com]().
-
-يعتمد Alpine على `function` لتنفيذ خصائصه. على الرغم من كونها أكثرَ أماناً من <span dir="ltr">`eval()`</span> إلا أن هذه الممارسة مازالت محظورة في بعض البيئات المقيّدة مثل Google Chrome App باستخدام سياسة أمان المحتوى المقيد ([CSP](https://csp.withgoogle.com/docs/strict-csp.html)).
-
-إذا كنت تستخدم Alpine في بيئة بها بيانات حساسة وتحتاج إلى [CSP](https://csp.withgoogle.com/docs/strict-csp.html)، فأنت بحاجة إلى تضمين التقييم غير الآمن `unsafe-eval` في سياستك. يساعد في وضع سياسات قوية على حماية المستخدمين عند استخدام المعلومات الشخصية والمالية.
-
-نظرًا لأن السياسة تنطبق على جميع البرامج النصية في صفحتك، فمن المهم أن تتم مراجعة المكتبات الخارجية الأخرى المضمنة في موقعك بعناية للتأكد من أنها جديرة لاستعمالها وآمنة ولن تقدم أي ثغرة أمنية XSS أو (Cross Site Scripting vulnerability)  عبر الموقع سواء باستخدام وظيفة <span dir="ltr">`eval()`</span> أو التلاعب بـ DOM لإدخال تعليمات برمجية ضارة في صفحتك.
-
-## الرخصة
-
-حقوق النشر محفوظة  © 2019-2021 لـ Caleb Porzio والمساهمين.
-
-مرخص بموجب ترخيص MIT، راجع [LICENSE.md](LICENSE.md) للحصول على التفاصيل.
-
-</div>

+ 0 - 806
README.ckb.md

@@ -1,806 +0,0 @@
-<div style="direction:rtl;">
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js دەستەبەری سروشتێکی کاردانەوەو ڕاگەیاندراوی گەورە چوارچێوەکارەکانی وەک Vue و React بە کەمترین تێچوون.
-
-دەتوانیت DOM ەکەت لەشوێنی خۆیدا بپارێزیت و ئەو فرمان و کردارەی بۆ زیاد بکەیت، کە خۆت بەگونجاوی دەزانیت.
-
-بیری لێ بکەرەوە وەک [Tailwind](https://tailwindcss.com/) بۆ جاڤاسکریپت.
-
-> تێبینی: سینتاکسی ئەم توڵئامرازە بە تەواوی وەرگیراوە لە [Vue](https://vuejs.org/) (هەروەها بەشێک لە [Angular](https://angularjs.org/)). من بۆ هەمیشە سوپاسگوزاری ئەو دیارییەی ئەوانم بۆ وێب
-
-## بەڵگەنامە وەرگێڕدراوەکان
-
-| زمان | بەستەر بۆ بەڵگەنامە |
-| --- | --- |
-| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Chinese Simplified | [**简体中文文档**](./README.zh-CN.md) |
-| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
-| Kurdish (Sorani) Traditional | [**بەڵگەنامە بەزمانی کوردیی**](./README.zh-TW.md) |
-| German | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanese | [**日本語ドキュメント**](./README.ja.md) |
-| Norwegian | [**Dokumentasjon på norsk**](./README.no.md) |
-| Portuguese | [**Documentação em Português**](./README.pt.md) |
-| Russian | [**Документация на русском**](./README.ru.md) |
-| Spanish | [**Documentación en Español**](./README.es.md) |
-| Turkish | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| Français | [**Documentation en Français**](./README.fr.md) |
-| Korean | [**한국어 문서**](./README.ko.md) |
-
-## دامەزراندن
-
-**بە بەکارهێنانی CDN:** ئەم سکریپتەی خوارەوە زیاد بکە بۆ بڕگەی `<head>`.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-تەنها هەر ئەوەیە. خۆی دەست پێ دەکات.
-
-بۆ ژینگەی بەرهەمهێنان، پێشنیار دەکرێت ژمارەیەکی وەشانێکی دیاریکراو لە بەستەرەکەدا جێگیر بکرێت، بۆئەوەی لە شکانێکی چاوەڕوان نەکراو لە وەشانەکانی نوێتر دوور بێت.
-بۆ نموونە، بۆ بەکارهێنانی وەشانی `2.8.2` (دواترین):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**بە بەکارهێنانی npm:** دامەزراندنی گورزەکە لە npm.
-```js
-npm i alpinejs
-```
-
-بیخەرە ناو سکریپتەکەتەوە.
-```js
-import 'alpinejs'
-```
-
-**بۆ پاڵپشتی IE11** لەجیاتی ئەوە ئەم سکریپتانە بەکاربهێنە.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-ئەو نمونەی سەرەوە [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) دەبێتە هۆی ئەوەی کە بە شێوەیەکی خۆکارانە لە وێبگەڕە هاوچەرخەکان باربکرێت و ئەو چەپکە بە خۆکارانە لەسەر IE11 و وێبگەڕە میراتیەکانی تر بارکراوە.
-## بەکارهێنان
-
-*Dropdown/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*Tabs*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-تەنانەت دەتوانیت بەکاری بهێنیت بۆ شتە بێ بەهاکان(none-triviale):
-*Pre-fetching a dropdown's HTML content on hover.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## فێربوون
-
-١٤ فەرمان بەردەستە بۆ بەکارهێنان:
-
-| فەرمان | باسکردن |
-| --- | --- |
-| [`x-data`](#x-data) | ڕاگەیاندنی پێکهاتەیەکی نوێی بوار (scope) |
-| [`x-init`](#x-init) | دەربڕینێک ئیش پێدەکات کاتێک پێکهاتەیەک دەست پێ دەکات. |
-| [`x-show`](#x-show) | دەستەبەری `display: none;` لەسەر توخمەکە پشت دەبەستێت بە دەربڕینی (true or false). |
-| [`x-bind`](#x-bind) | بەهای تایبەتمەندییەک  (attribute) بۆ ئەنجامی دەربڕینی JS دادەنێت. |
-| [`x-on`](#x-on) | گوێگری ڕووداو (event listener) بە توخمەکەوە (element) گرێ دەدات. جێبەجێکردنی دەربڕینی JS کاتێک نێردرا. |
-| [`x-model`](#x-model) | زیادکردنی "two-way data binding" بۆ توخمێک (element). ڕاگرتنی دەرخواردەی توخم لەناو هاوکاتکردن(sync) لەگەڵ داتای پێکهاتە. |
-| [`x-text`](#x-text) | بەهەمانشێوە کاردەکات بۆ `x-bind`, بەڵام دەق نوێ دەکاتەوە بۆ `innerText` لەناو توخمێک. |
-| [`x-html`](#x-html) | بەهەمانشێوە کاردەکات بۆ `x-bind`, بەڵام دەق نوێ دەکاتەوە بۆ `innerHTML` لەناو توخمێک. |
-| [`x-ref`](#x-ref) | ڕێگەیەکی گونجاو بۆ گەڕاندنەوەی توخمە خاوەکانی DOM لە دەرەوەی پێکهاتەکەت. |
-| [`x-if`](#x-if) | توخمێک بە تەواوی لە DOM دەسڕێتەوە. پێویستە لەسەر تاگی '<template>' بەکاربهێنرێت. |
-| [`x-for`](#x-for) | دروستکردنی گرێی نوێی DOM بۆ هەر دانەیەک لە ریزێک. پێویستە لەسەر تاگی '<template>' بەکاربهێنرێت. |
-| [`x-transition`](#x-transition) | رێنیشاندەر بۆ جێبەجێکردنی پۆلەکان بۆ چەند قۆناغی جیاواز لە گواستنەوەی توخمێک |
-| [`x-spread`](#x-spread) | ڕێگەت پێدەدات بۆ ئەوەی ئامانجێک ببەستیت لە Apline بە توخمێک بۆ توانای باشتر. |
-| [`x-cloak`](#x-cloak) | ئەم تایبەتمەندیە لادەبرێت کاتێک Apline دەست پێ دەکات. بەسوودە بۆ شاردنەوەی DOM ی پێش ئامادەکراو. |
-
-هەروەها ٦ تایبەتمەندی جادوویی:
-
-| تایبەتمەندییە جادووییەکان | پێناسە |
-| --- | --- |
-| [`$el`](#el) |  گەڕاندنەوەی ڕەگی پێکهاتەی گرێی DOM. |
-| [`$refs`](#refs) | گەڕاندنەوەی توخمە دیاریکراوەکانی DOM لەگەڵ `x-ref` لەناو پێکهاتەیەک. |
-| [`$event`](#event) | Retrieve the native browser "Event" object within an event listener.  |
-| [`$dispatch`](#dispatch) | Create a `CustomEvent` and dispatch it using `.dispatchEvent()` internally. |
-| [`$nextTick`](#nexttick) | Execute a given expression AFTER Alpine has made its reactive DOM updates. |
-| [`$watch`](#watch) | Will fire a provided callback when a component property you "watched" gets changed. |
-
-
-## Sponsors
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Want your logo here? [DM on Twitter](https://twitter.com/calebporzio)**
-
-## Community Projects
-
-* [Alpine Devtools](https://github.com/HugoDF/alpinejs-devtools)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Alpine Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-
-### Directives
-
----
-
-### `x-data`
-
-**نمونە:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Structure:** `<div x-data="[object literal]">...</div>`
-
-`x-data` declares a new component scope. It tells the framework to initialize a new component with the following data object.
-
-Think of it like the `data` property of a Vue component.
-
-**Extract Component Logic**
-
-You can extract data (and behavior) into reusable functions:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **For bundler users**, note that Alpine.js accesses functions that are in the global scope (`window`), you'll need to explicitly assign your functions to `window` in order to use them with `x-data` for example `window.dropdown = function () {}` (this is because with Webpack, Rollup, Parcel etc. `function`'s you define will default to the module's scope not `window`).
-
-
-You can also mix-in multiple data objects using object destructuring:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**نمونە:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Structure:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` runs an expression when a component is initialized.
-
-If you wish to run code AFTER Alpine has made its initial updates to the DOM (something like a `mounted()` hook in VueJS), you can return a callback from `x-init`, and it will be run after:
-
-`x-init="() => { // we have access to the post-dom-initialization state here // }"`
-
----
-
-### `x-show`
-**نمونە:** `<div x-show="open"></div>`
-
-**Structure:** `<div x-show="[expression]"></div>`
-
-`x-show` toggles the `display: none;` style on the element depending if the expression resolves to `true` or `false`.
-
-**x-show.transition**
-
-`x-show.transition` is a convenience API for making your `x-show`s more pleasant using CSS transitions.
-
-```html
-<div x-show.transition="open">
-    These contents will be transitioned in and out.
-</div>
-```
-
-| Directive | Description |
-| --- | --- |
-| `x-show.transition` | A simultaneous fade and scale. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Only transition in. |
-| `x-show.transition.out` | Only transition out. |
-| `x-show.transition.opacity` | Only use the fade. |
-| `x-show.transition.scale` | Only use the scale. |
-| `x-show.transition.scale.75` | Customize the CSS scale transform `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Sets the "in" transition to 200ms. The out will be set to half that (100ms). |
-| `x-show.transition.origin.top.right` | Customize the CSS transform origin `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Different durations for "in" and "out". |
-
-> Note: All of these transition modifiers can be used in conjunction with each other. This is possible (although ridiculous lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Note: `x-show` will wait for any children to finish transitioning out. If you want to bypass this behavior, add the `.immediate` modifier:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Note: You are free to use the shorter ":" syntax: `:type="..."`.
-
-**نمونە:** `<input x-bind:type="inputType">`
-
-**Structure:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` sets the value of an attribute to the result of a JavaScript expression. The expression has access to all the keys of the component's data object, and will update every-time its data is updated.
-
-> Note: attribute bindings ONLY update when their dependencies update. The framework is smart enough to observe data changes and detect which bindings care about them.
-
-**`x-bind` for class attributes**
-
-`x-bind` behaves a little differently when binding to the `class` attribute.
-
-For classes, you pass in an object whose keys are class names, and values are boolean expressions to determine if those class names are applied or not.
-
-For example:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-In this example, the "hidden" class will only be applied when the value of the `foo` data attribute is `true`.
-
-**`x-bind` for boolean attributes**
-
-`x-bind` supports boolean attributes in the same way as value attributes, using a variable as the condition or any JavaScript expression that resolves to `true` or `false`.
-
-For example:
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- When myVar == true: -->
-<button disabled="disabled">Click me</button>
-
-<!-- When myVar == false: -->
-<button>Click me</button>
-```
-
-This will add or remove the `disabled` attribute when `myVar` is true or false respectively.
-
-Boolean attributes are supported as per the [HTML specification](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), for example `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-> Note: If you need a false state to show for your attribute, such as `aria-*`, chain `.toString()` to the value while binding to the attribute. For example: `:aria-expanded="isOpen.toString()"` would persist whether  `isOpen` was `true` or `false`.
-
-**`.camel` modifier**
-**نمونە:** `<svg x-bind:view-box.camel="viewBox">`
-
-The `camel` modifier will bind to the camel case equivalent of the attribute name. In the example above, the value of `viewBox` will be bound the `viewBox` attribute as opposed to the `view-box` attribute.
-
----
-
-### `x-on`
-
-> Note: You are free to use the shorter "@" syntax: `@click="..."`.
-
-**نمونە:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Structure:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` attaches an event listener to the element it's declared on. When that event is emitted, the JavaScript expression set as its value is executed. You can use `x-on` with any event available for the element you're adding the directive on, for a full list of events, see [the Event reference on MDN](https://developer.mozilla.org/en-US/docs/Web/Events) for a list of possible values.
-
-If any data is modified in the expression, other element attributes "bound" to this data, will be updated.
-
-> Note: You can also specify a JavaScript function name.
-
-**نمونە:** `<button x-on:click="myFunction"></button>`
-
-This is equivalent to: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` modifiers**
-
-**نمونە:** `<input type="text" x-on:keydown.escape="open = false">`
-
-You can specify specific keys to listen for using keydown modifiers appended to the `x-on:keydown` directive. Note that the modifiers are kebab-cased versions of `Event.key` values.
-
-نمونەکان: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Note: You can also listen for system-modifier key combinations like: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` modifier**
-
-**نمونە:** `<div x-on:click.away="showModal = false"></div>`
-
-When the `.away` modifier is present, the event handler will only be executed when the event originates from a source other than itself, or its children.
-
-This is useful for hiding dropdowns and modals when a user clicks away from them.
-
-**`.prevent` modifier**
-**نمونە:** `<input type="checkbox" x-on:click.prevent>`
-
-Adding `.prevent` to an event listener will call `preventDefault` on the triggered event. In the above example, this means the checkbox wouldn't actually get checked when a user clicks on it.
-
-**`.stop` modifier**
-**نمونە:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Adding `.stop` to an event listener will call `stopPropagation` on the triggered event. In the above example, this means the "click" event won't bubble from the button to the outer `<div>`. Or in other words, when a user clicks the button, `foo` won't be set to `'bar'`.
-
-**`.self` modifier**
-**نمونە:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Adding `.self` to an event listener will only trigger the handler if the `$event.target` is the element itself. In the above example, this means the "click" event that bubbles from the button to the outer `<div>` will **not** run the handler.
-
-**`.window` modifier**
-**نمونە:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Adding `.window` to an event listener will install the listener on the global window object instead of the DOM node on which it is declared. This is useful for when you want to modify component state when something changes with the window, like the resize event. In this example, when the window grows larger than 768 pixels wide, we will close the modal/dropdown, otherwise maintain the same state.
-
->Note: You can also use the `.document` modifier to attach listeners to `document` instead of `window`
-
-**`.once` modifier**
-**نمونە:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Adding the `.once` modifier to an event listener will ensure that the listener will only be handled once. This is useful for things you only want to do once, like fetching HTML partials and such.
-
-**`.passive` modifier**
-**نمونە:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Adding the `.passive` modifier to an event listener will make the listener a passive one, which means `preventDefault()` will not work on any events being processed, this can help, for example with scroll performance on touch devices.
-
-**`.debounce` modifier**
-**نمونە:** `<input x-on:input.debounce="fetchSomething()">`
-
-The `debounce` modifier allows you to "debounce" an event handler. In other words, the event handler will NOT run until a certain amount of time has elapsed since the last event that fired. When the handler is ready to be called, the last handler call will execute.
-
-The default debounce "wait" time is 250 milliseconds.
-
-If you wish to customize this, you can specify a custom wait time like so:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` modifier**
-**نمونە:** `<input x-on:event-name.camel="doSomething()">`
-
-The `camel` modifier will attach an event listener for the camel case equivalent event name. In the example above, the expression will be evaluated when the `eventName` event is fired on the element.
-
----
-
-### `x-model`
-**نمونە:** `<input type="text" x-model="foo">`
-
-**Structure:** `<input type="text" x-model="[data item]">`
-
-`x-model` adds "two-way data binding" to an element. In other words, the value of the input element will be kept in sync with the value of the data item of the component.
-
-> Note: `x-model` is smart enough to detect changes on text inputs, checkboxes, radio buttons, textareas, selects, and multiple selects. It should behave [how Vue would](https://vuejs.org/v2/guide/forms.html) in those scenarios.
-
-**`.number` modifier**
-**نمونە:** `<input x-model.number="age">`
-
-The `number` modifier will convert the input's value to a number. If the value cannot be parsed as a valid number, the original value is returned.
-
-**`.debounce` modifier**
-**نمونە:** `<input x-model.debounce="search">`
-
-The `debounce` modifier allows you to add a "debounce" to a value update. In other words, the event handler will NOT run until a certain amount of time has elapsed since the last event that fired. When the handler is ready to be called, the last handler call will execute.
-
-The default debounce "wait" time is 250 milliseconds.
-
-If you wish to customize this, you can specify a custom wait time like so:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**نمونە:** `<span x-text="foo"></span>`
-
-**Structure:** `<span x-text="[expression]"`
-
-`x-text` works similarly to `x-bind`, except instead of updating the value of an attribute, it will update the `innerText` of an element.
-
----
-
-### `x-html`
-**نمونە:** `<span x-html="foo"></span>`
-
-**Structure:** `<span x-html="[expression]"`
-
-`x-html` works similarly to `x-bind`, except instead of updating the value of an attribute, it will update the `innerHTML` of an element.
-
-> :warning: **Only use on trusted content and never on user-provided content.** :warning:
->
-> Dynamically rendering HTML from third parties can easily lead to [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) vulnerabilities.
-
----
-
-### `x-ref`
-**نمونە:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Structure:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` provides a convenient way to retrieve raw DOM elements out of your component. By setting an `x-ref` attribute on an element, you are making it available to all event handlers inside an object called `$refs`.
-
-This is a helpful alternative to setting ids and using `document.querySelector` all over the place.
-
-> Note: you can also bind dynamic values for x-ref: `<span :x-ref="item.id"></span>` if you need to.
-
----
-
-### `x-if`
-**نمونە:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Structure:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-For cases where `x-show` isn't sufficient (`x-show` sets an element to `display: none` if it's false), `x-if` can be used to  actually remove an element completely from the DOM.
-
-It's important that `x-if` is used on a `<template></template>` tag because Alpine doesn't use a virtual DOM. This implementation allows Alpine to stay rugged and use the real DOM to work its magic.
-
-> Note: `x-if` must have a single root element inside the `<template></template>` tag.
-
-> Note: When using `template` in a `svg` tag, you need to add a [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) that should be run before Alpine.js is initialized.
-
----
-
-### `x-for`
-**نمونە:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Note: the `:key` binding is optional, but HIGHLY recommended.
-
-`x-for` is available for cases when you want to create new DOM nodes for each item in an array. This should appear similar to `v-for` in Vue, with one exception of needing to exist on a `template` tag, and not a regular DOM element.
-
-If you want to access the current index of the iteration, use the following syntax:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- You can also reference "index" inside the iteration if you need. -->
-    <div x-text="index"></div>
-</template>
-```
-
-If you want to access the array object (collection) of the iteration, use the following syntax:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <div>
-        <!-- You can also reference "collection" inside the iteration if you need. -->
-        <!-- Current item. -->
-        <div x-text="item"></div>
-        <!-- Same as above. -->
-        <div x-text="collection[index]"></div>
-        <!-- Previous item. -->
-        <div x-text="collection[index - 1]"></div>
-    </div>
-</template>
-```
-
-> Note: `x-for` must have a single root element inside of the `<template></template>` tag.
-
-> Note: When using `template` in a `svg` tag, you need to add a [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) that should be run before Alpine.js is initialized.
-
-#### Nesting `x-for`s
-You can nest `x-for` loops, but you MUST wrap each loop in an element. For example:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Iterating over a range
-
-Alpine supports the `i in n` syntax, where `n` is an integer, allowing you to iterate over a fixed range of elements.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**نمونە:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> The example above uses classes from [Tailwind CSS](https://tailwindcss.com).
-
-Alpine offers 6 different transition directives for applying classes to various stages of an element's transition between "hidden" and "shown" states. These directives work both with `x-show` AND `x-if`.
-
-These behave exactly like VueJS's transition directives, except they have different, more sensible names:
-
-| Directive | Description |
-| --- | --- |
-| `:enter` | Applied during the entire entering phase. |
-| `:enter-start` | Added before element is inserted, removed one frame after element is inserted. |
-| `:enter-end` | Added one frame after element is inserted (at the same time `enter-start` is removed), removed when transition/animation finishes.
-| `:leave` | Applied during the entire leaving phase. |
-| `:leave-start` | Added immediately when a leaving transition is triggered, removed after one frame. |
-| `:leave-end` | Added one frame after a leaving transition is triggered (at the same time `leave-start` is removed), removed when the transition/animation finishes.
-
----
-
-### `x-spread`
-**نمونە:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` allows you to extract an element's Alpine bindings into a reusable object.
-
-The object keys are the directives (Can be any directive including modifiers), and the values are callbacks to be evaluated by Alpine.
-
-> Note: There are a couple of caveats to x-spread:
-> - When the directive being "spread" is `x-for`, you should return a normal expression string from the callback. For example: `['x-for']() { return 'item in items' }`.
-> - `x-data` and `x-init` can't be used inside a "spread" object.
-
----
-
-### `x-cloak`
-**نمونە:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. It's typical to add the following global style for this to work:
-
-```html
-<style>
-    [x-cloak] {
-        display: none !important;
-    }
-</style>
-```
-
-### Magic Properties
-
-> With the exception of `$el`, magic properties are **not available within `x-data`** as the component isn't initialized yet.
-
----
-
-### `$el`
-**نمونە:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
-</div>
-```
-
-`$el` is a magic property that can be used to retrieve the root component DOM node.
-
-### `$refs`
-**نمونە:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` is a magic property that can be used to retrieve DOM elements marked with `x-ref` inside the component. This is useful when you need to manually manipulate DOM elements.
-
----
-
-### `$event`
-**نمونە:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` is a magic property that can be used within an event listener to retrieve the native browser "Event" object.
-
-> Note: The $event property is only available in DOM expressions.
-
-If you need to access $event inside of a JavaScript function you can pass it in directly:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**نمونە:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- When clicked, will console.log "bar" -->
-</div>
-```
-
-**Note on Event Propagation**
-
-Notice that, because of [event bubbling](https://en.wikipedia.org/wiki/Event_bubbling), when you need to capture events dispatched from nodes that are under the same nesting hierarchy, you'll need to use the [`.window`](https://github.com/alpinejs/alpine#x-on) modifier:
-
-**نمونە:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> This won't work because when `custom-event` is dispatched, it'll propagate to its common ancestor, the `div`.
-
-**Dispatching to Components**
-
-You can also take advantage of the previous technique to make your components talk to each other:
-
-**نمونە:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- When clicked, will console.log "Hello World!". -->
-```
-
-`$dispatch` is a shortcut for creating a `CustomEvent` and dispatching it using `.dispatchEvent()` internally. There are lots of good use cases for passing data around and between components using custom events. [Read here](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) for more information on the underlying `CustomEvent` system in browsers.
-
-You will notice that any data passed as the second parameter to `$dispatch('some-event', { some: 'data' })`, becomes available through the new events "detail" property: `$event.detail.some`. Attaching custom event data to the `.detail` property is standard practice for `CustomEvent`s in browsers. [Read here](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) for more info.
-
-You can also use `$dispatch()` to trigger data updates for `x-model` bindings. For example:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- After the button is clicked, `x-model` will catch the bubbling "input" event, and update foo to "baz". -->
-    </span>
-</div>
-```
-
-> Note: The $dispatch property is only available in DOM expressions.
-
-If you need to access $dispatch inside of a JavaScript function you can pass it in directly:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**نمونە:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` is a magic property that allows you to only execute a given expression AFTER Alpine has made its reactive DOM updates. This is useful for times you want to interact with the DOM state AFTER it's reflected any data updates you've made.
-
----
-
-### `$watch`
-**نمونە:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-You can "watch" a component property with the `$watch` magic method. In the above example, when the button is clicked and `open` is changed, the provided callback will fire and `console.log` the new value.
-
-## Security
-If you find a security vulnerability, please send an email to [calebporzio@gmail.com]().
-
-Alpine relies on a custom implementation using the `Function` object to evaluate its directives. Despite being more secure then `eval()`, its use is prohibited in some environments, such as Google Chrome App, using restrictive Content Security Policy (CSP).
-
-If you use Alpine in a website dealing with sensitive data and requiring [CSP](https://csp.withgoogle.com/docs/strict-csp.html), you need to include `unsafe-eval` in your policy. A robust policy correctly configured will help protecting your users when using personal or financial data.
-
-Since a policy applies to all scripts in your page, it's important that other external libraries included in the website are carefully reviewed to ensure that they are trustworthy and they won't introduce any Cross Site Scripting vulnerability either using the `eval()` function or manipulating the DOM to inject malicious code in your page.
-
-## V3 Roadmap
-* Move from `x-ref` to `ref` for Vue parity?
-* Add `Alpine.directive()`
-* Add `Alpine.component('foo', {...})` (With magic `__init()` method)
-* Dispatch Alpine events for "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Remove "object" (and array) syntax from `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) to add support for object syntax for the `style` attribute)
-* Improve `x-for` mutation reactivity ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Add "deep watching" support in V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Add `$el` shortcut
-* Change `@click.away` to `@click.outside`?
-
-## License
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.
-
-</div>

+ 0 - 795
README.de.md

@@ -1,795 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js bietet dir die gewohnte Reaktivität und deklarative Natur von Vue und React, verzichtet jedoch auf den gegebenen Ballast, der bei solchen Frameworks anfallen kann.
-
-Du erweiterst dein DOM nur dort um zusätzliche Funktionalität, wo du es für richtig hältst.
-
-Unsere Philosophie erinnert dich vielleicht an [Tailwind](https://tailwindcss.com/), nur eben für Javascript.
-
-> Hinweis: Alpines Syntax baut fast gänzlich auf der Syntax von [Vue](https://vuejs.org/) auf (zum Teil auch von [Angular](https://angularjs.org/)). Ich bin für immer dankbar für den Mehrwert, den diese Frameworks der Entwicklung des Webs gebracht haben.
-
-## Übersetzungen der Dokumentation
-
-| Sprache | Link zur Dokumentation |
-| --- | --- |
-| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Chinesisch Vereinfacht | [**简体中文文档**](./README.zh-CN.md) |
-| Chinesisch Traditionell | [**繁體中文說明文件**](./README.zh-TW.md) |
-| Deutsch | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesisch | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanisch | [**日本語ドキュメント**](./README.ja.md) |
-| Norwegisch | [**Dokumentasjon på norsk**](./README.no.md) |
-| Portugiesisch | [**Documentação em Português**](./README.pt.md) |
-| Russisch | [**Документация на русском**](./README.ru.md) |
-| Spanisch | [**Documentación en Español**](./README.es.md) |
-| Türkisch | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| Französisch | [**Documentation en Français**](./README.fr.md) |
-| Koreanisch | [**한국어 문서**](./README.ko.md) |
-
-## Installation
-
-**Von einem CDN:** Erweitere deinen HTML-Kopf (`<head>`) um folgendes Skript.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-Das wars. Die Initialisierung passiert automatisch.
-
-Für die Produktionsumgebung wird empfohlen, den Link mit einer spezifischen Versionsnummer zu versehen. Somit kann präventiv sichergestellt werden, dass keine unerwarteten Fehler durch Versionsaktualisierungen zustande kommen.
-Als Beispiel wird hier die (letzte) Version `2.8.2` spezifiziert:
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Über npm:** Installiere das Paket über npm.
-```js
-npm i alpinejs
-```
-
-Inkludiere es in deinem Skript.
-```js
-import 'alpinejs'
-```
-
-**Für IE11 Support** Nutze stattdessen die folgenden Skripts.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-Da obige Schema wird als [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) bezeichnet. Dadurch wird bezweckt, dass in modernen Browsern automatisch das "modern"-Bundle geladen wird, und das IE11-spezifische Bundle automatisch in IE11 und anderen "legacy"-Browsern geladen wird.
-
-## Use
-
-*Dropdown/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Öffne Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Inhalt
-    </ul>
-</div>
-```
-
-*Tabs*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-Du kannst es sogar für nicht-triviale Dinge verwenden:
-*Pre-fetching a dropdown's HTML content on hover*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Zeige Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Lade Spinner...
-    </div>
-</div>
-```
-
-## Lerne
-
-Es stehen 14 Direktiven zur Verfügung:
-
-| Direktive | Beschreibung |
-| --- | --- |
-| [`x-data`](#x-data) | Deklariert einen neuen Komponenten-Geltungsbereich. |
-| [`x-init`](#x-init) | Wertet einen Ausdruck aus, sobald die Komponente initialisiert wurde. |
-| [`x-show`](#x-show) | Schaltet anhand des Ausdrucks (true oder false) das Element auf `display: none;`. |
-| [`x-bind`](#x-bind) | Setzt den Wert eines Attributs auf das Ergebnis eines JS-Ausdrucks. |
-| [`x-on`](#x-on) | Verbindet einen EventHandler mit einem HTML-Element. Der spezifizierte JS-Code wird nur dann aufgerufen, wenn das jeweilige Ereignis empfangen wird. |
-| [`x-model`](#x-model) | Das Direktive sorgt für das Databinding mit Input-Elementen. Hierbei wird ein Databinding in beide Richtungen ermöglicht ("Two way databinding"). |
-| [`x-text`](#x-text) | Funktioniert ähnlich wie `x-bind`, wobei hier das `innerText` eines Elements aktualisiert wird. |
-| [`x-html`](#x-html) | Funktioniert ähnlich wie `x-bind`, wobei hier das `innerHTML` eines Elements aktualisiert wird. |
-| [`x-ref`](#x-ref) | Ermöglicht es, die Elemente einer Komponente im DOM zu referenzieren. |
-| [`x-if`](#x-if) | Entfernt ein Element aus dem DOM. Kann nur in Kombination mit `<template>`-Tags benutzt werden. |
-| [`x-for`](#x-for) | Erstellt einen neuen DOM-Knoten (node) für jedes Element in einem Array. Kann nur in Kombination mit `<template>`-Tags benutzt werden. |
-| [`x-transition`](#x-transition) | Ein Direktive zur Anwendung von Klassen auf unterschiedliche Phasen der Transition eines Elements. |
-| [`x-spread`](#x-spread) | Ermöglicht die Bindung von einem Objekt aus Alpine Direktiven an ein Element. Dies erlaubt eine bessere Wiederverwendbarkeit von Direktiven. |
-| [`x-cloak`](#x-cloak) | Dieses Attribut wird entfernt, sobald Alpine initialisiert wird. Das Direktive wird genutzt, um das pre-initialisierte DOM auszublenden. |
-
-
-Und 6 magische Eigenschaften (englisch *magic properties*):
-
-| Magische Eigenschaft | Beschreibung |
-| --- | --- |
-| [`$el`](#el) | Liefert den DOM-Knoten der Stammkomponente. |
-| [`$refs`](#refs) | Liefert jene Elemente des DOM innerhalb der Komponente, welche mit `x-ref` markiert sind. |
-| [`$event`](#event) | Liefert das native "Event"-Objekt innerhalb eines EventHandlers.  |
-| [`$dispatch`](#dispatch) | Erstellt ein `CustomEvent`, welches intern via `.dispatchEvent()` versendet werden kann. |
-| [`$nextTick`](#nexttick) | Führt den gegebenen Ausdruck aus, NACHDEM Alpine die reaktiven DOM-Aktualisierungen durchgeführt hat. |
-| [`$watch`](#watch) | Wenn sich der Wert einer beobachteten (englisch *watched*) Eigenschaft einer Komponente ändert, wird die angegebene Callback-Funktion aufgerufen. |
-
-
-## Sponsoren
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Du möchtest Sponsor werden? [Schreib mir auf Twitter](https://twitter.com/calebporzio)**
-
-## Gemeinschaftsprojekte
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### Direktiven
-
----
-
-### `x-data`
-
-**Beispiel:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Struktur:** `<div x-data="[JSON data object]">...</div>`
-
-`x-data` deklariert einen neuen Komponenten-Geltungsbereich. Jede neu erstellte Komponente wird nun mit der angegebenen Datenquelle initialisiert.
-
-Dies verhält sich ähnlich wie die `data`-Eigenschaft einer Vue-Komponente.
-
-**Extrahieren von Komponenten-Logik**
-
-Datenquellen und zugehörige Funktionalität können in wiederverwendbare Funktionen extrahiert werden.
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Öffne</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Für Nutzer von Modul-Packern**: Alpine.js ruft Funktionen auf, welche sich im globalen Geltungsbereich (`window`) befinden. Um Funktionen mit `x-data` zu benutzen, müssen sie daher explizit dem Geltungsbereich `window` zugewiesen werden. Zum Beispiel `window.dropdown = function () {}` (Dieses Verhalten ist auf Webpack, Rollup, Parcel etc. zurückzuführen. Hier leben selbstdefinierte Funktionen defaultmäßig im Geltungsbereich des Moduls, und nicht `window`).
-
-Durch Objektdestrukturierung können mehrere Datenobjekte an `x-data` übergeben werden:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Beispiel:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Struktur:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` Wertet einen Ausdruck aus, sobald die Komponente initialisiert wurde.
-
-Wenn der Code erst aufgerufen werden soll, NACHDEM Alpine die initialen Aktualisierungen des DOM vorgenommen hat (ähnlich zum `mounted()` Lebenszyklus in VueJS), kann eine Callback-Funktion von `x-init` retourniert werden:
-
-`x-init="() => { // Im Funktionsblock haben wir Zugriff auf den Zustand nach der DOM-Initialisierung // }"`
-
----
-
-### `x-show`
-**Beispiel:** `<div x-show="open"></div>`
-
-**Struktur:** `<div x-show="[expression]"></div>`
-
-`x-show` schaltet die Eigenschaft `display: none;` des Elements, je nachdem ob der Ausdruck `true` oder `false` zurückliefert.
-
-**x-show.transition**
-
-`x-show.transition` ist eine convenience API, um Übergänge mit `x-show` durch CSS Transitionen ansprechender zu gestalten.
-
-```html
-<div x-show.transition="open">
-    Die Inhalte werden mithilfe von Transitionen ein- und ausgeblendet.
-</div>
-```
-
-| Direktive | Beschreibung |
-| --- | --- |
-| `x-show.transition` | Ein simultaner Fading- und Skalierungseffekt. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Die Transition gilt nur für den anfänglichen Übergang. |
-| `x-show.transition.out` | Die Transition gilt nur für den abschließenden Übergang. |
-| `x-show.transition.opacity` | Nur das Fading wird genutzt. |
-| `x-show.transition.scale` | Nur die Skalierung wird genutzt. |
-| `x-show.transition.scale.75` | Zur Anpassung des Skalierungswerts `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Setzt den Wert der anfänglichen Transition auf 200ms. Der Wert der abschließenden Transition nimmt die Hälfte des angegebenen Werts an (in diesem Fall 100ms). |
-| `x-show.transition.origin.top.right` | Zur Anpassung des Ursprungs der CSS-Transformation `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Zur Spezifizierung der einzelnen Dauern einer Transition. |
-
-> Hinweis: Alle oben genannten Modifikatoren können miteinander kombiniert werden. Auch solche Spielerein sind möglich (lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Hinweis: Defaultmäßig wartet `x-show`, bis jede untergeordnete Komponente seine Transition beendet hat. Um dieses Verhalten zu umgehen, kann der Modifikator `.immediate` eingesetzt werden:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Hinweis: Es kann auch folgende Kurzschreibweise genutzt werden: `:type="..."`
-
-**Beispiel:** `<input x-bind:type="inputType">`
-
-**Struktur:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` setzt den Wert eines Attributs auf das Ergebnis eines JavaScript Ausdrucks. Dabei hat der Ausdruck Zugang zu allen Datenquellen der Komponente und wird jedes Mal aktualisiert, wenn sich eine der Datenquellen ändert.
-
-> Hinweis: Attributbindungen aktualisieren sich nur dann, WENN sich deren Abhängigkeiten aktualisieren. Das Framework erkennt solche Abhängigkeiten automatisch und führt dementsprechend Aktualisierungen durch.
-
-**`x-bind` für Klassenattribute**
-
-`x-bind` hat eine spezielle Verhaltensweise, wenn es mit dem Attribut `class` verknüpft wird.
-
-Hierbei wird ein Objekt übergeben, dessen Namen die potenziellen Klassenselektoren sind. Die Werte dieser Paare sind boolesche Ausdrücke, durch welche determiniert wird, ob die Klasse auf das Element angewendet wird oder nicht.
-
-Zum Beispiel:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-In diesem Beispiel wird die Klasse "hidden" nur dann angewendet, wenn `foo` den Wert `true` liefert.
-
-**`x-bind` für boolesche Attribute**
-
-`x-bind` unterstützt sowohl Variablen als auch JavaScript Ausdrücke in seiner Bedingung, wenn diese einen booleschen Wert (`true` oder `false`) zurückliefern.
-
-Zum Beispiel:
-```html
-<!-- Gegeben: -->
-<button x-bind:disabled="myVar">Klick mich</button>
-
-<!-- Wenn myVar == true: -->
-<button disabled="disabled">Klick mich</button>
-
-<!-- Wenn myVar == false: -->
-<button>Klick mich</button>
-```
-
-Hier wird das Attribut `disabled` je nach der Auswertung von `myVar` hinzugefügt oder entfernt.
-
-
-Alle in der [HTML Spezifikation](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute) angeführten booleschen Attribute werden unterstützt. Dazu zählen `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-**`.camel` Modifikator**
-**Beispiel:** `<svg x-bind:view-box.camel="viewBox">`
-
-Mithilfe des Modifikators `camel` kann die Bedingung an die camel-case Schreibweise des angegebenen Attributnamens gebunden werden. In obigen Beispiel wird der Wert von `viewBox` mit dem Attribut `viewBox` (anstelle von `view-box`) verknüpft.
-
----
-
-### `x-on`
-
-> Hinweis: Es kann auch folgende Kurzschreibweise genutzt werden: `@click="..."`
-
-**Beispiel:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Struktur:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` bindet einen EventHandler an das HTML-Element. Der spezifizierte JavaScript-Ausdruck wird genau dann ausgewertet, wenn das Ereignis ausgelöst wurde.
-
-Andere Attribute des Elements welche an diese Datenquelle gebunden sind, werden aktualisiert, sobald Daten im Ausdruck modifiziert werden.
-
-> Hinweis: Wahlweise kann auch der Name einer JavaScript-Funktion angegeben werden
-
-**Beispiel:** `<button x-on:click="myFunction"></button>`
-
-Ist äquivalent zu: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` Modifikator**
-
-**Beispiel:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Um auf bestimmte Tastaturereignisse zu reagieren, können keydown-Modifikatoren an das Direktive `x-on:keydown` angehängt werden. Die Modifikatoren sind hierbei Werte von `Event.key`, jedoch in kebab-case-Schreibweise.
-
-Beispiele: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Hinweis: Zusätzlich kann auch auf System-Modifikator-Tastenkombinationen reagiert werden: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` Modifikator**
-
-**Beispiel:** `<div x-on:click.away="showModal = false"></div>`
-
-Durch die Nutzung des Modifikators `.away`, wird der Ausdruck eines EventHandlers nur dann ausgewertet, wenn das Ereignis nicht vom Element selbst (oder dessen untergeordnete Komponenten) ausgelöst wird.
-
-Dies kann zum Beispiel genutzt werden, um ein Dropdown-Menü oder ein Modal auszublenden, sobald der Nutzer außerhalb des Elements einen Mausklick durchführt.
-
-**`.prevent` Modifikator**
-**Beispiel:** `<input type="checkbox" x-on:click.prevent>`
-
-Durch das Anhängen von `.prevent` an einen EventHandler, wir die Methode `preventDefault` auf dem ausgelösten Ereignis ausgeführt. Im obigen Beispiel wird somit die native Funktionalität des `<input>`-Elements unterdrückt, wenn der Nutzer das Element anklickt.
-
-**`.stop` Modifikator**
-**Beispiel:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Durch das Anhängen von `.stop` an einen EventHandler, wird die Methode `stopPropagation` auf dem ausgelösten Ereignis ausgeführt. Klickt ein Nutzer im obigen Beispiel auf das `<button>`-Element, wird das Ereignis "click" nicht an das übergeordnete Element `<div>` gesendet. Anders gesagt wird im Falle eine Klicks `foo` nicht auf `'bar'` gesetzt.
-
-**`.self` Modifikator**
-**Beispiel:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Durch das Anhängen von `.self` an einen EventHandler, wird das Ereignis nur dann behandelt, wenn das `$event.target` das Element selbst ist. Klickt ein Nutzer im obigen Beispiel auf das `<button>`-Element, wird das Ereignis "click" somit **NICHT** im übergeordnete Element `<div>` behandelt.
-
-**`.window` Modifikator**
-**Beispiel:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Durch das Anhängen von `.window` an einen EventHandler, wird der Listener auf das globale Window-Objekt anstelle des zugrundeliegenden DOM-Knotens registriert. Dieses Vorgehen ist beispielsweise hilfreich, wenn du den Zustand einer Komponente modifizieren willst, sobald sich die Eigenschaften des Window-Objekts ändern (zB das Event "resize"). Im obigen Beispiel wird das Modal/Dropdown genau dann geschlossen, wenn die Breite des Window-Objekts 768 Pixel überschreitet. Andernfalls bleibt der momentante Zustand bestehen.
-
-> Hinweis: Nach dem selben Prinzup kann der Modifikator `.document` genutzt werden, um auf Änderungen im Document-Objekt zu reagieren.
-
-**`.once` Modifikator**
-**Beispiel:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Durch das Anhängen von `.once` an einen EventHandler wird sichergestellt, dass das Ereignis nur ein einziges Mal behandelt wird.
-
-**`.passive` Modifikator**
-**Beispiel:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Durch das Anhängen von `.passive` an einen EventHandler, wird der gegebene Listener passiv. Dadurch wird verhindert, dass das spezifizierte Ereignis abgebrochen werden kann (`preventDefault()` wird ignoriert). Dieses Vorgehen ist zum Beispiel für die Bildlaufleistung auf Touch-Geräten relevant.
-
-**`.debounce` Modifikator**
-**Beispiel:** `<input x-on:input.debounce="fetchSomething()">`
-
-Mithilfe des Modifikators `debounce` kann ein EventHandler "debounced" werden. Hiermit wird sichergestellt, dass das spezifizierte Ereignis nur dann behandelt wird, wenn eine gewisse Zeitspanne zum letzten Vorkommnis des Ereignisses vergangen ist. Erst wenn der Handler bereit ist, wird die Ereignisbehandlung ausgeführt.
-
-Die defaultmäßige Wartezeit beträgt 250 Millisekunden.
-
-Die Wartezeit kann folgendermaßen individualisiert werden:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` Modifikator**
-**Beispiel:** `<input x-on:event-name.camel="doSomething()">`
-
-Mithilfe des Modifikators `camel` kann ein EventHandler an die camel-case Schreibweise des angegebenen Ereignisnamens gebunden werden. Im obigen Beispiel wird der Ausdruck ausgewertet, sobald ein Ereignis namens `eventName` auf dem Element empfangen wird.
-
----
-
-### `x-model`
-**Beispiel:** `<input type="text" x-model="foo">`
-
-**Struktur:** `<input type="text" x-model="[data item]">`
-
-`x-model` erweitert ein Element um ein "two-way data binding" (d.h. Databinding ist in beide Richtungen möglich). Der Wert des `<input>`-Elements wird mit dem Wert der Komponenten-Datenquelle `item` synchronisiert.
-
-> Hinweis: `x-model` erkennt automatisch Änderungen auf den folgenden Elementen: text inputs, checkboxes, radio buttons, textareas, selects, multiple selects. In den genannten Szenarien sollte die Funktionsweise von `x-model` das [Verhalten von Vue](https://vuejs.org/v2/guide/forms.html) widerspiegeln.
-
-**`.number` Modifikator**
-**Beispiel:** `<input x-model.number="age">`
-
-Durch die Nutzung des Modifikators `number` wird der Wert des `<input>`-Elements in eine Zahl umgewandelt. Wenn der Wert hierbei nicht als valide Zahl ausgelesen werden kann, wird der ursprüngliche Wert retourniert.
-
-**`.debounce` Modifikator**
-**Beispiel:** `<input x-model.debounce="search">`
-
-Mithilfe des Modifikators `debounce` kann der Aktualisierung eines Wertes ein "debounce" hinzugefügt werden. Hiermit wird sichergestellt, dass das spezifizierte Ereignis nur dann behandelt wird, wenn eine gewisse Zeitspanne zum letzten Vorkommnis des Ereignisses vergangen ist. Erst wenn der Handler bereit ist, wird die Ereignisbehandlung ausgeführt.
-
-Die defaultmäßige Wartezeit beträgt 250 Millisekunden.
-
-Die Wartezeit kann folgendermaßen individualisiert werden:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Beispiel:** `<span x-text="foo"></span>`
-
-**Struktur:** `<span x-text="[expression]"`
-
-`x-text` funktioniert ähnlich wie `x-bind`, außer dass anstelle des Wertes eine Attributs, das `innerText` eines Elements aktualisiert wird.
-
----
-
-### `x-html`
-**Beispiel:** `<span x-html="foo"></span>`
-
-**Struktur:** `<span x-html="[expression]"`
-
-`x-html` funktioniert ähnlich wie `x-bind`, außer dass anstelle des Wertes eine Attributs, das `innerHTML` eines Elements aktualisiert wird.
-
-> :warning: **Es wird empfohlen, in diesem Fall nur vertrauenswürdige bzw. selbsterstellte Inhalte zu nutzen und auf nutzererstellte Inhalte zu verzichten.** :warning:
->
-> Dynamisch gerendertes HTML von Drittparteien kann leicht zu Sicherheitslücken wie [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) führen.
-
----
-
-### `x-ref`
-**Beispiel:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Struktur:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` Ermöglicht es, die Elemente einer Komponente im DOM zu referenzieren. Wird das Attribut `x-ref` auf ein Element gesetzt, wird das Element durch das `$refs`-Objekt für alle EventHandler verfügbar gemacht.
-
-Dieses Vorgehen präsentiert sich als hilfreiche Alternative, wenn vermehrt der Befehl `document.querySelector` zur Referenzierung von Elementen eingesetzt werden muss.
-
-> Hinweis: Auch dynamische Werte können an x-ref gebunden werden: `<span :x-ref="item.id"></span>`.
-
----
-
-### `x-if`
-**Beispiel:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Struktur:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-Falls die Funktionalität von `x-show` (`x-show` setzt ein Element auf `display: none`, wenn die Bedingung `false` liefert) nicht ausreichen sollte, kann stattdessen `x-if` genutzt werden, um ein Element vollständig aus dem DOM zu entfernen.
-
-Da Alpine über kein virtuelles DOM verfügt, muss `x-if` unbedingt mit `<template></template>`-Tags genutzt werden. Diese Implementierung erlaubt es Alpine stabil zu bleiben und auf das echte DOM zuzugreifen.
-
-> Hinweis: Im Zuge der Nutzung von `x-if` muss der HTML-Stammknoten innerhalb des `<template></template>`-Tags ein einzelnes Element sein.
-
-> Hinweis: Im Zuge der Nutzung von `template` innerhalb eines `svg`-Tags, muss auf ein [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) zurückgegriffen werden. Die Ausführung des polyfills sollte vor der Initialisierung von Alpine.js stattfinden.
-
----
-
-### `x-for`
-**Beispiel:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Hinweis: Das `:key`-Binding ist optional, wird jedoch DRINGEND empfohlen.
-
-`x-for` ist sinnvoll für Fälle, in denen für jedes Element in einem Array ein DOM-Knoten erstellt werden soll. Zwar erinnert die Funktionsweise an `v-for` in Vue, jedoch kann `x-for` nur in Kombination mit `template`-Tags eingesetzt werden (d.h. es besteht keine Kompatibilität mit regulären DOM-Elementen).
-
-Wird Zugriff auf den Index des momentanten Schleifendurchgangs benötigt, kann die folgende Schreibweise eingesetzt werden:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- Bei Bedarf kann "index" innerhalb der Schleife referenziert werden. -->
-    <div x-text="index"></div>
-</template>
-```
-
-Wird Zugriff auf das Array-Ojekt (colletion) des momentanten Schleifendurchgangs benötigt, kann die folgende Schreibweise eingesetzt werden:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- Bei Bedarf kann "collection" innerhalb der Schleife referenziert werden. -->
-    <!-- Momentanes Element (item). -->
-    <div x-text="item"></div>
-    <!-- Selbiges Element wie oben. -->
-    <div x-text="collection[index]"></div>
-    <!-- Element an der vorherigen Position. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> Hinweis: Im Zuge der Nutzung von `x-for` muss der HTML-Stammknoten innerhalb des `<template></template>`-Tags ein einzelnes Element sein.
-
-> Hinweis: Im Zuge der Nutzung von `template` innerhalb eines `svg`-Tags, muss auf ein [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) zurückgegriffen werden. Die Ausführung des polyfills sollte vor der Initialisierung von Alpine.js stattfinden.
-
-#### Verschachteln von `x-for`-Schleifen
-`x-for`-Schleifen können verschachtelt werden, jedoch MUSS jede Schleife innerhalb eines regulären Elements liegen. Zum Beispiel:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Iterieren über einen Bereich
-
-Alpine unterstützt die `i in n` Syntax, wobei `n` eine Ganzzahl ist. Dies ermöglicht es, über einen bestimmten Bereich an Elementen zu iterieren.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Beispiel:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> Das obenstehende Beispiel nutzt Klassen aus [Tailwind CSS](https://tailwindcss.com)
-
-Alpine bietet 6 verschiedene Transitionen-Direktiven, um den verschiedenen Phasen einer Transition einen Elements Klassen hinzuzufügen, während sich diese zwischen den Zuständen "hidden" und "shown" befindet. Die Direktiven sind sowohl mit `x-show` als auch mit `x-if` kompatibel.
-
-Sieht man über die Differenzen in der Namensgebung hinweg, verhalten sie sich exakt gleich wie die Transitionen-Direktiven von VueJs. 
-
-| Direktive | Beschreibung |
-| --- | --- |
-| `:enter` | Wird während der gesamten Eintrittsphase angewendet. |
-| `:enter-start` | Wird hinzugefügt, bevor das Element eingefügt wurde. Wird entfernt, ein Frame nachdem das Element eingefügt wurde. |
-| `:enter-end` | Wird hinzugefügt, ein Frame nachdem das Element eingefügt wurde (zum selben Zeitpunkt, an dem `enter-start` entfernt wird). Wird entfernt, sobald der Übergang/die Animation beendet ist.
-| `:leave` | Wird während der gesamten Austrittsphase angewendet. |
-| `:leave-start` |  Wird sofort hinzugefügt, sobald eine ausgehende Transition ausgelöst wird. Wird nach einem Frame entfernt. |
-| `:leave-end` | Wird hinzugefügt, ein Frame nachdem eine ausgehende Transition ausgelöst wurde (zum selben Zeitpunkt, an dem `leave-start` entfernt wird). Wird entfernt, sobald der Übergang/die Animation beendet ist. |
-
----
-
-### `x-spread`
-**Beispiel:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Öffne Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Inhalt</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` ermöglicht es, die Alpine-Bindings eines Elements in ein wiederverwendbares Objekt auszulagern.
-
-Die Namen des Objekts sind die Direktiven (jedes mögliche Direktive inklusive Modifikatoren). Die Werte sind Callback-Funktionen, welche von Alpine ausgewertet werden.
-
-> Hinweis: Der einzige Sonderfall von `x-spread` ist dessen Nutzung in Kombination mit `x-for`. Wenn es auf das Direktive `x-for` angewendet wird, sollte ein normaler String-Ausdruck von der Callback-Funktion retourniert werden. Zum Beispiel: `['x-for']() { return 'item in items' }`.
-
----
-
-### `x-cloak`
-**Beispiel:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak`-Attribute werden vom Element entfernt, sobald Alpine initialisiert wird. Das Direktive wird genutzt, um das pre-initialisierte DOM auszublenden. Typischerweise wird das folgende Styling im globalen Geltungsbereich gesetzt, um die Funktionalität von `x-cloak` sicherzustellen:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Magische Eigenschaften
-
-> Mit der Ausnahme von `$el`, sind magische Eigenschaften **nicht innerhalb von `x-data` verfügbar**, da die Komponente noch nicht initialisiert wurde.
-
----
-
-### `$el`
-**Beispiel:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Tausch mich mit "foo" aus</button>
-</div>
-```
-
-`$el` ist eine magische Eigenschaft, um auf den DOM-Knoten der Stammkomponente zuzugreifen.
-
-### `$refs`
-**Beispiel:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` ist eine magische Eigenschaft, um jene DOM-Elemente innerhalb einer Komponente aufzurufen, welche mit `x-ref` markiert sind. Dies ist nützlich, wenn DOM-Elemente manuell bearbeitet werden müssen.
-
----
-
-### `$event`
-**Beispiel:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` ist eine magische Eigenschaft, um innerhalb eines EventHandlers auf das native Event-Objekt des Browsers zuzugreifen.
-
-> Hinweis: Die Eigenschaft $event ist nur in DOM-Ausdrücken verfügbar.
-
-Um innerhalb einer JavaScript-Funktion auf $event zuzugreifen, kann dieses als Argument an die Funktion übergeben werden.
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Beispiel:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Wenn geklickt, wird "bar" in der Konsole ausgegeben -->
-</div>
-```
-
-**Hinweise bezüglich der Ereignisverbreitung (engl. "Event Propagation")**
-
-Wenn Ereignisse abgefangen werden sollen, welche von HTML-Knoten innerhalb derselben Verschachtelungshierarchie ausgelöst werden, muss der Modifikator [`.window`](https://github.com/alpinejs/alpine#x-on) eingesetzt werden. Dieses Verhalten ist auf das [Bubbling von Ereignissen](https://en.wikipedia.org/wiki/Event_bubbling) zurückzuführen:
-
-**Beispiel:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Das oben beschriebene Konstrukt wird nicht die gewünschte Funktionsweise erfüllen. Wird das Ereignis `custom-event` ausgelöst, wird es an das gemeinsame übergeordnete Element `div` propagiert.
-
-**Versand von Ereignissen an Komponenten**
-
-Die oben beschriebene Methode kann auch dazu verwendet werden, um die Kommunikation zwischen Komponenten zu ermöglichen:
-
-**Beispiel:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Wenn geklickt, wird "Hello World!" in der Konsole ausgegeben. -->
-```
-
-`$dispatch` ist eine Kurzschreibweise für die Erstellung von `CustomEvent` und dessen interner Versand mittels `.dispatchEvent()`. Es gibt zahlreiche Anwendungsfälle, in welchen der Versand von Daten durch benutzerdefinierten Ereignisse zwischen Komponenten eine sinnvolle Option darstellt. [Hier](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) gibt es weitere Informationen bezüglich dem zugrundenliegenden `CustomEvent`-System in Browsern.
-
-Jegliche Datenquelle, welche als zweiter Parameter an `$dispatch('some-event', { some: 'data' })` weitergegeben wird, kann mithilfe der Eigenschaft "detail" aufgerufen werden: `$event.detail.some`. Das Hinzufügen von benutzerdefinierten Ereignis-Daten zur `.detail`-Eigenschaft ist Standard für `CustomEvent`s in Browsern. [Hier](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) gibt es mehr Informationen dazu.
-
-`$dispatch()` kann zusätzlich genutzt werden, um die Aktualisierung von Daten von `x-model`-Bindings auszulösen. Zum Beispiel:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- Nachdem das Element `<button>` angeklickt wurde, wird `x-model` das durch Bubbling verbreitete "input"-Ereignis abfangen und foo auf "baz" setzen. -->
-    </span>
-</div>
-```
-
-> Hinweis: Die Eigenschaft $dispatch ist nur innerhalb von DOM-Ausdrücken verfügbar.
-
-Um innerhalb einer JavaScript-Funktion auf $dispatch zuzugreifen, kann dieses als Argument an die Funktion übergeben werden:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Beispiel:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` ist eine magische Eigenschaft, durch welche der gegebene Ausdruck erst dann ausgeführt wird, NACHDEM Alpine die reaktiven DOM-Aktualisierungen durchgeführt hat. Dieses Verhalten ist nützlich, wenn mit dem DOM erst interagiert werden soll, NACHDEM alle Datenaktualisierungen durchgeführt wurden.
-
----
-
-### `$watch`
-**Beispiel:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-Die Eigenschaft einer Komponente kann mithilfe der magischen Methode `$watch` "beobachtet" werden. Erst wenn das `<button>`-Element im obigen Beispiel angeklickt wird und die Eigenschaft `open` aktualisiert wurde, wird die angegebene Callback-Funktion ausgelöst. Der neue Wert wird dann in der Konsole ausgegeben.
-
-## Sicherheit
-Wenn du eine Sicherheitslücke findest, sende bitte eine E-mail an [calebporzio@gmail.com]().
-
-Alpine basiert auf einer benutzerdefinierten Implementierung, welche das `Function`-Objekt nutzt, um seine Direktiven auszuwerten. Obwohl dieses Vorgehen sicherer ist als die Auswertung mittels `eval()`, ist dessen Nutzung in manchen Umgebungen nicht gestattet (z.B. in der Google Chrome App, aufgrund der restriktiven Content Security Policy (CSP)).
-
-Wenn du Alpine innerhalb einer Website nutzt, welche sensible Daten verarbeitet und auf [CSP](https://csp.withgoogle.com/docs/strict-csp.html) angewiesen ist, muss die Eigenschaft `unsafe-eval` in die policy eingefügt werden. Eine korrekt konfigurierte policy ist ein sinnvoller Mechanismus, um die persönlichen und finanziellen Daten von Nutzern zu schützen.
-
-Da sich die policy auf alle Skripts einer Seite auswirkt, ist es wichtig sicherzustellen, dass alle benutzten externen Bibliotheken und Pakete auf ihre Sicherheit geprüft wurden. Somit soll verhindert werden, dass deine Website Opfer von Cross Site Scripting Attacken (durch `eval()` oder DOM-Manipulation) wird.
-
-## V3 Roadmap
-* Move from `x-ref` to `ref` for Vue parity?
-* Add `Alpine.directive()`
-* Add `Alpine.component('foo', {...})` (With magic `__init()` method)
-* Dispatch Alpine events for "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Remove "object" (and array) syntax from `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) to add support for object syntax for the `style` attribute)
-* Improve `x-for` mutation reactivity ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Add "deep watching" support in V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Add `$el` shortcut
-* Change `@click.away` to `@click.outside`?
-
-## License
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.

+ 0 - 752
README.es.md

@@ -1,752 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js ofrece las propiedades reactivas y declarativas de grandes *frameworks* como Vue o React con un coste mucho menor.
-
-Mantiene el DOM, pudiendo mejorar y perfeccionar el comportamiento como más convenga.
-
-Podríamos considerarlo como un [Tailwind](https://tailwindcss.com/) para JavaScript.
-
-> Nota: La sintaxis de esta herramienta está mayormente inspirada por [Vue](https://vuejs.org/) (y por extensión, de [Angular](https://angularjs.org/))). Estaré agradecido eternamente por lo que han aportado al desarrollo web.
-
-## Instalación
-
-**Desde CDN:** Añade el siguiente script al final de tu sección `<head>`.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-Eso es todo. Se inicializará solo.
-
-Para entornos de producción, se recomienda especificar una número de versión en concreto en el enlace para evitar comportamientos inesperados que puedan romper las nuevas versiones. Por ejemplo, para usar la versión `2.8.2` (la última):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Desde npm:** Instalar el paquete desde npm.
-```js
-npm i alpinejs
-```
-
-Incluir en tu script.
-```js
-import 'alpinejs'
-```
-
-**Para soporte en IE11** Utilizar los siguientes scripts.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-El patrón de arriba es el [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/), que resultará en un empaquetado moderno cargado automáticamente en navegadores modernos, y el empaquetado para IE11 cargado automáticamente en IE11 y otros navegadores de legado.
-
-## Usar
-
-*Desplegable/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Abrir Desplegable</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Cuerpo del Desplegable
-    </ul>
-</div>
-```
-
-*Pestañas*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Pestaña Foo</div>
-    <div x-show="tab === 'bar'">Pestaña Bar</div>
-</div>
-```
-
-También se puede utilizar para fines no-triviales:
-*Pre-fetching del contenido de un desplegable HTML al pasar el cursor por encima*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Mostrar Desplegable</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Cargando Ruleta...
-    </div>
-</div>
-```
-
-## Aprender
-
-Hay 14 directivas disponibles:
-
-| Directiva | Descripción |
-| --- | --- |
-| [`x-data`](#x-data) | Declara un nuevo *scope* del componente. |
-| [`x-init`](#x-init) | Ejecuta una expresión cuando un componente se inicializa. |
-| [`x-show`](#x-show) | Alterna `display: none;` en el elemento dependiendo de la expresión booleana (true o false). |
-| [`x-bind`](#x-bind) | Asigna el valor de un atributo a partir de el resultado de una expresión de JS. |
-| [`x-on`](#x-on) | Adjunta un evento *listener* al elemento. Ejecuta una expresión de JS cuando se emite el evento. |
-| [`x-model`](#x-model) | Añade *"two-way data binding"* al elemento. Mantiene la entrada del elemento sincronizado con los datos del componente. |
-| [`x-text`](#x-text) | Funciona similar a `x-bind`, pero actualiza el `innerText` del elemento. |
-| [`x-html`](#x-html) | Funciona similar a `x-bind`, pero actualiza el `innerHTML` del elemento. |
-| [`x-ref`](#x-ref) | Forma conveniente de extraer elementos crudos del DOM del componente. |
-| [`x-if`](#x-if) | Elimina totalmente un elemento del DOM. Debe ser utilizado en una etiqueta `<template>`. |
-| [`x-for`](#x-for) | Crea nuevos nodos en el DOM por cada elemento en un arreglo. Debe ser utilizado en una etiqueta `<template>`. |
-| [`x-transition`](#x-transition) | Directivas para aplicar clases a varias etapas de la transición del elemento. |
-| [`x-spread`](#x-spread) | Permite hacer *bind* de un objeto de las directivas de Alpine a un elemento para mejor reusabilidad. |
-| [`x-cloak`](#x-cloak) | Este atributo se elimina cuando Alpine se inicializa. Útil para ocultar el DOM pre-inicializado. |
-
-Y 6 propiedades mágicas:
-
-| Propiedades Mágicas | Descripción |
-| --- | --- |
-| [`$el`](#el) | Extrae el componente raíz de un nodo del DOM. |
-| [`$refs`](#refs) | Extrae elementos del DOM marcados con `x-ref` dentro del componente. |
-| [`$event`](#event) | Extrae el objeto "Event" del navegador nativo de dentro de un evento *listener*. |
-| [`$dispatch`](#dispatch) | Crea un `CustomEvent` y hace *dispatch* utilizando `.dispatchEvent()` internamente. |
-| [`$nextTick`](#nexttick) | Ejecuta la expresión dada DESPUÉS que Alpine ha hecho los cambios reactivos en las actualizaciones del DOM. |
-| [`$watch`](#watch) | Ejecuta la *callback* provista cuando una propiedad del componente al cual se ha hecho `watch` cambia. |
-
-
-## Sponsors
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**¿Quieres tu logo aquí? [Escríbe MP en Twitter](https://twitter.com/calebporzio)**
-
-## Proyectos de la Comunidad
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### Directivas
-
----
-
-### `x-data`
-
-**Ejemplo:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Estructura:** `<div x-data="[object literal]">...</div>`
-
-`x-data` declara un nuevo *scope* del componente. Indica al *framework* que debe inicializar un nuevo componente con el objeto especificado.
-
-Es análogo a la propiedad `data` de un componente en Vue.
-
-**Extraer Lógica del Componente**
-
-Se pueden extraer datos (y comportamiento) en funciones reutilizables:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Abrir</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Desplegable
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Para usuarios de bundler**, notad que Alpine.js accede a funciones que están en el *scope* global (`window`), es necesario asignar explicitamente las funciones a `window` para poder usarlas con `x-data`. Por ejemplo, `window.dropdown = function () {}` (eso pasa porque Webpack, Rollup, Parcel etc. pone las funciones que defines en el *scope* del módulo y no de `window`).
-
-
-También puedes mezclar múltiples tipos de datos usando desestructuración de objetos:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Ejemplo:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Estructura:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` ejecuta una expresión cuando se inicializa un componente.
-
-Si deseas ejecutar código DESPUÉS que Alpine haga las actualizaciones iniciales al DOM (similar al *hook* de `mounted()` en VueJS), puedes devolver un *callback* en `x-init`, y se ejecutará después:
-
-`x-init="() => { // aquí tenemos acceso al estado de post-inicialización del DOM // }"`
-
----
-
-### `x-show`
-**Ejemplo:** `<div x-show="open"></div>`
-
-**Estructura:** `<div x-show="[expression]"></div>`
-
-`x-show` alterna el estilo `display: none;` del elemento dependiendo de si la expresión evalúa a `true` o `false`.
-
-**x-show.transition**
-
-`x-show.transition` es una API de conveniencia para hacer `x-show`s más agradables utilizando transiciones de CSS.
-
-```html
-<div x-show.transition="open">
-    Estos contenidos entraran y saldrán de transición.
-</div>
-```
-
-| Directiva | Descripción |
-| --- | --- |
-| `x-show.transition` | A simultaneous fade and scale. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Only transition in. |
-| `x-show.transition.out` | Only transition out. |
-| `x-show.transition.opacity` | Only use the fade. |
-| `x-show.transition.scale` | Only use the scale. |
-| `x-show.transition.scale.75` | Customize the CSS scale transform `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Sets the "in" transition to 200ms. The out will be set to half that (100ms). |
-| `x-show.transition.origin.top.right` | Customize the CSS transform origin `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Different durations for "in" and "out". |
-
-> Nota: Todas esos modificadores de transiciones se pueden usar conjuntamente con cualquiera de los otros. Esto es posible (aunque ridículo lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Nota: `x-show` espera a que cualquier hijo acabe de salir de la transición. Si quieres evitar este comportamiento, añade el modificador `.immediate`:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Nota: Eres libre de usar la sintaxis abreviada ":": `:type="..."`
-
-**Ejemplo:** `<input x-bind:type="inputType">`
-
-**Estructura:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` asigna el valor de un atributo como el resultado de evaluar una expresión de Javascript. La expresión tiene acceso a todos las claves del objeto de datos del componente, y se actualizará cada vez que se actualizan los datos.
-
-> Nota: *bindings* de atributos SÓLO se actualizan cuando se actualizan las dependencias. El *framework* es lo suficientemente inteligente para observar cambios en los datos y detectar que *bindings* se encargan de esos.
-
-**`x-bind` para atributos de clase**
-
-`x-bind` se comporta un poco distinto cuando hacemos *binding* de un atributo `class`.
-
-Para clases, es necesario pasar un objeto cuyas claves sean los nombres de la clase, y los valores sean expresiones booleanas que determinan si las clases se aplican o no.
-
-Por ejemplo:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-En este ejemplo, la clase "hidden" solo se aplicará cuando el valor del atributo `foo` sea `true`.
-
-**`x-bind` para atributos booleanos**
-
-`x-bind` da soporte a atributos booleanos del mismo modo que funciona para atributos valuables, utilizando una variable como condicion o cualquier expresión de JavaScript que resuelve a `true` o `false`.
-
-Por ejemplo:
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Hazme click</button>
-
-<!-- When myVar == true: -->
-<button disabled="disabled">Hazme click</button>
-
-<!-- When myVar == false: -->
-<button>Click me</button>
-```
-
-Esto añadirá o eliminará el atributo `disabled` cuando `myVar` sea `true` o `false` respectivamente.
-
-Se soportan atributos booleanos de la [especificación de HTML](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), por ejemplo `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-**Modificador `.camel`**
-**Ejemplo:** `<svg x-bind:view-box.camel="viewBox">`
-
-El modificador `camel` hace *binding* del equivalente al nombre del atributo en *camel case*. En el ejemplo de arriba, el valor de `viewBox` se asignará al atributo `viewBox` y no al atributo `view-box`.
-
----
-
-### `x-on`
-
-> Nota: Eres libre de usar la sintaxis abreviada "@": `@click="..."`
-
-**Ejemplo:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Structure:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` adjunta un evento *listener* al elemento en el cual se declara. Cuando se emite el evento, se ejecuta la expresion de JavaScript especificada.
-
-Si cualquier dato es modificado en la expresión, otros atributos de elementos "vinculados" con dicho dato, se actualizarán.
-
-> Nota: También se puede especificar el nombre de una función de JavaScript
-
-**Ejemplo:** `<button x-on:click="myFunction"></button>`
-
-Eso es equivalente a: `<button x-on:click="myFunction($event)"></button>`
-
-**Modificador `keydown`**
-
-**Ejemplo:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Puedes especificar teclas en conreto a escuchar utilizando modificadores *keydown* anexados a la directiva `x-on:keydown`. Nótese que los modificadores son versiones *kebab-cased* de los valores de `Event.key`.
-
-Ejemplos: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Nota: También puedes escuchar combinaciones de teclas de sistema como: `x-on:keydown.cmd.enter="foo"`
-
-**Modificador `.away`**
-
-**Ejemplo:** `<div x-on:click.away="showModal = false"></div>`
-
-Cuando el modificador `.away` está presente, el evento solo se ejecutara cuando el evento se origina de una fuente distinta al propio elemento o sus hijos.
-
-**Modificador `.prevent`**
-**Ejemplo:** `<input type="checkbox" x-on:click.prevent>`
-
-Añadir `.prevent` en un *listener* de eventos llama a `preventDefault` sobre el evento disparado. En el ejemplo de arriba, esto significa que realmente la casilla no se marcará cuando el usuario haga click en ella.
-
-**Modificador `.stop`**
-**Ejemplo:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Añadir `.stop` en un *listener* de eventos llama a `stopPropagation` sobre el evento disparado. En el ejemplo de arriba, esto significa que el evento de "click" no saltará hacia el `<div>` exterior. En otras palabras, cuando un usuario pulse el botón, no se asignará `'bar'` a `foo`.
-
-**Modificador `.self`**
-**Ejemplo:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Añadir `.self` en un *listener* de eventos hará que el evento solo se dispare si `$event.target` es el propio elemento. En el ejemplo de arriba, esto significa que el evento de "click" que propaga el evento hacia el `<div>`exterior **no** correrá el código indicado.
-
-**Modificador `.window`**
-**Ejemplo:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Añadir `.window` en un *listener* de eventos instalará el *listener* en el objeto global `window` y no en el nodo del DOM en el que se declara. Esto es útil cuando quieres modificar el estado de un componente cuando algo cambia en `window`, como un evento de redimensión. En este ejemplo, cuando la ventana supera los 768 píxeles de anchura, cierra el modal/desplegable, y en el caso contrario mantiene el mismo estado.
-
->Nota: También se puede usar el modificador `.document` para adjuntar *listeners* a `document` y no en `window`
-
-**Modificador `.once`**
-**Ejemplo:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Añadir el modificador `.once` en un *listener* de eventos asegura que el *listener* solo se ejecute una sola vez. Esto es útil para tareas que solo quieres realizar una vez, como un *fetch* parcial de un HTML o similares.
-
-**Modificador `.passive`**
-**Ejemplo:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Añadir el modificador `.passive` en un *listener* de eventos hará que el *listener* sea pasivo, lo que significa que `preventDefault()` no funcionará en ninguno de los eventos procesados. Esto puede ayudar, por ejemplo, con el buen desempeño del desplazamiento en dispositivos táctiles.
-
-**Modificador `.debounce`**
-**Ejemplo:** `<input x-on:input.debounce="fetchSomething()">`
-
-El modificador `debounce` permite hacer "debounce" de un evento. En otras palabras, la respuesta al evento NO se ejecutará hasta que haya pasado una cierta cantidad de tiempo desde que el evento se lanzó por última vez. Cuando está listo para ser llamado, se ejecutará la última respuesta.
-
-El valor de "espera" por defecto es de 250 milisegundos.
-
-Para personalizar este valor, es posible especificar una cifra en concreto de la siguiente forma:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**Modificador `.camel`**
-**Ejemplo:** `<input x-on:event-name.camel="doSomething()">`
-
-El modificador `camel` hace *binding* del equivalente al nombre del evento en *camel case*. En el ejemplo de arriba, la expresión se evaluara cuando se dispare el evento `eventName`.
-
----
-
-### `x-model`
-**Ejemplo:** `<input type="text" x-model="foo">`
-
-**Estructura:** `<input type="text" x-model="[data item]">`
-
-`x-model` añade *"two-way data binding"* en un elemento. En otras palabras, el valor del elemento de entrada estara sincronizado con el valor del dato en el componente.
-
-> Nota: `x-model` es lo suficientemente inteligente para detectar cambios en inputs de texto, checkboxes, radio buttons, radio buttons, textareas, selects, y multiple selects. Debería comportarse [igual que lo hace Vue](https://vuejs.org/v2/guide/forms.html) en esos escenarios.
-
-**Modificador `.number`**
-**Ejemplo:** `<input x-model.number="age">`
-
-El modificador `number` convierte el valor de entrada a un número. En caso que no se pueda convertir a número, devuelve el valor original.
-
-**Modificador `.debounce`**
-**Ejemplo:** `<input x-model.debounce="search">`
-
-El modificador `debounce` permite añadir "debounce" en la actualización de un valor. En otras palabras, la respuesta al evento NO se ejecutará hasta que haya pasado una cierta cantidad de tiempo desde que se disparó el último evento. Cuando la respuesta está lista para ser llamada, se ejecutará la respuesta al último evento.
-
-El valor de "espera" por defecto es de 250 milisegundos.
-
-Para personalizar este valor, es posible especificar una cifra en concreto de la siguiente forma:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Ejemplo:** `<span x-text="foo"></span>`
-
-**Estructura:** `<span x-text="[expression]"`
-
-`x-text` funciona similar a `x-bind`, pero actualiza el `innerText` del elemento en lugar del valor del atributo.
-
----
-
-### `x-html`
-**Ejemplo:** `<span x-html="foo"></span>`
-
-**Estructura:** `<span x-html="[expression]"`
-
-`x-html` funciona similar a `x-bind`, pero actualiza el `innerHTML` del elemento en lugar del valor del atributo.
-
-> :warning: **Utiliza solo contenido confiable y no elementos introducidos por el usuario.** :warning:
->
-> Renderizar HTML de terceros dinamicamente puede facilmente llevarnos a vulnerabilidades [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting).
-
----
-
-### `x-ref`
-**Ejemplo:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Estructura:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` permite una forma conveniente de extraer elementos crudos del DOM del componente. Colocando el atributo `x-ref` en un elemento, pasa a estar disponible para todas las respuestas de eventos dentro de un objeto llamado `$refs`.
-
-Esta es una alternativa útil para evitar tener ids y utilizar `document.querySelector` en todos lados.
-
-> Nota: También se puede hacer *bind* dinámico de valores para x-ref: `<span :x-ref="item.id"></span>` en caso de ser necesario.
-
----
-
-### `x-if`
-**Ejemplo:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Estructura:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-En casos donde `x-show` no es suficiente (`x-show` pone el elemento con `display: none` si es false) `x-if` se puede utilizar para eliminar un elemento del DOM completamente.
-
-Es importante que `x-if` se use en una etiqueta `<template></template>` porque Alpine no utiliza un DOM virtual. Esta implementación permite a Alpine a ser robusto usando el DOM real y hacer su magia.
-
-> Nota: `x-if` debe tener un único elemento raíz dentro de la etiqueta `<template></template>`.
-
-> Nota: Cuando se usa `template` dentro de una etiqueta `svg`, es necesario añadir un [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) que debe ejecutarse antes que Alpine.js se inicialice.
-
----
-
-### `x-for`
-**Ejemplo:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Nota: El *binding* `:key` es opcional, pero es ALTAMENTE recomendado.
-
-`x-for` está disponible para casos donde se requiere de crear nuevos nodos en el DOM por cada elemento en un arreglo. Actua similar a `v-for` en Vue, con la exepción que es necesario usarlo con una etiqueta `template` y no un elemento cualquiera.
-
-Si quieres acceder al indice actual de la iteración, utiliza la siguiente sintaxis:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- También se puede referenciar a "index" dentro de la iteración si es necesario. -->
-    <div x-text="index"></div>
-</template>
-```
-
-> Nota: `x-for` debe tener un único elemento raíz dentro de la etiqueta `<template></template>`.
-
-> Nota: Cuando se usa `template` dentro de una etiqueta `svg`, es necesario añadir un [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) que debe ejecutarse antes que Alpine.js se inicialice.
-
-
-#### Anidando `x-for`s
-Se pueden anidar bucles `x-for`, pero se debe envolver cada bucle en un elemento. Por ejemplo:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
----
-
-### `x-transition`
-**Ejemplo:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> El ejemplo de arriba utiliza clases de [Tailwind CSS](https://tailwindcss.com)
-
-Alpine ofrece 6 formas distintas de directivas de transición para aplicar clases en varias etapas de transición de un elemento, entre los estados "hidden" y "shown". Estas directivas funcionan con ambos `x-show` y `x-if`.
-
-Estas, funcionan exactamente igual que las directivas de transición de VueJS con la diferencia de que tienen distintos nombres y más sensibles:
-
-| Directiva | Descripción |
-| --- | --- |
-| `:enter` | Se aplica durante toda la fase de entrada. |
-| `:enter-start` | Se añade antes que el elemento se inserte y se elimina un fotograma después de que se inserte el elemento. |
-| `:enter-end` | Añadido un fotograma después se inserir el elemento (al mismo tiempo que se elimina `enter-start`), y se elimina cuando la transición/animación finaliza. |
-| `:leave` | Aplicado durante toda la fase de abandono. |
-| `:leave-start` | Añadido inmediatamente cuando se dispara el abandono de la transición, y eliminado después de un fotograma. |
-| `:leave-end` | Añadido un fotograma después de que se dispare el dejar la transición (al mismo tiempo que se elimina `leave-start`), y se elimina cuando la transición/animación finaliza.
-
----
-
-### `x-spread`
-**Ejemplo:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Abrir Desplegable</button>
-
-    <span x-spread="dialogue">Desplegar Contenidos</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` permite extraer los *bindings* de Alpine de un elemento en un objeto reutilizable.
-
-Las claves del objeto son las directivas (puede ser cualquiera, incluyendo modificadores), y los valores son *callbacks* a evaluar por Alpine.
-
-> Note: Excepciónes con `x-spread`:
-> - Cuando la directiva a extender es `x-for`, es necesario retornar una expresion en formato de *string* en el *callback*. Por ejemplo: `['x-for']() { return 'item in items' }`.
-> - `x-init` y `x-data` no se pueden usar dentro de un objeto para "spread".
-
----
-
-### `x-cloak`
-**Ejemplo:** `<div x-data="{}" x-cloak></div>`
-
-Los atributos de `x-cloak` se eliminan de los elementos cuando Alpine se inicializa. Esto es util para ocultar elementos pre-inicializados del DOM. Es recomendado añadir el siguiente estilo global para que esto funcione:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Propiedades Mágicas
-
-> Con la excepción de `$el`, las propiedades mágicas **no están disponibles junto a `x-data`** ya que el componente aún no ha sido inicializado.
-
----
-
-### `$el`
-**Ejemplo:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Reemplázame con "foo"</button>
-</div>
-```
-
-`$el` es una propiedad mágica que puede ser utilizada para extraer el nodo DOM del componente raíz.
-
-### `$refs`
-**Ejemplo:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` es una propiedad mágica que puede ser utilizada para extraer elementos DOM marcados con `x-ref` dentro del componente. Esto es útil cuando es necesario manipular manualmente elementos del DOM.
-
----
-
-### `$event`
-**Ejemplo:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` es una propiedad mágica que puede ser utilizada junto un a un *listener* de eventos para extraer el objeto nativo "Event" del navegador.
-
-> Nota: La propiedad $event sólo está disponible en expresiones del DOM.
-
-Si se requiere acceder a $event dentro de una función de JavaScript puedes pasar el objecto directamente como parámetro:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Ejemplo:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Al hacer click, hará console.log de "bar" -->
-</div>
-```
-
-**Nota en la Propagación de Eventos**
-
-Nótese que, por el [event bubbling](https://en.wikipedia.org/wiki/Event_bubbling), cuando se necesita capturar eventos enviados desde nodes que están anidado bajo el mismo nivel de jerarquía, es necesario usar el modificador [`.window`](https://github.com/alpinejs/alpine#x-on):
-
-**Ejemplo:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Esto no funcionará porqué cuando se dispara `custom-event`, se propagará hacia el antepasado común, el `div`.
-
-**_Dispatching_ Componentes**
-
-También se puede aprovechar la técnica anterior para hacer que los componentes se comuniquen entre ellos:
-
-**Ejemplo:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Al hacer click, hará console.log de "Hello World!". -->
-```
-
-`$dispatch` es un atajo para crear un evento personalizado `CustomEvent` y enviarlo utilizando `.dispatchEvent()` internamente. Hay muchos casos de uso buenos en donde se requiere pasar los datos entre componentes utilizando eventos personalizados. [Leer esto](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) para mas información sobre el sistema de `CustomEvent` en los navegadores.
-
-Nótese que cualquier dato que se pasa como segundo parametro de `$dispatch('some-event', { some: 'data' })`, pasa a estar disponible a través de la propiedad "detail" de los nuevos eventos: `$event.detail.some`. Añadir datos de eventos personalizados a la propiedad `.detail` es la práctica estándar para usar `CustomEvent` en navegadores. [Leer esto](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) para mas información.
-
-También se puede utilizar `$dispatch()` para disparar actualizaciones de los datos para bindings con `x-model`. Por ejemplo:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- Después de pulsar el botón, `x-model` captura el evento "input", y actualiza foo a "baz". -->
-    </span>
-</div>
-```
-
-> Nota: La propiedad $dispatch sólo está disponible en expresiones del DOM.
-
-Si necesitas acceder a $dispatch desde dentro de una función de JavaScript, puedes pasarlo como parámetro:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Ejemplo:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` es una propiedad mágica que permite ejecutar la expresión indicada sólo DESPUÉS que Alpine haga las actualizaciones reactivas del DOM. Esto es útil para las veces que se necesita interactuar con el DOM DESPUÉS que se reflejen todas las actualizaciones que has hecho de los datos.
-
----
-
-### `$watch`
-**Ejemplo:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-Puedes hacer "watch" a la propiedad de un componente con el método mágico `$watch`. En el ejemplo de arriba, cuando se pulsa el botón y `open` cambia, la retrollamada provista ejecutara el `console.log` con el nuevo valor.
-
-## Seguridad
-Si encuentras una brecha de seguridad, por favor envía un email a [calebporzio@gmail.com]().
-
-Alpine depende de una implementación personalizada utilizando el objeto `Function` para evaluar las directivas. A pesar de ser más seguro que `eval()`, su uso está prohibido en algunos entornos, tels como Google Chrome App, utilizando Content Security Policy restrictivas (CSP).
-
-Si utilizas Alpine en un sitio web que maneja datos sensibles y requiere [CSP](https://csp.withgoogle.com/docs/strict-csp.html), necesitas incluir `unsafe-eval` en tu política. Una política robusta configurada correctamente ayudará a proteger a tus usuarios cuando utilizan datos personales o financieros.
-
-Ya que la política se aplica a todos los scripts de tu página, es improtante que otras bibliotecas externas incluidas en el sitio web sean revisadas cuidadosamente para asegurar que son confiables y que no intrudicen ninguna vulnerabilidad de Cross Site Scripting ni usando `eval()`ni manipulando el DOM para inyectar código malicioso en tu página.
-
-## V3 Roadmap
-* Migrar de `x-ref` a `ref` para paridad con Vue?
-* Añadir `Alpine.directive()`
-* Añadir `Alpine.component('foo', {...})` (Con el método mágico `__init()`)
-* Enviar eventos de Alpine para "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Eliminar síntaxis de "object" (y array) de `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) para añadir soporte a sintaxis de objeto para el atributo `style`)
-* Mejorar `x-for` para reactividad con mutaciones ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Añadir soporte "deep watching" en V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Añadir atajo `$el`
-* Cambiar `@click.away` a `@click.outside`?
-
-## Licencia
-
-Copyright © 2019-2021 Caleb Porzio y colaboradores
-
-Licenciado bajo la licencia MIT, ve [LICENSE.md](LICENSE.md) para más detalles.

+ 0 - 1061
README.fa.md

@@ -1,1061 +0,0 @@
-<div dir="rtl">
-  
-# Alpine.js - آلپاین‌جی‌اس
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js ماهیت واکنشی و اعلانی چهارچوب‌های بزرگی مانند Vue یا React را با هزینه‌ای بسیار کمتر به شما ارائه می‌دهد.
-
-شما می‌توانید ضمن حفظ ساختار DOM، رفتارهای مورد نظرتان را به شکلی صلاح می‌دانید به برنامه‌تان اضافه کنید.
-
-فکر کنید آلپاین برای جاوااسکریپت، همانند [Tailwind](https://tailwindcss.com/) است برای سی‌اس‌اس.
-
-> نکته: قواعد گارشی و نحو این ابزار، تقریبا به صورت کامل از [Vue](https://vuejs.org/) ( و به طبع آن از [Angular](https://angularjs.org/) ) اقتباس شده است.
-من تا ابد شکرگزار موهبت این دو چهارچوب برای دنیای وب خواهم بود.
-
-## ترجمه‌های مستندات
-
-| زبان | پیوند به مستندات |
-| --- | --- |
-| انگلیسی | [**Documentation In English**](./README.md) |
-| عربی | [**التوثيق باللغة العربية**](./README.ar.md) |
-| چینی ساده | [**简体中文文档**](./README.zh-CN.md) |
-| چینی سنتی | [**繁體中文說明文件**](./README.zh-TW.md) |
-| آلمانی | [**Dokumentation in Deutsch**](./README.de.md) |
-| اندونزیایی | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| ژاپنی | [**日本語ドキュメント**](./README.ja.md) |
-| نروژی | [**Dokumentasjon på norsk**](./README.no.md) |
-| پرتغالی | [**Documentação em Português**](./README.pt.md) |
-| روسی | [**Документация на русском**](./README.ru.md) |
-| اسپانیایی | [**Documentación en Español**](./README.es.md) |
-| ترکی | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| فرانسوی | [**Documentation en Français**](./README.fr.md) |
-| کره‌ای | [**한국어 문서**](./README.ko.md) |
-
-## نصب
-
-**از CDN :** اسکریپت زیر را به انتهای بخش `<head>` کد خود اضافه کنید.
-
-<div dir="ltr">
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-</div>
-
-همین کافی است! خودش مقداردهی اولیه را انجام می‌دهد.
-
-برای محیط تولید (Production Environment)، پیشنهاد می‌شود که عدد نگارش مورد نظر خود را به انتهای پیوند اضافه کنید تا جلوی خطاهای غیر منتظره از نگارش‌های جدید گرفته شود.
-
-برای مثال برای استفاده از نگارش `2.8.2` (آخرین نگارش در زمان نوشتن این ترجمه):
-
-<div dir="ltr">
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-</div>
-
-**از npm :** بسته را از npm نصب کنید.
-
-<div dir="ltr">
-
-```js
-npm i alpinejs
-```
-
-</div>
-
-در اسکریپت خود وارد کنید.
-
-<div dir="ltr">
-
-```js
-import 'alpinejs'
-```
-
-</div>
-
-** برای پشتیبانی از اینترنت اکسپلورر ۱۱: ** از اسکریپت‌های زیر استفاده کنید.
-
-<div dir="ltr">
-
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-</div>
-
-الگوی بالا، [module/nomodule الگوی ](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/)
-است که باعث می‌شود بسته مدرن بصورت اتوماتیک در مرورگرهای مدرن بارگیری شود، و بسته مخصوص اینترنت اکسپلورر ۱۱، در مرورگر اینترنت اکسپلورر ۱۱ و سایر مرورگرهای قدیمی بارگیری شود.
-
-## استفاده
-
-کشویی / مودال - *Dropdown/Modal*
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-</div>
-
-زبانه - *Tabs*
-
-<div dir="ltr">
-
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-</div>
-
-حتی می‌توانید برای چیزهای پیچیده هم از این استفاده کنید:
-
-*پیش دریافت محتوای HTML عنصر کشویی ( Dropdown ) حین قرارگیری زیر موشی.*
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-</div>
-
-## یادگیری
-
-۱۴ فرمان (Directive) در اختیار شما قرار دارد:
-
-| فرمان | توضیحات |
-| --- | --- |
-| <div dir="ltr">[`x-data`](#x-data)</div> | محدوده مؤلفه جدید را تعریف می‌کند. |
-| <div dir="ltr">[`x-init`](#x-init)</div> | یک عبارت را در هنگاه مقداردهی اولیه مؤلفه اجرا می‌کند. |
-| <div dir="ltr">[`x-show`](#x-show)</div> | درج/حذف سبک `display: none;` روی عنصر، بسته به نتیجه عبارت محتوا ( true یا false ) |
-| <div dir="ltr">[`x-bind`](#x-bind)</div> | مقدار یک نشانه ( attribute ) را برابر با نتیجه یک عبارت جاوااسکریپت قرار می‌دهد. |
-| <div dir="ltr">[`x-on`](#x-on)</div> | یک شنوندهٔ رویداد را به عنصر متصل می‌کند. عبارت JS را در زمان انتشار ( Emit ) Event اجرا می‌کند. |
-| <div dir="ltr">[`x-model`](#x-model)</div> | یک «اتصال دوطرفه داده» به عنصر اضافه می‌کند. مقدار یک عنصر input را با دادهٔ مؤلفه هم‌گام نگه می‌دارد. |
-| <div dir="ltr">[`x-text`](#x-text)</div> | مانند `x-bind` عمل می‌کند، اما مقدار `innerText` یک عنصر را به‌روز می‌کند. |
-| <div dir="ltr">[`x-html`](#x-html)</div> | مانند `x-bind` عمل می‌کند، اما مقدار `innerHTML` یک عنصر را به‌روز می‌کند. |
-| <div dir="ltr">[`x-ref`](#x-ref)</div> | راهی ساده برای دریافت عنصر خام DOM از یک مؤلفه. |
-| <div dir="ltr">[`x-if`](#x-if)</div> | یک عنصر را بصورت کامل از DOM حذف می‌کند. باید روی عنصر با برچسب `<template>` استفاده شود. |
-| <div dir="ltr">[`x-for`](#x-for)</div> | به ازای هر عضو داخل یک آرایه، یک گره DOM جدید می‌سازد. باید روی عنصر با برچسب `<template>` استفاده شود. |
-| <div dir="ltr">[`x-transition`](#x-transition)</div> | فرمان‌هایی برای اضافه کردن کلاس‌های لازم به عنصر در مراحل مختلف یک transition |
-| <div dir="ltr">[`x-spread`](#x-spread)</div> | اجازه می‌دهد به منظور قابلیت استفاده مجدد بتوانید یک شیء از فرمان‌های آلپاین را به یک عنصر متصل کنید. |
-| <div dir="ltr">[`x-cloak`](#x-cloak)</div> | این نشانه در زمان مقداردهی اولیه آلپاین حذف خواهد شد و برای مخفی کردن DOM تا زمان مقداردهی اولیه کاربرد دارد. |
-
-و 6 ویژگی (property) جادویی:
-
-| ویژگی‌های جادویی | توضیحات |
-| --- | --- |
-| <div dir="ltr">[`$el`](#el)</div> |  دریافت گره DOM ریشهء مؤلفه |
-| <div dir="ltr">[`$refs`](#refs)</div> | دریافت عناصر DOM علامت خورده با `x-ref` داخل مؤلفه. |
-| <div dir="ltr">[`$event`](#event)</div> | دریافت شیء "Event" محلی مرورگر از داخل یک شنوندهٔ رویداد. |
-| <div dir="ltr">[`$dispatch`](#dispatch)</div> | یک `CustomEvent` ایجاد کرده و توسط <span dir="ltr">`.dispatchEvent()`</span> بصورت داخلی آن را مخابره می‌کند. |
-| <div dir="ltr">[`$nextTick`](#nexttick)</div> | عبارت داده شده را بعد از اینکه آلپاین، به‌روزرسانی‌های واکنشی مربوط به DOM را انجام داد، اجرا می‌کند. |
-| <div dir="ltr">[`$watch`](#watch)</div> | وقتی عنصری که در حال تماشا ( watch ) شدن است تغییر کند، متد Callback داده شده را اجرا می‌کند. |
-
-
-## حامیان مالی
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**می‌خواهید لوگوی شما اینجا بیاید؟ [در توییتر پیام دهید.](https://twitter.com/calebporzio)**
-
-## پروژه‌های انجام شده توسط جامعه
-
-* [Alpine Devtools](https://github.com/HugoDF/alpinejs-devtools)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Alpine Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-
-### فرمان‌ها - Directives
-
----
-
-### `x-data`
-
-**مثال :**
-<span dir="ltr">`<div x-data="{ foo: 'bar' }">...</div>`</span>
-
-**ساختار**
-<span dir="ltr">`<div x-data="[object literal]">...</div>`</span>
-
-`x-data` یک محدودهٔ مؤلفه جدید تعریف می‌کند و به چهارچوب دستور می‌دهد که یک مؤلفه با شیء دادهٔ وارد شده بسازد.
-
-فرض کنید این همان ویژگی `data` در یک مؤلفه Vue است.
-
-**استخراج منطق مؤلفه**
-
-می‌توانید داده (و رفتار) را بصورت متدهایی با قابلیت استفاده مجدد استخراج کنید.
-
-<div dir="ltr">
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // عنصر کشویی - Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-</div>
-
-> **برای کاربرانی که از سامانه‌های بسته‌بندی کننده (Bundler) استفاده می‌کنند:**
-لطفا این نکته را در نظر داشته باشید که آلپاین به متدهایی دسترسی پیدا می‌کند که در محدوده ی کلی ( `window` ) تعریف شده باشند، باید بطور مشخص متدهایتان را به `window` متصل کنید تا بتوانید در `x-data` از آنها استفاده کنید. مانند <span dir="ltr">`window.dropdown = function () {}`</span>.
-( این به آن خاطر است که در Webpack، Rollup، Parcel و ... توابعی که تعریف می‌کنید بصورت پیش فرض در محدوده ماژولِ مورد استفاده تعریف می‌شوند، نه `window`. )
-
-
-همچنین می‌توانید چندیدن شیء داده را با استفاده از تخریب شیء (object destructuring) با هم مخلوط کنید.
-
-<div dir="ltr">
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
-</div>
-
----
-
-### `x-init`
-**مثال:**
-<span dir="ltr">`<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`</span>
-
-**ساختار:**
-<span dir="ltr">`<div x-data="..." x-init="[expression]"></div>`</span>
-
-`x-init` یک عبارت را در هنگاه مقدار دهی اولیه مؤلفه اجرا می‌کند.
-
-If you wish to run code AFTER Alpine has made its initial updates to the DOM (something like a `mounted()` hook in VueJS), you can return a callback from `x-init`, and it will be run after:
-
-اگر می‌خواهید که کدی را بعد از اینکه Alpine آپدیت‌های اولیه ی خود روی DOM را انجام داده، اجرا کنید ( چیزی مانند قلاب `mounted` در VueJS )، می‌توانید یک callback از `x-init` بازگردانید، که پس از آن اجرا خواهد شد.
-
-<div dir="ltr">`x-init="() => { // در اینجا ما به وضعیت پس از مقداردهی اولیه DOM دسترسی داریم. // }"`</div>
-
----
-
-### `x-show`
-**مثال:**
-<span dir="ltr">`<div x-show="open"></div>`</span>
-
-**ساختار:**
-<span dir="ltr">`<div x-show="[عبارت]"></div>`</span>
-
-`x-show` استایل `display: none;` روی عنصر را بسته به نتیجه عبارت محتوا ( `true` یا `false` ) درج یا حذف می‌کند.
-
-**x-show.transition**
-
-`x-show.transition` یک API ساده برای این است که بتوانید عملیات `x-show` را با استفاده از transition‌های css لذت بخش تر کنید.
-
-<div dir="ltr">
-
-```html
-<div x-show.transition="open">
-    این محتوا با انتقال وارد و خارج می‌شود.
-</div>
-```
-
-</div>
-
-| فرمان | توضیحات |
-| --- | --- |
-| <span dir="ltr">`x-show.transition`</span> | یک Fade و Scale همزمان. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| <span dir="ltr">`x-show.transition.in`</span> | فقط transition به داخل. |
-| <span dir="ltr">`x-show.transition.out`</span> | فقط transition به خارج. |
-| <span dir="ltr">`x-show.transition.opacity`</span> | فقط از fade استفاده کن. |
-| <span dir="ltr">`x-show.transition.scale`</span> | فقط از scale استفاده کن. |
-| <span dir="ltr">`x-show.transition.scale.75`</span> | سفارشی کردن مقدار "scale" در CSS به `transform: scale(.75)`. |
-| <span dir="ltr">`x-show.transition.duration.200ms`</span> | تنظیم ورود transition به 200ms. خروج به نصف این مقدار تنظیم می‌شود(100ms). |
-| <span dir="ltr">`x-show.transition.origin.top.right`</span> | سفارشی کردن مقدار "transform origin" در CSS به `transform-origin: top right`. |
-| <span dir="ltr">`x-show.transition.in.duration.200ms.out.duration.50ms`</span> | مدت‌های مختلف برای "ورود - in" و "خروج - in". |
-
-
-> نکته: تمام این اصلاح‌کننده‌های transition می‌توانند با همدیگر به کار بروند. برای مثال این فرمان (هرچند مسخره! اما) درست است :
-> 
-> `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> نکته: `x-show` منتظر خواهد ماند تا تمامی فرزندان عنصرش transition خروجشان را به پایان برسانند، اگر می‌خواهید این رفتار را دور بزنید، عبارت `.immediate` را اضافه کنید.
-
-
-<div dir="ltr">
-
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
-
-</div>
-
----
-
-### `x-bind`
-
-> نکته: می‌توانید از ترکیب کوتاه‌تر ":" استفاده کنید:
-<span dir="ltr">`:type="..."`.</span>
-
-**مثال:**
-<span dir="ltr">`<input x-bind:type="inputType">`</span>
-
-**ساختار:**
-<span dir="ltr">`<input x-bind:[attribute]="[expression]">`</span>
-
-`x-bind` مقدار یک نشانه ( attribute ) را برابر با نتیجه ی یک عبارت جاوااسکریپت قرار می‌دهد. عبارت داخل آن، به تمامی کلید‌های آبجکت دیتای مؤلفه دسترسی دارد، و هر  زمان که دیتای آن آپدیت شد، آن هم آپدیت می‌شود.
-
-> نکته: اتصالات نشانه ها، تنها زمانی آپدیت می‌شوند که وابستگی هایشان آپدیت شوند. چهارچوب آنقدر باهوش هست که تغییرات دیتا را نظارت کند و بفهمد کدام اتصالات به دیتای تغییر یافته بستگی دارند.
-
-**`x-bind` برای نشانه ی کلاس ها**
-
-`x-bind` وقتی که به یک نشانه ی `class` متصل شود، به شیوه ی متفاوتی عمل می‌کند.
-
-برای کلاس ها، شما مقدار را برابر یا یک آبجکت قرار می‌دهید که کلید‌های آن، نام `class`‌های مورد نظر می‌باشد، و مقادیر این کلیدها، عبارت هایی هستند که نتیجه ی ( یا مقدار ) آنها، مشخص می‌کند که `class` مورد نظر در عنصر اعمال شود یا خیر.
-
-برای مثال:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-در این مثال, کلاس "hidden" فقط زمانی اعمال می‌شود که مقدار دیتای `foo` برابر با `true` شود.
-
-**`x-bind` برای نشانه‌های بولی ( True یا False )**
-
-
-`x-bind` همانطور که از نشانه‌های مقداری پشتیبانی می‌کند، از نشانه‌ها boolean هم پشتیبانی می‌کند، استفاده از یک متغیر به عنوان شرط یا هر عبارت جاوااسکریپت که به مقادیر `true` یا `false` نتیجه می‌شود.
-
-برای مثال:
-
-<div dir="ltr">
-
-```html
-<!-- با در نظر گرفتن: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- زمانی که `myVar` برابر با `true` باشد: -->
-<button disabled="disabled">Click me</button>
-
-<!-- زمانی که `myVar` برابر با `false` باشد: -->
-<button>Click me</button>
-```
-
-</div>
-
-این نشانه ی `disabled` را بسته به `true` یا `false` بودن مقدار `myVar` به عنصر اضافه / حذف می‌کند.
-
-
-نشانه‌های بولین طبق [ مشخصات HTML ](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute) پشتیبانی می‌شوند. برای مثال `disabled`، `readonly`، `required`، `checked`، `hidden`، `selected`، `open` و ... .
-
-> نکته: اگر می‌خواهید وضعیت `false` برای نشانه ی شما نمایش داده شود، مثل
-<span dir="ltr">`aria-*`</span>
-، عبارت
-<span dir="ltr">`.toString()`</span>
-را به مقدار نشانه اضافه کنید و به نشانه متصل کنید. برای مثال : 
-<span dir="ltr">`:aria-expanded="isOpen.toString()"`</span>
- برای هر مقدار `isOpen` به عنصر اضافه خواهد شد، چه `true` باشد و چه `false`.
-
-**تغییر دهنده <span dir="ltr">`.camel`</span>**
-**مثل :**
-<span dir="ltr">`<svg x-bind:view-box.camel="viewBox">`</span>
-
-
-تغییر دهنده `camel`، معادل "camel case" یک نشانه را به مقدار خود متصل می‌کند. در مثال بالا، مقدار نشانه `viewBox`، به نشانه  با نام `viewBox` متصل می‌شود، به جای نشانه با نام `view-box`.
-
----
-
-### `x-on`
-
-> نکته: شما آزادید تا از ترکیب "@" استفاده کنید. : <span dir="ltr">`@click="..."`</span>.
-
-**مثال:** <span dir="ltr">`<button x-on:click="foo = 'bar'"></button>`</span>
-
-**ساختار:** <span dir="ltr">`<button x-on:[event]="[expression]"></button>`</span>
-
-`x-on` به المنتی که به آن متصل شده است، یک "Event Listener" وصل می‌کند. وقتی که "event" مورد نظر اعلان می‌شود، عبارت جاوااسکریپتی که به عنوان مقدار `x-on` ست کرده اید، اجرا می‌شود. شما می‌توانید `x-on` را با هر "Event" ای که برای عنصر مورد نظر در دسترس است استفاده کنید. برای دسترسی به لیست کامل "Event"‌ها و مقادیر احتمالی آنها، به [مرجع "Event"‌ها در MDN](https://developer.mozilla.org/en-US/docs/Web/Events) مراجعه کنید.
-
-اگر هر دیتایی در این عبارت تغییر داده شود، سایر نشانه‌های "متصل" به این دیتا هم آپدیت خواهند شد.
-
-> نکته: شما همچنین می‌توانید در مقدار آن، نام یک متد را قرار دهید.
-
-**مثال:** <span dir="ltr">`<button x-on:click="myFunction"></button>`</span>
-
-این برابر است با: <span dir="ltr">`<button x-on:click="myFunction($event)"></button>`</span>
-
-**تغییر دهنده‌های `keydown`**
-
-**مثال:** <span dir="ltr">`<input type="text" x-on:keydown.escape="open = false">`</span>
-
-شما می‌توانید برای استفاده از تغییر دهنده‌های "keydown" اضافه شده به فرمان `x-on:keydown`، یک نوع کلید خاص را مشخص کنید. در نظر داشته باشید که نام تغییر دهنده ها، معادل "Kebab-case" مقادیر `Event.key` هستند.
-
-مثال ها: `enter`، `escape`، `arrow-up`، `arrow-down`
-
-> نکته: همچنین می‌توانید به "Event" ترکیب کلید‌های سیستمی "Listen" کنید:
-<span dir="ltr">`x-on:keydown.cmd.enter="foo"`</span>
-
-**تغییر دهنده <span dir="ltr">`.away`</span>**
-
-**مثال:** <span dir="ltr">`<div x-on:click.away="showModal = false"></div>`</span>
-
-زمانی که تغییر دهنده ی 
-<span dir="ltr">`.away`</span>
-حاضر باشد، عبارت مسئول رویداد فقط زمانی اجرا می‌شود که رویداد از یک منشا دیگری آغاز شده باشد، نه خود عنصر و فرزندان آن. 
-
-این زمانی به کار می‌آید که می‌خواهیم المنت‌های کشویی و مودال‌ها را با کلیک کاربر روی سایر نقاط DOM مخفی کنیم.
-
-**تغییر دهنده <span dir="ltr">`.prevent`</span>**
-**مثال:** <span dir="ltr">`<input type="checkbox" x-on:click.prevent>`</span>
-
-اضافه کردن `.prevent` به یک شنونده رویداد ( Event Listener )، باعث می‌شود که متد `preventDefault` روی رویداد مورد نظر اجرا شود. در مثال بالا، این باعث می‌شود که عنصر "Checkbox" با کلیک کاربر تیک نمیخورد.
-
-**تغییر دهنده <span dir="ltr">`.stop`</span>**
-**مثال:** <span dir="ltr">`<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`</span>
-
-
-اضافه کردن `.stop` به یک شنونده رویداد، باعث فراخوانی متد `stopPropagation` روی رویداد مورد نظر می‌شود. در مثال بالا، این به آن معنیست که رویداد "click" بصورت حبابی از عنصر `<button>` به عنصر خارجی `<div>` نخواهد رسید. به عبارت دیگر، وقتی کاربر روی `<button>` کلیک می‌کند، متغییر `foo` مقدار `'bar'` را نخواهد گرفت.
-
-**تغییر دهنده <span dir="ltr">`.self`</span>**
-**مثال:** <span dir="ltr">`<div x-on:click.self="foo = 'bar'"><button></button></div>`</span>
-
-اضافه کردن 
-<span dir="ltr">`.self`</span>
- به یک شنونده ی رویداد، باعث می‌شود که عبارت متصل شده به آن فقط زمانی فراخوانی شود که 
-<span dir="ltr">`$event.target`</span>
-خود عنصر باشد. در مثال بالا، این به به آن معنیست که رویداد "click" که بصورت حبابی از عنصر `<button>` به عنصر خارجی `<div>` می‌رسد، عبارت متصل به آن را **اجرا نخواهد کرد**.
-
-**تغییر دهنده <span dir="ltr">`.window`</span>**
-**مثال:** <span dir="ltr">`<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`</span>
-
-اضافه کردن 
-<span dir="ltr">`.window`</span>
- به یک شنونده ی رویداد، باعث می‌شود که شنونده به جای نصب روی نود DOM تعریف شده، روی آبجکت کلی "window" نصب می‌شود. این زمانی به کار می‌آید که می‌خواهید وضعیت یک مؤلفه را به همراه تغییری در "window" تغییر دهید، مثل رویداد "resize". در این مثال، وقتی که عرض پنجره از 768 پیکسل بیشتر شود، ما مودال یا عنصر کشویی مورد نظر را می‌بندیم، در غیر اینصورت وضعیت ثابت می‌ماند.
-
->نکته: شما همچنین می‌توانید از تغییر دهنده
-<span dir="ltr">`.document`</span>
-استفاده کنید تا شنونده را به جای `window` به `document` متصل کنید.
-
-**تغییر دهنده <span dir="ltr">`.once`</span>**
-**مثال:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-اضافه کردن تغییر دهنده
-<span dir="ltr">`.once`</span>
-به یک شنونده رویداد، اطمینان حاصل می‌کند که شنونده فقط یک بار اجرا می‌شود. این زمانی به کار می‌آید که بخواهیم کاری را فقط یک بار انجام دهیم، مثل دریافت بخش هایی از "HTML" و امثال آنها.
-
-
-**تغییر دهنده <span dir="ltr">`.passive`</span>**
-**مثال:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-اضافه کردن تغییر دهنده
-<span dir="ltr">`.passive`</span>
-به یک شنونده رویداد، آن شنونده را منفعل می‌کند، این به آن معناست که
-<span dir="ltr">`preventDefault()`</span>
-روی هیچ رویدادی که پردازش می‌شود کار نخواهد کرد. برای مثال، این رفتار می‌تواند به کارایی اسکرول در دستگاه‌های تاچ کمک کند.
-
-
-**تغییر دهنده <span dir="ltr">`.debounce`</span>**
-**مثال:** `<input x-on:input.debounce="fetchSomething()">`
-
-تغییر دهنده ی `debounce`، اجازه می‌دهد تا یک شنونده ی رویداد را "رد" کرد. به عبارت دیگر، شنونده ی رویداد تا وقتی که یک زمان معین از آخرین اعلان رویداد نگذشته باشد، اجرا نخواهد شد. وقتی که زمان اجرای شنونده ی رویداد فرارسید، آخرین فراخوانی شنونده اجرا خواهد شد.
-
-زمان پیش فرض انتظار "debounce" 250 میلی ثانیه است.
-
-اگر مایلید این زمان را شخصی سازی کنید، می‌توانید به این شکل عمل کنید :
-
-<div dir="ltr">
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-</div>
-
-**تغییر دهنده <span dir="ltr">`.camel`</span>**
-**مثال:** `<input x-on:event-name.camel="doSomething()">`
-
-تغییر دهنده
-<span dir="ltr">`.camel`</span>
-، یک شنونده به رویداد با نامی معادل "camel case" شده ی نام رویداد داده شده متصل خواهد کرد.
-در مثال بالا، عبارت مشخص شده، زمانی اجرا می‌شود که رویدادی با نام `eventName` منتشر شده باشد.
-
----
-
-### `x-model`
-**مثال:** <span dir="ltr">`<input type="text" x-model="foo">`</span>
-
-**ساختار:** <span dir="ltr">`<input type="text" x-model="[data item]">`</span>
-
-`x-model` یک "اتصال دوطرفه داده" به عنصر اضافه می‌کند. به عبارت دیگر، مقدار یک عنصر input را با داده ی متناظر آن در مؤلفه هماهنگ نگه می‌دارد.
-
-> نکته: `x-model` به اندازه ای باهوش است که می‌تواند تغییرات در المنت‌ها ورودی text، checkboxها، دکمه‌های radio، textarea ها، select ها، و multiple select‌ها را تشخیص دهد. در این سناریو ها، باید آنطور که
-[Vue عمل می‌کند](https://vuejs.org/v2/guide/forms.html)
-، عمل کند.
-
-**تغییر دهنده <span dir="ltr">`.number`</span>**
-**مثال:** <span dir="ltr">`<input x-model.number="age">`</span>
-
-تغییر دهنده
-<span dir="ltr">`.number`</span>
-، مقدار یک فیلد ورودی را به عدد تبدیل می‌کند. اگر مقدار مورد نظر قابل پارس کردن به عدد نباشد، مقدار اصلی را باز می‌گرداند.
-
-**تغییر دهنده <span dir="ltr">`.debounce`</span>**
-**مثال:** <span dir="ltr">`<input x-model.debounce="search">`</span>
-
-The `debounce` modifier allows you to add a "debounce" to a value update. In other words, the event handler will NOT run until a certain amount of time has elapsed since the last event that fired. When the handler is ready to be called, the last handler call will execute.
-
-تغییر دهنده
-<span dir="ltr">`.debounce`</span>
-اجازه میدهد که به آپدیت مقدار فیلد ورودی، رفتار رد کردن ( Debounce ) بدهید. به عبارت دیگر، شنونده ی رویداد تا وقتی که یک زمان معین از آخرین اعلان رویداد نگذشته باشد، اجرا نخواهد شد. وقتی که زمان اجرای شنونده ی رویداد فرارسید، آخرین فراخوانی شنونده اجرا خواهد شد.
-
-زمان پیش فرض انتظار "debounce" 250 میلی ثانیه است.
-
-اگر مایلید این زمان را شخصی سازی کنید، می‌توانید به این شکل عمل کنید :
-
-<div dir="ltr">
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
-</div>
-
----
-
-### `x-text`
-**مثال:** <span dir="ltr">`<span x-text="foo"></span>`</span>
-
-**ساختار:** <span dir="ltr">`<span x-text="[expression]"`</span>
-
-`x-text` مانند `x-bind` عمل می‌کند، اما به جای آپدیت کردن مقدار یک نشانه، مقدار `innerText` عنصر را آپدیت می‌کند.
-
----
-
-### `x-html`
-**مثال:** <span dir="ltr">`<span x-html="foo"></span>`</span>
-
-**ساختار:** <span dir="ltr">`<span x-html="[expression]"`</span>
-
-`x-text` مانند `x-bind` عمل می‌کند، اما به جای آپدیت کردن مقدار یک نشانه، مقدار `innerHTML` عنصر را آپدیت می‌کند.
-
-
-> :اخطار: **فقط روی محتوای قابل اعتماد استفاده کنید، هرگز روی محتوایی که کاربر وارد کرده است استفاده نکنید.** :اخطار:
->
-> رندر کردن HTML از سمت شخص ثالث، به راحتی منجر به آسیب پذیری [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) خواهد شد.
-
----
-
-### `x-ref`
-**مثال:** <span dir="ltr">`<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`</span>
-
-**ساختار:** <span dir="ltr">`<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`</span>
-
-`x-ref` یک راه ساده برای دریافت عنصر DOM بصورت خام از مؤلفهتان فراهم می‌کند. با قرار دادن نشانه ی `x-ref` روی یک المنت، شما عنصر مورد نظر را در اختیار تمامی شنونده‌های رویداد قرار خواهید داد که می‌توانند از طریق آبجکت
-<span dir="ltr">`$refs`</span>
-به آن دسترسی داشته باشند.
-
-این یک جایگزین مفید به جای اختصاص دادن id روی المنت‌ها و استفاده از
-<span dir="ltr">`document.querySelector`</span>
-در همه جای کدتان است.
-
-> نکته: اگر نیاز داشته باشید، می‌توانید از مقادیر داینامیک هم برای `x-ref` استفاده کنید:
-<span dir="ltr">`<span :x-ref="item.id"></span>`</span>
-
----
-
-### `x-if`
-**مثال:** <span dir="ltr">`<template x-if="true"><div>Some Element</div></template>`</span>
-
-**ساختار:** <span dir="ltr">`<template x-if="[expression]"><div>Some Element</div></template>`</span>
-
-برای مواقعی که استفاده از `x-show` کافی نیست، می‌توانید از `x-if` استفاده کنید تا عنصر را بصورت کامل از DOM حذف کند.
-یادآوری `x-show` : درج/حذف استایل display: none; روی عنصر بسته به نتیجه عبارت محتوا ( true یا false )
-
-لازم است که از `x-if` روی تگ
-<span dir="ltr">`<template></template>`</span>
-استفاده شود، به این دلیل که Alpine از DOM مجازی استفاده نمی‌کند، و این روش پیاده سازی اجازه می‌دهد که Alpine قدرتمند بماند و از DOM واقعی برای جادوی خودش استفاده کند.
-
-> نکته: `x-if` باید در داخل تگ 
-<span dir="ltr">`<template></template>`</span>
-یک عنصر ریشه بیشتر نداشته باشد.
-
-> نکته: در هنگام استفاده از `template` داخل تگ `svg`، باید یک
-[polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)
-به صفحه اضافه کنید که قبل از مقداردهی اولیه Alpine اجرا شود.
-
----
-
-### `x-for`
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-</div>
-
-> نکته: اتصال `:key` اختیاری است، اما به شدت توصیه می‌شود.
-
-`x-for` در اختیار شماست برای زمانی که می‌خواهید به ازای هر آیتم داخل یک آرایه، یک نود DOM جدید بسازید. این باید شبیه `v-for` در Vue باشد، با این تفاوت که باید روی تگ `template` قرار گیرد، نه روی یک عنصر DOM معمولی.
-
-اگر می‌خواهید به اندیس کنونی حلقه دستیابی داشته باشید، از سینتکس زیر استفاده کنید :
-
-<div dir="ltr">
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- You can also reference "index" inside the iteration if you need. -->
-    <div x-text="index"></div>
-</template>
-```
-
-</div>
-
-اگر می‌خواهید به آبجکت آرایه ( کالکشن ) دور مورد نظر دست یابید، از سینتکس زیر استفاده کنید:
-
-<div dir="ltr">
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <div>
-        <!-- You can also reference "collection" inside the iteration if you need. -->
-        <!-- Current item. -->
-        <div x-text="item"></div>
-        <!-- Same as above. -->
-        <div x-text="collection[index]"></div>
-        <!-- Previous item. -->
-        <div x-text="collection[index - 1]"></div>
-    </div>
-</template>
-```
-
-</div>
-
-> نکته: `x-for` باید در داخل تگ 
-<span dir="ltr">`<template></template>`</span>
-یک عنصر ریشه بیشتر نداشته باشد.
-
-> نکته: در هنگام استفاده از `template` داخل تگ `svg`، باید یک
-[polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)
-به صفحه اضافه کنید که قبل از مقداردهی اولیه Alpine اجرا شود.
-
-#### `x-for`‌های تودرتو :
-شما می‌توانید حلقه‌های `x-for` را داخل هم قرار دهید، اما باید هر حلقه را درون یک عنصر بگذارید، برای مثال :
-
-<div dir="ltr">
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-</div>
-
-#### دور زدن روی یک رنج
-
-Alpine از سینتکس `i in n` پشتیبانی می‌کند، که `n` یک عدد است و به شما اجازه ی دور زدن حول یک رنج ثابت از عناصر را می‌دهد.
-
-<div dir="ltr">
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
-</div>
-
----
-
-### `x-transition`
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-</div>
-
-<div dir="ltr">
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-</div>
-
-> مثال بالا، از کلاس‌های چهارچوب [Tailwind CSS](https://tailwindcss.com) استفاده می‌کند.
-
-آلپاین شش فرمان مختلف transition برای قراردادن کلاس در مراحل گوناگون transition یک عنصر بین وضعیت مخفی (Hidden) و (Shown) در اختیار قرار می‌دهد. این فرمان‌ها، هم با `x-show` کار می‌کنند و هم با `x-if`.
-
-این فرمان‌ها کاملا مثل فرمان‌های Transition چهارچوب VueJS رفتار می‌کنند، منتها نام گذاری اینها متفاوت و معقولانه تر است.
-
-| فرمان‌ها | توضیحات |
-| --- | --- |
-| <div dir="ltr">`:enter`</div> | در کل فاز ورود اعمال می‌شود. |
-| <div dir="ltr">`:enter-start`</div> | قبل از اینکه عنصر وارد شود اضافه می‌شود، و 1 فریم بعد از ورود عنصر حذف می‌شود. |
-| <div dir="ltr">`:enter-end`</div> | 1 فریم بعد از ورود عنصر اضافه می‌شود ( زمانی که `enter-start` حذف میشود )، وقتی که transition یا animation پایان می‌یابد، حذف می‌شود. 
-| <div dir="ltr">`:leave`</div> | در کل فاز خروج اعمال می‌شود. |
-| <div dir="ltr">`:leave-start`</div> | به محض شروع transition خروجی اضافه میشود، 1 فریم بعد حذف می‌شود. |
-| <div dir="ltr">`:leave-end`</div> | 1 فریم بعد از شروع transition خروجی اضافه می‌شود ( زمانی که `leave-start` حذف میشود )، وقتی که transition یا animation پایان می‌یابد، حذف می‌شود. 
-
----
-
-### `x-spread`
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">کشو رو باز کن</button>
-
-    <span x-spread="dialogue">محتوای کشو </span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-</div>
-
-`x-spread` به شما اجازه می‌دهد اتصالات Alpine برای یک عنصر را به یک آبجکت قابل استفاده مجدد استخراج کنید.
-
-کلید‌های آبجکت، فرمان‌ها هستند ( می‌تواند هر فرمان ای به همراه تغییر دهنده هایش باشد )، و مقادیر آن، متد هایی هستند که توسط Alpine ارزیابی می‌شوند.
-
-
-> نکته: برای استفاده از x-spread، یک سری هشدار‌ها وجود دارد :
-> - وقتی فرمان ای که می‌خواهیم "spread" کنیم `x-for` باشد، باید از متد مورد نظر، یک عبارت نرمال داخل یک رشته را برگردانید. برای مثال : <span dir="ltr">`['x-for']() { return 'item in items' }`</span>.
-> - `x-data` و `x-init` را نمی‌توان داخل یک آبجکت "spread" استفاده کرد.
-
----
-
-### `x-cloak`
-**مثال:** <span dir="ltr">`<div x-data="{}" x-cloak></div>`</span>
-
-نشانه‌های `x-cloak` در زمان مقدار دهی اولیه Alpine از عنصر حذف خواهد شد، این رفتار برای مخفی کردن DOM تا زمان مقداردهی اولیه کاربرد دارد. به طور معمول، این استایل کلی را برای این هدف اضافه می‌کنند.
-
-<div dir="ltr">
-
-```html
-<style>
-    [x-cloak] {
-        display: none !important;
-    }
-</style>
-```
-
-</div>
-
-### ویژگی‌های جادویی
-
-> به جز <span dir="ltr">`$el`</span>، سایر ویژگی‌های جادویی **داخل `x-data` در دسترس نیستند**، زیرا هنوز مؤلفه مقدار دهی اولیه نشده.
-
----
-
-### <span dir="ltr">`$el`</span>
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">من را با "foo" جایگزین کن</button>
-</div>
-```
-
-</div>
-
-<span dir="ltr">`$el`</span> یک ویژگی جادویی است که می‌توان با استفاده از آن، نود DOM ریشه ی مؤلفه را دریافت کرد.
-
-### <span dir="ltr">`$refs`</span>
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-</div>
-
-<span dir="ltr">`$refs`</span> یک ویژگی جادویی است که با استفاده از آن می‌توان المنت‌های DOM علامت خورده با x-ref داخل مؤلفه را دریافت کرد. این زمانی به کار می‌آید که می‌خواهیم بطور دستی المنت‌های DOM را دستکاری کنیم.
-
----
-
-### <span dir="ltr">`$event`</span>
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-</div>
-
-<span dir="ltr">`$event`</span>
-یک ویژگی جادویی است که با استفاده از آن می‌توان داخل یک شنونده ی رویداد، آبجکت "Event" محلی مرورگر از دریافت کرد.
-
-> نکته: ویژگی <span dir="ltr">`$event`</span> فقط در عبارات DOM در دسترس است.
-
-اگر می‌خواهید از داخل یک متد جاوااسکریپت به
-<span dir="ltr">`$event`</span>
-دسترسی داشته باشید، می‌توانید مستقیما به متد اضافه کنید:
-
-<span dir="ltr">`<button x-on:click="myFunction($event)"></button>`</span>
-
----
-
-### <span dir="ltr">`$dispatch`</span>
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- وقتی کلیک شود، رشته "bar" را در کنسول مرورگر لاگ می‌کند. ( console.log ) -->
-</div>
-```
-
-</div>
-
-**نکته درباره انتشار رویداد ( Event Propagation )**
-
-توجه داشته باشید که به علت 
-[حرکت حبابی رویداد](https://en.wikipedia.org/wiki/Event_bubbling)
-، وقتی می‌خواهید رویدادی را بگیرید که توسط نودی فرستاده شده، که تحت همان سلسله مراتب ( شجره نامه ) عنصر شماست، نیاز خواهید داشت که از تغییر دهنده 
-[`.window`](https://github.com/alpinejs/alpine#x-on)
- استفاده کنید.
-
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-</div>
-
-> این کار نمی‌کند، زیرا وقتی `custom-event` اعلان می‌شود، به سمت جد مشترکشان، عنصر `div` منتشر می‌شود.
-
-**ارسال به مؤلفه ها**
-
-شما همچنین می‌توانید از تکنیک قبلی برای ارتباط بین مؤلفه‌ها استفاده کنید.
-
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- وقتی کلیک شود، رشته "Hello World" را در کنسول مرورگر لاگ می‌کند. ( console.log ) -->
-```
-
-</div>
-
-`$dispatch` یک میانبر برای ساخت یک `CustomEvent` و ارسال آن توسط `.dispatchEvent()` بصورت داخلی است. دلایل خوب زیادی برای انتقال دیتا بین مؤلفه‌ها با استفاده از رویداد‌های شخصی وجود دارد.
-برای اطلاعات بیشتر درباره اساس سیستم `CustomEvent` در مرورگر ها
-[اینجا را بخوانید](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events)
-
-
-متوجه خواهید شد که هر دیتایی که به عنوان پارامتر دوم به
-<span dir="ltr">`$dispatch('some-event', { some: 'data' })`</span>
-فرستاده شود، توسط ویژگی "detail" در رویداد جدید در دسترس قرار می‌گیرد : 
-<span dir="ltr">`$event.detail.some`</span> .
-اتصال دیتا به ویژگی `.detail` در رویداد‌های شخصی، یک استاندارد برای `CustomEvent`‌ها در مرورگر هاست.
-
-شما همچنین می‌توانید از `$dispatch()` برای راه انداختن آپدیت برای اتصالات `x-model` استفاده کنید.
-
-<div dir="ltr">
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- پس از کلیک دکمه، `x-model` رویداد "input" حباب شده را دریافت می‌کند، و مقدار متغیر "foo" را به "baz" تغییر می‌دهد.  -->
-    </span>
-</div>
-```
-
-</div>
-
-> نکته: ویژگی <span dir="ltr">`$dispatch`</span> فقط در عبارات DOM در دسترس است.
-
-
-اگر می‌خواهید از داخل یک متد جاوااسکریپت به
-<span dir="ltr">`$dispatch`</span>
-دسترسی داشته باشید، می‌توانید مستقیما به متد اضافه کنید:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### <span dir="ltr">`$nextTick`</span>
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-</div>
-
-<span dir="ltr">`$nextTick`</span>
-یک ویژگی جادویی است که به شما اجازه می‌دهد یک عبارت را بعد از اینکه Alpine آپدیت‌های ری اکتیو مربوط به DOM را انجام داد، اجرا کند. این زمانی به کار می‌آید که شما می‌خواهید با DOM کار کنید، اما فقط بعد از اینکه تغییرات دیتایی انجام شده را اعمال کرده باشد.
-
----
-
-### `$watch`
-**مثال:**
-
-<div dir="ltr">
-
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-</div>
-
-شما می‌توانید یک ویژگی مؤلفه را با متد جادویی
-<span dir="ltr">`$watch`</span>
-تحت نظر بگیرید. در مثال بالا، وقتی دکمه کلیک می‌شود و متغیر `open` تغییر می‌کند، متد فراهم شده فراخوانی می‌شود و مقدار جدید را در کنسول مرورگر لاگ می‌کند.
-
-## امنیت
-
-اگر تهدیدی امنیتی در سیستم پیدا کردید، لطفا یک ایمیل به آدرس [calebporzio@gmail.com]() ارسال کنید.
-
-</div>
-
-آلپاین به یک پیاده‌سازی سفارشی از شیء`function` برای ارزیابی فرمان‌هایش متکی است. فارغ از اینک به مراتب از `eval()` امن‌تر است، استفاده از آن در برخی محیط‌ها مانند Google Chrome App به خاطر سیاست امنیت محتوا (CSP) محدودکننده، ممنوع است.
-
-اگر یکی وب‌گاهی با داده‌های حساس و که نیازمند [CSP](https://csp.withgoogle.com/docs/strict-csp.html) است از آلپاین استفاده می‌کنید لازم است `unsafe-eval` را در سیاست خود وارد کنید. یک سیاست مستحکم که به درستی پیکربندی شده باشد، به حفاظت است کابران‌تان زمانی که داده‌های شخصی یا مالی استفاده می‌شود کمک می‌کند.
-
-از آن جایی که یک سیاست به تمام اسکریپت‌های یک صفحه اعمال می‌شود، این مساله دارای اهمیت است که سایر کتاب‌خانه‌های خارجی که در وب‌گاه وارد شده‌اند به دقت مورد بازبینی قرار گرفته و اطمینان حاصل شود که قابل اعتماد هستند و آسیب‌پذیری‌های XSS را به واسطه استفاده از تابع `eval()` یا دستکاری ساختار DOM به منظور تزریع کدهای بد در صفحه ایجاد نمی‌کنند.
-
-## نقشه راه نگارش ۳
-* Move from `x-ref` to `ref` for Vue parity?
-* Add `Alpine.directive()`
-* Add `Alpine.component('foo', {...})` (With magic `__init()` method)
-* Dispatch Alpine events for "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Remove "object" (and array) syntax from `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) to add support for object syntax for the `style` attribute)
-* Improve `x-for` mutation reactivity ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Add "deep watching" support in V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Add `$el` shortcut
-* Change `@click.away` to `@click.outside`?
-
-## پروانه
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.

+ 0 - 793
README.fr.md

@@ -1,793 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js offre les propriétés déclaratives et réactives des grands frameworks tels que Vue ou React à un coût bien moindre.
-
-Le DOM est préservé, et vous pouvez lui attribuer les comportements comme bon vous semble.
-
-C'est un peu le [Tailwind](https://tailwindcss.com/) du JavaScript.
-
-> Note : La syntaxe de cet outil est presque entièrement inspirée de [Vue](https://vuejs.org/) (et par extension [Angular](https://angularjs.org/)). Je suis à jamais reconnaissant pour ce qu'ils ont apporté au web.
-
-## Documentations traduites
-
-| Langue | Lien vers la documentation |
-| --- | --- |
-| Chinois Traditionel | [**繁體中文說明文件**](./README.zh-TW.md) |
-| Allemand | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesien | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japonais | [**日本語ドキュメント**](./README.ja.md) |
-| Portuguais | [**Documentação em Português**](./README.pt.md) |
-| Russe | [**Документация на русском**](./README.ru.md) |
-| Espagnol | [**Documentación en Español**](./README.es.md) |
-| Français | [**Documentation en Français**](./README.fr.md) |
-
-## Installation
-
-**Avec CDN :** Ajoutez le script suivant à la fin de votre section `<head>`.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-C'est tout. L'initialisation est automatique.
-
-Dans les environnements de production, il est recommandé d'inscrire un numéro de version spécifique dans le lien, afin d'éviter qu'une nouvelle version ne provoque un comportement inattendu.
-Par exemple, pour utiliser la version `2.8.2` (la dernière) :
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Avec npm :** Installer le paquet avec npm.
-```js
-npm i alpinejs
-```
-
-Importez-le dans votre script.
-```js
-import 'alpinejs'
-```
-
-**Pour la compatibilité IE11** utilisez plutôt les scripts suivants.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-Le schéma ci-dessus représente le [schéma module/nomodule](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/). Il permet  de faire en sorte que le pack soit automatiquement chargé dans les navigateurs modernes, mais aussi pour IE11 et les autres navigateurs anciens.
-
-## Utilisation
-
-*Menu déroulant/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Ouvrir le menu</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Elément de menu
-    </ul>
-</div>
-```
-
-*Onglets*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Onglet Foo</div>
-    <div x-show="tab === 'bar'">Onglet Bar</div>
-</div>
-```
-
-Vous pouvez même l'utiliser pour faire des choses moins courantes:
-*Précharger le HTML d'un élément de menu lors du survol.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Afficher Menu</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Chargement Spinner...
-    </div>
-</div>
-```
-
-## Apprentissage
-
-Il existe 14 directives disponibles:
-
-| Directive | Description |
-| --- | --- |
-| [`x-data`](#x-data) | Déclare la portée d'un nouveau composant. |
-| [`x-init`](#x-init) | Exécute une expression lors de l'initialisation d'un composant. |
-| [`x-show`](#x-show) | Alterne `display: none;` sur l'élément selon l'expression (true ou false). |
-| [`x-bind`](#x-bind) | Fixe la valeur d'un attribut au résultat d'une expression JS. |
-| [`x-on`](#x-on) | Attache un écouteur d'évènement à l'élément. Exécute une expression JS lorsque l'évènement est déclenché. |
-| [`x-model`](#x-model) | Ajoute une liaison de données bidirectionnelle (two-way data binding) à un élément. Conserve la synchronisation de l'élément d'entrée avec les données du composant. |
-| [`x-text`](#x-text) | Fonctionne de manière similaire à `x-bind`, mais avec mise à jour du `innerText` d'un élément. |
-| [`x-html`](#x-html) | Fonctionne de manière similaire à `x-bind`, mais avec mise à jour du `innerHTML` d'un élément. |
-| [`x-ref`](#x-ref) | Un moyen pratique de récupérer des éléments bruts du DOM de votre composant. |
-| [`x-if`](#x-if) | Supprime totalement un élément du DOM. Doit s'utiliser avec la balise `<template>`. |
-| [`x-for`](#x-for) | Crée de nouveaux noeuds DOM pour chaque élément d'un tableau. Doit s'utiliser avec la balise `<template>`. |
-| [`x-transition`](#x-transition) | Directives pour renseigner les classes aux différentes étapes de transition d'un élément. |
-| [`x-spread`](#x-spread) | Permet de lier l'objet de directives d'Alpine à un élément pour une meilleure réutilisation. |
-| [`x-cloak`](#x-cloak) | Cet attribut est supprimé lorsque Alpine s'initialise. Utile pour masquer les DOM pré-initialisés. |
-
-Et 6 propriétés magiques:
-
-| Propriétés magiques | Description |
-| --- | --- |
-| [`$el`](#el) |  Récupère le nœud DOM du composant racine. |
-| [`$refs`](#refs) | Récupère les éléments du DOM marqués par `x-ref` à l'intérieur du composant. |
-| [`$event`](#event) | Récupère l'objet natif "Event" du navigateur dans un écouteur d'évènements.  |
-| [`$dispatch`](#dispatch) | Crée un `CustomEvent` et le distribue à l'aide de `.dispatchEvent()` en interne. |
-| [`$nextTick`](#nexttick) | Exécute une expression donnée APRES qu'Alpine ait fait ses mises à jour réactives du DOM. |
-| [`$watch`](#watch) | Effectue un rappel (callback) préalablement défini lorsque la propriété d'un composant "surveillé" (watch) est modifiée. |
-
-
-## Sponsors
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Votre logo ici ? [DM sur Twitter](https://twitter.com/calebporzio)**
-
-## Projets Communautaires
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### Directives
-
----
-
-### `x-data`
-
-**Exemple :** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Structure :** `<div x-data="[object literal]">...</div>`
-
-`x-data` déclare la portée d'un nouveau composant. Indique au framework d'initialiser un nouveau composant avec le prochain objet de données.
-
-Il faut voir cela comme la propriété de `données` d'un composant Vue.
-
-**Extraction de la Logique des Composants**
-
-Vous pouvez extraire les données (et le comportement) en fonctions réutilisables :
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Ouvrir</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Menu déroulant
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Pour les utilisateurs de modules bundler**, notez que Alpine.js accède à des fonctions qui sont dans la portée globale (`window`). Vous devrez explicitement assigner vos fonctions à `window` pour les utiliser avec `x-data`. Par exemple `window.dropdown = function () {}` ( c'est parce qu'avec Webpack, Rollup, Parcel etc. les fonctions que vous écrivez sont par défaut dans la portée du module et non dans celle de la page - `window`).
-
-
-Vous pouvez également mélanger plusieurs objets de données en utilisant la décomposition d'objet :
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Exemple :** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Structure :** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` exécute une expression lorsqu'un composant est initialisé.
-
-Si vous souhaitez exécuter du code APRES qu'Alpine ait effectué ses mises à jour initiales dans le DOM (un peu comme le hook `mounted()` de VueJS), vous pouvez retourner un callback depuis `x-init`, et il sera ensuite exécuté :
-
-`x-init="() => { // on a ici accès à l'état du DOM post-initialisation // }"`
-
----
-
-### `x-show`
-**Exemple :** `<div x-show="open"></div>`
-
-**Structure :** `<div x-show="[expression]"></div>`
-
-`x-show` alterne le style `display: none;` sur l'élément selon que l'expression retourne `true` ou `false`.
-
-**x-show.transition**
-
-`x-show.transition` est une API de commodité pour rendre vos `x-show` plus agréables en utilisant des transitions CSS.
-
-```html
-<div x-show.transition="open">
-    Le contenu ici fera l'objet de transitions "in" et "out".
-</div>
-```
-
-| Directive | Description |
-| --- | --- |
-| `x-show.transition` | Fondu et échelle simultanés. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Transition `in` seule. |
-| `x-show.transition.out` | Transition `out` seule. |
-| `x-show.transition.opacity` |Fondu seul. |
-| `x-show.transition.scale` | Echelle seule. |
-| `x-show.transition.scale.75` | Personnalise la modification CSS de l'échelle `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Fixe la transition "in" à 200 ms. La transition "out" sera fixée à la moitié de cette valeur (100 ms). |
-| `x-show.transition.origin.top.right` | Personnalise l'origine de la transformation CSS `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Durées différentes pour "in" et "out". |
-
-> Note : Tous ces modificateurs de transition peuvent être utilisés conjointement les uns avec les autres. Il est même possible de faire ceci (bien que ridicule lol) : `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Note : `x-show` attendra que les objets enfants aient terminé leur transition. Si vous voulez contourner ce comportement, ajoutez le modificateur `.immediate` :
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Note : vous êtes libre d'utiliser la syntaxe ":" plus courte: `:type="..."`.
-
-**Exemple :** `<input x-bind:type="inputType">`
-
-**Structure :** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` fixe la valeur d'un attribut au résultat d'une expression JavaScript. Cette expression a accès à toutes les clés de l'objet de données du composant, et se met à jour à chaque fois que ses données changent.
-
-> Note : les liaisons d'attributs (attribute bindings) ne se mettent à jour QUE lorsque leurs dépendances changent. Le framework est suffisamment intelligent pour observer les changements de données et détecter les liens qui les concernent.
-
-**`x-bind` pour les attributs de classe**
-
-`x-bind` se comporte un peu différemment lorsqu'il est lié à l'attribut `class`.
-
-En ce qui concerne les classes, vous passez un objet dont les clés sont des noms de classe, et les valeurs sont des expressions booléennes pour déterminer si ces noms de classe sont appliqués ou non.
-
-Par exemple :
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-Dans cet exemple, la classe "hidden" ne sera appliquée que si la valeur de l'attribut de données `foo` est `true`.
-
-**`x-bind` pour les attributs booléens**
-
-`x-bind` supporte les attributs booléens de la même manière que les attributs de valeur, en utilisant une variable comme condition ou toute expression JavaScript qui se résout en `true` ou `false`.
-
-Par exemple :
-```html
-<!-- Soit: -->
-<button x-bind:disabled="myVar">Cliquez moi</button>
-
-<!-- Lorsque myVar == true: -->
-<button disabled="disabled">Cliquez moi</button>
-
-<!-- Lorsque myVar == false: -->
-<button>Cliquez moi</button>
-```
-
-Cela ajoute ou supprime l'attribut `disabled` lorsque la valeur de `myVar` est respectivement vraie ou fausse.
-
-Les attributs booléens sont pris en charge conformément à la [spécification HTML](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), par exemple `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-> Note : Si vous avez besoin d'un état `false` pour afficher un attribut, comme par exemple `aria-*`, chainez `.toString()` à la valeur tout en liant l'attribut (bind). Par exemple : `:aria-expanded="isOpen.toString()"` va persister, que `isOpen` soit `true` ou `false`.
-
-**Modificateur `.camel`**
-**Exemple :** `<svg x-bind:view-box.camel="viewBox">`
-
-Le modificateur `camel` liera l'équivalent "camel case" au nom de l'attribut. Dans l'exemple ci-dessus, la valeur de `viewBox` sera liée à l'attribut `viewBox` par opposition à l'attribut  `view-box`.
-
----
-
-### `x-on`
-
-> Note : Vous êtes libre d'utiliser la syntaxe "@" plus courte : `@click="..."`.
-
-**Exemple :** `<button x-on:click="foo = 'bar'"></button>`
-
-**Structure :** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` rattache un écouteur d'événement à l'élément sur lequel il est déclaré. Lorsque cet événement est émis, l'expression JavaScript définie comme sa valeur est exécutée. Vous pouvez utiliser `x-on` avec tout événement disponible pour l'élément sur lequel vous ajoutez la directive. Pour une liste complète des événements, voir [la référence des événements sur le MDN](https://developer.mozilla.org/fr/docs/Web/Events).
-
-Si une donnée est modifiée dans l'expression, les attributs des autres éléments "liés" à cette donnée seront mis à jour.
-
-> Note : Vous pouvez également spécifier un nom de fonction JavaScript.
-
-**Exemple :** `<button x-on:click="myFunction"></button>`
-
-C'est la même chose que : `<button x-on:click="myFunction($event)"></button>`
-
-**Modificateurs `keydown`**
-
-**Exemple :** `<input type="text" x-on:keydown.escape="open = false">`
-
-Vous pouvez indiquer des clés spécifiques à écouter à l'aide des modificateurs keydown rajoutés à la directive `x-on:keydown`. Notez que les modificateurs sont des versions kebab-case des valeurs de `Event.key`.
-
-Exemples : `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Note : Vous pouvez également écouter des combinaisons de commandes système comme : `x-on:keydown.cmd.enter="foo"`
-
-**Modificateur `.away`**
-
-**Exemple :** `<div x-on:click.away="showModal = false"></div>`
-
-Lorsque le modificateur `.away` est présent, le gestionnaire d'événement ne sera exécuté que lorsque l'événement provient d'une source externe à lui-même ou ses enfants.
-
-Cela s'avère utile pour masquer des menus déroulants ou des fenêtres modales lorsque l'utilisateur clique ailleurs.
-
-**Modificateur `.prevent`**
-**Exemple :** `<input type="checkbox" x-on:click.prevent>`
-
-L'ajout de `.prevent` à un écouteur d'événement appelle `preventDefault` sur l'événement déclenché. Dans l'exemple ci-dessus, cela signifie que la case à cocher ne sera pas réellement cochée lorsqu'un utilisateur cliquera dessus.
-
-**Modificateur `.stop`**
-**Exemple :** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-L'ajout de `.stop` à un écouteur d'événement appelle `stopPropagation` sur l'événement déclenché. Dans l'exemple ci-dessus, cela signifie que l'évènement "click" ne se propage pas à l'élément `<div>`. En d'autres termes, lorqu'un utilisateur clique sur le bouton, `foo` ne prend pas la valeur `'bar'`.
-
-**Modificateur `.self`**
-**Exemple :** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-L'ajout de `.self` à un écouteur d'évènement déclenchera une action seulement si `$event.target` est lui-même l'élément. Dans l'exemple ci-dessus, cela signifie que lorsqu'on clique sur le bouton, **aucune** action ne sera déclenchée.
-
-**Modificateur `.window`**
-**Exemple :** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-L'ajout de `.window` à un écouteur d'événement installera l'écouteur sur l'objet global "window" au lieu du noeud DOM sur lequel il est déclaré. Ceci est utile quand vous souhaitez modifier l'état d'un composant lorsque quelque chose change dans la fenêtre, comme l'événement de redimensionnement. Dans l'exemple ci-dessus, lorsque la fenêtre s'agrandit de plus de 768 pixels de large, nous fermons le modal/dropdown, sinon nous maintenons le même état.
-
->Note : Vous pouvez également utiliser le modificateur `.document` pour rattacher des écouteurs d'évènements à `document` au lieu de `window`
-
-**Modificateur `.once`**
-**Exemple :** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-L'ajout du modificateur `.once` à un écouteur d'événement garantira que l'écouteur ne sera traité qu'une seule fois. C'est utile pour les choses que vous ne voulez faire qu'une seule fois, comme la récupération de morceaux de HTML et autres.
-
-**Modificateur `.passive`**
-**Exemple :** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-L'ajout du modificateur `.passive` à un écouteur d'événement rendra l'écouteur passif, ce qui signifie que `preventDefault()` ne fonctionnera pas sur les événements en cours de traitement, cela peut aider, par exemple pour les performances de défilement sur les périphériques tactiles.
-
-**Modificateur `.debounce`**
-**Exemple :** `<input x-on:input.debounce="fetchSomething()">`
-
-Le modificateur `debounce` vous permet de limiter la fréquence d'exécution d'un gestionnaire d'événements. En d'autres termes, le gestionnaire d'événements ne fonctionnera PAS avant qu'un certain temps ne se soit écoulé depuis le dernier événement qui s'est déclenché. Lorsque le gestionnaire est prêt à être appelé, le dernier appel du gestionnaire s'exécutera.
-
-Le temps d'attente par défaut de la fonction de rétention ("debounce") est de 250 millisecondes.
-
-Pour personnaliser cette fonction, vous pouvez définir un temps d'attente :
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**Modificateur `.camel`**
-**Exemple :** `<input x-on:event-name.camel="doSomething()">`
-
-Le modificateur `camel` attache un écouteur d'évènement en version "camel case" du nom d'un évènement. Dans l'exemple ci-dessus, l'expression est évaluée lorsque l'évènement `eventName` est déclenché sur l'élément.
-
----
-
-### `x-model`
-**Exemple :** `<input type="text" x-model="foo">`
-
-**Structure :** `<input type="text" x-model="[data item]">`
-
-`x-model` ajoute à un élément une liaison de données à double sens ("two-way data binding"). En d'autres termes, la valeur de l'élément d'entrée sera maintenue en synchronisation avec la valeur de l'élément de données du composant.
-
-> Note : `x-model` est assez intelligent pour détecter les changements sur les entrées de texte, les cases à cocher, les boutons radio, les textareas, les sélections et les sélections multiples. Il devrait se comporter [comme le ferait Vue](https://fr.vuejs.org/v2/guide/forms.html) dans ces scénarios.
-
-**Modificateur `.number`**
-**Exemple :** `<input x-model.number="age">`
-
-Le modificateur `number` convertira la valeur de l'entrée en un nombre. Si la valeur ne peut pas être analysée comme un nombre valide, la valeur originale est renvoyée.
-
-**Modificateur `.debounce`**
-**Exemple :** `<input x-model.debounce="search">`
-
-Le modificateur `debounce` vous permet d'émettre un temps de réponse sur la mise à jour d'une valeur. En d'autres termes, le gestionnaire d'événements ne fonctionnera PAS avant qu'un certain temps ne se soit écoulé depuis le dernier événement qui s'est déclenché. Lorsque le gestionnaire est prêt à être appelé, le dernier appel du gestionnaire s'exécutera.
-
-Le temps d'attente par défaut de la fonction de rétention ("debounce") est de 250 millisecondes.
-
-Pour personnaliser cette fonction, vous pouvez définir un temps d'attente :
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Exemple :** `<span x-text="foo"></span>`
-
-**Structure :** `<span x-text="[expression]"`
-
-`x-text` fonctionne comme `x-bind`, sauf qu'au lieu de mettre à jour la valeur d'un attribut, il mettra à jour le `innerText` d'un élément.
-
----
-
-### `x-html`
-**Exemple :** `<span x-html="foo"></span>`
-
-**Structure :** `<span x-html="[expression]"`
-
-`x-html` fonctionne comme `x-bind`, sauf qu'au lieu de mettre à jour la valeur d'un attribut, il mettra à jour le `innerHTML` d'un élément.
-
-> :warning: **A n'utiliser uniquement sur du contenu de confiance et jamais sur du contenu fourni par l'utilisateur.** :warning:
->
-> Le rendu dynamique de HTML provenant de tiers peut facilement conduire à des vulnérabilités [XSS](https://developer.mozilla.org/fr/docs/Glossaire/Cross-site_scripting).
-
----
-
-### `x-ref`
-**Exemple :** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Structure :** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-La fonction `x-ref` offre un moyen pratique de récupérer les éléments DOM bruts de votre composant. En plaçant un attribut `x-ref` sur un élément, vous le rendez disponible à tous les gestionnaires d'événements à l'intérieur d'un objet appelé `$refs`.
-
-C'est une alternative utile à la mise en place d'identifiants et à l'utilisation de `document.querySelector` partout.
-
-> Note : si vous en avez besoin, vous pouvez également lier des valeurs dynamiques pour x-ref : `<span :x-ref="item.id"></span>`.
-
----
-
-### `x-if`
-**Exemple :** `<template x-if="true"><div>Quelques éléments</div></template>`
-
-**Structure :** `<template x-if="[expression]"><div>Quelques éléments</div></template>`
-
-Pour les cas où `x-show` n'est pas suffisant (`x-show` met un élément à `display : none` s'il est faux), `x-if` peut être utilisé pour supprimer complètement un élément du DOM.
-
-Il est important que `x-if` soit utilisé sur des balises `<template></template>` car Alpine n'utilise pas de DOM virtuel. Cette implémentation permet à Alpine de rester robuste et d'utiliser le DOM réel pour opérer sa magie.
-
-> Note : `x-if` doit avoir une racine d'élément unique (root element) à l'intérieur des balises `<template></template>`.
-
-> Note : Lorsque vous utilisez un `template` dans une balise `svg`, vous devez ajouter un [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) qui doit être exécuté avant que Alpine.js ne soit initialisé.
-
----
-
-### `x-for`
-**Exemple :**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Note : la liaison `:key` est facultative, mais FORTEMENT recommandée.
-
-La fonction `x-for` est disponible dans les cas où vous souhaitez créer de nouveaux nœuds DOM pour chaque élément d'un tableau. Cela devrait ressembler à `v-for` dans Vue, à l'exception de la nécessité d'exister sur une balise `template`, et non sur un élément DOM ordinaire.
-
-Si vous voulez accéder à l'index actuel de l'itération, utilisez la syntaxe suivante :
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- Vous pouvez également faire référence à un "index" à l'intérieur de l'itération si vous le souhaitez. -->
-    <div x-text="index"></div>
-</template>
-```
-
-Si vous voulez accéder à l'objet tableau (collection) de l'itération, utilisez la syntaxe suivante :
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- Vous pouvez également faire référence à la "collection" à l'intérieur de l'itération si vous le souhaitez. -->
-    <!-- Elément actuel. -->
-    <div x-text="item"></div>
-    <!-- Même chose que ci-dessus. -->
-    <div x-text="collection[index]"></div>
-    <!-- Elément précédent. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> Note : `x-for` doit avoir une racine d'élément unique (root element) à l'intérieur des balises `<template></template>`.
-
-> Note : Lorsque vous utilisez un `template` dans une balise `svg`, vous devez ajouter un [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) qui doit être exécuté avant que Alpine.js ne soit initialisé.
-
-#### Imbriquer les `x-for`
-Vous pouvez imbriquer des boucles `x-for`, mais vous DEVEZ envelopper chaque boucle dans un élément. Par exemple :
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Itération sur une gamme (range)
-
-Alpine supporte la syntaxe `i in n`, où `n` est un entier, ce qui vous permet d'itérer sur une gamme fixe d'éléments.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Exemple :**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> L'exemple ci-dessus utilise des classes provenant de [Tailwind CSS](https://tailwindcss.com).
-
-Alpine propose 6 directives de transition différentes pour appliquer des classes aux différentes étapes de la transition d'un élément entre les états "caché" et "montré". Ces directives fonctionnent à la fois avec `x-show` ET `x-if`.
-
-Celles-ci se comportent exactement comme les directives de transition de VueJS, sauf qu'elles portent des noms différents et plus sensés :
-
-| Directive | Description |
-| --- | --- |
-| `:enter` | Appliqué pendant toute la phase d'entrée. |
-| `:enter-start` | Ajouté avant l'insertion de l'élément, retiré un bloc après l'insertion de l'élément. |
-| `:enter-end` | Ajout d'un bloc après l'insertion d'un élément (en même temps que la suppression de `enter-start`), suppression lorsque la transition/animation se termine.
-| `:leave` | Appliqué pendant toute la phase de sortie. |
-| `:leave-start` | Ajouté immédiatement lorsqu'une transition de sortie est déclenchée, supprimé au bloc suivant. |
-| `:leave-end` | Ajout d'un bloc après le déclenchement d'une transition de sortie (en même temps que la suppression du `leave-start`), suppression lorsque la transition/animation se termine.
-
----
-
-### `x-spread`
-**Exemple :**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Ouvrir Menu</button>
-
-    <span x-spread="dialogue">Contenu du Menu</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` permet d'extraire les liaisons d'Alpine (bindings) d'un élément pour en faire un objet réutilisable.
-
-Les clés d'objet sont les directives (peut être n'importe quelle directive y compris les modificateurs), et les valeurs sont des callbacks à évaluer par Alpine.
-
-> Note : l y a quelques restrictions à x-spread :
-> - Lorsque la directive en cours de diffusion ("spread") est `x-for`, vous devez renvoyer une chaîne d'expression normale à partir du callback. Par exemple : `['x-for']() { return 'item in items' }`.
-> - `x-data` et `x-init` ne peuvent pas être utilisés à l'intérieur d'un objet "spread".
-
----
-
-### `x-cloak`
-**Exemple :** `<div x-data="{}" x-cloak></div>`
-
-Les attributs `x-cloak` sont retirés des éléments lorsque Alpine s'initialise. Ceci est utile pour masquer les DOM pré-initialisés. Il est typique d'ajouter le style global suivant pour que cela fonctionne :
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Propriétés magiques
-
-> À l'exception de `$el`, les propriétés magiques ne sont **pas disponibles dans `x-data`** car le composant n'est pas encore initialisé.
-
----
-
-### `$el`
-**Exemple :**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Remplacez-moi par "foo".</button>
-</div>
-```
-
-`$el` est une propriété magique qui peut être utilisée pour récupérer le nœud DOM du composant racine.
-
-### `$refs`
-**Exemple :**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` est une propriété magique qui peut être utilisée pour récupérer les éléments du DOM marqués avec `x-ref` à l'intérieur du composant. C'est utile lorsque vous devez manipuler manuellement des éléments du DOM.
-
----
-
-### `$event`
-**Exemple :**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` est une propriété magique qui peut être utilisée dans un écouteur d'événement pour récupérer l'objet "Event" du navigateur natif.
-
-> Note : La propriété $event n'est disponible que dans les expressions DOM.
-
-Si vous avez besoin d'accéder à $event à l'intérieur d'une fonction JavaScript, vous pouvez le passer directement :
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Exemple :**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Lorsque cliqué, enregistre "bar" dans console.log  -->
-</div>
-```
-
-**Note sur la propagation des événements**
-
-Notez que, en raison du [event bubbling](https://en.wikipedia.org/wiki/Event_bubbling), lorsque vous devez capturer des événements envoyés par des nœuds qui sont sous la même hiérarchie d'imbrication, vous devrez utiliser le modificateur [`.window`](https://github.com/alpinejs/alpine#x-on) :
-
-**Exemple :**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Cela ne fonctionnera pas, car lorsque le `custom-event` sera dispatché, il se propagera à son ancêtre commun, le `div`.
-
-**Envoi (dispatch) aux composants**
-
-Vous pouvez également profiter de la technique précédente pour faire communiquer vos composants entre eux :
-
-**Exemple :**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Lorsque cliqué, enregistre "Hello World!" dans console.log. -->
-```
-
-`$dispatch` est un raccourci pour créer un `CustomEvent` et l'envoyer en utilisant `.dispatchEvent()` en interne. Il existe de nombreux cas d'utilisation pour faire circuler des données entre les composants en utilisant des événements personnalisés. [Voir ici](https://developer.mozilla.org/fr/docs/Web/Guide/DOM/Events/Creating_and_triggering_events) pour plus d'informations sur le système `CustomEvent` sous-jacent dans les navigateurs.
-
-Vous remarquerez que toute donnée passée comme deuxième paramètre à `$dispatch('some-event', { some : 'data' })`, devient disponible grâce à la nouvelle propriété "detail" des événements : `$event.detail.some`. Attacher des données d'événements personnalisés à la propriété `.detail` est une pratique standard pour les `CustomEvent` dans les navigateurs. Pour plus d'informations, [cliquez ici](https://developer.mozilla.org/fr/docs/Web/API/CustomEvent/detail).
-
-Vous pouvez également utiliser `$dispatch()` pour déclencher des mises à jour de données pour les liaisons `x-model`. Par exemple :
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- Après avoir cliqué sur le bouton, `x-model` captera l'événement "input" et remplacera foo par "baz". -->
-    </span>
-</div>
-```
-
-> Note : La propriété $dispatch n'est disponible que dans les expressions DOM.
-
-Si vous avez besoin d'accéder à $dispatch à l'intérieur d'une fonction JavaScript, vous pouvez le passer directement :
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Exemple :**
-```html
-<div x-data="{ fruit: 'pomme' }">
-    <button
-        x-on:click="
-            fruit = 'poire';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` est une propriété magique qui vous permet de n'exécuter une expression donnée qu'APRÈS qu'Alpine ait fait ses mises à jour réactives du DOM. Ceci est utile pour les fois où vous voulez interagir avec l'état DOM APRÈS qu'il ait reflété les mises à jour de données que vous avez faites.
-
----
-
-### `$watch`
-**Exemple :**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Alterne Ouvrir</button>
-</div>
-```
-
-Vous pouvez surveiller ("watch") une propriété d'un composant avec la méthode magique `$watch`. Dans l'exemple ci-dessus, lorsque l'on clique sur le bouton et que `open` change, le callback indiqué se déclenche et `console.log` enregistre la nouvelle valeur.
-
-## Sécurité
-Si vous trouvez une faille de sécurité, veuillez envoyer un courriel à [calebporzio@gmail.com]().
-
-Alpine s'appuie sur une mise en œuvre personnalisée utilisant l'objet `Function` pour évaluer ses directives. Bien qu'il soit plus sûr que `eval()`, son utilisation est interdite dans certains environnements, comme Google Chrome App, qui utilise une politique de sécurité de contenu (Content Security Policy - CSP) restrictive.
-
-Si vous utilisez Alpine sur un site web traitant des données sensibles et nécessitant un [CSP](https://csp.withgoogle.com/docs/strict-csp.html), vous devez inclure la mention `unsafe-eval` dans votre politique. Une politique solide et correctement configurée contribuera à protéger vos utilisateurs lors de l'utilisation de données personnelles ou financières.
-
-Étant donné qu'une politique s'applique à tous les scripts de votre page, il est important que les autres bibliothèques externes incluses dans le site web soient soigneusement examinées pour s'assurer qu'elles sont dignes de confiance et qu'elles n'introduiront aucune vulnérabilité de Cross Site Scripting, que ce soit en utilisant la fonction `eval()` ou en manipulant le DOM pour injecter du code malveillant dans votre page.
-
-## Feuille de route V3
-* Passer de `x-ref` à `ref` pour la parité de Vue ?
-* Ajouter `Alpine.directive()`
-* Ajouter `Alpine.component('foo', {...})` (Avec la méthode magique `__init()`)
-* Dispatcher des évènements d'Alpine pour "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Supprimer la syntaxe "objet" (et tableau) de `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) pour ajouter le support de la syntaxe d'objet pour l'attribut `style`)
-* Améliorer la réactivité des mutations `x-for` ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Ajouter le support de "deep watching" dans la V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Ajouter le raccourci `$el`
-* Remplacer `@click.away` par `@click.outside`?
-
-## License
-
-Copyright © 2019-2021 Caleb Porzio et contributeurs
-
-Licencié sous la licence du MIT, voir [LICENSE.md](LICENSE.md) pour plus de détails.

+ 0 - 802
README.id.md

@@ -1,802 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js menawarkan kepada Anda sifat reaktif dan deklaratif dari framework besar seperti Vue atau React dengan biaya yang jauh lebih rendah.
-
-Anda bisa mempertahankan DOM Anda, dan taburkan dalam perilaku sesuai keinginan Anda.
-
-Anggap saja seperti [Tailwind](https://tailwindcss.com/) untuk JavaScript.
-
-> Catatan: Hampir seluruh sintaks dipinjam dari [Vue](https://vuejs.org/) (dan dengan ekstensi [Angular](https://angularjs.org/)). Saya selamanya berterima kasih atas hadiah mereka untuk web.
-
-## Dokumentasi yang diterjemahkan
-
-| Bahasa | Tautan untuk dokumentasi |
-| --- | --- |
-| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Chinese Simplified | [**简体中文文档**](./README.zh-CN.md) |
-| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
-| Français | [**Documentation en Français**](./README.fr.md) |
-| German | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanese | [**日本語ドキュメント**](./README.ja.md) |
-| Korean | [**한국어 문서**](./README.ko.md) |
-| Portuguese | [**Documentação em Português**](./README.pt.md) |
-| Russian | [**Документация на русском**](./README.ru.md) |
-| Spanish | [**Documentación en Español**](./README.es.md) |
-| Turkish | [**Türkçe Dokümantasyon**](./README.tr.md) |
-
-## Instalasi
-
-**Dari CDN:** Tambahkan skrip berikut ke akhir bagian `<head>` Anda.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-Itu saja. Itu akan menginisialisasi dirinya sendiri.
-
-Untuk lingkungan produksi, disarankan untuk memasang pin pada nomor versi tertentu di link untuk menghindari kerusakan yang tidak terduga dari versi yang lebih baru. Misalnya, untuk menggunakan versi `2.8.2` (terbaru):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Dari NPM:** Instal paket dari NPM.
-```js
-npm i alpinejs
-```
-
-Sertakan dalam skrip Anda.
-```js
-import 'alpinejs'
-```
-
-**Untuk dukungan IE11** Gunakan skrip berikut sebagai gantinya.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-Pola di atas adalah pola [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) yang akan membuat bundel modern dimuat secara otomatis di browser modern, dan bundel IE11 dimuat secara otomatis di IE11 dan browser lama lainnya.
-
-## Penggunaan
-
-*Dropdown/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*Tabs*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-Anda bahkan dapat menggunakannya untuk hal-hal yang tidak sepele: 
-*Mengambil konten HTML dari dropdown terlebih dahulu saat mengarahkan kursor*.
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## Belajar
-
-Ada 14 perintah yang tersedia untuk Anda:
-
-| Perintah | Deskripsi |
-| --- | --- |
-| [`x-data`](#x-data) | Mendeklarasikan cakupan komponen baru. |
-| [`x-init`](#x-init) | Menjalankan ekspresi saat komponen diinisialisasi. |
-| [`x-show`](#x-show) | Merubah properti `display: none;` pada elemen tergantung pada ekspresi (true atau false). |
-| [`x-bind`](#x-bind) | Menetapkan nilai atribut ke hasil ekspresi JS |
-| [`x-on`](#x-on) | Melampirkan event listener ke elemen. Menjalankan ekspresi JS saat dipancarkan. |
-| [`x-model`](#x-model) | Menambahkan "two-way data binding (pengikatan data dua arah)" ke sebuah elemen. Menjaga elemen masukan tetap sinkron dengan data komponen. |
-| [`x-text`](#x-text) | Bekerja mirip dengan `x-bind`, tetapi akan memperbarui `innerText` dari sebuah elemen. |
-| [`x-html`](#x-html) | Bekerja mirip dengan `x-bind`, tetapi akan memperbarui `innerHTML` dari sebuah elemen. |
-| [`x-ref`](#x-ref) | Cara mudah untuk mengambil elemen DOM mentah dari komponen Anda. |
-| [`x-if`](#x-if) | Hapus elemen sepenuhnya dari DOM. Harus digunakan pada tag `<template>`. |
-| [`x-for`](#x-for) | Buat node DOM baru untuk setiap item dalam array. Harus digunakan pada tag `<template>`. |
-| [`x-transition`](#x-transition) | Arahan untuk menerapkan kelas ke berbagai tahapan transisi elemen. |
-| [`x-spread`](#x-spread) | Memungkinkan Anda mengikat objek arahan Alpine ke elemen agar dapat digunakan kembali dengan lebih baik. |
-| [`x-cloak`](#x-cloak) | Atribut ini dihapus saat Alpine menginisialisasi. Berguna untuk menyembunyikan DOM yang sudah diinisialisasi. |
-
-dan 6 properti-properti ajaib:
-
-| Properti Ajaib | Deskripsi |
-| --- | --- |
-| [`$el`](#el) |  Ambil node DOM komponen akar. |
-| [`$refs`](#refs) | Ambil elemen DOM yang ditandai dengan `x-ref` di dalam komponen. |
-| [`$event`](#event) | Mengambil objek "Event" browser asli dalam event listener.  |
-| [`$dispatch`](#dispatch) | Buat `CustomEvent` dan kirim menggunakan `.dispatchEvent()` secara internal. |
-| [`$nextTick`](#nexttick) | Jalankan ekspresi tertentu SETELAH Alpine membuat pembaruan DOM reaktifnya. |
-| [`$watch`](#watch) | Akan mengaktifkan callback yang diberikan saat properti komponen yang Anda "awasi" berubah. |
-
-
-## Sponsor
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Ingin logo Anda di sini? [DM di Twitter](https://twitter.com/calebporzio)**
-
-## Proyek Komunitas
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### Perintah
-
----
-
-### `x-data`
-
-**Contoh:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Struktur:** `<div x-data="[object literal]">...</div>`
-
-`x-data` mendeklarasikan cakupan komponen baru. Ini memberi tahu kerangka kerja untuk menginisialisasi komponen baru dengan objek data berikut.
-
-Anggap saja seperti properti data dari komponen Vue.
-
-**Ekstrak Logika Komponen**
-
-Anda dapat mengekstrak data (dan perilaku) menjadi fungsi yang dapat digunakan kembali:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Untuk pengguna bundler**, perhatikan bahwa Alpine.js mengakses fungsi yang ada dalam cakupan global (`window`), Anda harus secara eksplisit menetapkan fungsi Anda ke `window` untuk menggunakannya dengan `x-data` misalnya `window.dropdown = function () {}` (ini karena dengan fungsi Webpack, Rollup, Parcel, dll. yang Anda tentukan akan secara default ke lingkup modul, bukan `window`).
-
-
-Anda juga dapat mencampur beberapa objek data menggunakan penghancuran objek:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Contoh:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Struktur:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` menjalankan ekspresi saat komponen diinisialisasi.
-
-Jika Anda ingin menjalankan kode SETELAH Alpine telah melakukan pembaruan awal ke DOM (sesuatu seperti hook `mounted()` yang di VueJS), Anda dapat mengembalikan callback dari `x-init`, dan itu akan dijalankan setelah:
-
-`x-init="() => { // kami memiliki akses ke status inisialisasi post-dom di sini // }"`
-
----
-
-### `x-show`
-**Contoh:** `<div x-show="open"></div>`
-
-**Struktur:** `<div x-show="[expression]"></div>`
-
-`x-show` mengubah gaya `display: none;` pada elemen tergantung apakah ekspresi ditetapkan ke `true` atau `false`.
-
-**x-show.transition**
-
-`x-show.transition` adalah API kenyamanan untuk membuat `x-show` Anda lebih menyenangkan menggunakan transisi CSS.
-
-```html
-<div x-show.transition="open">
-    Konten ini akan ditransisikan masuk dan keluar.
-</div>
-```
-
-| Perintah | Deskripsi |
-| --- | --- |
-| `x-show.transition` | Fade dan skala simultan. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Hanya transisi masuk. |
-| `x-show.transition.out` | Hanya transisi keluar. |
-| `x-show.transition.opacity` | Hanya menggunakan fade saja. |
-| `x-show.transition.scale` | Hanya menggunakan timbangan saja. |
-| `x-show.transition.scale.75` | Sesuaikan transformasi skala CSS `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Menyetel transisi "masuk" ke 200ms. Transisi "keluar" akan disetel menjadi setengahnya (100ms). |
-| `x-show.transition.origin.top.right` | Sesuaikan asal transformasi CSS `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Durasi berbeda untuk "masuk" dan "keluar". |
-
-> Catatan: Semua pengubah transisi ini dapat digunakan bersama satu sama lain. Ini mungkin (meskipun konyol lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Catatan: `x-show` akan menunggu setiap anak menyelesaikan transisi keluar. Jika Anda ingin mengabaikan perilaku ini, tambahkan modifer `.immediate`:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Catatan: Anda bebas menggunakan sintaks ":" yang lebih pendek: `:type = "..."`
-
-**Contoh:** `<input x-bind:type="inputType">`
-
-**Struktur:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` menyetel nilai atribut ke hasil ekspresi JavaScript. Ekspresi memiliki akses ke semua kunci objek data komponen, dan akan diperbarui setiap kali datanya diperbarui.
-
-> Catatan: Binding atribut HANYA diperbarui ketika dependensinya diperbarui. Framework ini cukup pintar untuk mengamati perubahan data dan mendeteksi binding mana yang mempedulikannya.
-
-**`x-bind` untuk atribut kelas**
-
-`x-bind` berperilaku sedikit berbeda saat mengikat ke atribut class.
-
-Untuk kelas, Anda meneruskan objek yang kuncinya adalah nama kelas, dan nilai adalah ekspresi boolean untuk menentukan apakah nama kelas tersebut diterapkan atau tidak.
-
-Sebagai contoh:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-Dalam contoh ini, kelas "hidden" hanya akan diterapkan jika nilai atribut data `foo` adalah `true`.
-
-**`x-bind` untuk atribut boolean**
-
-`x-bind` mendukung atribut boolean dengan cara yang sama seperti atribut nilai, menggunakan variabel sebagai kondisi atau ekspresi JavaScript apa pun yang menghasilkan `true` atau `false`.
-
-Sebagai contoh:
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- When myVar == true: -->
-<button disabled="disabled">Click me</button>
-
-<!-- When myVar == false: -->
-<button>Click me</button>
-```
-
-Ini akan menambah atau menghapus atribut `disabled` ketika `myVar` masing-masing bernilai `true` atau `false`.
-
-Atribut Boolean didukung sesuai dengan [HTML spesifikasi](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), sebagai contoh `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, dll.
-
-**pengubah `.camel`**
-
-**Contoh:** `<svg x-bind:view-box.camel="viewBox">`
-
-Pengubah `camel` akan mengikat kasus unta yang setara dengan nama atribut. Dalam contoh di atas, nilai `viewBox` akan terikat pada atribut `viewBox` sebagai lawan dari atribut `view-box`.
-
----
-
-### `x-on`
-
-> Catatan: Anda bebas menggunakan sintaks "@" yang lebih pendek: `@click="..."`
-
-**Contoh:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Struktur:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` melampirkan event listener ke elemen tempatnya dideklarasikan. Saat peristiwa itu dipancarkan, ekspresi JavaScript disetel sebagai nilainya dijalankan.
-
-Jika ada data yang diubah dalam ekspresi, atribut elemen yang lain "bound" ke data ini, akan diperbarui.
-
-> Catatan: Anda juga dapat menentukan nama fungsi JavaScript
-
-**Contoh:** `<button x-on:click="myFunction"></button>`
-
-Ini sama dengan: `<button x-on:click="myFunction($event)"></button>`
-
-**pengubah `keydown`**
-
-**Contoh:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Anda dapat menentukan kunci tertentu untuk didengarkan menggunakan pengubah keydown yang ditambahkan ke perintah `x-on: keydown`. Perhatikan bahwa pengubah adalah versi nilai `Event.key` berbasis kebab.
-
-Contoh: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Catatan: Anda juga dapat mendengarkan kombinasi tombol pengubah sistem seperti: `x-on:keydown.cmd.enter="foo"`
-
-**pengubah `.away`**
-
-**Contoh:** `<div x-on:click.away="showModal = false"></div>`
-
-Saat pengubah `.away` ada, pengendali kejadian hanya akan dijalankan ketika kejadian berasal dari sumber selain dirinya sendiri, atau turunannya.
-
-Ini berguna untuk menyembunyikan dropdown dan modals saat pengguna mengkliknya.
-
-**pengubah `.prevent`**
-
-**Contoh:** `<input type="checkbox" x-on:click.prevent>`
-
-Menambahkan `.prevent` ke pemroses acara akan memanggil `preventDefault` pada acara yang dipicu. Dalam contoh di atas, ini berarti kotak centang tidak akan benar-benar dicentang ketika pengguna mengkliknya.
-
-**pengubah `.stop`**
-
-**Contoh:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Menambahkan `.stop` ke event listener akan memanggil `stopPropagation` pada event yang dipicu. Dalam contoh di atas, ini berarti peristiwa "click" tidak akan menggelembung dari tombol ke luar `<div>`. Atau dengan kata lain, saat pengguna mengklik tombol, `foo` tidak akan disetel ke `'bar'`.
-
-**pengubah `.self`**
-
-**Contoh:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Menambahkan `.self` ke pemroses acara hanya akan memicu penangan jika `$event.target` adalah elemen itu sendiri. Dalam contoh di atas, ini berarti peristiwa "klik" yang menggelembung dari tombol ke luar `<div>` **tidak akan** menjalankan penangan.
-
-**pengubah `.window`**
-
-**Contoh:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Menambahkan `.window` ke event listener akan menginstal listener di objek global window, bukan di simpul DOM tempat ia dideklarasikan. Ini berguna ketika Anda ingin mengubah status komponen ketika sesuatu berubah dengan jendela, seperti acara pengubahan ukuran. Dalam contoh ini, ketika jendela tumbuh lebih besar dari lebar 768 piksel, kami akan menutup modal / dropdown, jika tidak, pertahankan status yang sama.
-
->Catatan: Anda juga bisa menggunakan pengubah `.document` untuk melampirkan listener ke `dokumen`, bukan `window`
-
-**pengubah `.once`**
-
-**Contoh:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Menambahkan pengubah `.once` ke event listener akan memastikan bahwa listener hanya akan ditangani satu kali. Ini berguna untuk hal-hal yang hanya ingin Anda lakukan sekali, seperti mengambil sebagian HTML dan semacamnya.
-
-**pengubah `.passive`**
-
-**Contoh:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Menambahkan `.passive` modifier ke event listener akan membuat pemroses menjadi pasif, yang berarti `preventDefault()` tidak akan berfungsi pada acara apa pun yang sedang diproses, hal ini dapat membantu, misalnya dengan kinerja scroll pada perangkat sentuh.
-
-**pengubah `.debounce`**
-
-**Contoh:** `<input x-on:input.debounce="fetchSomething()">`
-
-Pengubah `debounce` memungkinkan Anda untuk "melepaskan" pengendali event. Dengan kata lain, event handler TIDAK akan berjalan hingga waktu tertentu berlalu sejak event terakhir yang diaktifkan. Saat penangan siap dipanggil, pemanggilan penangan terakhir akan dijalankan.
-
-Waktu "tunggu" debounce default adalah 250 milidetik.
-
-Jika Anda ingin menyesuaikan ini, Anda dapat menentukan waktu tunggu khusus seperti:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**pengubah `.camel`**
-
-**Contoh:** `<input x-on:event-name.camel="doSomething()">`
-
-Pengubah `camel` akan melampirkan pendengar acara untuk nama acara yang setara dengan kasus unta. Dalam contoh di atas, ekspresi akan dievaluasi ketika event `eventName` diaktifkan pada elemen.
-
----
-
-### `x-model`
-**Contoh:** `<input type="text" x-model="foo">`
-
-**Struktur:** `<input type="text" x-model="[data item]">`
-
-`x-model` menambahkan "pengikatan data dua arah" ke elemen. Dengan kata lain, nilai elemen input akan tetap sinkron dengan nilai item data komponen.
-
-> Catatan: `x-model` cukup pintar untuk mendeteksi perubahan pada input teks, kotak centang, tombol radio, textarea, pemilihan, dan beberapa pilihan. Ini harus berperilaku [seperti Vue](https://vuejs.org/v2/guide/forms.html) dalam skenario tersebut.
-
-**pengubah `.number`**
-**Contoh:** `<input x-model.number="age">`
-
-Pengubah angka akan mengubah nilai input menjadi angka. Jika nilai tidak dapat diurai sebagai angka yang valid, nilai asli dikembalikan.
-
-**pengubah `.debounce`**
-**Contoh:** `<input x-model.debounce="search">`
-
-Pengubah `debounce` memungkinkan Anda menambahkan "debounce" ke pembaruan nilai. Dengan kata lain, event handler TIDAK akan berjalan hingga waktu tertentu berlalu sejak event terakhir yang diaktifkan. Saat penangan siap dipanggil, pemanggilan penangan terakhir akan dijalankan.
-
-Waktu "tunggu" debounce default adalah 250 milidetik.
-
-Jika Anda ingin menyesuaikan ini, Anda dapat menentukan waktu tunggu khusus seperti:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Contoh:** `<span x-text="foo"></span>`
-
-**Struktur:** `<span x-text="[expression]"`
-
-`x-text` bekerja mirip dengan `x-bind`, kecuali memperbarui nilai atribut, itu akan memperbarui `innerText` dari sebuah elemen.
-
----
-
-### `x-html`
-**Contoh:** `<span x-html="foo"></span>`
-
-**Struktur:** `<span x-html="[expression]"`
-
-`x-html` bekerja mirip dengan `x-bind`, kecuali untuk memperbarui nilai atribut, itu akan memperbarui `innerHTML` dari sebuah elemen.
-
-> :warning: **Hanya gunakan pada konten tepercaya dan jangan pernah pada konten yang disediakan pengguna.** :warning:
->
-> Merender HTML secara dinamis dari pihak ketiga dapat dengan mudah menyebabkan kerentanan [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting).
-
----
-
-### `x-ref`
-**Contoh:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Struktur:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` menyediakan cara mudah untuk mengambil elemen DOM mentah dari komponen Anda. Dengan menyetel atribut `x-ref` pada sebuah elemen, Anda membuatnya tersedia untuk semua penangan kejadian di dalam sebuah objek yang disebut `$refs`.
-
-Ini adalah alternatif yang berguna untuk menyetel id dan menggunakan `document.querySelector` di semua tempat.
-
-> Catatan: Anda juga dapat mengikat nilai dinamis untuk x-ref: `<span: x-ref = "item.id"> </span>` jika perlu.
-
----
-
-### `x-if`
-**Contoh:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Struktur:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-Untuk kasus di mana `x-show` tidak cukup (`x-show` menyetel elemen ke `display: none` if false), `x-if` dapat digunakan untuk benar-benar menghapus elemen sepenuhnya dari DOM.
-
-Penting bahwa `x-if` digunakan pada tag `<template></template>` karena Alpine tidak menggunakan DOM virtual. Implementasi ini memungkinkan Alpine untuk tetap bertahan dan menggunakan DOM asli untuk melakukan keajaibannya.
-
-> Catatan: `x-if` harus memiliki root elemen tunggal di dalam tag `<template></template>`.
-
-> Catatan: Saat menggunakan `template` di tag `svg`, Anda perlu menambahkan [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) yang harus dijalankan sebelum Alpine.js diinisialisasi.
----
-
-### `x-for`
-**Contoh:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Catatan: pengikat `:key` bersifat opsional, tetapi SANGAT disarankan.
-
-`x-for` tersedia untuk kasus ketika Anda ingin membuat simpul DOM baru untuk setiap item dalam larik. Ini akan tampak mirip dengan `v-for` di Vue, dengan satu pengecualian yaitu harus ada di tag `template`, dan bukan elemen DOM biasa.
-
-Jika Anda ingin mengakses indeks iterasi saat ini, gunakan sintaks berikut:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- You can also reference "index" inside the iteration if you need. -->
-    <div x-text="index"></div>
-</template>
-```
-
-Jika Anda ingin mengakses objek array (kumpulan) dari iterasi, gunakan sintaks berikut:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- You can also reference "collection" inside the iteration if you need. -->
-    <!-- Current item. -->
-    <div x-text="item"></div>
-    <!-- Same as above. -->
-    <div x-text="collection[index]"></div>
-    <!-- Previous item. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> Catatan: `x-for` harus memiliki root elemen tunggal di dalam tag `<template></template>`.
-
-> Catatan: Saat menggunakan `template` di tag `svg`, Anda perlu menambahkan [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) yang harus dijalankan sebelum Alpine.js diinisialisasi.
-
-#### Nesting `x-for`s
-Anda dapat melapisi pengulangan `x-for`, tetapi Anda HARUS membungkus setiap pengulangan dalam sebuah elemen. Sebagai contoh:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Iterasi dalam rentang tertentu
-
-Alpine mendukung sintaks `i in n`, di mana `n` adalah bilangan bulat, memungkinkan Anda untuk melakukan iterasi pada rentang elemen yang tetap.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Contoh:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> Contoh di atas menggunakan kelas dari [Tailwind CSS](https://tailwindcss.com)
-
-Alpine menawarkan 6 arahan transisi berbeda untuk menerapkan kelas ke berbagai tahap transisi elemen antara status "tersembunyi" dan "ditampilkan". Arahan ini bekerja dengan `x-show` DAN `x-if`.
-
-Ini berperilaku persis seperti arahan transisi VueJs, kecuali mereka memiliki nama yang berbeda dan lebih masuk akal:
-
-| Perintah | Deskripsi |
-| --- | --- |
-| `:enter` | Diterapkan selama seluruh fase masuk. |
-| `:enter-start` | Ditambahkan sebelum elemen dimasukkan, dihapus satu bingkai setelah elemen dimasukkan. |
-| `:enter-end` | Menambahkan satu bingkai setelah elemen dimasukkan (pada saat yang sama `enter-start` dihapus), dihapus ketika transisi / animasi selesai.
-| `:leave` | Diterapkan selama seluruh fase keluar. |
-| `:leave-start` | Ditambahkan segera ketika transisi keluar dipicu, dihapus setelah satu frame. |
-| `:leave-end` | Ditambahkan satu frame setelah transisi keluar dipicu (pada saat yang sama `leave-start` dihapus), dihapus ketika transisi / animasi selesai.
-
----
-
-### `x-spread`
-**Contoh:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` memungkinkan Anda untuk mengekstrak binding Alpine sebuah elemen menjadi objek yang dapat digunakan kembali.
-
-Kunci objek adalah arahan (Bisa berupa arahan apa pun termasuk pengubah), dan nilainya adalah callback untuk dievaluasi oleh Alpine.
-
-> Catatan: Ada beberapa peringatan untuk x-spread:
-> - Jika direktif yang menjadi "spread" adalah `x-for`, Anda harus mengembalikan string ekspresi normal dari callback. Misalnya: `['x-for'] () {return 'item in items'}`.
-> - `x-data` dan `x-init` tidak dapat digunakan di dalam objek "spread"
-
----
-
-### `x-cloak`
-**Contoh:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` atribut dihapus dari elemen saat Alpine menginisialisasi. Ini berguna untuk menyembunyikan DOM yang telah diinisialisasi sebelumnya. Biasanya untuk menambahkan gaya global berikut agar ini berfungsi:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Properti Ajaib
-
-> Dengan pengecualian `$el`, properti ajaib tidak tersedia dalam `x-data` karena komponen belum diinisialisasi.
-
----
-
-### `$el`
-**Contoh:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
-</div>
-```
-
-`$el` adalah properti ajaib yang bisa digunakan untuk mengambil simpul DOM komponen akar.
-
-### `$refs`
-**Contoh:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` adalah properti ajaib yang bisa digunakan untuk mengambil elemen DOM yang ditandai dengan `x-ref` di dalam komponen. Ini berguna saat Anda perlu memanipulasi elemen DOM secara manual.
-
----
-
-### `$event`
-**Contoh:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` adalah properti ajaib yang bisa digunakan dalam event listener untuk mengambil objek "Event" dari browser asli.
-
-> Catatan: Properti $event hanya tersedia dalam ekspresi DOM.
-
-If you need to access $event inside of a JavaScript function you can pass it in directly:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Contoh:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- When clicked, will console.log "bar" -->
-</div>
-```
-
-**Catatan tentang Propagasi Peristiwa**
-
-Perhatikan bahwa, karena [peristiwa menggelegak](https://en.wikipedia.org/wiki/Event_bubbling), saat Anda perlu merekam peristiwa yang dikirim dari node yang berada di bawah hierarki bersarang yang sama, Anda harus menggunakan pengubah [`.window`](https://github.com/alpinejs/alpine#x-on) :
-
-**Contoh:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Ini tidak akan berfungsi karena saat `custom-event` dikirim, itu akan disebarkan ke leluhur yang sama, `div`.
-
-**Pengiriman ke Komponen**
-
-Anda juga dapat memanfaatkan teknik sebelumnya untuk membuat komponen Anda saling berhubungan:
-
-**Contoh:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Saat diklik, akan console.log "Hello World!". -->
-```
-
-`$dispatch` adalah jalan pintas untuk membuat `CustomEvent` dan mengirimkannya menggunakan `.dispatchEvent()` secara internal. Ada banyak kasus penggunaan yang baik untuk meneruskan data di sekitar dan di antara komponen menggunakan peristiwa khusus. [Baca di sini](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) untuk informasi lebih lanjut tentang sistem `CustomEvent` yang mendasari di browser.
-
-Anda akan melihat bahwa setiap data yang diteruskan sebagai parameter kedua ke `$dispatch('some-event', { some: 'data' })`, tersedia melalui properti "detail" event baru: $ event.detail.some. Melampirkan data peristiwa khusus ke properti .detail adalah praktik standar untuk `CustomEvents` di browser. [Baca di sini](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) untuk info lebih lanjut.
-
-Anda juga dapat menggunakan `$dispatch()` untuk memicu pembaruan data untuk binding `x-model`. Sebagai contoh:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- After the button is clicked, `x-model` will catch the bubbling "input" event, and update foo to "baz". -->
-    </span>
-</div>
-```
-
-> Catatan: Properti $dispatch hanya tersedia dalam ekspresi DOM.
-
-Jika Anda perlu mengakses $dispatch di dalam fungsi JavaScript, Anda dapat mengirimkannya secara langsung:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Contoh:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` adalah properti ajaib yang memungkinkan Anda untuk hanya mengeksekusi ekspresi tertentu SETELAH Alpine melakukan pembaruan DOM reaktifnya. Ini berguna pada saat Anda ingin berinteraksi dengan status DOM SETELAH itu tercermin setiap pembaruan data yang Anda buat.
-
----
-
-### `$watch`
-**Contoh:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-Anda bisa "melihat" properti komponen dengan metode ajaib $watch. Dalam contoh di atas, ketika tombol diklik dan `buka` diubah, callback yang disediakan akan aktif dan `console.log` nilai baru.
-
-## Keamanan
-Jika Anda menemukan kerentanan keamanan, silakan kirim email ke [calebporzio@gmail.com]()
-
-Alpine mengandalkan implementasi kustom yang menggunakan objek Function untuk mengevaluasi arahannya. Meskipun lebih aman daripada `eval()`, penggunaannya dilarang di beberapa lingkungan, seperti Aplikasi Google Chrome, menggunakan Kebijakan Keamanan Konten yang membatasi.
-
-Jika Anda menggunakan Alpine di situs web yang berurusan dengan data sensitif dan membutuhkan [CSP](https://csp.withgoogle.com/docs/strict-csp.html), Anda perlu menyertakan `unsafe-eval` dalam kebijakan Anda. Kebijakan kuat yang dikonfigurasi dengan benar akan membantu melindungi pengguna Anda saat menggunakan data pribadi atau keuangan.
-
-Karena kebijakan berlaku untuk semua skrip di halaman Anda, penting agar pustaka eksternal lain yang termasuk dalam situs web ditinjau dengan cermat untuk memastikan bahwa mereka dapat dipercaya dan tidak akan menimbulkan kerentanan Cross Site Scripting baik menggunakan fungsi `eval()` atau memanipulasi DOM untuk memasukkan kode berbahaya ke halaman Anda.
-
-## Tujuan selanjutnya di V3
-* Pindah dari `x-ref` ke `ref` untuk paritas Vue?
-* Menambahkan `Alpine.directive()`
-* Menambahkan `Alpine.component('foo', {...})` (Dengan metode ajaib `__init()`)
-* Mengirim peristiwa Alpine untuk "loaded", "transition-start", dll ... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Menghapus "object" (dan array) sintaks dari `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) untuk menambah dukungan untuk sintaks objek untuk atribut `style`)
-* Memperbaiki `x-for` reaktivitas mutasi ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Menambahkan "deep watching" dukungan di V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Menambahkan jalan pintas `$el`
-* Perubahan `@click.away` ke `@click.outside`?
-
-## Lisensi
-
-hak cipta © 2019-2021 Caleb Porzio dan kontributor
-
-Berlisensi di bawah lisensi MIT, lihat [LICENSE.md](LICENSE.md) untuk detailnya.

+ 0 - 551
README.ja.md

@@ -1,551 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-
-Alpine.js は、Vue や React などの大きなフレームワークのリアクティブで宣言的な性質をはるかに低いコストで提供します。
-
-DOM を保持し、適切な動作を施すことができます。
-
-[Tailwind](https://tailwindcss.com/) の JavaScript 版のようなものです。
-
-> 注意: このツールのシンタックスは、ほぼ完全に [Vue](https://vuejs.org/)(それと、[Angular](https://angularjs.org/) による拡張)から借用しています。ウェブからの賜り物に感謝しています。
-
-## Install
-
-**CDNより:** `<head>` セクションの最後に次のスクリプトを追加します。
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.js" defer></script>
-```
-
-それだけです。初期は自身で行われます。
-
-**npmより:** npm からパッケージをインストールします。
-```js
-npm i alpinejs
-```
-
-各自スクリプトでインクルードします。
-```js
-import 'alpinejs'
-```
-
-IE11 では、ポリフィルを提供する必要があります。次のスクリプトを上記の Alpine スクリプトの前にロードしてください。
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-## 使う
-
-*ドロップダウン/モーダル*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*タブ*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-自明ではないことにも使用できます:
-*ホバー時にドロップダウンの HTML コンテンツをプリフェッチする*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## Learn
-
-次の14のディレクティブを使用できます。
-
-| ディレクティブ | 説明 |
-| --- | --- |
-| [`x-data`](#x-data) | 新しいコンポーネントのスコープを宣言します。 |
-| [`x-init`](#x-init) | コンポーネントが初期化されると式を実行します。 |
-| [`x-show`](#x-show) | 式の `true` `false` に応じて、要素の `display: none;` スタイルを切り替えます。 |
-| [`x-bind`](#x-bind) | 属性の値にJS式の結果を設定します。 |
-| [`x-on`](#x-on) | イベントリスナーを要素にアタッチします。イベント発行時に指定されたJS式を実行します。 |
-| [`x-model`](#x-model) | `x-model` は要素に「双方向データバインディング」を追加します。つまり、入力要素の値はコンポーネントデータと同期します。 |
-| [`x-text`](#x-text) | `x-text` は `x-bind` と同様に機能しますが、属性値を更新する代わりに要素の `innerText` を更新します。 |
-| [`x-html`](#x-html) | `x-text` は `x-bind` と同様に機能しますが、属性値を更新する代わりに要素の `innerHtml` を更新します。 |
-| [`x-ref`](#x-ref) | コンポーネントから生 DOM 要素を取得する便利な方法を提供します。 |
-| [`x-if`](#x-if) | DOMから完全に要素を削除します。`<template>` タグでネストする必要があります。 |
-| [`x-for`](#x-for) | 配列の各要素から新しいDOMを作成します。`<template>` タグでネストする必要があります。 |
-| [`x-transition`](#x-transition) | 要素の遷移の様々な段階にクラスを適用するためのディレクティブです。 |
-| [`x-spread`](#x-spread) | 再利用可能なAlpineディレクティブのオブジェクトを要素にバインドすることができます。 |
-| [`x-cloak`](#x-cloak) | この属性はAlpineの初期化時に削除されます。これは、事前に初期化されたDOMを隠すのに役立ちます。 |
-
-それと6つのマジックプロパティ:
-
-| マジックプロパティ | 説明 |
-| --- | --- |
-| [`$el`](#el) | ルートコンポーネントのDOMノードを取得できます。 |
-| [`$refs`](#refs) | コンポーネント内の `x-ref` でマークされたDOM要素を取得できます。 |
-| [`$event`](#event) | イベントリスナ内でネイティブブラウザの「Event」オブジェクトを取得できます。 |
-| [`$dispatch`](#dispatch) | `CustomEvent` を作成し、内部的に`.dispatchEvent()`を使用してディスパッチします。 |
-| [`$nextTick`](#nexttick) | AlpineがリアクティブなDOM更新を行った後に実行する式を指定できます。 |
-| [`$watch`](#watch) | コンポーネントのプロパティを「監視」し、変更があったときに指定されたコールバックを実行します。 |
-
-
-### ディレクティブ
-
----
-
-### `x-data`
-
-**例:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**構造:** `<div x-data="[object literal]">...</div>`
-
-`x-data` は新しいコンポーネントスコープを宣言します。フレームワークに、データオブジェクトを使用して新しいコンポーネントを初期化するよう指示します。
-
-Vue コンポーネントの `data` プロパティのように考えてください。
-
-**コンポーネントロジックの抽出**
-
-データ(と動作)を再利用可能な関数に抽出できます:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open()">オープン</button>
-
-    <div x-show="isOpen()" x-on:click.away="close()">
-        // ドロップダウン
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-オブジェクトの構造化を使用して、複数のデータオブジェクトを混在も出来ます:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**例:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**構造:** `<div x-data="..." x-init="[式]"></div>`
-
-`x-init` はコンポーネントが初期化されると式を実行します。
-
-Alpine が DOM(VueJS の `mounted()` フックのようなもの)に最初の更新を行った後にコードを実行したい場合、`x-init` からコールバックを返すことができ、その後実行されます:
-
-`x-init="return () => { // ここで初期化後の DOM ステートにアクセスできます // }"`
-
----
-
-### `x-show`
-**例:** `<div x-show="open"></div>`
-
-**構造:** `<div x-show="[式]]"></div>`
-
-`x-show` は、式が `true` または `false` のどちらかの結果によって、要素の `display: none;` スタイルを切り替えます。
-
----
-
-### `x-bind`
-
-> 注意: 短い「:」シンタックスを使えます: `:type="..."`
-
-**例:** `<input x-bind:type="inputType">`
-
-**構造:** `<input x-bind:[属性]="[式]">`
-
-`x-bind` は、属性の値を JavaScript 式の結果を設定します。この式は、コンポーネントのデータオブジェクトのすべてのキーにアクセスでき、データが更新されるたびに反映されます。
-
-> 注意: 属性バインディングは、依存関係が更新されたときにのみ更新されます。このフレームワークは、データの変化を観察し、どのバインディングがそれらを検出するのか最適化されています。
-
-**`x-bind` for class attributes**
-
-`x-bind` は、`class` 属性にバインドするときの動作が少し異なります。
-
-クラスの場合、キーがクラス名であり、値がそれらのクラス名が適用されるかどうかを決定するブール式であるオブジェクトを渡します。
-
-例:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-この例では、「hidden」クラスは、`foo` データ属性値が `true` の場合にのみ適用されます。
-
-**ブール属性の `x-bind`**
-
-`x-bind` は、値属性と同じ方法でブール値属性をサポートします。条件として変数を使用するか、`true` または `false` に解決される JavaScript 式を使用します。
-
-例:
-`<button x-bind:disabled="myVar">Click me</button>`
-
-`myVar` が true または false の場合に `disabled` 属性を追加または削除します。
-
-`readonly`, `required` など、最も一般的なブール属性がサポートされています。
-
----
-
-### `x-on`
-
-> 注意: より短い「@」シンタックスを自由に使用できます: `@click="..."`
-
-**例:** `<button x-on:click="foo = 'bar'"></button>`
-
-**構造:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` は、イベントリスナを宣言された要素にアタッチします。そのイベントが発行されると、その値として設定された JavaScript 式が実行されます。
-
-式でデータが変更されると、このデータに「バインドされた」他の要素属性が更新されます。
-
-**`keydown` 修飾子**
-
-**例:** `<input type="text" x-on:keydown.escape="open = false">`
-
-`x-on:keydown` ディレクティブに追加された keydown 修飾子を使用し、待ち受けする特定のキーを指定できます。修飾子は `Event.key` 値のケバブケースであることに注意してください。
-
-例: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> 注意: 次のようなシステム修飾子キーの組み合わせを待ち受けもできます: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` 修飾子**
-
-**例:** `<div x-on:click.away="showModal = false"></div>`
-
-`.away` 修飾子を付与すると、イベントがそれ自体またはその子以外のソースから発生した場合にのみイベントハンドラは実行されます。
-
-ユーザがクリックしたときにドロップダウンやモーダルを非表示にするのに便利です。
-
-**`.prevent` 修飾子**
-**例:** `<input type="checkbox" x-on:click.prevent>`
-
-イベントリスナに `.prevent` を追加すると、トリガされたイベントで `preventDefault` が呼び出されます。上記の例では、ユーザがクリックしたときにチェックボックスが実際にチェックされないことを意味します。
-
-**`.stop` 修飾子**
-**例:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-イベントリスナに `.stop` を追加すると、トリガされたイベントで `stopPropagation` が呼び出されます。上記の例では、ボタンから外側の `<div>` に「click」イベントが浮上しないことを意味します。言い換えると、ユーザがボタンをクリックしても、`foo` は `'bar'` に設定されません。
-
-**`.window` 修飾子**
-**例:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-イベントリスナに `.window` を付与すると、それが宣言されている DOM ノードではなく、グローバル window オブジェクトにリスナがインストールされます。これは、resize イベントなど window で何かが変更されたときにコンポーネントの状態を変更する場合に役立ちます。この例では、ウィンドウの幅が768ピクセルを超えた場合、モーダル/ドロップダウンを閉じます。それ以外の場合は同じ状態を維持します。
-
-> 注意: `.document` 修飾子を使用して、リスナを `window` の代わりに `document` にアタッチすることもできます。
-
-**`.once` 修飾子**
-**例:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-イベントリスナに `.once` 修飾子を付与すると、リスナが1回だけ処理されることが保証されます。HTML パーシャルの取得など、1度だけ実行したい場合に便利です。
-
----
-
-### `x-model`
-**例:** `<input type="text" x-model="foo">`
-
-**構造:** `<input type="text" x-model="[data item]">`
-
-`x-model` は要素に「双方向データバインディング」を追加します。つまり、入力要素の値はコンポーネントの項目データの値と同期します。
-
-> 注意: `x-model` は、テキストインプット、チェックボックス、ラジオボタン、テキストエリア、セレクト、およびマルチセレクトの変更を検出するのに最適です。これらのシナリオで [Vue がどのように](https://vuejs.org/v2/guide/forms.html)動作するのか確認してください。
-
----
-
-### `x-text`
-**例:** `<span x-text="foo"></span>`
-
-**構造:** `<span x-text="[expression]"`
-
-`x-text` は `x-bind` と同様に機能しますが、属性値を更新する代わりに要素の `innerText` を更新します。
-
----
-
-### `x-html`
-**例:** `<span x-html="foo"></span>`
-
-**構造:** `<span x-html="[expression]"`
-
-`x-html` は `x-bind` と同様に機能しますが、属性の値を更新する代わりに要素の `innerHTML` を更新します。
-
----
-
-### `x-ref`
-**例:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**構造:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` は、コンポーネントから生 DOM 要素を取得する便利な方法を提供します。要素に `x-ref` 属性を設定することで、すべてのイベントハンドラで `$refs` というオブジェクト内から利用できるようになります。
-
-これは、ID を設定し、あらゆる場所で `document.querySelector` を使用する代替手段に役立ちます。
-
----
-
-### `x-if`
-**例:** `<template x-if="true"><div>Some Element</div></template>`
-
-**構造:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-`x-show` では不十分な場合(`x-show` が false の場合、要素を `display: none` に設定します)、`x-if` を使用して DOM から要素を完全に削除できます。
-
-Alpine は仮想 DOM を使用しないため、`<template></template>` タグで `x-if` を使用することが重要です。この実装により、Alpine は堅牢性を保ち、実際の DOM を使用してその仕様を働かせることができます。
-
-> 注意: `x-if` には、`<template></template>` タグ内に単一要素のルートが必要です。
-
----
-
-### `x-for`
-**例:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-`x-for` は、配列の各アイテム毎に新しい DOM ノードを作成する場合に使用します。これは、Vue の `v-for` に似ています。ただし、通常の DOM 要素ではなく、`template` タグに存在する必要があります。
-
-> 注意: `:key` バインディングはオプションですが、強く推奨しています。
-
----
-
-### `x-transition`
-**例:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-Alpine は、「非表示」と「表示」の遷移間のさまざまな段階にクラスを要素に適用するための6つの異なるトランジションディレクティブを提供します。これらのディレクティブは、`x-show` と `x-if` の両方で機能します。
-
-これらは、VueJs のトランジションディレクティブとまったく同じように動作しますが、より理にかなった異なる名前を持っています。
-
-| ディレクティブ | 説明 |
-| --- | --- |
-| `:enter` | エンターフェーズ全体に適用されます。 |
-| `:enter-start` | 要素が挿入される前に追加され、要素が挿入の1フレーム後に削除されます。 |
-| `:enter-end` | 要素が挿入後(`enter-start` が削除されると同時)の1フレームに追加され、トランジション/アニメーションが終了すると削除されます。
-| `:leave` | リーブフェーズ全体に適用されます。 |
-| `:leave-start` | リーブ遷移がトリガされるとすぐに追加され、1フレーム後に削除されます。 |
-| `:leave-end` | リーブ遷移がトリガされた後(同時に `leave-start` が削除される)の1フレームに追加され、トランジション/アニメーションが終了すると削除されます。
-
----
-
-### `x-spread`
-**Example:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` は、Alpineのバインディングを要素から再利用可能なオブジェクトに抽出することができます。
-
-オブジェクトのキーはディレクティブ(もちろん修飾子を含むことができます)として、値はコールバックとして評価されます。
-
-> 注意: x-spreadにはいくつかの注意点があります。
-> - 展開されるディレクティブが`x-for` の場合、コールバックから通常の式の文字列を返す必要があります。例えば `['x-for']() { return 'item in items' }` のようにです。
-> - `x-data` と `x-init` は "spread" オブジェクトの中では使えません。
-
----
-
-### `x-cloak`
-**例:** `<div x-data="{}" x-cloak></div>`
-
-Alpine の初期化時に、要素から `x-cloak` 属性が削除されます。これは、事前に初期化された DOM を隠すのに役立ちます。これが機能するためには、通常、次のグローバルスタイルを追加します。:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### マジックプロパティ
-
----
-
-### `$el`
-**例:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">"foo"に置換します</button>
-</div>
-```
-
-`$el` は、ルートコンポーネントの DOM ノードを取得するために使用できるマジックプロパティです。
-
-### `$refs`
-**例:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` は、コンポーネント内で `x-ref` でマークされた DOM 要素を取得するために使用できるマジックプロパティです。これは、DOM 要素を手動で操作する必要がある場合に便利です。
-
----
-
-### `$event`
-**例:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` は、ネイティブブラウザの「Event」オブジェクトを取得するためにイベントリスナ内で使用できるマジックプロパティです。
-
----
-
-### `$dispatch`
-**例:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- クリックされると、 console.log が「bar」を出力します -->
-</div>
-```
-
-`$dispatch` は、`CustomEvent` を作成し、内部で `.dispatchEvent()` を使用してディスパッチするためのショートカットです。カスタムイベントを使用してコンポーネント間およびコンポーネント間でデータを渡すには、多くの適切なユースケースがあります。基礎となるブラウザの `CustomEvent` システムの詳細については、[こちらをご覧ください。](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events)
-
-`$dispatch('some-event', { some: 'data' })` の2番目のパラメータとして渡されるデータは、新しいイベントの「detail」プロパティ: `$event.detail.some` です。カスタムイベントデータを `.detail` プロパティにアタッチすることは、ブラウザの `CustomEvent` の標準的な方法です。詳細は[こちらをご覧ください。](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)
-
-また、`$dispatch()` を使用して、`x-model` バインディングのデータ更新をトリガすることもできます。 例えば:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- ボタンがクリックされると、`x-model` は浮上する「input」イベントをキャッチし、foo を「baz」に更新します。 -->
-    </span>
-</div>
-```
-
----
-
-### `$nextTick`
-**例:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` は、Alpine がリアクティブな DOM 更新を行った後、指定された式のみを実行できるマジックプロパティです。これは、データ更新が反映された後に DOM ステートとやり取りしたい場合に便利です。
-
----
-
-### `$watch`
-**例:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">開閉を切り替える</button>
-</div>
-```
-
-マジックメソッド `$watch` を使用してコンポーネントのプロパティを「監視」することができます。上の例では、ボタンがクリックされて `open` が変更されるとコールバックが実行され、新しい値が `console.log` によって出力されます。
-
-## セキュリティ
-もしも脆弱性を発見した場合, [calebporzio@gmail.com]() 宛にメールを送ってください。
-
-Alpineでは `Function` オブジェクトを使用したカスタム実装に依存しています。この関数は `eval()` より安全ですが、Google Chromeアプリのような [CSP](https://csp.withgoogle.com/docs/strict-csp.html) が制限されている環境では使用が禁止されています。
-
-もしも機密データを扱う環境でAlpineを使用している場合かつ [CSP](https://csp.withgoogle.com/docs/strict-csp.html) を必要とする場合は、ポリシーに `unsafe-eval`を含める必要があります。堅牢なポリシーを設定することで、個人情報や財務情報を利用する際のユーザー保護に役立ちます。
-
-ポリシーはページ内すべてのスクリプトに適用されるので、Webサイトに含まれる他の外部ライブラリを信用できるかどうか慎重に検討し、 `eval()` 関数を使用したり、DOMを操作して悪意あるコードをページに注入したりするクロスサイトスクリプティング脆弱性を防ぐことが重要です。
-
-## V3 ロードマップ
-* Vueと互換性を持たせるために `x-ref` から `ref` に変更する?
-* `Alpine.directive()` を追加する
-* `Alpine.component('foo', {...})` ( `__init()` マジックメソッドと一緒に) を追加する
-* "loaded"や"transition-start"のようなイベントを追加する ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* オブジェクトや配列を `x-bind:class="{ 'foo': true }"` から削除する([#236](https://github.com/alpinejs/alpine/pull/236) では `style` 属性をサポートしようとしている)
-* `x-for` の性能を改善する ([#165](https://github.com/alpinejs/alpine/pull/165))
-* 「深い監視」をV3で追加する ([#294](https://github.com/alpinejs/alpine/pull/294))
-* `$el` ショートカットを追加する
-* `@click.away` から `@click.outside` に変更する?
-
-## ライセンス
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-MIT ライセンスの下でライセンスされています。詳細については、[LICENSE.md](LICENSE.md) を参照してください。

+ 0 - 783
README.ko.md

@@ -1,783 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js는 저렴한 비용으로 Vue 또는 React와 같은 대규모 프레임워크의 반응성 및 선언적 특성을 제공합니다.
-
-DOM을 유지하고 적절한 동작을 사용할 수 있습니다.
-
-JavaScript용 [Tailwind](https://tailwindcss.com/)라고 생각하시면 됩니다.
-
-> 참고: 이 도구는 [Vue](https://vuejs.org/) (및 [Angular](https://angularjs.org/))에서 영감을 받았습니다. 저는 이러한 도구의 개발자들이 웹에 기여한 것에 대해 대단히 감사하고있습니다.
-
-
-## 설치
-
-**CDN 사용:** `<head>`섹션 끝에 다음 스크립트를 추가합니다.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-그것으로 끝입니다. 자체적으로 초기화됩니다.
-
-프로덕션 환경의 경우 최신 버전의 예상치 못한 문제를 방지하기 위해 링크에 특정 버전 번호를 설정하는 것이 좋습니다.
-예를 들어 `2.8.2` 버전 사용:
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**NPM 사용:** NPM에서 패키지를 설치합니다.
-```js
-npm i alpinejs
-```
-
-스크립트에 다음 내용을 추가하세요.
-```js
-import 'alpinejs'
-```
-
-**IE11을 지원하려면** 다음 스크립트를 사용하세요.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-위의 패턴은 [module/nomodule 패턴](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/)으로 최신 브라우저와 IE11 및 기타 레거시 브라우저에서 자동으로 로드됩니다.
-
-## 사용법
-
-*드롭다운/모달*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*탭*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-사소한 목적으로도 사용할 수 있습니다.
-*드롭다운에 마우스 오버 시 HTML 내용을 미리 가져옵니다.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## 배우기
-
-다음과 같이 총 14개의 지침이 있습니다:
-
-| 지침 | 설명 |
-| --- | --- |
-| [`x-data`](#x-data) | 새로운 구성요소의 범위를 선언합니다. |
-| [`x-init`](#x-init) | 구성요소가 초기화될 때 제공된 식을 실행합니다. |
-| [`x-show`](#x-show) | `display: none;` 부울 표현식에 따라 요소를 토글합니다. (true 또는 false). |
-| [`x-bind`](#x-bind) | 전달 된 JS 표현식의 결과와 동일한 속성 값을 설정합니다. |
-| [`x-on`](#x-on) | 요소에 이벤트 리스너를 설치합니다. 이벤트가 발생하면 제공된 JS 표현식을 실행합니다. |
-| [`x-model`](#x-model) | 지시문은 입력 요소와의 데이터 바인딩을 보장합니다. 이를 통해 양방향으로 데이터 바인딩이 가능합니다. |
-| [`x-text`](#x-text) | 유사한 방식으로 작동 `x-bind`의 `innerText` 요소가 업데이트됩니다. |
-| [`x-html`](#x-html) | 유사한 방식으로 작동 `x-bind`의 `innerHTML` 요소가 업데이트됩니다. |
-| [`x-ref`](#x-ref) | 구성 요소의 DOM 요소를 가져오는 편리한 방법입니다. |
-| [`x-if`](#x-if) | 전달된 조건이 충족되지 않으면 DOM에서 요소를 완전히 제거합니다. `<template>` 태그에 사용되어야 합니다.
-| [`x-for`](#x-for) | 배열의 각 항목에 대해 새 DOM 노드를 만듭니다. `<template>`태그에 사용해야합니다. |
-| [`x-transition`](#x-transition) | 요소 전환의 다양한 단계에 클래스를 추가하기 위한 지시. |
-| [`x-spread`](#x-spread) | Alpine 지시문이 있는 개체를 요소에 바인딩하여 재사용성을 높일 수 있습니다. |
-| [`x-cloak`](#x-cloak) | Alpine이 초기화되면 해제됩니다. 초기화 전에 DOM을 숨기는 데 유용합니다. |
-
-그리고 6가지 마법속성:
-
-| 마법속성 | 설명 |
-| --- | --- |
-| [`$el`](#el) | 루트 구성 요소의 DOM 노드를 검색합니다. |
-| [`$refs`](#refs) | `x-ref` 컴포넌트 내부에 표시된 DOM 요소를 검색합니다. |
-| [`$event`](#event) | 이벤트 핸들러에서 기본 브라우저 "Event" 객체를 검색합니다.  |
-| [`$dispatch`](#dispatch) | `CustomEvent`를 만들고 `.dispatchEvent()` 내부적으로 보냅니다. |
-| [`$nextTick`](#nexttick) | Alpine이 반응형 DOM 업데이트를 수행한 후 제공된 표현식을 실행합니다. |
-| [`$watch`](#watch) | "수신(watched)"중인 구성 요소의 속성이 변경될 때 제공되는 콜백을 트리거합니다. |
-
-
-## 스폰서
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**여기에 로고를 등록하고 싶으신가요? [Twitter로 DM을 보내주세요](https://twitter.com/calebporzio)**
-
-## 커뮤니티 프로젝트
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### 지시어
-
----
-
-### `x-data`
-
-**예제:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**구조:** `<div x-data="[object literal]">...</div>`
-
-`x-data` 구성 요소의 새 범위를 선언합니다.  다음 데이터 개체를 사용하여 새 구성 요소를 초기화하도록 프레임워크에 지시합니다.
-
-Vue 컴포넌트의 `data` 속성과 유사합니다.
-
-**컴포넌트 로직 추출**
-
-재사용이 가능한 데이터(동작)를 추출할 수 있습니다.
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **번들러 사용자의 경우**, Alpine.js는 전역 범위(`window`)의 함수에만 액세스합니다. 예를 들어 `x-data`를 사용하려면 함수를 `window.dropdown = function () {}`처럼 `window`에 명시적으로 할당해야합니다. (이것은 Webpack, Rollup, Parcel 등의 `함수(function)`를 사용하면 기본적으로 `window`가 아닌 모듈의 범위로 설정되기 때문입니다.)
-
-
-객체를 분리 사용하여 여러 데이터 객체를 혼합하여 사용할수도 있습니다.
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**예제:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**구조:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` 구성 요소가 초기화될 때 제공된 식을 실행합니다.
-
-초기 Alpine DOM 업데이트 (예 : VueJS의 `mounted()` 후크 ) 후에 코드를 실행하려면 `x-init` 콜백을 전달할 수 있으며 초기화 후에 실행합니다:
-
-`x-init="() => { // we have access to the post-dom-initialization state here // }"`
-
----
-
-### `x-show`
-**예제:** `<div x-show="open"></div>`
-
-**구조:** `<div x-show="[expression]"></div>`
-
-`x-show` 표현식이 true 또는 false로 결정됨에 따라 요소의 `display: none;` 스타일 속성을 전환합니다.
-
-**x-show.transition**
-
-`x-show.transition`은 `x-show` 보다 더 나은 CSS transition을 제공하는 편리한 API입니다.
-
-```html
-<div x-show.transition="open">
-    이곳의 컨텐츠들은 transition in, out이 동작됨.
-</div>
-```
-
-| 지침 | 설명 |
-| --- | --- |
-| `x-show.transition` | fade 와 scale이 동시에 동작됨. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | transition in만 동작됨. |
-| `x-show.transition.out` | transition out만 동작됨. |
-| `x-show.transition.opacity` | fade만 사용됨. |
-| `x-show.transition.scale` | scale만 사용됨. |
-| `x-show.transition.scale.75` | CSS scale transform 사용자화 `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | transition "in"을 200ms로 설정. out은 그것의 절반(100ms)으로 설정됨. |
-| `x-show.transition.origin.top.right` | CSS transform origin 사용자화 `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | "in" and "out"에 대한 서로 다른 동작시간. |
-
-> 참고: 모든 transition 수정자을 서로 결합하여 사용할 수 있습니다. 이것이 가능합니다(말도 안되지만 lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> 참고: `x-show`는 모든 자식이 전환을 완료할 때 까지 대기합니다. 이 동작을 우회하려면 `.immediate`수정자를 추가하세요:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> 참고: 조금 더 간단한 구문을 사용할 수 있습니다. ":" syntax: `:type="..."`.
-
-**예제:** `<input x-bind:type="inputType">`
-
-**구조:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` JavaScript 표현식의 결과를 속성값으로 설정합니다. 표현식은 component가 가지고 있는 데이터 객체의 모든 키에 접근할 수 있으며, component의 데이터가 변경될 때마다 자동으로 갱신됩니다.
-
-> 참고: 속성 바인딩은 종속성이 업데이트될 때만 업데이트됩니다. Framework는 데이터 변경 사항을 관찰하고 어떤 바인딩이 이를 처리하는지 감지할 수 있을 만큼 똑똑합니다.
-
-**클래스 속성일 경우 `x-bind`**
-
-`x-bind` 가 `class` 속성에 바인딩 될 때는 조금 다르게 동작합니다.
-
-클래스의 경우, 키가 클래스 이름이고 값이 부울 표현 식인 객체를 전달하여 해당 클래스 이름의 적용여부를 결정합니다.
-
-예제:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-이 예제에서, "hidden" 클래스는 `foo` 데이터 속성값이 `true` 인 경우에만 적용됩니다.
-
-**부울 속성일 경우 `x-bind`**
-
-`x-bind`는 변수를 조건식으로 사용하거나 `true` 또는 `false`로 확인되는 JavaScript 표현식을 사용하여, 값 속성과 동일한 방식으로 부울 속성을 지원합니다.
-
-예제:
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- When myVar == true: -->
-<button disabled="disabled">Click me</button>
-
-<!-- When myVar == false: -->
-<button>Click me</button>
-```
-
-위 예제에서는 `myVar`의 값이 각각 true 또는 false 인지에 따라 `disabled`속성이 추가 또는 삭제됩니다.
-
-부울 속성은 다음과 같은 속성에 대해 지원됩니다.[HTML specification](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), 예 `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, 그 외.
-
-> 참고: `aria-*`와 같이 속성에 대해 보여줄 거짓 상태가 필요한 경우 속성에 바인딩 하는 동안 `.toString()`을 값에 연결합니다. 예: `:aria-expanded="isOpen.toString()"`는 `isOpen`가 `true` 또는 `false`여부에 관계없이 유지됩니다.
-
-**`.camel` 수정자**
-**예제:** `<svg x-bind:view-box.camel="viewBox">`
-
-`camel`수정자는 camel 표기법에 해당하는 속성명으로 바인딩 합니다. 위 예제에서 `viewBox`의 값은 `view-box`속성이 아닌 `viewBox` 속성으로 바인딩 됩니다.
-
----
-
-### `x-on`
-
-> 참고: 조금 더 간단한 구문을 사용할 수 있습니다. "@" syntax: `@click="..."`.
-
-**예제:** `<button x-on:click="foo = 'bar'"></button>`
-
-**구조:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on`은 선언 된 요소에 이벤트 리스너를 연결합니다. 해당 이벤트가 발생하면 해당 값으로 설정된 JavaScript 표현식이 실행됩니다. 전체 이벤트 목록을 보려면 지시문을 추가하는 요소에 사용할 수있는 모든 이벤트와 함께`x-on`을 사용할 수 있습니다. 사용 가능한 값 항목들은 [the Event reference on MDN](https://developer.mozilla.org/en-US/docs/Web/Events)에서 확인할 수 있습니다.
-
-표현식에서 데이터가 수정되면, 이 데이터와 연관되어 있는 다른 요소의 속성도 업데이트됩니다.
-> 참고: 자바스크립트 함수 이름을 지정할 수도 있습니다.
-
-**예제:** `<button x-on:click="myFunction"></button>`
-
-위 예제는 다음코드와 동일합니다: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` 수정자**
-
-**예제:** `<input type="text" x-on:keydown.escape="open = false">`
-
-`x-on:keydown` 디렉티브에 keydown 수정자를 사용하여 수신 할 특정 키를 지정할 수 있습니다. 수정자는 `Event.key` 값의 케밥 케이스 버전입니다.
-
-예제: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> 참고: `x-on:keydown.cmd.enter="foo"`와 같이 시스템 수정자 키 조합을 사용하여 수신할 수 있습니다.
-
-**`.away` 수정자**
-
-**예제:** `<div x-on:click.away="showModal = false"></div>`
-
-`.away`수정자가 있는 경우, 이벤트 핸들러는 자신 자체가 아닌 다른 소스 또는 하위 소스에서 발생할 때 실행됩니다.
-
-이것은 사용자 클릭할 때 드롭다운과 모달을 숨기는데 유용합니다.
-
-**`.prevent` 수정자**
-**예제:** `<input type="checkbox" x-on:click.prevent>`
-
-이벤트 리스너에 `.prevent`를 추가하면 트리거된 이벤트에서 `preventDefault`가 호출됩니다. 위 예제에서 이것은 사용자가 체크박스를 클릭할 때, 체크박스가 실제로 선택되지 않음을 의미합니다.
-
-**`.stop` 수정자**
-**예제:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-이벤트 리스너에 `.stop`를 추가하면 트리거된 이벤트에서 `stopPropagation`가 호출됩니다. 위 예제에서 이것은 "클릭" 이벤트가 외부 `<div>`로 버블링되지 않음을 의미합니다. 즉, 사용자가 버튼을 클릭해도 `foo`는 `'bar'`로 설정되지 않습니다.
-
-**`.self` 수정자**
-**예제:** `<div? x-on:click.self="foo = 'bar'"><button></button></div?>`
-
-이벤트 리스너에 `.self`를 추가하면 `$event.target`이 요소 자체인 경우에만 이벤트 핸들러가 트리거됩니다. 위 예제에서 이것은 버튼에서 외부 `<div>`로 버블링된 "클릭"이벤트가 핸들러를 실행시키지 **않음**을 의미합니다.
-
-**`.window` 수정자**
-**예제:** `< x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-이벤트 리스너에 `.window`를 추가하면 선언된 DOM 노드 대신 전역 윈도우 객체에 리스너가 설정됩니다. 이것은 리사이즈 이벤트와 같이 윈도우에서 무언가 변경될 때 컴포넌트의 상태를 변경하고 싶은 경우 유용합니다. 이 예제에서 우리는 윈도우 너비가 768 픽셀보다 커지면, 모달/드롭다운을 닫고 그렇지 않으면 동일한 상태를 유지합니다
-
->참고: `window` 대신 `.document` 수정자를 사용하여 `document`에 리스너를 추가 할 수 있습니다.
-
-**`.once` 수정자**
-**예제:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-이벤트 리스너에 `.once` 수정자를 추가하면, 리스너가 한 번만 처리됩니다. 이것은 HTML부분 가져오기와 같이 한 번만 수행하려는 작업에 유용합니다.
-
-**`.passive` 수정자**
-**예제:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-이벤트 리스너에 `.passive` 수정자를 추가하면 리스너를 수동적으로 동작하게 만듭니다. 처리 중인 어떤 이벤트에도 `preventDefault()`가 동작하지 않음을 의미합니다. 예를 들어 터치 기기의 스크롤 성능에 도움이 될 수 있습니다.
-
-**`.debounce` 수정자**
-**예제:** `<input x-on:input.debounce="fetchSomething()">`
-
-`debounce` 수정자를 사용하면 이벤트 핸들러를 "디바운스" 할 수 있습니다. 즉, 이벤트 핸들러는 마지막 이벤트가 발생한 이후 일정 시간이 지날 때까지 실행되지 않습니다. 핸들러가 호출될 준비가 되면 마지막 핸들러 호출이 실행됩니다.
-
-디바운스의 기본 "대기" 시간은 250 밀리세컨드 입니다.
-
-이를 사용자화 하려면 다음과 같이 사용자 대기 시간을 지정할 수 있습니다:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` 수정자**
-**예제:** `<input x-on:event-name.camel="doSomething()">`
-
-`camel` 수정자는 이벤트명과 동등한 카멜 표기법으로 이벤트 리스너를 연결합니다. 위 예제에서 표현식은 요소에서 `eventName` 이벤트가 발생할 때 평가됩니다.
-
----
-
-### `x-model`
-**예제:** `<input type="text" x-model="foo">`
-
-**구조:** `<input type="text" x-model="[data item]">`
-
-`x-model`은 요소에 "양방향 데이터 바인딩"을 추가합니다. 즉, 입력 요소의 값은 컴포넌트 데이터 아이템의 값과 동기화되고 유지됩니다.
-
-> 참고: `x-model`은 text inputs, checkboxes, radio buttons, textareas, selects, 그리고 multiple selects 요소의 변경을 감지하는데 뛰어납니다. 이러한 시나리오에서 [how Vue would](https://vuejs.org/v2/guide/forms.html) 동작해야 합니다.
-
-**`.number` 수정자**
-**예제:** `<input x-model.number="age">`
-
-`number`수정자는 input의 값을 숫자로 변환합니다. 만약 값이 유효한 숫자로 분석되지 않으면, 원본 값을 반환합니다.
-
-**`.debounce` 수정자**
-**예제:** `<input x-model.debounce="search">`
-
-`debounce` 수정자를 사용하면 값 업데이트에 "debounce"를 추가 할 수 있습니다. 즉, 이벤트 핸들러는 마지막 이벤트가 발생한 이후 일정 시간이 지날 때까지 실행되지 않습니다. 핸들러가 호출될 준비가 되면 마지막 핸들러 호출이 실행됩니다.
-
-디바운스의 기본 "대기" 시간은 250 밀리세컨드 입니다.
-
-이를 사용자화 하려면 다음과 같이 사용자 대기 시간을 지정할 수 있습니다:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**예제:** `<span x-text="foo"></span>`
-
-**구조:** `<span x-text="[expression]"`
-
-`x-text`는 속성값을 업데이트하는 대신 요소의 `innerText`를 업데이트한다는 점을 제외하면,`x-bind`와 유사하게 동작합니다.
-
----
-
-### `x-html`
-**예제:** `<span x-html="foo"></span>`
-
-**구조:** `<span x-html="[expression]"`
-
-`x-html`는 속성값을 업데이트하는 대신 요소의 `innerHTML`을 업데이트한다는 점을 제외하면, `x-bind`와
-유사하게 동작합니다.
-
-> :warning: **신뢰성있는 컨텐트에 대해서만 사용하고 사용자 제공 컨텐트에는 절대로 사용하지 마세요** :warning:
->
-> 제 3자를 통한 동적 HTML 렌더링은 쉽게 [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)에 취약해질 수 있습니다.
-
----
-
-### `x-ref`
-**예제:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**구조:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref`는 컴포넌트의 원시 DOM 요소를 검색하는 편리한 방법을 제공합니다. 요소에 `x-ref`속성을 설정하면 `$refs`라는 객체 내부에서 모든 이벤트 핸들러를 사용할 수 있습니다.
-
-이것은 아이디를 설정하고 모든 곳에서 `document.querySelector`를 사용하는 것에 대한 유용한 대안입니다.
-
-> 참고: 필요하다면 x-ref: `<span :x-ref="item.id"></span>`와 같이 동적으로 값을 바인딩 할 수도 있습니다.
-
----
-
-### `x-if`
-**예제:** `<template x-if="true"><div>Some Element</div></template>`
-
-**구조:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-`x-show`로 충분하지 않은 경우(`x-show`는 값이 거짓이면 요소를 `display: none`로 설정합니다.)
-, `x-if`는 DOM으로 부터 요소를 완전히 삭제할 때 사용할 수 있습니다.
-
-Alpine은 가상 DOM을 사용하지 않기 때문에 `x-if`를 `<template></template>` 태그에 사용하는게 중요합니다. 이러한 구현을 통해 Alpine은 견고함을 유지하고 실제 DOM을 사용하여 마법을 부릴 수 있습니다.
-
-> 참고: `x-if`는 `<template></template>`태그 내에 단일 루트 요소만 가져야 합니다.
-
-> 참고: `svg`에 `template`를 사용할 땐 Alpine.js 가 초기화 되기 전에 실행되도록 [폴리필](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)을 추가해야 합니다.
-
----
-
-### `x-for`
-**예제:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> 참고: `:key` 바인딩은 선택사항이지만, 사용하는 것을 적극추천합니다.
-
-`x-for`는 배열의 각 항목에 대해 새로운 DOM 노드를 생성하려는 경우 사용할 수 있습니다. 이것은 일반적인 DOM 요소가 아닌 `template` 태그에 있어야 한다는 것을 제외하면 Vue의 `v-for`와 유사하게 나타나야 합니다.
-
-반복문의 현재 색인에 접근하고 싶다면, 다음 구문을 사용하세요:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- 원한다면 반복문 내부의 "색인"을 참조할 수도 있습니다. -->
-    <div x-text="index"></div>
-</template>
-```
-
-반복문의 배열객체(컬렉션)에 접근하고 싶다면, 다음 구문을 사용하세요:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- 원한다면 반복문 내부의 "컬렉션"을 참조할 수도 있습니다. -->
-    <!-- 현재 항목. -->
-    <div x-text="item"></div>
-    <!-- 위와 동일. -->
-    <div x-text="collection[index]"></div>
-    <!-- 이전 항목. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> 참고: `x-for`는 `<template></template>`태그 내에 단일 루트 요소만 가져야 합니다.
-
-> 참고: `svg`에 `template`를 사용할 땐 Alpine.js 가 초기화 되기 전에 실행되도록 [폴리필](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)을 추가해야 합니다.
-
-#### `x-for`s 중첩
-`x-for`루프를 중첩할 수는 있지만, 이 경우 각 루프를 요소로 감싸야합니다. 예제:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### 범위 내의 반복
-
-Alpine은 `i in n` 구문을 지원하고, 여기서 `n`은 정수이며, 고정된 범위의 요소들을 반복할 수 있습니다.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**예제:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> 위 예제는 [Tailwind CSS](https://tailwindcss.com)의 클래스를 사용합니다.
-
-Alpine은 요소의 "숨져진" 상태와 "보여진" 상태 사이의 다양한 단계에 클래스를 적용하기 위해 6가지의 서로 다른 전환 지시자들을 제공합니다. 이 지시자들은 `x-show` 및 `x-if` 모두에서 작동합니다.
-
-이것들은 VueJs의 전환 지시자와 정확히 동일한 동작을 한다. 단, 그들은 조금 다른 더 합리적인 이름을 가지고 있다:
-
-| 지침 | 설명 |
-| --- | --- |
-| `:enter` | 전체 진입 단계에서 적용됨. |
-| `:enter-start` | 요소가 삽입되기 전에 추가되고, 요소가 삽입되고 1 프레임 이후에 삭제됨. |
-| `:enter-end` | 요소가 삽입되고 1 프레임 이후에 추가되고(동시에 `enter-start`는 삭제됨) 전환/애니메이션 종료 후 삭제됨.
-| `:leave` | 전체 이탈 단계에서 적용됨. |
-| `:leave-start` | 이탈 전환이 발생될 때 즉시 추가되고, 1 프레임 후 제거됨. |
-| `:leave-end` | 이탈 전환이 발생된 후 1 프레임 후 추가되고(동시에 `leave-start`는 삭제됨) 전환/애니메이션 종료 후 삭제됨.
-
----
-
-### `x-spread`
-**예제:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread`를 사용하면 요소의 Alpine 바인딩을 재사용 가능한 객체로 추출 할 수 있습니다.
-
-객체 키들은 지시자들이며(수정사를 포함해 모든 지시자가 될 수 있습니다), 값들은 Alpine에 의해 평가되는 콜백입니다.
-
-> 참고: x-spread에는 몇 가지 주의사항이 있습니다:
-> - `x-for`가 "spread" 지시자 일 때, 콜백에서 반드시 일반 문자열 표현식을 반환해야 합니다. 예제: `['x-for']() { return 'item in items' }`.
-> - "spread" 객체 내애서 `x-data` 와 `x-init`는 사용할 수 없습니다.
-
----
-
-### `x-cloak`
-**예제:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak`속성들은 Alpine 초기화할 때 요소에서 제거됩니다. 이것은 미리 초기화된 DOM을 숨기는데 유용합니다. 이 작업을 수행하려면 다음과 같이 전역 스타일을 추가하는 것이 일반적입니다:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### 마법 속성들
-
-> `$el`을 제외하고, 컴포넌트가 아직 초기화 되지 않은 상태에서 마법 속성들을 **`x-data`내에서 사용할 수 없습니다.**
-
----
-
-### `$el`
-**예제:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
-</div>
-```
-
-`$el`은 루트 컴포넌트 DOM 노드를 검색하는데 사용할 수 있는 마법 속성입니다.
-
-### `$refs`
-**예제:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs`는 컴포넌트 내에 `x-ref`로 표시된 DOM 요소를 검색하는데 사용할 수 있는 마법 속성입니다. 이것은 DOM 요소를 수동으로 조작해야 할 때 유용합니다.
-
----
-
-### `$event`
-**예제:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event`는 이벤트 리스너 내에서 기본 브라우저 "이벤트" 객체를 검색하는데 사용할 수 있는 마법 속성입니다.
-
-> 참고: $event 속성은 DOM 표현식에서만 사용할 수 있습니다.
-
-자바스크립트 함수 내에서 $event에 접근해야 하는 싶은 경우 직접 전달할 수 있습니다:
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**예제:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- 클릭하면, "bar" 콘솔로그가 출력됨 -->
-</div>
-```
-
-**이벤트 전파에 대한 참고 사항**
-
-[이벤트 버블링](https://en.wikipedia.org/wiki/Event_bubbling)으로 인해 동일한 중첩 계층에 있는 노드에서 전달된 이벤트를 캡처해야 하는 경우 [`.window`](https://github.com/alpinejs/alpine#x-on)수정자를 사용해야 합니다:
-
-**예제:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> 이것은 `custom-event`가 전달될 때, 공통 조상인 `div`로 전파되기 때문에 작동하지 않습니다.
-
-**컴포넌트로 전달**
-
-또한 이전 기술을 활용하여 컴포넌트가 서로 통신하도록 할 수도 있습니다:
-
-**예제:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- 클릭하면 "Hello World!" 콘솔로그가 출력됨. -->
-```
-
-`$dispatch`는 `CustomEvent`를 생성하고, 내부적으로 `.dispatchEvent()`를 사용하여 그것을 전달하는 간단한 방법입니다. 사용자 지정 이벤트를 이용하여 컴포넌트간에 데이터 전달하는 유용한 사용사례가 많이 있습니다. 브라우저의 `CustomEvent`시스템에 대한 자세한 내용은 [이곳을 읽어보세요](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events).
-
-`$dispatch('some-event', { some: 'data' })`에 두 번째 파라메터로 전달되는 데이터는 새로운 이벤트의 "detail"속성: `$event.detail.some`을 이용해 사용할 수 있습니다. 브라우저에서 `.detail`속성에 사용자화 이벤트 데이터를 연결하는 것은 `CustomEvent`에 대한 표준 관행입니다. 더 자세한 내용은 [이곳을 읽어보세요](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail).
-
-`x-model`로 바인딩된 데이터의 업데이트가 발생하도록 `$dispatch()`를 사용할 수도 있습니다. 예제:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- 버튼 클릭 이후, `x-model`은 버블링된 "input" 이벤트를 포착하고, foo를 "baz"로 업데이트 함. -->
-    </span>
-</div>
-```
-
-> 참고: $dispatch 속성은  DOM 표현식에서만 사용 가능합니다.
-
-자바스크립트 함수에서 $dispatch에 접근하고 싶은 경우 직접 전달할 수 있습니다:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**예제:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick`은 Alpine이 반응형 DOM 업데이트를 수행한 이후에만 주어진 표현식이 실행되도록 하는 마법 속성입니다. 이것은 당신이 만든 데이터 업데이트가 반영된 DOM과 상호작용하고자 할 때 유용합니다.
-
----
-
-### `$watch`
-**예제:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-`$watch`마법 메소드를 통해 컴포넌트 속성을 "감시"할 수있습니다. 위 예제에서, 버튼이 클릭되면 `open`이 변경되고, 제공된 콜백이 실행되며 `console.log`에 새로운 값이 출력됩니다.
-
-## Security
-보안 취약점을 발견하면, [calebporzio@gmail.com]()으로 메일을 보내주세요.
-
-Alpine은 지시자을 평가하기 위해 `Function` 객체를 사용하는 사용자 정의 구현에 의존합니다.
-`eval ()`보다 더 안전하지만 Google Chrome 앱과 같은 일부 환경에서는 제한적인 콘텐츠 보안 정책(CSP)을 사용하여 사용이 금지됩니다.
-
-민감한 데이터를 다루고 [CSP](https://csp.withgoogle.com/docs/strict-csp.html)가 필요한 웹 사이트에서 Alpine을 사용하는 경우, 정책에 `unsafe-eval`을 포함해야합니다. 올바르게 구성된 강력한 정책은 개인 또는 금융 데이터를 사용할 때 사용자를 보호하는 데 도움이됩니다.
-
-정책이 페이지의 모든 스크립트에 적용되므로 웹 사이트에 포함 된 다른 외부 라이브러리를 신중하게 검토하여 신뢰할 수 있고 `eval()`함수를 사용하여 교차 사이트 스크립팅 취약점 또는 DOM을 조작하여 페이지에 악성 코드를 삽입을 유발하지 않는지 확인하는 것이 중요합니다.
-
-## V3 Roadmap
-* Vue와 동등하게 `x-ref`에서 `ref`로 변경?
-* `Alpine.directive()` 추가
-* `Alpine.component('foo', {...})`(매직 `__init()`메소드 사용) 추가
-* "loaded", "transition-start", 그 외...([#299](https://github.com/alpinejs/alpine/pull/299))에 대한 Alpine이벤트 전달?
-* `x-bind:class="{ 'foo': true }"`에서 "객체"(그리고 배열) 제거([#236](https://github.com/alpinejs/alpine/pull/236) `style` 속성에 대한 객지 구문 지원 추가)
-* `x-for`변이 반응성 개선 ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Add "deep watching" support in V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* V3에 "깊은 감시" 지원 추가 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* `$el` 간편한 방법 추가
-* `@click.away`를 `@click.outside`로 변경?
-
-## 라이센스
-
-저작권 © 2019-2021 Caleb Porzio 와 기여자들
-
-MIT 라이센스에 따라 허가되며, 더 자세한 내용은 [LICENSE.md](LICENSE.md)를 확인하세요.

+ 29 - 797
README.md

@@ -1,814 +1,46 @@
-# Alpine.js
+## Alpine V3
 
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
+### Coming From Alpine Day?
+This repo is temporary until V3 is fully published. For now, here is the Alpine V3 file you can drop into a `<script>` tag and test it out!
 
-## Announcement: Alpine V3 Launching Soon!
-Alpine is getting a complete overhaul in almost every way. It's all dropping on Alpine Day, June 10th 2021.
+[→ Alpine V3 JS File](/packages/alpinejs/dist/cdn.js)
 
-**[Go here for all the details!](https://alpineday.com)**
+### Quickstart
 
-![](https://alpineday.com/img/twitter_card.jpg)
+* clone this repo locally
+* run `npm install` & `npm run build`
+* Include the `/packages/alpinejs/dist/cdn.js` file from a `<script>` tag on a webpage and you're good to go!
 
----
+### Brief Tour
+You can get everything installed with: `npm install` in the root directory of this repo after cloning it locally.
 
-Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost.
+This repo is a "mono-repo" using npm workspaces for managing the packages. Each package has its own folder in the `/packages` directory.
 
-You get to keep your DOM, and sprinkle in behavior as you see fit.
+Rather than having to run seperate builds for each package, all package bundles are handled with the same command: `npm run build`
 
-Think of it like [Tailwind](https://tailwindcss.com/) for JavaScript.
+Here's a brief look at each package in this repo:
 
-> Note: This tool's syntax is almost entirely borrowed from [Vue](https://vuejs.org/) (and by extension [Angular](https://angularjs.org/)). I am forever grateful for the gift they are to the web.
+Package | Description
+--- | ---
+[alpinejs](packages/alpinejs) | The main Alpine repo with all of Alpine's core
+[csp](packages/csp) | A repo to provide a "CSP safe" build of Alpine
+[history](packages/history) | A plugin for binding data to query string parameters using the history API (name is likely to change)
+[intersect](packages/intersect) | A plugin for triggering JS expressions based on elements intersecting with the viewport
+[morph](packages/morph) | A plugin for morphing HTML (like morphdom) inside the page intelligently
 
-## Translated documentation
+The compiled JS files (as a result of running `npm run [build/watch]`) to be included as a `<script>` tag for example are stored in each package's `packages/[package]/dist` directory.
 
-| Language | Link for documentation |
-| --- | --- |
-| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Chinese Simplified | [**简体中文文档**](./README.zh-CN.md) |
-| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
-| German | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanese | [**日本語ドキュメント**](./README.ja.md) |
-| Norwegian | [**Dokumentasjon på norsk**](./README.no.md) |
-| Portuguese | [**Documentação em Português**](./README.pt.md) |
-| Russian | [**Документация на русском**](./README.ru.md) |
-| Spanish | [**Documentación en Español**](./README.es.md) |
-| Turkish | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| Farsi | [**مستندات به فارسی**](./README.fa.md) |
-| Français | [**Documentation en Français**](./README.fr.md) |
-| Korean | [**한국어 문서**](./README.ko.md) |
+Each package should at least have: a "cdn" build that is self-initializing and can be included using the `src` attribute in a `<script defer>` tag, and a `module.[esm/cjs].js` file that is used for importing as a JS module (cjs for node, esm for everything else).
 
-## Install
+The bundling for Alpine V3 is handled exclusively by ESBuild. All of the configuration for these builds is stored in the `scripts/build.js` file.
 
-**From CDN:** Add the following script to the end of your `<head>` section.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
+### Testing
+There are 2 different testing tools used in this repo: Cypress (for integration tests), and Jest (for unit tests).
 
-That's it. It will initialize itself.
+All tests are stored inside the `/tests` folder under `/tests/cypress` and `/tests/jest`.
 
-For production environments, it's recommended to pin a specific version number in the link to avoid unexpected breakage from newer versions.
-For example, to use version `2.8.2` (latest):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
+You can run them both from the command line using: `npm run test`
 
-**From npm:** Install the package from npm.
-```js
-npm i alpinejs
-```
+If you wish to only run cypress and open it's user interface (recommended during development), you can run: `npm run cypress`
 
-Include it in your script.
-```js
-import 'alpinejs'
-```
-
-**For IE11 support** Use the following scripts instead.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-The pattern above is the [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) that will result in the modern bundle automatically loaded on modern browsers, and the IE11 bundle loaded automatically on IE11 and other legacy browsers.
-
-## Use
-
-*Dropdown/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*Tabs*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-You can even use it for non-trivial things:
-*Pre-fetching a dropdown's HTML content on hover.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## Learn
-
-There are 14 directives available to you:
-
-| Directive | Description |
-| --- | --- |
-| [`x-data`](#x-data) | Declares a new component scope. |
-| [`x-init`](#x-init) | Runs an expression when a component is initialized. |
-| [`x-show`](#x-show) | Toggles `display: none;` on the element depending on expression (true or false). |
-| [`x-bind`](#x-bind) | Sets the value of an attribute to the result of a JS expression. |
-| [`x-on`](#x-on) | Attaches an event listener to the element. Executes JS expression when emitted. |
-| [`x-model`](#x-model) | Adds "two-way data binding" to an element. Keeps input element in sync with component data. |
-| [`x-text`](#x-text) | Works similarly to `x-bind`, but will update the `innerText` of an element. |
-| [`x-html`](#x-html) | Works similarly to `x-bind`, but will update the `innerHTML` of an element. |
-| [`x-ref`](#x-ref) | Convenient way to retrieve raw DOM elements out of your component. |
-| [`x-if`](#x-if) | Removes an element completely from the DOM. Needs to be used on a `<template>` tag. |
-| [`x-for`](#x-for) | Creates new DOM nodes for each item in an array. Needs to be used on a `<template>` tag. |
-| [`x-transition`](#x-transition) | Directives for applying classes to various stages of an element's transition. |
-| [`x-spread`](#x-spread) | Allows you to bind an object of Alpine directives to an element for better reusability. |
-| [`x-cloak`](#x-cloak) | This attribute is removed when Alpine initializes. Useful for hiding pre-initialized DOM. |
-
-And 6 magic properties:
-
-| Magic Properties | Description |
-| --- | --- |
-| [`$el`](#el) |  Retrieve the root component DOM node. |
-| [`$refs`](#refs) | Retrieve DOM elements marked with `x-ref` inside the component. |
-| [`$event`](#event) | Retrieve the native browser "Event" object within an event listener.  |
-| [`$dispatch`](#dispatch) | Create a `CustomEvent` and dispatch it using `.dispatchEvent()` internally. |
-| [`$nextTick`](#nexttick) | Execute a given expression AFTER Alpine has made its reactive DOM updates. |
-| [`$watch`](#watch) | Will fire a provided callback when a component property you "watched" gets changed. |
-
-
-## Sponsors
-
-[<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">](https://tailwindcss.com)
-
-
-**Want your logo here? [DM on Twitter](https://twitter.com/calebporzio)**
-
-## Community Projects
-
-* [Alpine Devtools](https://github.com/HugoDF/alpinejs-devtools)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Alpine Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-
-### Directives
-
----
-
-### `x-data`
-
-**Example:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Structure:** `<div x-data="[object literal]">...</div>`
-
-`x-data` declares a new component scope. It tells the framework to initialize a new component with the following data object. It's also possible to leave it empty when you don't have any data in your component.
-
-Think of it like the `data` property of a Vue component.
-
-**Extract Component Logic**
-
-You can extract data (and behavior) into reusable functions:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        <!-- Dropdown -->
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **For bundler users**, note that Alpine.js accesses functions that are in the global scope (`window`), you'll need to explicitly assign your functions to `window` in order to use them with `x-data` for example `window.dropdown = function () {}` (this is because with Webpack, Rollup, Parcel etc. `function`'s you define will default to the module's scope not `window`).
-
-
-You can also mix-in multiple data objects using object destructuring:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Example:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Structure:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` runs an expression when a component is initialized.
-
-If you wish to run code AFTER Alpine has made its initial updates to the DOM (something like a `mounted()` hook in VueJS), you can return a callback from `x-init`, and it will be run after:
-
-`x-init="() => { // we have access to the post-dom-initialization state here // }"`
-
----
-
-### `x-show`
-**Example:** `<div x-show="open"></div>`
-
-**Structure:** `<div x-show="[expression]"></div>`
-
-`x-show` toggles the `display: none;` style on the element depending if the expression resolves to `true` or `false`.
-
-**x-show.transition**
-
-`x-show.transition` is a convenience API for making your `x-show`s more pleasant using CSS transitions.
-
-```html
-<div x-show.transition="open">
-    These contents will be transitioned in and out.
-</div>
-```
-
-| Directive | Description |
-| --- | --- |
-| `x-show.transition` | A simultaneous fade and scale. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Only transition in. |
-| `x-show.transition.out` | Only transition out. |
-| `x-show.transition.opacity` | Only use the fade. |
-| `x-show.transition.scale` | Only use the scale. |
-| `x-show.transition.scale.75` | Customize the CSS scale transform `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Sets the "in" transition to 200ms. The out will be set to half that (100ms). |
-| `x-show.transition.origin.top.right` | Customize the CSS transform origin `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Different durations for "in" and "out". |
-
-> Note: All of these transition modifiers can be used in conjunction with each other. This is possible (although ridiculous lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Note: `x-show` will wait for any children to finish transitioning out. If you want to bypass this behavior, add the `.immediate` modifier:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Note: You are free to use the shorter ":" syntax: `:type="..."`.
-
-**Example:** `<input x-bind:type="inputType">`
-
-**Structure:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` sets the value of an attribute to the result of a JavaScript expression. The expression has access to all the keys of the component's data object, and will update every-time its data is updated.
-
-> Note: attribute bindings ONLY update when their dependencies update. The framework is smart enough to observe data changes and detect which bindings care about them.
-
-**`x-bind` for class attributes**
-
-`x-bind` behaves a little differently when binding to the `class` attribute.
-
-For classes, you pass in an object whose keys are class names, and values are boolean expressions to determine if those class names are applied or not.
-
-For example:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-In this example, the "hidden" class will only be applied when the value of the `foo` data attribute is `true`.
-
-**`x-bind` for boolean attributes**
-
-`x-bind` supports boolean attributes in the same way as value attributes, using a variable as the condition or any JavaScript expression that resolves to `true` or `false`.
-
-For example:
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- When myVar == true: -->
-<button disabled="disabled">Click me</button>
-
-<!-- When myVar == false: -->
-<button>Click me</button>
-```
-
-This will add or remove the `disabled` attribute when `myVar` is true or false respectively.
-
-Boolean attributes are supported as per the [HTML specification](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), for example `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-> Note: If you need a false state to show for your attribute, such as `aria-*`, chain `.toString()` to the value while binding to the attribute. For example: `:aria-expanded="isOpen.toString()"` would persist whether  `isOpen` was `true` or `false`.
-
-**`.camel` modifier**
-**Example:** `<svg x-bind:view-box.camel="viewBox">`
-
-The `camel` modifier will bind to the camel case equivalent of the attribute name. In the example above, the value of `viewBox` will be bound the `viewBox` attribute as opposed to the `view-box` attribute.
-
----
-
-### `x-on`
-
-> Note: You are free to use the shorter "@" syntax: `@click="..."`.
-
-**Example:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Structure:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` attaches an event listener to the element it's declared on. When that event is emitted, the JavaScript expression set as its value is executed. You can use `x-on` with any event available for the element you're adding the directive on, for a full list of events, see [the Event reference on MDN](https://developer.mozilla.org/en-US/docs/Web/Events) for a list of possible values.
-
-If any data is modified in the expression, other element attributes "bound" to this data, will be updated.
-
-> Note: You can also specify a JavaScript function name.
-
-**Example:** `<button x-on:click="myFunction"></button>`
-
-This is equivalent to: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` modifiers**
-
-**Example:** `<input type="text" x-on:keydown.escape="open = false">`
-
-You can specify specific keys to listen for using keydown modifiers appended to the `x-on:keydown` directive. Note that the modifiers are kebab-cased versions of `Event.key` values.
-
-Examples: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Note: You can also listen for system-modifier key combinations like: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` modifier**
-
-**Example:** `<div x-on:click.away="showModal = false"></div>`
-
-When the `.away` modifier is present, the event handler will only be executed when the event originates from a source other than itself, or its children.
-
-This is useful for hiding dropdowns and modals when a user clicks away from them.
-
-**`.prevent` modifier**
-**Example:** `<input type="checkbox" x-on:click.prevent>`
-
-Adding `.prevent` to an event listener will call `preventDefault` on the triggered event. In the above example, this means the checkbox wouldn't actually get checked when a user clicks on it.
-
-**`.stop` modifier**
-**Example:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Adding `.stop` to an event listener will call `stopPropagation` on the triggered event. In the above example, this means the "click" event won't bubble from the button to the outer `<div>`. Or in other words, when a user clicks the button, `foo` won't be set to `'bar'`.
-
-**`.self` modifier**
-**Example:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Adding `.self` to an event listener will only trigger the handler if the `$event.target` is the element itself. In the above example, this means the "click" event that bubbles from the button to the outer `<div>` will **not** run the handler.
-
-**`.window` modifier**
-**Example:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Adding `.window` to an event listener will install the listener on the global window object instead of the DOM node on which it is declared. This is useful for when you want to modify component state when something changes with the window, like the resize event. In this example, when the window grows larger than 768 pixels wide, we will close the modal/dropdown, otherwise maintain the same state.
-
->Note: You can also use the `.document` modifier to attach listeners to `document` instead of `window`
-
-**`.once` modifier**
-**Example:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Adding the `.once` modifier to an event listener will ensure that the listener will only be handled once. This is useful for things you only want to do once, like fetching HTML partials and such.
-
-**`.passive` modifier**
-**Example:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Adding the `.passive` modifier to an event listener will make the listener a passive one, which means `preventDefault()` will not work on any events being processed, this can help, for example with scroll performance on touch devices.
-
-**`.debounce` modifier**
-**Example:** `<input x-on:input.debounce="fetchSomething()">`
-
-The `debounce` modifier allows you to "debounce" an event handler. In other words, the event handler will NOT run until a certain amount of time has elapsed since the last event that fired. When the handler is ready to be called, the last handler call will execute.
-
-The default debounce "wait" time is 250 milliseconds.
-
-If you wish to customize this, you can specify a custom wait time like so:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` modifier**
-**Example:** `<input x-on:event-name.camel="doSomething()">`
-
-The `camel` modifier will attach an event listener for the camel case equivalent event name. In the example above, the expression will be evaluated when the `eventName` event is fired on the element.
-
----
-
-### `x-model`
-**Example:** `<input type="text" x-model="foo">`
-
-**Structure:** `<input type="text" x-model="[data item]">`
-
-`x-model` adds "two-way data binding" to an element. In other words, the value of the input element will be kept in sync with the value of the data item of the component.
-
-> Note: `x-model` is smart enough to detect changes on text inputs, checkboxes, radio buttons, textareas, selects, and multiple selects. It should behave [how Vue would](https://vuejs.org/v2/guide/forms.html) in those scenarios.
-
-**`.number` modifier**
-**Example:** `<input x-model.number="age">`
-
-The `number` modifier will convert the input's value to a number. If the value cannot be parsed as a valid number, the original value is returned.
-
-**`.debounce` modifier**
-**Example:** `<input x-model.debounce="search">`
-
-The `debounce` modifier allows you to add a "debounce" to a value update. In other words, the event handler will NOT run until a certain amount of time has elapsed since the last event that fired. When the handler is ready to be called, the last handler call will execute.
-
-The default debounce "wait" time is 250 milliseconds.
-
-If you wish to customize this, you can specify a custom wait time like so:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Example:** `<span x-text="foo"></span>`
-
-**Structure:** `<span x-text="[expression]"`
-
-`x-text` works similarly to `x-bind`, except instead of updating the value of an attribute, it will update the `innerText` of an element.
-
----
-
-### `x-html`
-**Example:** `<span x-html="foo"></span>`
-
-**Structure:** `<span x-html="[expression]"`
-
-`x-html` works similarly to `x-bind`, except instead of updating the value of an attribute, it will update the `innerHTML` of an element.
-
-> :warning: **Only use on trusted content and never on user-provided content.** :warning:
->
-> Dynamically rendering HTML from third parties can easily lead to [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) vulnerabilities.
-
----
-
-### `x-ref`
-**Example:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Structure:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` provides a convenient way to retrieve raw DOM elements out of your component. By setting an `x-ref` attribute on an element, you are making it available to all event handlers inside an object called `$refs`.
-
-This is a helpful alternative to setting ids and using `document.querySelector` all over the place.
-
-> Note: you can also bind dynamic values for x-ref: `<span :x-ref="item.id"></span>` if you need to.
-
----
-
-### `x-if`
-**Example:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Structure:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-For cases where `x-show` isn't sufficient (`x-show` sets an element to `display: none` if it's false), `x-if` can be used to  actually remove an element completely from the DOM.
-
-It's important that `x-if` is used on a `<template></template>` tag because Alpine doesn't use a virtual DOM. This implementation allows Alpine to stay rugged and use the real DOM to work its magic.
-
-> Note: `x-if` must have a single root element inside the `<template></template>` tag.
-
-> Note: When using `template` in a `svg` tag, you need to add a [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) that should be run before Alpine.js is initialized.
-
----
-
-### `x-for`
-**Example:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Note: the `:key` binding is optional, but HIGHLY recommended.
-
-`x-for` is available for cases when you want to create new DOM nodes for each item in an array. This should appear similar to `v-for` in Vue, with one exception of needing to exist on a `template` tag, and not a regular DOM element.
-
-If you want to access the current index of the iteration, use the following syntax:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- You can also reference "index" inside the iteration if you need. -->
-    <div x-text="index"></div>
-</template>
-```
-
-If you want to access the array object (collection) of the iteration, use the following syntax:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <div>
-        <!-- You can also reference "collection" inside the iteration if you need. -->
-        <!-- Current item. -->
-        <div x-text="item"></div>
-        <!-- Same as above. -->
-        <div x-text="collection[index]"></div>
-        <!-- Previous item. -->
-        <div x-text="collection[index - 1]"></div>
-    </div>
-</template>
-```
-
-> Note: `x-for` must have a single root element inside of the `<template></template>` tag.
-
-> Note: When using `template` in a `svg` tag, you need to add a [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) that should be run before Alpine.js is initialized.
-
-#### Nesting `x-for`s
-You can nest `x-for` loops, but you MUST wrap each loop in an element. For example:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Iterating over a range
-
-Alpine supports the `i in n` syntax, where `n` is an integer, allowing you to iterate over a fixed range of elements.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Example:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> The example above uses classes from [Tailwind CSS](https://tailwindcss.com).
-
-Alpine offers 6 different transition directives for applying classes to various stages of an element's transition between "hidden" and "shown" states. These directives work both with `x-show` AND `x-if`.
-
-These behave exactly like VueJS's transition directives, except they have different, more sensible names:
-
-| Directive | Description |
-| --- | --- |
-| `:enter` | Applied during the entire entering phase. |
-| `:enter-start` | Added before element is inserted, removed one frame after element is inserted. |
-| `:enter-end` | Added one frame after element is inserted (at the same time `enter-start` is removed), removed when transition/animation finishes.
-| `:leave` | Applied during the entire leaving phase. |
-| `:leave-start` | Added immediately when a leaving transition is triggered, removed after one frame. |
-| `:leave-end` | Added one frame after a leaving transition is triggered (at the same time `leave-start` is removed), removed when the transition/animation finishes.
-
----
-
-### `x-spread`
-**Example:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` allows you to extract an element's Alpine bindings into a reusable object.
-
-The object keys are the directives (Can be any directive including modifiers), and the values are callbacks to be evaluated by Alpine.
-
-> Note: There are a couple of caveats to x-spread:
-> - When the directive being "spread" is `x-for`, you should return a normal expression string from the callback. For example: `['x-for']() { return 'item in items' }`.
-> - `x-data` and `x-init` can't be used inside a "spread" object.
-
----
-
-### `x-cloak`
-**Example:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. It's typical to add the following global style for this to work:
-
-```html
-<style>
-    [x-cloak] {
-        display: none !important;
-    }
-</style>
-```
-
-### Magic Properties
-
-> With the exception of `$el`, magic properties are **not available within `x-data`** as the component isn't initialized yet.
-
----
-
-### `$el`
-**Example:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
-</div>
-```
-
-`$el` is a magic property that can be used to retrieve the root component DOM node.
-
-### `$refs`
-**Example:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` is a magic property that can be used to retrieve DOM elements marked with `x-ref` inside the component. This is useful when you need to manually manipulate DOM elements.
-
----
-
-### `$event`
-**Example:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` is a magic property that can be used within an event listener to retrieve the native browser "Event" object.
-
-> Note: The $event property is only available in DOM expressions.
-
-If you need to access $event inside of a JavaScript function you can pass it in directly:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Example:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- When clicked, will console.log "bar" -->
-</div>
-```
-
-**Note on Event Propagation**
-
-Notice that, because of [event bubbling](https://en.wikipedia.org/wiki/Event_bubbling), when you need to capture events dispatched from nodes that are under the same nesting hierarchy, you'll need to use the [`.window`](https://github.com/alpinejs/alpine#x-on) modifier:
-
-**Example:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> This won't work because when `custom-event` is dispatched, it'll propagate to its common ancestor, the `div`.
-
-**Dispatching to Components**
-
-You can also take advantage of the previous technique to make your components talk to each other:
-
-**Example:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- When clicked, will console.log "Hello World!". -->
-```
-
-`$dispatch` is a shortcut for creating a `CustomEvent` and dispatching it using `.dispatchEvent()` internally. There are lots of good use cases for passing data around and between components using custom events. [Read here](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) for more information on the underlying `CustomEvent` system in browsers.
-
-You will notice that any data passed as the second parameter to `$dispatch('some-event', { some: 'data' })`, becomes available through the new events "detail" property: `$event.detail.some`. Attaching custom event data to the `.detail` property is standard practice for `CustomEvent`s in browsers. [Read here](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) for more info.
-
-You can also use `$dispatch()` to trigger data updates for `x-model` bindings. For example:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- After the button is clicked, `x-model` will catch the bubbling "input" event, and update foo to "baz". -->
-    </span>
-</div>
-```
-
-> Note: The $dispatch property is only available in DOM expressions.
-
-If you need to access $dispatch inside of a JavaScript function you can pass it in directly:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Example:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` is a magic property that allows you to only execute a given expression AFTER Alpine has made its reactive DOM updates. This is useful for times you want to interact with the DOM state AFTER it's reflected any data updates you've made.
-
----
-
-### `$watch`
-**Example:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-You can "watch" a component property with the `$watch` magic method. In the above example, when the button is clicked and `open` is changed, the provided callback will fire and `console.log` the new value.
-
-## Security
-If you find a security vulnerability, please send an email to [calebporzio@gmail.com]().
-
-Alpine relies on a custom implementation using the `Function` object to evaluate its directives. Despite being more secure then `eval()`, its use is prohibited in some environments, such as Google Chrome App, using restrictive Content Security Policy (CSP).
-
-If you use Alpine in a website dealing with sensitive data and requiring [CSP](https://csp.withgoogle.com/docs/strict-csp.html), you need to include `unsafe-eval` in your policy. A robust policy correctly configured will help protecting your users when using personal or financial data.
-
-Since a policy applies to all scripts in your page, it's important that other external libraries included in the website are carefully reviewed to ensure that they are trustworthy and they won't introduce any Cross Site Scripting vulnerability either using the `eval()` function or manipulating the DOM to inject malicious code in your page.
-
-## V3 Roadmap
-* Move from `x-ref` to `ref` for Vue parity?
-* Add `Alpine.directive()`
-* Add `Alpine.component('foo', {...})` (With magic `__init()` method)
-* Dispatch Alpine events for "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Remove "object" (and array) syntax from `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) to add support for object syntax for the `style` attribute)
-* Improve `x-for` mutation reactivity ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Add "deep watching" support in V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Add `$el` shortcut
-* Change `@click.away` to `@click.outside`?
-
-## License
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.
+If you wish to only run Jest tests, you can run `npm run jest` like normal and target specific tests. You can specify command line config options to forward to the jest command with `--` like so: `npm run jest -- --watch`

+ 0 - 796
README.no.md

@@ -1,796 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js gir deg den reaktive og deklarative kvaliteten til store rammeverk som Vue og React, men til en mye lavere kostnad.
-
-Du beholder din DOM og kan drysse over adferd slik du selv finner passende.
-
-Tenk på det som [Tailwind](https://tailwindcss.com/) for JavaScript.
-
-> Merk: Dette verktøyets syntaks er omtrent i sin helhet lånt fra [Vue](https://vuejs.org/) (og i forlengelsen [Angular](https://angularjs.org/)). Jeg er for evig og alltid takknemlig for den gaven disse er til webben.
-
-## Oversatt dokumentasjon
-
-| Språk | Lenke til dokumentasjon |
-| --- | --- |
-| Arabisk | [**التوثيق باللغة العربية**](./README.ar.md) |
-| Kinesisk, forenklet | [**简体中文文档**](./README.zh-CN.md) |
-| Kinesisk, tradisjonell | [**繁體中文說明文件**](./README.zh-TW.md) |
-| Tysk | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesisk | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japansk | [**日本語ドキュメント**](./README.ja.md) |
-| Portugisisk | [**Documentação em Português**](./README.pt.md) |
-| Russisk | [**Документация на русском**](./README.ru.md) |
-| Spansk | [**Documentación en Español**](./README.es.md) |
-| Tyrkisk | [**Türkçe Dokümantasyon**](./README.tr.md) |
-| Fransk | [**Documentation en Français**](./README.fr.md) |
-| Koreansk | [**한국어 문서**](./README.ko.md) |
-
-## Installasjon
-
-**Fra CDN:** Legg til følgende skript på slutten av ditt `<head>`-område.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-Det er alt du trenger å gjøre. Resten initialiserer seg automatisk.
-
-For produksjonsmiljø anbefales det å benytte et spesifikt versjonsnummer i lenken for å unngå uventede feil som følge av nyere versjoner.
-For eksempel, for å bruke versjon `2.8.2` (nyeste):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Fra npm:** Installer pakken fra npm.
-```js
-npm i alpinejs
-```
-Inkluder den i skriptet ditt.
-```js
-import 'alpinejs'
-```
-
-**For kompabilitet med IE11** Bruk de følgende skriptene i stedet.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-Mønsteret vist her over er det såkalte [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/), som vil resultere at den moderne bunten lastes i moderne nettlesere, og at bunten til IE11 lastes automatisk i IE11 og andre eldre nettlesere.
-
-## Bruk
-
-*Rullegardinmeny/Modal*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Åpne rullegardinmeny</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Innhold i rullegardinmenyen
-    </ul>
-</div>
-```
-
-*Faner*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Fane Foo</div>
-    <div x-show="tab === 'bar'">Fane Bar</div>
-</div>
-```
-
-Du kan til og med benytte dette for ikke-trivielle ting:
-*Forhåndshenting av HTML for en rullegardinmeny ved sveving.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Vis rullegardinmeny</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Lastespinner...
-    </div>
-</div>
-```
-
-## Lære
-
-Det finnes 14 direktiver du kan benytte:
-
-| Direktiv | Beskrivelse |
-| --- | --- |
-| [`x-data`](#x-data) | Deklarerer et nytt komponentvirkefelt. |
-| [`x-init`](#x-init) | Utfører et uttrykk når komponenten er initialisert. |
-| [`x-show`](#x-show) | Slår av eller på `display: none;` på elementet avhengig av uttrykket (sant eller usant). |
-| [`x-bind`](#x-bind) | Setter verdien av en egenskap til resultatet av et JS-uttrykk. |
-| [`x-on`](#x-on) | Kobler en hendelseslytter på elementet. Utfører et JS-uttrykk når den avgis. |
-| [`x-model`](#x-model) | Legger til "toveis databinding" til et element. Holder inndataelementet synkronisert med komponentdataene. |
-| [`x-text`](#x-text) | Fungerer tilsvarende som `x-bind`, men oppdaterer elementets `innerText`. |
-| [`x-html`](#x-html) | Fungerer tilsvarende som `x-bind`, men oppdaterer elementets `innerHTML`. |
-| [`x-ref`](#x-ref) | En praktisk måte å hente ut rå DOM-elementer fra komponenten din . |
-| [`x-if`](#x-if) | Fjerner et element fullstendig fra DOM. Må brukes på en `<template>`-tagg. |
-| [`x-for`](#x-for) | Lager nye DOM-noder for hvert element i en matrise. Må brukes på en `<template>`-tagg. |
-| [`x-transition`](#x-transition) | Direktiver for å legge til klasser på forskjellige stadier i et elements overgang. |
-| [`x-spread`](#x-spread) | Lar deg binde et objekt med Alpine-direktiver til et element for bedre gjenbrukbarhet. |
-| [`x-cloak`](#x-cloak) | Denne egenskapen fjernes i det Alpine initialiseres. Nyttig for å skjule forhåndsinitialisert DOM. |
-
-Og 6 magiske egenskaper:
-
-| Magisk egenskap | Beskrivelse |
-| --- | --- |
-| [`$el`](#el) |  Henter rot-komponentens DOM-node. |
-| [`$refs`](#refs) | Henter DOM-elementer som er markert med `x-ref` inne i komponenten. |
-| [`$event`](#event) | Henter det lokale nettleserobjektet "Event" inne i en hendelseslytter.  |
-| [`$dispatch`](#dispatch) | Lager en `CustomEvent` og sender den internt ved hjelp av `.dispatchEvent()`. |
-| [`$nextTick`](#nexttick) | Utfører et gitt utrykk ETTER AT Alpine har utført sine reaktive oppdateringer i DOM. |
-| [`$watch`](#watch) | Gjennomfører det oppgitte tilbakekallet i det øyeblikket en komponentegenskap du har observert ("watched"), har blitt endret. |
-
-
-## Sponsorer
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Vil du se din logo her? [DM på Twitter](https://twitter.com/calebporzio)**
-
-## Fellesskapsprosjekter
-
-* [Alpine Devtools](https://github.com/HugoDF/alpinejs-devtools)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Alpine Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-
-### Direktiver
-
----
-
-### `x-data`
-
-**Eksempel:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Struktur:** `<div x-data="[object literal]">...</div>`
-
-`x-data` deklarerer et nytt komponentvirkefelt. Den forteller rammeverket at det skal initialisere en ny komponent med det følgende dataobjektet.
-
-Tenk på det som `data` egenskapen i en Vue-komponent.
-
-**Trekke ut logikk fra komponenten**
-
-Du trekke ut data (og adferd) til gjenbrukbare funksjoner:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Rullegardinmeny
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **For buntbrukere**, noter deg at Alpine.js benytter funksjoner som er i det globale virkefeltet (`window`). Du må derfor eksplisitt tildele dine funksjoner til `window` for å kunne bruke dem med `x-data`. For eksempel `window.dropdown = function () {}` (dette er fordi du med Webpack, Rollup, Parcel etc. sine `function` som du definerer som standard vil benytte komponentens virkeområde og ikke `window`).
-
-Du kan også mikse inn flere dataobjekter ved å benytte objektdestrukturering:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Eksempel:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Struktur:** `<div x-data="..." x-init="[uttrykk]"></div>`
-
-`x-init` utfører et uttrykk når en komponent er initialisert.
-
-Dersom du ønsker å kjøre kode ETTER AT Alpine har utført sine initielle oppdateringer til DOM (slik som en `mounted()`-krok i VueJS), kan du returnere et tilbakekall fra `x-init`, og det vil bli utført etter:
-
-`x-init="() => { // her har vi tilgang tilstanden etter initialisering av DOM // }"`
-
----
-
-### `x-show`
-**Eksempel:** `<div x-show="open"></div>`
-
-**Struktur:** `<div x-show="[uttrykk]"></div>`
-
-`x-show` slår av eller på `display: none;`-stilen på elementet avhengig av om uttrykket løses som `true` eller `false`.
-
-**x-show.transition**
-
-`x-show.transition` er et bekvemmelighets-API for å gjøre dine `x-show` mer behagelig ved å bruke CSS-overganger.
-
-```html
-<div x-show.transition="open">
-    Dette innholdet vil få en overgang inn og ut.
-</div>
-```
-
-| Direktiv | Beskrivelse |
-| --- | --- |
-| `x-show.transition` | En samtidig fadings- og skaleringseffekt. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Kun overgang inn. |
-| `x-show.transition.out` | Kun overgang ut. |
-| `x-show.transition.opacity` | Kun fading. |
-| `x-show.transition.scale` | Kun skalering. |
-| `x-show.transition.scale.75` | Tilpass CSS-skaleringen for overgangen `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Setter "in"-overgangen til 200ms. Ut vil bli satt til halvparten av det (100ms). |
-| `x-show.transition.origin.top.right` | Tilpass utgangspunktet for CSS-overgangen `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Forskjellig varighet for "in" og "out". |
-
-> Merk: Alle disse overgangene kan brukes i sammenheng med hverandre. Dette er mulig (selv om det er tullete lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Merk: `x-show` venter på at eventuelle barn fullfører sine overganger ut. Hvis du ønsker overstyre denne adferden, legg til modifikatoren `.immediate`:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Merk: Du står fritt til å bruke den kortere syntaksen ":" `:type="..."`.
-
-**Eksempel:** `<input x-bind:type="inputType">`
-
-**Struktur:** `<input x-bind:[attribute]="[uttrykk]">`
-
-`x-bind` setter verdien for en egenskap til resultatet av et JavaScript-uttrykk. Uttrykket har tilgang til alle nøklene i komponentens dataobjekt, og vil oppdateres hver gang dens data blir oppdatert.
-
-> Merk: egenskapsbindinger oppdateres KUN når deres avhengigheter oppdateres. Rammeverket er smart nok til å observere dataendringer og oppdage hvilke bindinger som er interessert i dem.
-
-**`x-bind` for klasseegenskaper**
-
-`x-bind` oppfører seg litt anderledes når det bindes til `class` egenskapen.
-
-For klasser må du sende inn et objekt hvor nøklene er klassenavn og hvor verdiene er boolske uttrykk for å avgjøre om disse klassenavnene skal anvendes eller ikke.
-
-For eksempel:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-I dette eksempelet vil klassen "hidden" kun anvendes dersom verdien av dataegenskapen `foo` er `true`.
-
-**`x-bind` for boolske egenskaper**
-
-`x-bind` støtter boolske egenskaper på samme måte som verdiegenskaper ved å bruke en variabel som betingelse eller et annet JavaScript-uttrykk som løses til enten `true` eller `false`.
-
-For eksempel:
-```html
-<!-- Gitt at: -->
-<button x-bind:disabled="myVar">Klikk meg</button>
-
-<!-- Når myVar == true (sann):  -->
-<button disabled="disabled">Klikk meg</button>
-
-<!-- Når myVar == false (usann): -->
-<button>Klikk meg</button>
-```
-
-Dette legger til eller fjerner egenskapen `disabled` når `myVar` henholdsvis er sann eller usann.
-
-Boolske egenskaper støttes slik de fremkommer i [HTML-spesifikasjonen](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), for eksempel `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
-
-> Merk: Hvis du trenger at en usann tilstand vises for egenskapen din, slik som `aria-*`, kjed `.toString()` til verdien når du binder til egenskapen. For eksempel: `:aria-expanded="isOpen.toString()"` vil vedvare uansett om `isOpen` er `true` eller `false`.
-
-**`.camel` modifikator**
-
-**Eksempel:** `<svg x-bind:view-box.camel="viewBox">`
-
-Modifikatoren `camel` binder til et egenskapsnavn med tilsvarende pukkelOrd. I eksempelet over vil verdien av `viewBox` bli bundet til egenskapen `viewBox` i stedet for egenskapen `view-box`.
-
----
-
-### `x-on`
-
-> Merk: Du står fritt til bruke den kortere syntaksen "@" : `@click="..."`.
-
-**Eksempel:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Struktur:** `<button x-on:[event]="[uttrykk]"></button>`
-
-`x-on` kobler en hendelseslytter til elementet det deklareres på. I det hendelsen avgis vil JavaScript-uttrykket som er satt som dens verdi bli utført. Du kan bruke `x-on` med hvilken som helst hendelse som er tilgjengelig for det elementet du deklarerer direktivet på. For en fullstendig oversikt over hendelser, se [the Event reference on MDN](https://developer.mozilla.org/en-US/docs/Web/Events).
-
-Hvis noen data er modifisert i uttrykket, så vil andre elementegenskaper som er "bundet" til disse dataene bli oppdatert.
-
-> Merk: Du kan også spesifisere navnet på en JavaScript-funksjon.
-**Eksempel:** `<button x-on:click="myFunction"></button>`
-
-Dette er tilsvarende til: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` modifikatorer**
-**Eksempel:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Du kan spesifisere spesifikke taster å lytte etter ved å bruke `keydown`modifikatorer lagt til på direktivet `x-on:keydown`. Merk at modifikatorene er kebabnotasjonen av `Event.key`-verdier.
-
-Eksempler: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Merk: Du kan også lytte etter systemmodfiserende tastekombinasjoner som: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` modifikator**
-**Eksempel:** `<div x-on:click.away="showModal = false"></div>`
-
-Når modifikatoren `.away` er tilstede, så vil hendelsesbehandlere kun utføres når hendelsen kommer fra en annen kilde enn seg selv, eller dens barn.
-
-Dette er nyttig for å skjule rullegardinmenyer eller modaler i det en bruker klikker seg bort fra dem.
-
-**`.prevent` modifikator**
-**Eksempel:** `<input type="checkbox" x-on:click.prevent>`
-
-Legger du til `.prevent` til en hendelseslytter, så vil `preventDefault` bli kalt på den utløste hendelsen. I eksempelet over vil dette bety at avkrysningsruten faktisk ikke blir avkrysset når brukeren klikker på den.
-
-**`.stop` modifikator**
-**Eksempel:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Legger du til `.stop` til en hendelseslytter, så vil `stopPropagation`bli kalt på den utløste hendelsen. I eksempelet over vil dette bety at hendelsen "click" ikke vil boble fra knappen til det ytre `<div>`. Med andre ord, når en bruker klikker på knappen så vil ikke `foo` bli satt til `'bar'`.
-
-**`.self` modifikator**
-**Eksempel:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Legger du til `.self`  til en hendelseslytter, så vil hendelsesbehandleren kun bli trigget hvis `$event.target` er det samme elementet. I eksempelet over vil dette bety at hendelsen "click", som bobler fra knappen til det ytre `<div>`  **ikke** utfører hendelsesbehandleren.
-
-**`.window` modifikator**
-**Eksempel:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Legger du til `.window` til en hendelseslytter, så vil lytteren festes på det globale vindusobjektet i stedet for på den DOM-noden som den ble deklarert på. Dette er nyttig i tilfeller hvor du ønsker å modifisere komponentens tilstand når noe endres i vinduet, eksempelvis hendelsen for endring av vinduets størrelse. I dette eksempelet betyr det at hvis viduet økes til en bredde større enn 768 piksler, så stenger vi modalen/rullegardinmenyen, eller i motsatt fall opprettholder vi samme tilstand.
-
->Merk: Du kan også bruke modifikatoren `.document` for å legge til lyttere til `document` i stedet for `window`
-
-**`.once` modifikator**
-**Eksempel:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Legger du til modifikatoren `.once` til en hendelseslytter, så sikrer det at lytteren kun blir behandlet én gang. Dette er nytt for ting du ønsker gjort én gang, som å hente HTML-partieller og lignende.
-
-**`.passive` modifikator**
-**Eksempel:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Legger du til modifikatoren `.passive`til en hendelseslytter, blir den passiv, hvilket betyr at `preventDefault()` ikke vil fungere for hendelser som blir behandlet. Dette kan for eksempel bidra til bedre ytelse ved rulling på berøringsenheter.
-
-**`.debounce` modifikator**
-**Eksempel:** `<input x-on:input.debounce="fetchSomething()">`
-
-Modifikatoren `debounce` lar deg midlertidig "avvise" en hendelseslytter. Med andre ord, hendelseslytteren vil IKKE behandles inntil en bestemt mengde tid har forløpt siden hendelsen sist ble fyrt av. Når behandleren er klar til å bli kallet, så vil den siste behandleren blir utført.
-
-Standard "ventetid" er 250 millisekunder.
-
-Hvis du ønsker å tilpasse dette, så kan du spesifisere en tilpasset ventetid på denne måten:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` modifikator**
-**Eksempel:** `<input x-on:event-name.camel="doSomething()">`
-
-Modifikatoren `camel` fester en hendelseslytter med et camelCase-navn som samsvarer med navnet på hendelsen. I eksempelet over, så vil uttrykket over bli evaluert når hendelsen ´eventName´ fyres av på elementet.
-
----
-
-### `x-model`
-**Eksempel:** `<input type="text" x-model="foo">`
-
-**Struktur:** `<input type="text" x-model="[data item]">`
-
-`x-model` legger til "toveis databinding" til et element. Med andre ord, verdien til et inndataelement vil bli holdt synkronisert ved verdien til dataelementet i komponenten.
-
-> Merk: `x-model` er smart nok til å oppdage endringer i tekstinndataelement, avkrysningsbokser, radioknapper, tekstområde, selects, and multiple selects. I slike scenario oppfører den seg [slik Vue ville gjort](https://vuejs.org/v2/guide/forms.html).
-
-**`.number` modifikator**
-**Eksempel:** `<input x-model.number="age">`
-
-Modifikatoren `number` konverterer en inndataverdi til et nummer. Hvis verdien ikke kan parses som et gyldig nummer, returneres den originale verdien.
-
-**`.debounce` modifikator**
-**Eksempel:** `<input x-model.debounce="search">`
-
-Modifikatoren `debounce` lar deg legge til en "avviser" til oppdateringen av en verdi. Med andre ord, hendelsesbehandleren vil IKKE behandles inntil en bestemt mengde tid siden hendelsen sist ble fyrt av. Når behandleren er klar til å bli kallet, så vil den siste behandleren bli utført.
-
-Standard "ventetid" er 250 millisekunder.
-
-Hvis du ønsker å tilpasse dette, så kan du spesifisere en tilpasset ventetid på denne måten:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Eksempel:** `<span x-text="foo"></span>`
-
-**Struktur:** `<span x-text="[uttrykk]"`
-
-`x-text` fungerer tilsvarende som  `x-bind`, men i stedet for å oppdatere verdien til en egenskap, så oppdaterer den elementets `innerText`.
-
----
-
-### `x-html`
-**Eksempel:** `<span x-html="foo"></span>`
-
-**Struktur:** `<span x-html="[uttrykk]"`
-
-`x-html` fungerer tilsvarende som `x-bind`, men i stedet for å oppdatere verdien til en egenskap, så oppdaterer den elementets `innerHTML`.
-
-> :warning: **Bruk kun innhold du kan stole på, og aldri innhold som kommer fra brukere.** :warning:
->
-> HTML som blir gjengitt dynamisk fra tredjepart kan lett føre til [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)-sårbarheter.
-
----
-
-### `x-ref`
-**Eksempel:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Struktur:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-Med `x-ref` får du en praktisk måte å hente ut rå DOM-elementer fra dine komponenter. Setter du en `x-ref`-egenskap på et element, så gjør du det tilgjengelig for alle hendelsesbehandlere inne i et objekt kalt `$refs`.
-
-Dette er et nyttig alternativ til å sette id-er og så bruke `document.querySelector` over alt.
-
-> Merk: du kan også binde dynamiske verdier til x-ref: `<span :x-ref="item.id"></span>`.
-
----
-
-### `x-if`
-**Eksempel:** `<template x-if="true"><div>Et element</div></template>`
-
-**Struktur:** `<template x-if="[expression]"><div>Et element</div></template>`
-
-For de tilfeller hvor `x-show` ikke er tilstrekkelig (`x-show` setter et element til `display: none` dersom den er usann), så kan `x-if` brukes til å fullstendig fjerne et element fra DOM.
-
-Det er viktig at `x-if` brukes på en `<template></template>`-tagg, fordi Alpine ikke bruker en virtuell DOM. Denne implementasjonen holder Alpine robust og gjør at den kan bruke den ekte DOM for sin magi.
-
-> Merk: `x-if` må ha ett enkelt rotelement inne i `<template></template>`-taggen.
-
-> Merk: Ved bruk av `template` i en `svg`-tagg, må du legge til en [polyfyll](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538), som må kjøres før Alpine.js er initialisert.
-
----
-
-### `x-for`
-**Eksempel:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Merk: bindingen `:key` er valgfri, men HØYST anbefalt.
-
-`x-for` er tilgjengelig for tilfeller der du vil opprette nye DOM-noder for hvert element i en matrise. Dette skal se ut som `v-for` i Vue, med det unntak at den må eksistere på en `template`-tagg, og ikke et vanlig DOM-element.
-
-Hvis du vil ha tilgang til gjeldende indeks for iterasjonen, bruker du følgende syntaks:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- Du kan også referere til "index" inne i iterasjonen om du behøver det. -->
-    <div x-text="index"></div>
-</template>
-```
-
-Hvis du vil ha tilgang til arrayobjektet ("collection") av iterasjonen, bruker du følgende syntaks:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <div>
-        <!-- Du kan også referere til "collection" inne i iterasjonen om du behøver det. -->
-        <!-- Current item. -->
-        <div x-text="item"></div>
-        <!-- Samme som over. -->
-        <div x-text="collection[index]"></div>
-        <!-- Forrige enhet. -->
-        <div x-text="collection[index - 1]"></div>
-    </div>
-</template>
-```
-
-> Merk: `x-for` må ha ett enkelt rotelement inne i `<template></template>`-taggen.
-
-> Merk: Ved bruk av `template` i en `svg`-tagg, må du legge til en [polyfyll](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538), som må kjøres før Alpine.js er initialisert.
-
-#### Nøsting av `x-for`
-Du kan nøste `x-for`-løkker, med du MÅ pakke inn hver løkke i et element. For eksempel:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Iterere over et område
-
-Alpine støtter syntaksen `i in n`, hvor `n` er et heltall, slik at du kan iterere over et fastsatt område med elementer.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Eksempel:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> Eksempelet over bruker klasser fra [Tailwind CSS](https://tailwindcss.com).
-
-Alpine tilbyr 6 forskjellige overgangsdirektiver for å anvende klasser på forskjellige stadier av et elementets overgang mellom "skjulte" og "viste" stater. Disse direktivene fungerer både med `x-show` og `x-if`.
-
-Disse oppfører seg akkurat slik som VueJS' overgangsdirektiver, bortsett fra at de har forskjellige, mer fornuftige navn:
-
-| Direktiv | Beskrivelse |
-| --- | --- |
-| `:enter` | Brukes i løpet av hele inngangsfasen. |
-| `:enter-start` | Legges til før elementet settes inn, fjernes én ramme etter at elementet er satt inn. |
-| `:enter-end` | Legges til én ramme etter at elementet er satt inn (samtidig fjernes `enter-start`). Fjernes når overgangen / animasjonen er ferdig.
-| `:leave` | Brukes i løpet av hele utgangsfasen. |
-| `:leave-start` | Legges til umiddelbart når en utgående overgang utløses, fjernes etter én ramme. |
-| `:leave-end` | Legges til én ramme etter at en utgangsovergang er utløst (samtidig fjernes `leave-start`). Fjernes når overgangen / animasjonen er ferdig.
-
-
----
-
-### `x-spread`
-**Eksempel:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Åpne rullegardinmeny</button>
-
-    <span x-spread="dialogue">Innhold i rullegardinmenyen</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` lar deg trekke ut elementets Alpine-bindinger til et gjenbrukbart objekt.
-
-Objektnøklene er direktivene (kan være et hvilket som helst direktiv inkludert modifikatorer), og verdiene er tilbakekallinger som skal evalueres av Alpine.
-
-> Merk: Det er et par forbehold å legge merke til ved bruk av x-spread:
-> - Dersom direktivet som blir "spredt" er `x-for`, bør du returnere en vanlig uttrykksstreng fra tilbakekallet. For eksempel: `['x-for']() { return 'item in items' }`.
-> - `x-data` og `x-init` kan ikke benyttes inne i et "spread"-object.
-
----
-
-### `x-cloak`
-**Eksempel:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak`-egenskaper fjernes fra elementene når Alpine initialiseres. Dette er nyttig for å skjule forhåndsinitialisert DOM. For at dette skal fungere legger man typisk til følgende globale stil:
-
-```html
-<style>
-    [x-cloak] {
-        display: none !important;
-    }
-</style>
-```
-
-### Magiske egenskaper
-
-> Med unntak av `$el`, så er magiske egenskaper **ikke tilgjengelig inne i `x-data`** da komponenten der ennå ikke er initialisert.
-
----
-
-### `$el`
-**Eksempel:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Erstatt meg med "foo"</button>
-</div>
-```
-
-`$el` er en magisk egenskap som kan benyttes til å hente ut rotkomponentens DOM-node.
-
-### `$refs`
-**Eksempel:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` er en magisk egenskap som kan benyttes til å hente ut DOM-elementer markert med `x-ref` inne i komponenten. Dette er nyttig når du har behov for å endre DOM-elementer manuelt.
-
----
-
-### `$event`
-**Eksempel:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event`  er en magisk egenskap som kan benyttes inne i en hendelseslytter for å hente ut nettleserens lokale "Event"-objekt.
-
-> Merk: Egenskapen $event er kun tilgjengelig i DOM-uttrykk.
-
-Hvis du trenger tilgang til $event inne i en JavaScript-funksjon, så kan du sende den inn direkte:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Eksempel:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Når knappen klikkes, så skrives "bar" til console.log -->
-</div>
-```
-
-**Merknad om hendelsesforplantning**
-
-Vær oppmerksom på at som følge av [hendelsesbobling](https://en.wikipedia.org/wiki/Event_bubbling) må du bruke modifikatoren [`.window`](https://github.com/alpinejs/alpine#x-on) når du skal fange hendelser under samme nøstede hierarki:
-
-**Eksempel:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Dette vil ikke fungere fordi når `custom-event` sendes, så vil den forplante seg til dens felles forfar, som her er `div`.
-
-**Avsending til komponenter**
-
-Du kan også dra nytte av den forrige teknikken for å få komponentene til å snakke med hverandre:
-
-**Eksempel:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Når knappen klikkes, så skrives "Hello World!" til console.log. -->
-```
-
-`$dispatch` er en forkortelse for å lage en `CustomEvent` og sende den internt ved hjelp av `.dispatchEvent()`. Det er mange gode bruksområder for å formidle data rundt og mellom komponenter ved hjelp av tilpassede hendelser. [Les her](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) for mer informasjon om det underliggende `CustomEvent`-systemet i nettlesere.
-
-Du vil legge merke til at data som sendes som den andre parameteren til `$dispatch('some-event', { some: 'data' })`, blir tilgjengelig gjennom den nye hendelsen "detail"-egenskapen: `$event.detail.some`. Å legge til egendefinerte hendelsesdata til egenskapen `.detail` er standard praksis for `CustomEvent` i nettlesere. [Les her](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) for mer informasjon.
-
-Du kan også bruke `$dispatch()` for å trigge dataoppdateringer `x-model`-bindinger. For eksempel:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-            <!-- Etter at knappen her blir klikket, så vil `x-model` fange den boblende "input"-hendelsen og oppdatere foo til "baz". -->
-    </span>
-</div>
-```
-
-> Merk: Egenskapen $dispatch er kun tilgjengelig i DOM-uttrykk.
-
-Hvis du trenger tilgang til $dispatch inne i en JavaScript-funksjon, så kan du sende den inn direkte:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Eksempel:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` er en magisk egenskap som lar deg bare utføre et gitt uttrykk etter at Alpine har gjort sine reaktive DOM-oppdateringer. Dette er nyttig når du vil samhandle med DOM-tilstanden ETTER at den gjenspeiler dataoppdateringer du har gjort.
-
----
-
-### `$watch`
-**Eksempel:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-Du kan observere ("watch") en komponentegenskap med den magiske metoden `$watch`. I eksempelet over betyr det at når du klikker på knappen og `open` endres, så vil det oppgitte tilbakekallet bli avfyrt og den nye verdien skrives til `console.log`.
-
-## Sikkerhet
-Hvis du finner et sikkerhetsavvik, vennligst send en e-post til [calebporzio@gmail.com]().
-
-Alpine benytter seg av en tilpasset implementasjon i form av `Function`-objektet for å evaluere sine direktiver. Til tross for at den er mer sikker enn `eval()`, så er den ikke tillatt i alle miljøer, slik som Google Chrome App, når den bruker restriktiv Content Security Policy (CSP).
-
-Hvis du benytter Alpine på et nettsted hvor sensitive data håndeteres og hvor [CSP](https://csp.withgoogle.com/docs/strict-csp.html) er påkrevd, må du inkludere `unsafe-eval` i din policy. En robust policy, riktig konfigurert, vil bidra til å beskytte brukerne dine når du håndterer personlige eller økonomiske data.
-
-Siden en policy gjelder alle skript på siden din, er det viktig at andre eksterne biblioteker som er inkludert på nettstedet, blir nøye gjennomgått for å sikre at de er pålitelige og at de ikke vil innføre noen Cross Site Scripting-sårbarheter enten ved å bruke `eval()`-funksjonen eller ved å manipulere DOM for å injisere skadelig kode på siden din.
-
-## Veikart til V3
-* Endre fra `x-ref` til `ref` for Vue-paritet?
-* Legge til `Alpine.directive()`
-* Legge til `Alpine.component('foo', {...})` (Med magisk `__init()`-metode)
-* Sende Alpine-hendelser for "loaded", "transition-start", etc... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Fjerne "object" (og matrise) syntaks fra `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236) for å legge til støtte for objektsyntaks for `style`-egenskapen)
-* Forbedre `x-for` mutasjonsreaktivitet ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Legge til "deep watching" støtte i V3 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Legge til `$el` snarvei
-* Endre `@click.away` til `@click.outside`?
-
-## Lisens
-
-Opphavsrettslig beskyttet © 2019-2021 Caleb Porzio og bidragsytere.
-
-Lisensiert under MIT-lisensen, se [LICENSE.md](LICENSE.md) for detaljer.

+ 0 - 789
README.pt.md

@@ -1,789 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-O Alpine.js oferece a natureza reativa e declarativa de grandes estruturas, como Vue ou React, a um custo muito menor.
-
-Podemos manter a DOM e aperfeiçoar o comportamento como acharmos melhor.
-
-Pensem nisso como o [Tailwind](https://tailwindcss.com/) para JavaScript.
-
-> Nota: A sintaxe desta ferramenta é quase totalmente inspirada no [Vue](https://vuejs.org/) (e por extensão [Angular](https://angularjs.org/)). Estou eternamente agradecido pelo presente que estas são para a web.
-
-## Instalação
-
-**Via CDN:** Adicionem o seguinte script no final da seção `<head>`.
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-E é isso. Ele vai se inicializar.
-
-Para ambiente de produção, é recomendado fixar o número da versão específico no link para evitar problemas inesperadas das versões mais recentes.
-Por exemplo, para usar a versão `2.8.2`:
-
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Via npm:** Instale o pacote pelo npm.
-
-```js
-npm i alpinejs
-```
-
-Incluir no script.
-
-```js
-import 'alpinejs';
-```
-
-**Para suportar IE11** Usar os seguintes scripts.
-
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-O padrão acima é o [padrão de módulo/nomodule](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) que resulta num pacote moderno carregado automaticamente em browsers modernos e o pacote IE11 carregado automaticamente no IE11 e em outros browsers herdados.
-
-## Usar
-
-_Dropdown/Modal_
-
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul x-show="open" @click.away="open = false">
-        Corpo do Dropdown
-    </ul>
-</div>
-```
-
-_Tabs_
-
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">
-        Foo
-    </button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">
-        Bar
-    </button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-Podemos até usá-lo para coisas não triviais:
-_Pré pedido de conteudo para o HTML da dropdown ao passar com o rato_.
-
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >
-        Mostrar Dropdown
-    </button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Carregando Spinner...
-    </div>
-</div>
-```
-
-## Aprenda
-
-Existem 14 diretrizes disponíveis:
-
-| Directiva                       | Descrição                                                                                                                     |
-| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
-| [`x-data`](#x-data)             | Declara um novo scope do componente.                                                                                          |
-| [`x-init`](#x-init)             | Executa uma expressão quando um componente é inicializado.                                                                    |
-| [`x-show`](#x-show)             | Alterna `display: none;` no elemento dependendo da expressão (verdadeiro ou falso).                                           |
-| [`x-bind`](#x-bind)             | Define o valor de um atributo para o resultado de uma expressão JS.                                                            |
-| [`x-on`](#x-on)                 | Anexa um evento de escuta ao elemento. Executa a expressão JS quando emitida.                                                 |
-| [`x-model`](#x-model)           | Adiciona "ligação de dados bidirecional" a um elemento. Mantém o elemento de entrada sincronizado com os dados do componente. |
-| [`x-text`](#x-text)             | Funciona da mesma forma que o `x-bind`, mas atualiza o `innerText` de um elemento.                                             |
-| [`x-html`](#x-html)             | Funciona de maneira semelhante ao `x-bind`, mas atualiza o `innerHTML` de um elemento.                                         |
-| [`x-ref`](#x-ref)               | Maneira conveniente de recuperar elementos DOM fora do seu componente.                                                        |
-| [`x-if`](#x-if)                 | Remove um elemento completamente na DOM. Precisa de usar uma tag `<template>`.                                           |
-| [`x-for`](#x-for)               | Crie novos nós DOM para cada item em uma matriz. Precisa de usar uma tag `<template>`.                                   |
-| [`x-transition`](#x-transition) | Diretrizes para aplicar classes a vários estágios da transição de um elemento.                                                 |
-| [`x-spread`](#x-spread)         | Permite definir um objeto de diretivas Alpine, a um elemento para melhor reutilização.                                         |
-| [`x-cloak`](#x-cloak)           | Este atributo é removido quando o Alpine é inicializado. Útil para ocultar a pré-inicialização da DOM.                       |
-
-E 6 propriedades mágicas:
-
-| Propriedades Mágicas     | Descrição                                                                                                        |
-| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
-| [`$el`](#el)             | Recupere o nó DOM do componente raiz.                                                                            |
-| [`$refs`](#refs)         | Recupera elementos DOM marcados com `x-ref` dentro do componente.                                                |
-| [`$event`](#event)       | Recupera o objeto "Evento" do browser nativo em um evento que estejamos a escuta.                                   |
-| [`$dispatch`](#dispatch) | Cria um `CustomEvent` e envio-o usando `.dispatchEvent ()` internamente.                                           |
-| [`$nextTick`](#nexttick) | Execute uma determinada expressão APÓS o Alpine fazer suas atualizações reativas na DOM.                         |
-| [`$watch`](#watch)       | Disparará um callback fornecida quando uma propriedade do componente que está a "escuta" for alterada. |
-
-## Patrocinadores
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Queres o teu logótipo aqui? [Mensagem pelo Twitter](https://twitter.com/calebporzio)**
-
-## Colaboradores VIP
-
-<table>
-  <tr>
-    <td align="center"><a href="http://calebporzio.com"><img src="https://avatars2.githubusercontent.com/u/3670578?v=4" width="100px;" alt="Caleb Porzio"/><br /><sub><b>Caleb Porzio</b></sub></a><br /><sub>(Creator)</sub></td>
-    <td align="center"><a href="https://github.com/HugoDF"><img src="https://avatars2.githubusercontent.com/u/6459679?v=4" width="100px;" alt="Hugo"/><br /><sub><b>Hugo</b></sub></a></td>
-    <td align="center"><a href="https://github.com/ryangjchandler"><img src="https://avatars2.githubusercontent.com/u/41837763?v=4" width="100px;" alt="Ryan Chandler"/><br /><sub><b>Ryan Chandler</b></sub></a></td>
-    <td align="center"><a href="https://github.com/SimoTod"><img src="https://avatars2.githubusercontent.com/u/8427737?v=4" width="100px;" alt="Simone Todaro"/><br /><sub><b>Simone Todaro</b></sub></a></td>
-  </tr>
-</table>
-
-### Diretivas
-
----
-
-### `x-data`
-
-**Exemplo:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Estrutura:** `<div x-data="[object literal]">...</div>`
-
-`x-data` declara um novo scope do componente. Diz à estrutura para inicializar um novo componente com o seguinte objeto de dados.
-
-Pensem nisso como a propriedade `data` de um componente Vue.
-
-**Extrair Lógica dos Componentes**
-
-Podemos extrair dados (e comportamentos) em funções reutilizáveis:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() {
-                this.show = true;
-            },
-            close() {
-                this.show = false;
-            },
-            isOpen() {
-                return this.show === true;
-            },
-        };
-    }
-</script>
-```
-
-> **Para utilizadores do bundler**, observem que o Alpine.js assede a funções que estão no scope global (`window`), vamos necessitar atribuir explicitamente as suas funções à `window` para usá-las com `x- data`, por exemplo `window.dropdown = function () {}` (isso ocorre com Webpack, Rollup, Parcel etc. `function`'s que defenir serão padronizados para o scope do módulo, e não para `window`).
-
-Também podemos misturar vários objetos de dados usando a desestruturação de objetos:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}"></div>
-```
-
----
-
-### `x-init`
-
-**Exemplo:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Estrutura:** `<div x-data="..." x-init="[expressão]"></div>`
-
-`x-init` executa uma expressão quando um componente é inicializado.
-
-Caso desejem executar o código ANTES do Alpine fazer as atualizações iniciais na DOM (algo como um gancho `mounted ()` no VueJS), podemos retornar um callback do `x-init`, e é executado após:
-
-`x-init="() => { // temos acesso ao estado de pós-inicialização aqui // }"`
-
----
-
-### `x-show`
-
-**Exemplo:** `<div x-show="open"></div>`
-
-**Estrutura:** `<div x-show="[expressão]"></div>`
-
-`x-show` alterna o estilo `display: none;` no elemento, dependendo se a expressão for resolvida como `verdadeiro` ou `falso`.
-
-**x-show.transition**
-
-`x-show.transition` é uma API de conveniência para tornar o seu `x-show` mais agradável usando transições CSS.
-
-```html
-<div x-show.transition="open">
-    Esses conteúdos serão transferidos para dentro e para fora.
-</div>
-```
-
-| Diretivas                                               | Descrição                                                                                                                                           |
-| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `x-show.transition`                                     | Desvanecer e escala em simultâneos. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms) |
-| `x-show.transition.in`                                  | Apenas transição de entrada.                                                                                                                        |
-| `x-show.transition.out`                                 | Apenas transição de saída.                                                                                                                          |
-| `x-show.transition.opacity`                             | Apenas transição de desvanecer.                                                                                                                     |
-| `x-show.transition.scale`                               | Apenas transição de escala.                                                                                                                         |
-| `x-show.transition.scale.75`                            | Personalizar a transformação de escala CSS `transform: scale(.75)`.                                                                                 |
-| `x-show.transition.duration.200ms`                      | Define a transição "entrada" para 200ms. A saída é ajustada para metade disso (100ms).                                                           |
-| `x-show.transition.origin.top.right`                    | Personalizar a origem da transformação CSS `transform-origin: top right`.                                                                           |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Durações diferentes para "entrada" e "saída".                                                                                                       |
-
-> Nota: Todos esses modificadores de transição podem ser usados em conjunto. Isso é possível (apesar de não fazer sentido): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Nota: `x-show` espera que todas os filhos terminem a transição. Caso desejem ignorar esse comportamento, adicionem o modificador `.immediate`:
-
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open"></div>
-</div>
-```
-
----
-
-### `x-bind`
-
-> Nota: Podemos usar uma sintaxe ":" mais curta: `:type =" ... "`
-
-**Exemplo:** `<input x-bind:type="inputType">`
-
-**Estrutura:** `<input x-bind:[attribute]="[expressão]">`
-
-`x-bind` define o valor de um atributo para o resultado de uma expressão JavaScript. A expressão tem acesso a todas as chaves do objeto de dados do componente e é atualizada sempre que os dados forem atualizados.
-
-> Nota: as ligações de atributo APENAS são atualizadas quando as dependências são atualizadas. A estrutura é inteligente o suficiente para observar alterações nos dados e detectar quais ligações se importam com elas.
-
-**`x-bind` para atributos de classes**
-
-`x-bind` comporta-se de maneira um pouco diferente ao definir o atributo`class`.
-
-Para classes, passamos um objeto cujas as chaves são nomes de classe e valores são expressões booleanas para determinar se esses nomes de classe são aplicados ou não.
-
-Por exemplo: `<div x-bind:class="{ 'hidden': foo }"></div>`
-
-Neste exemplo, a classe "hidden" é aplicada apenas quando o valor do atributo de dados `foo` for `verdadeiro`.
-
-**`x-bind` para atributos booleanos**
-
-O `x-bind` suporta atributos booleanos da mesma maneira que os atributos de valor, usando uma variável como a condição ou qualquer expressão JavaScript que resolva como `verdadeiro` ou `falso`.
-
-Por exemplo:
-
-```html
-<!-- Given: -->
-<button x-bind:disabled="myVar">Clique em mim</button>
-
-<!-- Quando myVar == true: -->
-<button disabled="disabled">Clique em mim</button>
-
-<!-- Quando myVar == false: -->
-<button>Clique em mim</button>
-```
-
-Isso adicionará ou removerá o atributo `disabled` quando`myVar` for verdadeiro ou falso, respectivamente.
-
-Os atributos booleanos são suportados de acordo com a [especificação HTML](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), por exemplo `disabled`,`readonly`, `required`, `checked`,`hidden`, `selected`,`open` etc.
-
-**`.camel` modificador**
-**Exemplo:** `<svg x-bind:view-box.camel="viewBox">`
-
-O modificador `camel` se ligará ao equivalente em maiúsculas e minúsculas do nome do atributo. No exemplo acima, o valor de `viewBox` é definido ao atributo`viewBox` em oposição ao atributo `viewbox`.
-
----
-
-### `x-on`
-
-> Nota: podemos usar a sintaxe "@" mais curta: `@click =" ... "
-
-**Exemplo:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Estrutura:** `<button x-on:[event]="[expressão]"></button>`
-
-O `x-on` anexa um evento de escuta ao elemento em que está declarado. Quando esse evento é emitido, a expressão JavaScript definida como seu valor é executada.
-
-Caso algum dado for modificado na expressão, outros atributos do elemento "definidos" a esses dados serão atualizados.
-
-> Nota: Também podemos especificar um nome de função JavaScript
-
-**Exemplo:** `<button x-on:click="myFunction"></button>`
-
-O equivalente é: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` modificadores**
-
-**Exemplo:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Podemos especificar chaves específicas para escutar usando modificadores de keydown anexados à diretiva `x-on: keydown`. Observem que os modificadores são versões em kebab dos valores do `Event.key`.
-
-Exemplos: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Nota: Também podemos ouvir a combinações de teclas do sistema como: `x-on:keydown.cmd.enter="foo"`.
-
-**`.away` modificador**
-
-**Exemplo:** `<div x-on:click.away="showModal = false"></div>`
-
-Quando o modificador `.away` estiver presente, o evento handler é executado apenas quando o evento se originar de uma fonte que não seja ela própria ou seus filhos.
-
-Isso é útil para ocultar dropdowns e modals quando um utilizador clicar longe deles.
-
-**`.prevent` modificador**
-**Exemplo:** `<input type="checkbox" x-on:click.prevent>`
-
-Adicionar `.prevent` a um evento de escuta ira chamar o ` preventDefault` no evento acionado. No exemplo acima, isso significa que a caixa de seleção não é realmente verificada quando um utilizador clicar nela.
-
-**`.stop` modificador**
-**Exemplo:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Adicionar `.stop` a um evento de escuta ira chamar o ` stopPropagation` no evento acionado. No exemplo acima, isso significa que o evento "click" não borbulha do botão para o exterior `<div>`. Ou seja, quando um utilizador clicar no botão, `foo` não é definido como 'bar'.
-
-**`.self` modificador**
-**Exemplo:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Adicionar `.self` a um evento de escuta só vai acionar o handler quando o `$event.target` for o próprio elemento. No exemplo acima, isso significa que o evento "click" que borbulha do botão para a `<div>` externo **não** executa o handler.
-
-**`.window` modificador**
-**Exemplo:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Adicionar `.window` a um evento de escuta instalará a escutas no objeto na window global em vez do nó DOM no qual está declarado. Isso é útil para quando desejamos modificar o estado do componente quando algo muda com a window, como o evento de redimensionamento. Neste exemplo, quando a janela tiver mais de 768 pixels de largura, fechamos a modal/dropdown, caso contrário, manteremos o mesmo estado.
-
-> Nota: Também podemos usar o modificador `.document` para anexar escutas ao` document` em vez de `window`
-
-**`.once` modificador**
-**Exemplo:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Adicionar o modificador `.once` a um evento de escuta vai garantir que a escuta seja tratado apenas uma vez. Isso é útil para coisas que desejamos fazer apenas uma vez, como ir procurar parciais HTML e outras coisas.
-
-**`.passive` modificador**
-**Exemplo:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Adicionar o modificador `.passive` a um evento de escuta fará com que a escuta seja passiva, o que significa que o `preventDefault()` não vai funcionar em nenhum evento sendo processado, isso pode ajudar, por exemplo, com o desempenho do scroll em dispositivos touch.
-
-**`.debounce` modificador**
-**Exemplo:** `<input x-on:input.debounce="fetchSomething()">`
-
-O modificador `debounce` permite fazer "debounce" a um evento handler. Em outras palavras, o evento handler NÃO será executado até que tenha decorrido um certo tempo desde o último evento que foi disparado. Quando o handler estiver pronto para ser chamado, a última chamada do handler será executada.
-
-O tempo de espera de debounce padrão é de 250 milissegundos.
-
-Caso desejem personalizar isso, pode especificar um tempo de espera personalizado da seguinte maneira:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` modificador**
-**Exemplo:** `<input x-on:event-name.camel="doSomething()">`
-
-O modificador `camel` anexa um evento de escuta ao nome em camel case do evento equivalente. No exemplo acima, a expressão é avaliada quando o evento `eventName` for disparado no elemento.
-
----
-
-### `x-model`
-
-**Exemplo:** `<input type="text" x-model="foo">`
-
-**Estrutura:** `<input type="text" x-model="[data item]">`
-
-O `x-model` adiciona "ligação de dados bidirecional" a um elemento. Em outras palavras, o valor do elemento de entrada é mantido sincronizado com o valor do item de dados do componente.
-
-> Nota: `x-model` é inteligente o suficiente para detectar alterações nos inputs, checkboxes, radio buttons, textareas, selects e multiplo selects. Devem comportar-se [como o Vue] (https://vuejs.org/v2/guide/forms.html) nesses casos.
-
-**`.debounce` modificador**
-**Exemplo:** `<input x-model.debounce="search">`
-
-O modificador `debounce` permite adicionar um "debounce" a uma atualização de valor. Em outras palavras, o evento handler NÃO é executado até que tenha decorrido um certo tempo desde o último evento que foi disparado. Quando o handler estiver pronto para ser chamado, a última chamada do handler é executada.
-
-O tempo de espera de debounce padrão é de 250 milissegundos.
-
-Caso desejem personalizar isso, pode especificar um tempo de espera personalizado da seguinte maneira:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-
-**Exemplo:** `<span x-text="foo"></span>`
-
-**Estrutura:** `<span x-text="[expressão]"`
-
-O `x-text` funciona da mesma forma que o` x-bind`, exceto que, em vez de atualizar o valor de um atributo, ele atualiza o `innerText` de um elemento.
-
----
-
-### `x-html`
-
-**Exemplo:** `<span x-html="foo"></span>`
-
-**Estrutura:** `<span x-html="[expressão]"`
-
-O `x-html` funciona de maneira semelhante ao` x-bind`, exceto que, em vez de atualizar o valor de um atributo, ele atualiza o `innerHTML` de um elemento.
-
-> :warning: **Usar apenas em conteúdo de confiança e nunca em conteúdo fornecido pelo utilizador.** :warning:
->
-> A renderização dinâmica do HTML de terceiros pode levar facilmente às vulnerabilidades de [XSS] (https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting).
----
-
-### `x-ref`
-
-**Exemplo:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Estrutura:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-O `x-ref` fornece uma maneira conveniente de recuperar elementos DOM fora do seu componente. Ao definir um atributo `x-ref` em um elemento, torna-o disponível para todos os eventos handlers dentro de um objeto chamando `$refs`.
-
-Esta é uma alternativa útil para definir ID's e usar o `document.querySelector` em todo o lago.
-
-> Nota: também podemos definir valores dinâmicos no x-ref: `<span: x-ref =" item.id "> </span>` se necessário.
-
----
-
-### `x-if`
-
-**Exemplo:** `<template x-if="true"><div>Algum elemento</div></template>`
-
-**Estrutura:** `<template x-if="[expressão]"><div>Algum elemento</div></template>`
-
-Nos casos em que `x-show` não é suficiente (`x-show` define um elemento para `display: none` se for falso),`x-if` pode ser usado para remover um elemento completamente na DOM.
-
-É importante que o `x-if` seja usado em uma tag `<template> </template>` porque o Alpine não usa um DOM virtual. Essa implementação permite que o Alpine permaneça robusto e use o DOM real para fazer sua mágia.
-
-> Nota: `x-if` deve ter uma raiz de elemento único dentro da tag` <template> </template> `.
-
----
-
-### `x-for`
-
-**Exemplo:**
-
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Nota: a ligação `:key` é opcional, mas ALTAMENTE recomendada.
-
-O `x-for` está disponível para casos em que desejem criar novos nós DOM para cada item em uma matriz. Isso deve parecer semelhante ao `v-for` no Vue, com uma exceção da necessidade de existir em uma tag`template`, e não em um elemento DOM comum.
-
-Caso desejem aceder ao índice atual da iteração, usem a seguinte sintaxe:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- You can also reference "index" inside the iteration if you need. -->
-    <div x-text="index"></div>
-</template>
-```
-
-> Nota: `x-for` deve ter uma raiz de elemento único dentro da tag`<template> </template>`.
-
-#### Encadeamento de `x-for`s
-
-Podemos ter encadeamento de ciclos `x-for`, mas DEVEMOS envolver cada ciclo em um elemento. Por exemplo:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
----
-
-### `x-transition`
-
-**Exemplo:**
-
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->
-    ...
-</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >
-        ...
-    </div>
-</template>
-```
-
-> O exemplo acima usa classes de [Tailwind CSS](https://tailwindcss.com).
-
-Alpine oferece 6 diretivas de transição diferentes para aplicar classes a vários estágios da transição de um elemento entre os estados "oculto" e "mostrado". Essas diretivas funcionam tanto com `x-show` E`x-if`.
-
-Elas se comportam exatamente como as diretivas de transição do VueJs, exceto que têm nomes diferentes e mais sensíveis:
-
-| Directiva      | Descrição                                                                                                                                            |
-| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `:enter`       | Aplicado durante toda a fase de entrada.                                                                                                             |
-| `:enter-start` | Adicionado antes que o elemento seja inserido, removido um frame após o elemento ser inserido.                                                                       |
-| `:enter-end`   | Adicionado um frame após a inserção do elemento (ao mesmo tempo em que o `enter-start` é removido), removido quando a transição/animação termina.                   |
-| `:leave`       | Aplicado durante toda a fase de partida.                                                                                                             |
-| `:leave-start` | Adicionado imediatamente quando uma transição de saída é acionada, removida após um frame.                                                                   |
-| `:leave-end`   | Adicionado um frame depois que uma transição de saída é acionada (ao mesmo tempo em que o `leave-start` é removido), removido quando a transição/animação termina. |
-
----
-
-### `x-spread`
-
-**Exemplo:**
-
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Dropdown Aberto</button>
-
-    <span x-spread="dialogue">Conteúdo da Dropdown</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true;
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open;
-                },
-                ['@click.away']() {
-                    this.open = false;
-                },
-            },
-        };
-    }
-</script>
-```
-
-O `x-spread` permite extrair as ligações de um elemento Alpine em um objeto reutilizável.
-
-As chaves do objeto são as diretivas (pode ser qualquer diretiva, incluindo modificadores), e os valores são callback's a serem avaliados pelo Alpine.
-
-> Nota: A única anomalia com propagação x é quando usada com `x-for`. Quando a diretiva "spread" é `x-for`, devemos retornar uma string de expressão normal a partir de um callback. Por exemplo: `['x-for'] () {return 'item in items'}`.
----
-
-### `x-cloak`
-
-**Exemplo:** `<div x-data="{}" x-cloak></div>`
-
-Os atributos `x-cloak` são removidos dos elementos quando o Alpine é inicializado. Isso é útil para ocultar o DOM pré-inicializado. É típico adicionar o seguinte estilo global para que isso funcione:
-
-```html
-<style>
-    [x-cloak] {
-        display: none;
-    }
-</style>
-```
-
-### Propriedades Mágicas
-
-> Com exceção de `$el`, as propriedades mágicas **não estão disponíveis no` x-data`**, pois o componente ainda não foi inicializado.
----
-
-### `$el`
-
-**Exemplo:**
-
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Substitua-me por "foo"</button>
-</div>
-```
-
-`$el` é uma propriedade mágica que pode ser usada para recuperar o nó DOM do componente raiz.
-
-### `$refs`
-
-**Exemplo:**
-
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` é uma propriedade mágica que pode ser usada para recuperar elementos DOM marcados com `x-ref` dentro do componente. Isso é útil quando necessitamos manipular manualmente os elementos na DOM.
-
----
-
-### `$event`
-
-**Exemplo:**
-
-```html
-<input x-on:input="alert($event.target.value)" />
-```
-
-`$event` é uma propriedade mágica que pode ser usada dentro de um evento de escuta para recuperar o objeto "Event" do browser nativo.
-
-> Nota: A propriedade $event está disponível apenas nas expressões DOM.
-
-Caso necessitem aceder ao $event dentro de uma função JavaScript, podemos passa-lo diretamente:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-
-**Exemplo:**
-
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Quando clicado, console.log "bar" ->
-</div>
-```
-
-**Nota sobre a propagação de eventos**
-
-Observem que, devido ao [evento com bolhas](https://en.wikipedia.org/wiki/Event_bubbling), quando for preciso capturar eventos enviados pelos nós que estão sob a mesma hierarquia de encadeamento, usem o modificador [`.window`](https://github.com/alpinejs/alpine#x-on):
-
-**Exemplo:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-        <div></div>
-    </button>
-</div>
-```
-
-> Isso não vai funcionar porque, quando o `custom-event` for executado, ele é propagado para seu ancestral comum, a `div`.
-
-**Expedição para componentes**
-
-Também podemos tirar proveito da técnica anterior para fazer os componentes comunicarem entre si:
-
-**Exemplo:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Olá Mundo!')">
-    <!-- Quando clicado, o console.log "Olá Mundo!". -->
-</button>
-```
-
-`$dispatch` é um atalho para criar um`CustomEvent` e enviá-lo internamente usando `.dispatchEvent ()`. Existem muitos casos de uso bons para transmitir dados entre componentes usando eventos personalizados. [Leia aqui](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) para obter mais informações sobre o sistema subjacente `CustomEvent` nos browsers.
-
-Notarão que todos os dados passados como o segundo parâmetro para `$dispatch('some-event', {some: 'data'})` ficam disponíveis através da nova propriedade "detail" de eventos: `$event.detail.some`. Anexar dados de eventos personalizados à propriedade `.detail` é uma prática padrão para o `CustomEvent`s nos browsers. [Leia aqui](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) para obter mais informações.
-
-Também podemos usar `$dispatch()` para acionar atualizações de dados para ligações `x-model`. Por exemplo:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- Depois que o botão é clicado, o `x-model` irá capturar o evento "input" e atualizar foo para "baz". -->
-    </span>
-</div>
-```
-
-> Nota: A propriedade $dispatch está disponível apenas nas expressões DOM.
-
-Caso necessitem aceder ao $dispatch dentro de uma função JavaScript, poderão transmiti-la diretamente:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-
-**Exemplo:**
-
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$ nextTick` é uma propriedade mágica que permite executar apenas uma determinada expressão APÓS o Alpine fazer suas atualizações a DOM. Isso é útil nos momentos em que desejam interagir com o estado da DOM, após refletir as atualizações de dados que fizemos.
-
----
-
-### `$watch`
-
-**Exemplo:**
-
-```html
-<div
-    x-data="{ open: false }"
-    x-init="$watch('open', value => console.log(value))"
->
-    <button @click="open = ! open">Alternar Abrir</button>
-</div>
-```
-
-Podemos "assistir" uma propriedade de componente com o método mágico `$watch`. No exemplo acima, quando o botão é clicado e o valor do `open` é alterado, e o callback fornecida é executada e o novo valor mostrado num `console.log`.
-
-## Segurança
-
-Caso encontrarem uma vulnerabilidade de segurança, envie um email para [calebporzio@gmail.com](mailto:calebporzio@gmail.com).
-
-O Alpine conta com uma implementação personalizada usando o objeto `Function` para avaliar suas diretivas. Apesar de ser mais seguro que o `eval()`, o seu uso é proibido em alguns ambientes, como o Google Chrome App, usando a Política de Segurança de Conteúdo restritiva (CSP).
-
-Caso usem o Alpine em uma página web que lida com dados confidenciais e exige [CSP](https://csp.withgoogle.com/docs/strict-csp.html), necessitam incluir `unsafe-eval` na sua política. Uma política robusta configurada corretamente ajudará a proteger os utilizadores ao usar dados pessoais ou financeiros.
-
-Como uma política se aplica a todos os scripts da sua página, é importante que outras bibliotecas externas incluídas na página web estejam cuidadosamente revisadas para garantir que sejam confiáveis e não apresentem nenhuma vulnerabilidade de Cross Site Scripting usando a função `eval()` ou manipular o DOM para injetar código malicioso na sua página.
-
-## Licença
-
-Copyright © 2019-2021 Caleb Porzio e colaboradores
-
-Licenciado sob a licença MIT, consulte [LICENSE.md](LICENSE.md) para obter detalhes.

+ 0 - 787
README.ru.md

@@ -1,787 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js предоставляет реактивность и декларативность как в больших фреймворках вроде Vue или React, но с меньшими затратами.
-
-Вы сможете использовать обычный DOM, при этом изменяя поведение по своему усмотрению.
-
-Можете думать о Alpine.js как о [Tailwind](https://tailwindcss.com/) для JavaScript.
-
-> Замечание: синтаксис Alpine.js почти полностью заимствован из [Vue](https://ru.vuejs.org/) (а, соответственно, и из [Angular](https://angularjs.org/)). Я безмерно благодарен разработчикам этих инструментов за тот вклад, который они внесли в Web.
-
-## Установка
-
-**С помощью CDN:** Добавьте следующий `<script>` в конец секции `<head>`.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-Вот и всё. Он инициализируется самостоятельно.
-
-Для рабочего окружения рекомендуется использовать ссылку с конкретным номером версии, чтобы избежать неожиданных поломок после выпуска новых версий.
-Например, чтобы использовать версию `2.8.2`:
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**С помощью npm:** Установите пакет из npm.
-```js
-npm i alpinejs
-```
-
-Добавьте его в свой код.
-```js
-import 'alpinejs'
-```
-
-**Для поддержки IE11** используйте вместо указанных выше следующие скрипты:
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-Паттерн, использующийся выше, называется [паттерн module/nomodule](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/). Он позволяет автоматически загружать современный пакет в современных браузерах, а в IE11 и других устаревших браузерах – пакет для IE11.
-
-## Использование
-
-*Выпадающий список/Модальное окно*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Открыть</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Содержимое
-    </ul>
-</div>
-```
-
-*Вкладки*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Вкладка Foo</div>
-    <div x-show="tab === 'bar'">Вкладка Bar</div>
-</div>
-```
-
-Alpine.js можно использовать и для более серьезных выражений. Например, *предзагрузка HTML-содержимого при наведении мыши*.
-
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Показать</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Загрузка...
-    </div>
-</div>
-```
-
-## Изучение
-
-Всего в Alpine 14 директив:
-
-| Директива | Описание |
-| --- | --- |
-| [`x-data`](#x-data) | Объявляет новый компонент и его данные. |
-| [`x-init`](#x-init) | Выполняет переданное выражение, когда компонент инициализируется. |
-| [`x-show`](#x-show) | Переключает `display: none;` на элементе, в зависимости от результата переданного выражения (true или false). |
-| [`x-bind`](#x-bind) | Устанавливает значение атрибута равным результату переданного JS-выражения. |
-| [`x-on`](#x-on) | Устанавливает обработчик события на элемент. Когда событие срабатывает, выполняет переданное JS-выражение. |
-| [`x-model`](#x-model) | Добавляет "двустороннюю привязку данных" (two-way data binding) на элемент. Синхронизирует элемент и данные компонента. |
-| [`x-text`](#x-text) | Устанавливает значение `innerText` элемента равным результату переданного JS-выражения. |
-| [`x-html`](#x-html) | Устанавливает значение `innerHTML` элемента равным результату переданного JS-выражения. |
-| [`x-ref`](#x-ref) | Удобный способ получения DOM-элементов вашего компонента. |
-| [`x-if`](#x-if) | При невыполнении переданного условия полностью удаляет элемент из DOM. Должна использоваться в теге `<template>`. |
-| [`x-for`](#x-for) | Создает новые DOM узлы для каждого элемента в массиве. Должна использоваться в теге `<template>`. |
-| [`x-transition`](#x-transition) | Директивы для добавления css-классов различным стадиям перехода (transition) элемента. |
-| [`x-spread`](#x-spread) | Позволяет привязывать объект с директивами Alpine к элементам, улучшая повторное использование кода. |
-| [`x-cloak`](#x-cloak) | Атрибут удаляется после инициализации Alpine. Используется для скрытия элементов до DOM инициализации. |
-
-И 6 магических свойств (magic properties):
-
-| Магическое свойство | Описание |
-| --- | --- |
-| [`$el`](#el) |  Получить DOM-узел корневого компонента. |
-| [`$refs`](#refs) | Получить DOM-элементы компонента, отмеченные `x-ref`. |
-| [`$event`](#event) | В обработчике события получить нативный объект браузера "Event".  |
-| [`$dispatch`](#dispatch) | Создать `CustomEvent` и вызвать его, используя `.dispatchEvent()`. |
-| [`$nextTick`](#nexttick) | Выполнить переданное выражение ПОСЛЕ того, как Alpine сделает реактивное обновление DOM. |
-| [`$watch`](#watch) | Выполнить переданный колбэк, когда наблюдаемое свойство компонента изменится. |
-
-
-## Спонсоры
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Хочешь здесь своё лого? [Напиши мне сообщение в Twitter](https://twitter.com/calebporzio)**
-
-## Сообщество проекта
-
-* [Еженедельная рассылка AlpineJS](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (глобальные данные между компонентами)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers (полезные хелперы для Alpine)](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine (ссылки на прочие проекты об Alpine)](https://github.com/ryangjchandler/awesome-alpine)
-
-### Директивы
-
----
-
-### `x-data`
-
-**Пример:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Синтаксис:** `<div x-data="[JSON-объект]">...</div>`
-
-`x-data` объявляет область видимости нового компонента с использованием переданного объекта данных.
-
-Аналогична свойству `data` в компонентах Vue.
-
-**Задание логики компонента отдельной функцией**
-
-Можно получить данные (и задать поведение компонента) в повторно используемых функциях:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Открыть</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Для пользователей бандлеров (bundler)**. Alpine.js получает доступ к функциям только из глобальной области видимости (`window`). Вам необходимо явно присвоить свои функции объекту `window`, чтобы использовать их с `x-data`. Например, вот так: `window.dropdown = function () {}` (с Webpack, Rollup, Parcel и другими бандлерами функции, которые вы объявляете, по умолчанию принадлежать области видимости бандлера, а не `window`).
-
-
-Вы также можете объединять несколько объектов с данными с помощью деструктуризации:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Пример:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Синтаксис:** `<div x-data="..." x-init="[выражение]"></div>`
-
-`x-init` выполняет переданное выражение, когда компонент инициализируется.
-
-Если вы хотите выполнить код ПОСЛЕ первоначальных обновлений DOM Alpine (наподобие хука `mounted()` во VueJS), то можете передать в `x-init` колбэк, и он выполнит его после инициализации:
-
-`x-init="() => { // здесь уже есть доступ к состоянию после инициализации DOM // }"`
-
----
-
-### `x-show`
-**Пример:** `<div x-show="open"></div>`
-
-**Синтаксис:** `<div x-show="[выражение]"></div>`
-
-`x-show` переключает `display: none;` на элементе в зависимости от результата выполнения выражения (`true` или `false`).
-
-**x-show.transition**
-
-`x-show.transition` – удобный API для добавления к `x-show` CSS-переходов (transitions).
-
-```html
-<div x-show.transition="open">
-    Это содержимое будет иметь переходы при появлении и исчезновении.
-</div>
-```
-
-| Директива | Описание |
-| --- | --- |
-| `x-show.transition` | Одновременный fade и scale. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Переход только при появлении. |
-| `x-show.transition.out` | Переход только при исчезновении. |
-| `x-show.transition.opacity` | Использовать только fade. |
-| `x-show.transition.scale` | Использовать только scale. |
-| `x-show.transition.scale.75` | Кастомизация scale перехода `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | Устанавливает время перехода при появлении на 200мс. Переход при исчезновении будет равен половине этого значения (100мс). |
-| `x-show.transition.origin.top.right` | Кастомизация места возникновения перехода `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Различные длительности для переходов при появлении и исчезновении. |
-
-> Замечание: Все эти модификаторы переходов могут использоваться в сочетании друг с другом. Это возможно (хоть и нелепо): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Замечание: `x-show` будет ждать окончания переходов всех дочерних элементов. Можно изменить это поведение модификатором `.immediate`:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Сокращенный синтаксис ":". Например: `:type="..."`
-
-**Пример:** `<input x-bind:type="inputType">`
-
-**Синтаксис:** `<input x-bind:[атрибут]="[выражение]">`
-
-`x-bind` устанавливает значение атрибута равным результату JS-выражения. Выражение имеет доступ ко всем ключам хранилища данных компонента и будет обновляться каждый раз при обновлении данных.
-
-> Замечание: обновление значения атрибута с `x-bind` будет происходить ТОЛЬКО при обновлении его зависимостей.
-
-**`x-bind` для атрибутов class**
-
-`x-bind` ведет себя немного иначе, когда привязан к атрибуту `class`.
-
-Для css-классов необходимо передавать объект, где ключи – это имена классов, а значения – логические выражения, которые определяют применяются эти классы или нет.
-
-Например:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-В этом примере, класс "hidden" будет применен только если значение выражения `foo` равно `true`.
-
-**`x-bind` для логических атрибутов**
-
-`x-bind` поддерживает логические атрибуты так же, как и атрибуты значения, используя переменную как условие или любое JS-выражение, которое разрешается в `true` или `false`.
-
-Например:
-```html
-<!-- Дано: -->
-<button x-bind:disabled="myVar">Нажми на меня</button>
-
-<!-- Когда myVar == true: -->
-<button disabled="disabled">Нажми на меня</button>
-
-<!-- Когда myVar == false: -->
-<button>Нажми на меня</button>
-```
-
-Это добавит или удалит атрибут `disabled`, в зависимости от того, равна `myVar` true или false.
-
-Логические атрибуты поддерживаются в соответствии с [HTML спецификацией](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), такие как, например, `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open` и другие.
-
-> Замечание: Если нужно вернуть логическое (true/false) значение атрибута в виде текста, например для `aria-*`, используйте метод `.toString()`. Например `:aria-expanded="isOpen.toString()"` вернёт строку `true` или `false`в зависимости от значения `isOpen`.
-
-**Модификатор `.camel`**
-**Пример:** `<svg x-bind:view-box.camel="myVar">`
-
-Модификатор `camel` позволяет задать имя атрибута, которое будет преобразовано к синтаксису "camelCase". В данном примере значение будет присвоено атрибуту `viewBox`, а не `view-box`.
-
----
-
-### `x-on`
-
-> Сокращенный синтаксис "@": `@click="..."`
-
-**Пример:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Синтаксис:** `<button x-on:[событие]="[выражение]"></button>`
-
-`x-on` цепляет слушатель события на элемент, в котором был объявлен. Когда событие срабатывает, выполняется переданное JS-выражение. Можно использовать `x-on` с любым событием. См. полный список событий в [документации MDN](https://developer.mozilla.org/en-US/docs/Web/Events).
-
-Если в этом выражении меняются какие-либо данные, другие элементы, "привязанные" к этим данным, также будут обновлены.
-
-> Замечание: Также можно задать имя JS-функции.
-
-**Пример:** `<button x-on:click="myFunction"></button>`
-
-Это равноценно: `<button x-on:click="myFunction($event)"></button>`
-
-**Модификатор `keydown`**
-
-**Пример:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Можно обозначить конкретные клавиши для прослушивания, присоединяя их через точку к директиве `x-on:keydown`. Модификаторы – это значения `Event.key`, записанные в kebab-стиле.
-
-Например: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Замечание: Можно также прослушивать комбинации с системными клавишами, например: `x-on:keydown.cmd.enter="foo"`
-
-**Модификатор `.away`**
-
-**Пример:** `<div x-on:click.away="showModal = false"></div>`
-
-При добавлении модификатора `.away` обработчик события сработает, только когда событие произошло на другом источнике, а не на этом элементе или его потомках.
-
-Это полезно для скрытия дропдаунов или модальных окон, когда пользователь кликает в другом месте экрана.
-
-**Модификатор `.prevent`**
-
-**Пример:** `<input type="checkbox" x-on:click.prevent>`
-
-При добавлении `.prevent` обработчик вызовет `preventDefault` на сработавшем событии. В примере выше это приведет к тому, что чекбокс не будет отмечен при нажатии на него.
-
-**Модификатор `.stop`**
-
-**Пример:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-При добавлении `.stop` обработчик вызовет `stopPropagation` на сработавшем событии. В примере выше это приведет к тому, что событие "click" не всплывет от кнопки к внешнему `<div>`. Другими словами, когда пользователь нажимает на кнопку, `foo` не устанавливается в `'bar'`.
-
-**Модификатор `.self`**
-
-**Пример:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-При добавлении `.self` обработчик события сработает, только если `$event.target` – это сам элемент. В примере выше это приведет к тому, что событие "click", всплыв от кнопки к внешнему `<div>`, **не** вызовет его обработчик.
-
-**Модификатор `.window`**
-
-**Пример:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-При добавлении `.window` слушатель события установится не на узел DOM, на котором был вызван, а на глобальный объект window. Это используется, когда нужно изменить состояние компонента при изменении чего-либо в window, например, при событии "resize". В примере выше, когда ширина окна будет больше 768 пикселей, модальное окно закроется.
-
->Замечание: Также можно использовать модификатор `.document` для добавления слушателей к `document`.
-
-**Модификатор `.once`**
-
-**Пример:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-При добавлении `.once` обработчик события будет вызван лишь единожды. Это полезно для вещей, которые нужно сделать только один раз, например, загрузка данных и т.п.
-
-**Модификатор `.passive`**
-
-**Пример:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-Добавление модификатора `.passive` к слушателю события сделает его пассивным. Это значит, что `preventDefault()` не будет работать ни с какими обрабатываемыми событиями. Это может помочь например с производительностью при прокрутке на сенсорных устройствах.
-
-**Модификатор `.debounce`**
-
-**Пример:** `<input x-on:input.debounce="fetchSomething()">`
-
-Модификатор `debounce` позволяет избавиться от ложных повторных вызовов обработчика события. Другими словами, обработчик НЕ будет вызван, пока не пройдет определенное количество времени с предыдущего вызова. Когда обработчик будет готов, будет вызван последний вызов.
-
-Время ожидания по умолчанию 250 миллисекунд.
-
-Вы также можете указать свое время:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**Модификатор `.camel`**
-
-**Пример:** `<input x-on:event-name.camel="doSomething()">`
-
-Модификатор `camel` позволяет задать событие, которое будет преобразовано к синтаксису "camelCase". В данном примере слушатель будет добавлен к событию `eventName`.
-
----
-
-### `x-model`
-**Пример:** `<input type="text" x-model="foo">`
-
-**Синтаксис:** `<input type="text" x-model="[хранилище данных]">`
-
-`x-model` добавляет элементу "двустороннюю привязку данных" (two-way data binding). Другими словами, значение поля ввода будет синхронизировано со значением в хранилище данных компонента.
-
-> Замечание: `x-model` достаточно умен, чтобы замечать изменения в текстовых полях ввода, чекбоксах, радио-кнопках, textarea, select, и множественных select. В данных сценариях `x-model` ведет себя аналогично `v-model` [во Vue](https://ru.vuejs.org/v2/guide/forms.html).
-
-**Модификатор `.number`**
-**Пример:** `<input x-model.number="age">`
-
-Модификатор `number` преобразует входное значение в число. Если оно не может быть преобразовано, то возвращается исходное значение.
-
-**Модификатор `.debounce`**
-**Пример:** `<input x-model.debounce="search">`
-
-Модификатор `debounce` позволяет избавиться от ложных повторных изменений значения. Другими словами, обработчик НЕ будет вызван, пока не пройдет определенное количество времени с предыдущего вызова. Когда обработчик будет готов, будет вызван последний вызов.
-
-Время ожидания по умолчанию 250 миллисекунд.
-
-Вы также можете указать свое время:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Пример:** `<span x-text="foo"></span>`
-
-**Синтаксис:** `<span x-text="[выражение]"`
-
-`x-text` устанавливает значение `innerText` элемента равным результату переданного JS-выражения. Другими словами, работает аналогично `x-bind`, но не для атрибута, а для `innerText` элемента.
-
----
-
-### `x-html`
-**Пример:** `<span x-html="foo"></span>`
-
-**Синтаксис:** `<span x-html="[выражение]"`
-
-`x-html` устанавливает значение `innerHTML` элемента равным результату переданного JS-выражения. Другими словами, работает аналогично `x-bind`, но не для атрибута, а для `innerHTML` элемента.
-
-> :warning: **Используйте только надежные источники контента и никогда не используйте контент, предоставленный пользователем.** :warning:
->
-> Динамически отрендеренный HTML от третьих сторон может легко привести к [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) уязвимостям.
-
----
-
-### `x-ref`
-**Пример:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Синтаксис:** `<div x-ref="[имя рефа]"></div><button x-on:click="$refs.[имя рефа].innerText = 'bar'"></button>`
-
-`x-ref` предоставляет удобный способ получения DOM-элементов ваших компонентов. При установлении атрибута `x-ref` на элемент, вы делаете его доступным всем обработчикам событий в объекте `$refs`.
-
-Это удобная альтернатива установке id и использования `document.querySelector`.
-
-> Замечание: при необходимости также можно привязывать x-ref динамические значения: `<span :x-ref="item.id"></span>`.
-
----
-
-### `x-if`
-**Пример:** `<template x-if="true"><div>Какой-то элемент</div></template>`
-
-**Синтаксис:** `<template x-if="[выражение]"><div>Какой-то элемент</div></template>`
-
-В случаях, когда `x-show` недостаточно (`x-show` устанавливает элементу `display: none`, если выражение ложно), можно использовать `x-if`, чтобы полностью удалить элемент из DOM.
-
-Alpine не использует Virtual DOM, поэтому важно, чтобы `x-if` использовался в теге `<template></template>`.
-
-> Замечание: Внутри тега `<template></template>` с `x-if` должен быть лишь один корневой элемент.
-
-> Замечание: При использовании `template` в тэге `svg`, используйте [полифил](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538). Он должен быть запущен до инициализации Alpine.js.
-
----
-
-### `x-for`
-**Пример:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Замечание: привязка `:key` опциональна, хотя КРАЙНЕ рекомендуется.
-
-`x-for` используется для создания новых DOM-узлов для каждого элемента в массиве. `x-for` похоже на `v-for` во Vue, с одним отличием: `x-for` может использовался только в теге `<template></template>`.
-
-Если вы хотите получить доступ к индексу текущей итерации, используйте следующий синтаксис:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- Если необходимо, вы также можете ссылаться на "index" внутри итерации. -->
-    <div x-text="index"></div>
-</template>
-```
-Если нужно получить доступ к массиву данных (collection) внутри цикла, используйте такой синтаксис:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- Можно ссылаться на массив "collection" -->
-    <!-- Текущий элемент -->
-    <div x-text="item"></div>
-    <!-- или так -->
-    <div x-text="collection[index]"></div>
-    <!-- Предыдущий элемент -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> Замечание: Внутри тега `<template></template>` с `x-for` должен быть лишь один корневой элемент.
-
-> Замечание: При использовании `template` в тэге `svg`, используйте [полифил](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538). Он должен быть запущен до инициализации Alpine.js.
-
-#### Вложенные `x-for`
-Можно вкладывать `x-for` друг в друга, но НУЖНО оборачивать каждый цикл в какой-нибудь элемент. Например:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Количество итераций
-
-Alpine поддерживает синтаксис `i in n`, где `n` число, указывающее на количество итераций цикла.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Пример:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> Пример выше использует классы из [Tailwind CSS](https://tailwindcss.com)
-
-Alpine предлагает 6 разных transition-директив для добавления классов к различным стадиям перехода элемента от состояния "скрытого" к "видимому". Все эти директивы работают как с `x-show`, так и с `x-if`.
-
-Они ведут себя абсолютно так же, как transition-директивы во VueJS, но у них более понятные названия:
-
-| Директива | Описание |
-| --- | --- |
-| `:enter` | Применяется в ходе всей фазы появления. |
-| `:enter-start` | Добавляется до введения элемента, удаляется на следующий фрейм после с введения элемента. |
-| `:enter-end` | Добавляется на следующий фрейм после с введения элемента (одновременно с удалением `enter-start`), удаляется, когда переход/анимация заканчивается.
-| `:leave` | Применяется в ходе всей фазы исчезновения. |
-| `:leave-start` | Добавляется, как только вызвано исчезновение, удаляется на следующий фрейм. |
-| `:leave-end` | Добавляется на следующий фрейм, как только вызвано исчезновение (одновременно с удалением `leave-start`), удаляется, когда переход/анимация заканчивается.
-
----
-
-### `x-spread`
-**Пример:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Открыть</button>
-
-    <span x-spread="dialogue">Содержимое</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` позволяет вынести привязки Alpine из элементов в объект (он может повторно использоваться в других компонентах).
-
-Ключи объекта – это директивы (любые, в том числе и с модификаторами), а значения – колбэки, с которыми будет работать Alpine.
-
-> Замечание: Единственная особенность при работе с x-spread – это то, как обрабатывается `x-for`. Когда директива, используемая в x-spread – это `x-for`, в колбэке необходимо возвращать выражение в виде строки. К примеру: `['x-for']() { return 'item in items' }`.
-
-> Замечание: Директивы `x-data` и `x-init` не могут использоваться в "spread"-объекте.
-
----
-
-### `x-cloak`
-**Пример:** `<div x-data="{}" x-cloak></div>`
-
-Атрибуты `x-cloak` удаляются с элементов, когда Alpine будет проинициализирован. Это полезно для скрытия элемента до построения DOM. Для использования `x-cloak` необходимо добавить следующие css-правила:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Магические свойства
-
-> Не считая `$el`, магические свойства **не доступны внутри `x-data`**, так как компонент еще не инициализирован.
-
----
-
-### `$el`
-**Пример:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Замени меня на "foo"</button>
-</div>
-```
-
-`$el` – магическое свойство, которое используется для получения корневого DOM-узла компонента.
-
-### `$refs`
-**Пример:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` – это магическое свойство, которое используется для получения DOM-элементов внутри компонента, помеченных `x-ref`. Оно используется, когда нужно вручную манипулировать элементами DOM.
-
----
-
-### `$event`
-**Пример:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` – это магическое свойство, которое можно использовать в слушателе событий для получения нативного объекта "Event".
-
-> Замечание: свойство $event доступно только в DOM-выражениях.
-
-Если нужно получить доступ к $event внутри функции JavaScript, вы можете передать его как параметр:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Пример:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })"></button>
-    <!-- После нажатия кнопки выводит в консоль "bar" -->
-</div>
-```
-
-**Примечание по распространению событий (event propagation)**
-
-Когда требуется перехватить событие, вызванное из узла на том же уровне вложенности, можно использовать модификатор [`.window`](https://github.com/alpinejs/alpine/blob/master/README.ru.md#x-on):
-
-**Пример неверного использования:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })"></button>
-<div>
-```
-
-> Это не будет работать, потому что, когда вызывается `custom-event`, он сразу всплывает ([event bubbling](https://en.wikipedia.org/wiki/Event_bubbling)) к родителю `div`.
-
-**Диспетчеризация для компонентов**
-
-Вы также можете использовать предыдущую технику для общения компонентов друг с другом:
-
-**Пример:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')"></button>
-<!-- При нажатии в консоль выведется "Hello World!". -->
-```
-
-`$dispatch` – это удобное сокращение для создания `CustomEvent` (пользовательские события) и их вызова с помощью `.dispatchEvent()`. Существует множество сценариев использования передачи данных между компонентами с помощью пользовательских событий. [Пройдите по этой ссылке](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events), чтобы больше узнать о системе, лежащей в основе `CustomEvent` в браузерах.
-
-Любые данные, переданные как второй параметр в `$dispatch('some-event', { some: 'data' })`, становятся доступны через свойство "detail" события: `$event.detail.some`. Добавление событию пользовательских данных через свойство `.detail` – стандартная практика для `CustomEvent` в браузерах. [Подробнее здесь](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail).
-
-Вы также можете использовать `$dispatch()` для вызова обновления данных в привязках `x-model`. Например:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')"></button>
-        <!-- После нажатия кнопки, `x-model` перехватит всплывающее событие "input" (oninput), и обновит foo на "baz". -->
-    </span>
-</div>
-```
-
-> Замечание: Свойство $dispatch доступно только в DOM-выражениях.
-
-Если нужен доступ к $dispatch внутри JavaScript-функции, вы можете передать его напрямую:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Пример:**
-```html
-<div x-data="{ fruit: 'яблоко' }">
-    <button
-        x-on:click="
-            fruit = 'груша';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` – это магическое свойство, которое выполняет переданное выражение только ПОСЛЕ того, как Alpine реактивно обновит DOM. Это полезно в тех случаях, когда вы хотите взаимодействовать с состоянием DOM, ПОСЛЕ того, как оно отразит сделанное вами обновление данных.
-
----
-
-### `$watch`
-**Пример:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-Магический метод `$watch` позволяет следить за выбранным свойством компонента. В примере выше при нажатии на кнопку: 1) значение `open` изменится; 2) выполнится переданный в `$watch` колбэк; 3) в консоль выведется новое значение.
-
-## Безопасность
-Если вы нашли уязвимость, пожалуйста, отправьте письмо на [calebporzio@gmail.com]().
-
-Alpine полагается на собственную реализацию, которая использует объект `Function` для оценки своих директив. Несмотря на то, что он безопаснее, чем `eval()`, его использование запрещено в некоторых средах, таких как Google Chrome App, т.е. использующих Политику защиты контента (CSP).
-
-Если вы используете Alpine на веб-сайте, имеющем дело с конфиденциальными данными и требующим [CSP](https://csp.withgoogle.com/docs/strict-csp.html), вы должны включить `unsafe-eval` в свою политику. Правильно настроенная политика поможет защитить ваших пользователей при использовании их личных или финансовых данных.
-
-Поскольку политика применяется ко всем скриптам на вашей странице, важно, чтобы другие внешние библиотеки, которые используются на сайте, были тщательно проверены, чтобы убедиться, что они заслуживают доверия, и не будут создавать XSS-уязвимость с помощью функции `eval()` или манипулировать DOM для внедрения вредоносного кода на вашу страницу.
-
-## Планы на третью версию
-* Перейти с `x-ref` на `ref` для соответствия с Vue?
-* Добавить `Alpine.directive()`
-* Добавить `Alpine.component('foo', {...})` (с магическим методом `__init()`)
-* Вызывать Alpine-события для "loaded", "transition-start", и т.д. ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* Удалить синтаксис объекта (и массива) у `x-bind:class="{ 'foo': true }"` ([#236](https://github.com/alpinejs/alpine/pull/236), чтобы добавить поддержку синтаксиса объекта для атрибута `style`)
-* Улучшить изменение реактивности `x-for` ([#165](https://github.com/alpinejs/alpine/pull/165))
-* Добавить поддержку "deep watching" ([#294](https://github.com/alpinejs/alpine/pull/294))
-* Добавить сокращение для `$el`
-* Изменить `@click.away` на `@click.outside`?
-
-## Лицензия
-
-Copyright © 2019-2021 Caleb Porzio и другие
-
-Лицензировано по лицензии MIT, смотрите [LICENSE.md](LICENSE.md) для подробностей.

+ 0 - 792
README.tr.md

@@ -1,792 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js, Vue.js yada React gibi önemli framework' ların yüksek seviye programlama (reaktif ve deklaratif vb.) yapısını daha düşük bir maliyetle sunar.
-
-DOM' unuza hükmedin ve uygun gördüğünüz şekilde düzenleyin.
-
-Bunu [Tailwind](https://tailwindcss.com/) 'ın JavaScript versiyonu olarak düşünebilirsiniz.
-
-> Not: Bu kütüphanenin sentaksının neredeyse tamamında [Vue](https://vuejs.org/) (ve dolayısıyla [Angular](https://angularjs.org/)) 'dan esinlenilmiştir. Onlara, web' e yaptıkları katkılarından ötürü sonsuza dek minnettarım.
-
-## Çevrilmiş Dökümanlar
-
-| Language | Link for documentation |
-| --- | --- |
-| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
-| German | [**Dokumentation in Deutsch**](./README.de.md) |
-| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
-| Japanese | [**日本語ドキュメント**](./README.ja.md) |
-| Portuguese | [**Documentação em Português**](./README.pt.md) |
-| Russian | [**Документация на русском**](./README.ru.md) |
-| Spanish | [**Documentación en Español**](./README.es.md) |
-| Türkçe | [**Türkçe Dökümantasyon**](./README.tr.md) |
-
-## Kurulum
-
-**CDN ile:** Aşağıdaki script' i `<head>` alanının sonuna ekleyin.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-İşte bu kadar. Kendini başlatması için yeterli.
-
-Gerçek ortamda kullanırken yeni çıkan sürümlerden kaynaklanabilecek bozukluklardan kaçınmak için bağlantıda versiyon numarasını tam olarak belirtmek önerilir.
-Örneğin, `2.8.2` (son sürüm) sürümünü kullanmak için:
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**Npm ile:** Npm kullanarak paketi yükleyin.
-```js
-npm i alpinejs
-```
-
-Kodunuza dahil edin.
-```js
-import 'alpinejs'
-```
-
-**IE11 desteği için** O halde aşağıdaki script' leri kullanın.
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-Yukarıdaki [module/nomodule üslubu](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) üslubu, modern tarayıcılarda otomatik olarak modern paketi, IE11 ve diğer eski tarayıcılarda ise ona uygun paketi yükleyecektir.
-
-## Kullanım
-
-*Dropdown/Modal Açılır menü ve pencere*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Menüyü Göster</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Menü İçeriği
-    </ul>
-</div>
-```
-
-*Tabs Sekmeler*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Foo Sekmesi</div>
-    <div x-show="tab === 'bar'">Bar Sekmesi</div>
-</div>
-```
-
-Basit olmayan yapılar için bile kullanabilirsiniz:
-*Daha hover event' i tetiklenirken açılır menünün içeriğini getirmeye başlayarak.*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## Öğrenme
-
-Sizin için 14 direktif var:
-
-| Direktif | Açıklaması |
-| --- | --- |
-| [`x-data`](#x-data) | Yeni bir bileşenin kapsamını tanımlar. |
-| [`x-init`](#x-init) | Bileşen başlar başlamaz bir ifadeyi çalıştırır. |
-| [`x-show`](#x-show) | (true or false) durumuna göre elemente `display: none;` özelliği ekler çıkarır. |
-| [`x-bind`](#x-bind) | JS ifadesinin sonucuna göre değişkene değer atar. |
-| [`x-on`](#x-on) | Elemente olay dinleyicisi ekler. Tetiklendiğinde JS ifadesini çalıştırır. |
-| [`x-model`](#x-model) | Elemente "çift yönlü bağlama" ekler. Bu input elementi ile bileşendeki datayı senkronize şekilde tutar. |
-| [`x-text`](#x-text) | 'x-bind' ile benzer çalışır, yalnız bu elementin `innerText` özelliğini günceller. |
-| [`x-html`](#x-html) | 'x-bind' ile benzer çalışır, yalnız bu elementin `innerHTML` özelliğini günceller. |
-| [`x-ref`](#x-ref) | İşlenmemiş DOM elementleri bileşeninizin dışından tekrar almak için kullanışlı bir yöntem. |
-| [`x-if`](#x-if) | Elementi DOM' dan tamamen kaldırır. `<template>` etiketi üzerinde kullanılması gerekir. |
-| [`x-for`](#x-for) | Dizideki her bir eleman için yeni DOM düğümü oluşturur. `<template>` etiketi üzerinde kullanılması gerekir. |
-| [`x-transition`](#x-transition) | Elementin çeşitli değişim aşamalarına sınıflar ekleyen direktifler. |
-| [`x-spread`](#x-spread) | Daha iyi yeniden kullanılabilirlik için Alpine direktifler nesnesini bir elemente bağlamanızı sağlar. |
-| [`x-cloak`](#x-cloak) | Bu özellik Alpine başlatıldığında kaldırılır. Önceden yüklenmiş DOM' u gizlemek için kullanışlıdır. |
-
-Ve altı sihirli özellik:
-
-| Sihirli Özellik | Açıklaması |
-| --- | --- |
-| [`$el`](#el) |  Kök bileşen DOM düğümünü getirir. |
-| [`$refs`](#refs) | Bileşen içindeki `x-ref` ile işaretlenmiş DOM elementlerini getirir. |
-| [`$event`](#event) | Olay dinleyicisine bağlı tarayıcıya ait "Event" nesnesini getirir. |
-| [`$dispatch`](#dispatch) | `CustomEvent` oluşturur ve dahili olarak `.dispatchEvent()` kullanıp gönderir. |
-| [`$nextTick`](#nexttick) | Alpine kendi reaktif DOM güncellemelerini yaptıktan SONRA verilen ifadeyi çalıştırır. |
-| [`$watch`](#watch) | "İzlediğiniz" bir bileşen özelliği değişir değişmez verilen bir callback fonksiyonu tetiklenecek. |
-
-
-## Sponsorlar
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**Logonuzun burada olmasını ister misiniz? [DM on Twitter](https://twitter.com/calebporzio)**
-
-## Topluluk Projeleri
-
-* [AlpineJS Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
-
-### Direktifler
-
----
-
-### `x-data`
-
-**Örnek:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**Yapı:** `<div x-data="[object literal]">...</div>`
-
-`x-data` yeni bileşenin kapsamını tanımlar. Framework' a akabindeki veri nesnesiyle yeni bir bileşen oluşturmasını söyler.
-
-Bunu Vue bileşenindeki `data` özelliği gibi düşünebilirsiniz.
-
-**Bileşenin Mantığını Ayırmak**
-
-Bileşenin veriyi (ve davranışı) yeniden kullanılabilir fonksiyonlara taşıyabilirsiniz:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **Bundler aracı kullananlar için**, Alpine.js global kapsamdaki (`window`) fonksiyonlara eriştiğinden, onları `x-data` ile kullanmak için açıkça `window`' a atamanız gerekir. Yani `window.dropdown = function () {}` şeklinde kullanmalısınız. (Bu durum, Webpack, Rollup, Parcel gibi bundler' lar kullandığınızda, tanımladığınız fonksiyonların `window` 'da değil de ilgili modülün kapsamında geçerli olmasından kaynaklanır.)
-
-
-Ayrıca nesne parçalama kullanarak birden çok veriyi karıştırabilirsiniz:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**Örnek:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**Yapı:** `<div x-data="..." x-init="[expression]"></div>`
-
-`x-init` bir bileşen başlar başlamaz bir ifadeyi çalıştırır.
-
-Eğer Alpine' ın DOM üzerindeki kendi başlangıç güncellemelerinden sonra bir kod parçası çalıştırmak istiyorsanız (VueJS' deki hayat döngüsü olaylarından biri olan `mounted()` olayı gibi), `x-init` 'dan bir geri çağırma fonksiyonu döndürebilir ve sonrasında çalıştırabilirsiniz:
-
-`x-init="() => { // DOM' un ilk kez yüklendikten sonraki durumuna burada erişebilirsiniz. // }"`
-
----
-
-### `x-show`
-**Örnek:** `<div x-show="open"></div>`
-
-**Yapı:** `<div x-show="[expression]"></div>`
-
-`x-show` ifadenin (true or false) olup olmamasına göre elemente `display: none;` özelliği ekler veya çıkarır. 
-
-**x-show.transition**
-
-`x-show.transition` CSS geçiş animasyonlarını kullanarak `x-show`' unuzu daha güzel hale getirmek için kullanışlı bir API' dir.
-
-```html
-<div x-show.transition="open">
-    Bu içerik görünürken ve kaybolurken geçiş animasyonuna sahip olacak.
-</div>
-```
-
-| Direktif | Açıklama |
-| --- | --- |
-| `x-show.transition` | Aynı anda solma efekti ve ölçeklendirme. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | Sadece içerik görünürken uygular. |
-| `x-show.transition.out` | Sadece içerik kaybolurken uygular. |
-| `x-show.transition.opacity` | Sadece solma efektini kullan. |
-| `x-show.transition.scale` | Sadece ölçeklendirme efektini kullan. |
-| `x-show.transition.scale.75` | CSS ölçeklendirme dönüşümünü `transform: scale(.75)` düzenler. |
-| `x-show.transition.duration.200ms` | Giriş süresini 200ms' ye ayarlar. Bu durumda çıkış onun yarısı olacaktır (100ms). |
-| `x-show.transition.origin.top.right` | CSS geçiş özelliğinin `transform-origin: top right` başlangıç noktasını düzenler. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | Giriş ve çıkış için ayrı ayrı süreler tanımlar. |
-
-> Not: Tüm bu geçişler birbirleriyle birlikte kullanılabilir. Note: All of these transition modifiers can be used in conjunction with each other. Aşırı komik olmasına rağmen bu mümkün: `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> Not: `x-show` tüm çocuk elementlerin çıkış animasyonlarını bitirmesini bekler. Eğer bunu istemiyorsanız `.immediate` belirtecini ekleyin:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> Not: Daha kısa sentaks ":" kullanmakta özgürsünüz: `:type="..."`.
-
-**Örnek:** `<input x-bind:type="inputType">`
-
-**Yapı:** `<input x-bind:[attribute]="[expression]">`
-
-`x-bind` bir JavaScript ifadesinin sonucunu bir özelliğe eşitler. Bu ifade bileşenin tüm verilerinin anahtarlarına erişimine sahiptir ve bileşenin datası her ne zaman güncellenirse o da güncellenecektir.
-
-> Not: özellik bağlamalar, sadece kendini ilgilendiren datalar güncellendiğinde güncellenir. Bu çatı, veri değişikliklerini izlemek ve hangi bağlamaların onları ilgilendiriğini anlamak için yeterince zekidir.
-
-**Sınıf özellikleri için `x-bind`**
-
-`x-bind` direktifi `class` özelliğine bağlandığında biraz farklı işlev görür.
-
-CSS sınıfları için bir veri nesnesi girersiniz. Bu nesnenin anahtarı sınıfın ismi iken, değeri ise sınıfın uygulanıp uygulanmayacağını belirleyen boolean ifadelerdir.
-
-Örneğin:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-Bu örnekte, "hidden" sınıfı sadece `foo` veri özelliği `true` olduğunda uygulanır.
-
-**Boolean özellikler için `x-bind`**
-
-`x-bind` değer özellikleriyle aynı şekilde boolean özelliklerini de destekler. Bunlar bir değişkenin şartlı durum olarak kullanılması veya herhangi bir Javascript ifadesinin `true` or `false` olarak döndürülmesidir.
-
-Örneğin:
-```html
-<!-- Verilen ifade: -->
-<button x-bind:disabled="myVar">Tıkla</button>
-
-<!-- myVar == true olduğunda: -->
-<button disabled="disabled">Tıkla</button>
-
-<!-- myVar == false olduğunda: -->
-<button>Tıkla</button>
-```
-
-Bu, `myVar` true ya da false olduğunda sırasıyla `disabled` özelliğini ekler veya kaldırır.
-
-[HTML specification](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute) 'e göre boolean ifadesinin hangi özelliklerde kullanılacağı görülebilir, örneğin `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, vb.
-
-> Not: `aria-*` gibi özelliklerin false durumunu göstermeniz gerekiyorsa özelliğe bağlama yaparken `.toString()` de kullanın. Örneğin: `isOpen` ister true olsun ister false olsun `:aria-expanded="isOpen.toString()"` görünmeye devam eder.
-
-**`.camel` belirteci**
-**Örnek:** `<svg x-bind:view-box.camel="viewBox">`
-
-`camel` belirteci özelliğinin adının deve notasyonuna karşılık gelen ifadeye bağlama yapar. Yukardaki örnekte, `viewBox` özelliği `view-box` ' a değil  `viewBox` 'a bağlanacak.
-
----
-
-### `x-on`
-
-> Not: Daha kısa sentaksı "@" kullanabilirsiniz: `@click="..."`.
-
-**Örnek:** `<button x-on:click="foo = 'bar'"></button>`
-
-**Yapı:** `<button x-on:[event]="[expression]"></button>`
-
-`x-on` tanımlandığı elemente bir olay dinleyici ekler. Bu olay tetiklendiği zaman, değeri olarak atanan Javascript ifadesi çalıştırılır. `x-on` özelliğini üzerine eklediğiniz elementin desteklediği bütün olayla için kullanabilirsiniz. Olayların tüm listesine ve muhtemel değerleri için [the Event reference on MDN](https://developer.mozilla.org/en-US/docs/Web/Events) adresine bakınız.
-
-Javascript ifadesinde herhangi bir data güncellenirse o dataya bağlı diğer element özellikleri de güncellenir.
-
-> Not: Ayrıca Javascript fonksiyon ismini de verebilirsiniz.
-
-**Örnek:** `<button x-on:click="myFunction"></button>`
-
-Yukardaki ifadeye denk: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` belirteçleri**
-
-**Örnek:** `<input type="text" x-on:keydown.escape="open = false">`
-
-Keydown belirteçlerini `x-on:keydown` direktifine ekleyip daha spesifik dinlemeler yapabilirsiniz. Bu belirteçler `Event.key` değerlerinin kebap notasyonu olduğuna dikkat edin.
-
-Örnekler: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> Not: Sistem-belirteci anahtar kombinasyonlarını da dinleyebilirsiniz: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` belirteci**
-
-**Örnek:** `<div x-on:click.away="showModal = false"></div>`
-
-`.away` belirteci kullanıldığında, olay yakalayıcı sadece kendi ve çocukları dışındaki bir kaynaktan gelen olayda çalıştırılır.
-
-Bu, açılır menü ve diyalog pencerelerinin dışına tıklandığında gizlenmesi için kullanışlıdır.
-
-**`.prevent` belirteci**
-**Örnek:** `<input type="checkbox" x-on:click.prevent>`
-
-Bir olay dinleyicisine `.prevent` eklemek tetiklenecek event üzerinde `preventDefault` çağırır. Yukarıdaki örneğe bakıldığında bu, kullanıcı checkbox 'a tıkladığında gerçek bir checked olayının gerçekleşmeyeceği anlamına gelir.
-
-**`.stop` belirteci**
-**Örnek:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-Bir olay dinleyicisine `.stop` eklemek tetiklenecek event üzerinde `stopPropagation` çağırır. Adding `.stop` to an event listener will call `stopPropagation` on the triggered event. Yukarıdaki örneğe bakıldığında bu, dıştaki `<div>` 'den gelen "click" olayının tetiklenmeyeceği anlamına gelir. Başka bir deyişle, kullanıcı butona bastığında `foo` özelliğine `'bar'` atanmayacak.
-
-**`.self` belirteci**
-**Örnek:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-Bir olay dinleyicisine `.self` eklersek  olay yakalayıcısını sadece `$event.target` kendisi olması durumunda tetikleyecek. Yukarıdaki örnekte bu, butondan kaynaklanan "click" olayının dış `<div>`' deki yakalayıcıyı **çalıştırmayacağı** anlamına gelir.
-
-**`.window` belirteci**
-**Örnek:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-Olay dinleyicisine `.window` eklemek onu tanımlandığı DOM düğümü üzerinde değil glonal window nesnesinde çalıştıracak.Bu, resize olayı gibi window'  da bazı değişiklikler olduğunda bileşenin durumunu düzenlemek için kullanışlıdır. Yukardaki örnekte, pencere genişliği 768 pikselden daha geniş olduğunda açılır menüyü kapatırız, aksi halde aynı kalır.
-
-> Not: Ayrıca dinleyicileri `window` yerine `document` 'e eklemek için `.document` belirtecini kullanabilirsiniz.
-
-**`.once` belirteci**
-**Örnek:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-Bir olay dinleyicisine `.once` belirtecini eklersek, dinleyicinin sadece bir kez çalışacağından emin oluruz. Bu, HTML kısımlar vb. şeyleri çekmek gibi sadece bir kez yapılmasını istediğiniz şeyler için kullanışlıdır.
-
-**`.passive` belirteci**
-**Örnek:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-`.passive` belirtecini bir olay dinleyicisine eklersek bu belirteç o dinleyiciyi pasif hale getirir. Bu da `preventDefault()` fonksiyonunun işletilecek hiç bir event üzerinde çalışmayacağı anlamına gelir. Bu dokunmatik cihazlardaki scroll performansları gibi durumlarda yardım edebilir.
-
-**`.debounce` belirteci**
-**Örnek:** `<input x-on:input.debounce="fetchSomething()">`
-
-`debounce` belirteci bir olay yakalayıcısına "dalgalı tıklama engelleyici" eklemenize izin verir. Başka bir deyişle, olay yakalayıcısı, son olayın tetiklenmesi üzerinden belli bir zaman geçmedikçe çalışmaz. Yakalayıcı tekrar çağrılmaya hazır olduğunda, en son ki yakalayıcı cağrısı çalışır.
-
-Varsayılan engelleme süresi 250 milisaniyedir.
-
-Bunu değiştirmek isterseniz, aşağıdaki gibi özel bir bekleme süresi belirtebilirsiniz:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` belirteci**
-**Örnek:** `<input x-on:event-name.camel="doSomething()">`
-
-`camel` belirteci, olay dinleyiciye olay isminin deve notasyonuna denk gelen ifadesini ekler. Yukarıdaki örnekte, `eventName` olayı element üzerinde tetiklendiğinde, ifade çalıştırılacak.
----
-
-### `x-model`
-**Örnek:** `<input type="text" x-model="foo">`
-
-**Yapı:** `<input type="text" x-model="[data item]">`
-
-`x-model` özelliği elemente "çift yönlü bağlama" ekler. Yani, input elementinin değeri bileşenin veri ögesiyle senkronize tutulur. 
-
-> Not: `x-model` metin girişleri, onay kutuları, radyo düğmeleri, metin alanları, seçimler ve çoklu seçimler üzerindeki değişiklikleri tespit edecek kadar zekidir. Bu [how Vue would](https://vuejs.org/v2/guide/forms.html) adresindeki senaryolara uygun çalışması gerekir.
-
-**`.number` belirteci**
-**Örnek:** `<input x-model.number="age">`
-
-`number` belirteci girişin değerini bir numaraya çevirir. Eğer giriş değeri geçerli bir numaraya çevrilemeyecekse, orijinal değer döndürülür.
-
-**`.debounce` belirteci**
-**Example:** `<input x-model.debounce="search">`
-
-The `debounce` belirteci bir değer güncellemesine bir "dalgalı tıklama engelleyici" ekler. Başka bir deyişle, olay yakalayıcısı, son olayın tetiklenmesi üzerinden belli bir zaman geçmedikçe çalışmaz. Yakalayıcı tekrar çağrılmaya hazır olduğunda, en son ki yakalayıcı cağrısı çalışır.
-
-Varsayılan engelleme süresi 250 milisaniyedir.
-
-Bunu değiştirmek isterseniz, aşağıdaki gibi özel bir bekleme süresi belirtebilirsiniz:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**Örnek:** `<span x-text="foo"></span>`
-
-**Yapı:** `<span x-text="[expression]"`
-
-`x-text` direktifi `x-bind` ile benzer şekilde çalışır. Tek fark, `x-text` bir özelliğin değerini güncellemek yerine, bir elementin `innerText` özelliğini günceller.
-
----
-
-### `x-html`
-**Örnek:** `<span x-html="foo"></span>`
-
-**Yapı:** `<span x-html="[expression]"`
-
-`x-html` direktifi `x-bind` ile benzer şekilde çalışır. Tek fark, `x-text` bir özelliğin değerini güncellemek yerine, bir elementin `innerHTML` özelliğini günceller.
-
-> :uyarı: **Yalnızca güvenilir içerikte kullanın ve asla kullanıcı tarafından sağlanan içerikte kullanmayın.** :uyarı:
->
-> Üçüncü şahıslardan gelen HTML' in dinamik olarak işlenmesi açıkça [XSS](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) zaaflarına yol açabilir.
-
----
-
-### `x-ref`
-**Örnek:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**Yapı:** `<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` bileşeninizin dışından işlenmemiş DOM elementlerini getirmek için kullanışlı bir yoldur. Bir element üzerinde `x-ref` kullanarak,onu, `$refs` denilen bir nesne içinde, tüm olay yakalayıcılarına erişebilir kılarsınız.
-
-Bu bir elemente "id" ler atayıp `document.querySelector` ile her yerden erişme mantığına yardımcı bir alternatiftir.
-
-> Not: Ayrıca ihtiyacınız olduğunda x-ref' e dinamik değerler `<span :x-ref="item.id"></span>` verebilirsiniz.
-
----
-
-### `x-if`
-**Örnek:** `<template x-if="true"><div>Some Element</div></template>`
-
-**Yapı:** `<template x-if="[expression]"><div>Some Element</div></template>`
-
-`x-show` 'in yetersiz olduğu durumlarda (`x-show` değeri false ise elemente `display: none` özelliği ekler), bir elementi tamamıyla DOM 'dan silmek için `x-if` kullanılabilir.
-
-Alpine sanal DOM mantığını kullanmadığı için `x-if` 'in `<template></template>` etiketiyle kullanıldığına dikkat edin. Bu uygulama Alpine 'nın kararlı kalmasını ve büyüsünü gerçekleştirmek için gerçek DOM 'u kullanmasını sağlar.
-
-> Not: `x-if` direktifi `<template></template>` etiketi içindeki tek bir kök element için kullanılması gerekir.
-
-> Not: Bir `svg` etiketi içinde `template` kullanacaksanız, Alpine.js başlatılmadan önce bir [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) eklemeniz gerekir.
-
----
-
-### `x-for`
-**Örnek:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> Not: `:key` ile atama isteğe bağlıdır ama Note: the `:key` binding is optional, ama ŞİDDETLE tavsiye edilir.
-
-Bir dizinin her bir elemanı için yeni bir DOM düğümü oluşturmak istediğiniz durumlar için `x-for` vardır. Bu Vue 'deki `x-for` etiketine benzerdir. Tek fark, Alpine bu direktifi normal bir DOM elementi üzerinde kullanamaz. Bunun için bir `template` etiketinin varlığına ihtiyaç duyar.
-
-Eğer iterasyonun o anki indeksine erişmek istiyorsanız aşağıdaki sentaksı kullanın:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- İhtiyacanız olduğunda iterasyon içinde "index" 'i ayrıca referans olarak gösterebilirsiniz. -->
-    <div x-text="index"></div>
-</template>
-```
-
-Bir nesne dizisinin (koleksiyon) iterasyonuna erişmek istiyorsanız aşağıdaki sentaksı kullanın:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <!-- İhtiyacınız olduğunda iterasyon içinde ayrıca "collection" 'a referans gösterebilirsiniz. -->
-    <!-- Geçerli öge. -->
-    <div x-text="item"></div>
-    <!-- Üsteki ile aynı. -->
-    <div x-text="collection[index]"></div>
-    <!-- Bir önceki öge. -->
-    <div x-text="collection[index - 1]"></div>
-</template>
-```
-
-> Not: `x-for` etiketi `<template></template>` etiketi içindeki tek bir kök element için kullanılması gerekir.
-
-> Not: Bir `svg` etiketi içinde `template` kullanacaksanız, Alpine.js başlatılmadan önce bir [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) eklemeniz gerekir.
-
-#### İç içe `x-for` lar
-İç içe `x-for` döngüleri kullanabilirsiniz; ama her bir döngüyü bir elemente sarmanız ŞARTTIR. Örneğin:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### Bir aralık üzerinde iterasyon (yineleme)
-
-Alpine `n` bir tam sayı olduğu durumlar için `i in n` sentaksını destekler. Bu belirlenmiş bir dizi eleman üzerinde dolaşmanızı sağlar.
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**Örnek:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> Yukarıdaki örnek [Tailwind CSS](https://tailwindcss.com) 'daki sınıfları kullanıyor.
-
-Alpine, bir elementin "hidden" ve "shown" durumları arasındaki çeşitli aşamalara uygulamak için 6 farklı geçiş direktifi sunar. Bu direktifler hem `x-show` hem de `x-if` ile çalışır.
-
-Bunlar farklı ve daha mantıklı isimli olmaları dışında, tam olarak VueJS 'in geçiş direktifleri gibi çalışır:
-
-| Direktif | Açıklama |
-| --- | --- |
-| `:enter` | Giriş aşaması boyunca uygulanır. |
-| `:enter-start` | Element yerleştirilmeden önce eklenir ve yerleştikten bir kare sonra kaldırılır. |
-| `:enter-end` | Element yerleştirildikten bir kare sonrası eklenir (aynı anda `enter-start` kaldırılır), geçiş/animasyon bittiğinde kaldırılır.
-| `:leave` | Ayrılma aşaması boyunca uygulanır.
-| `:leave-start` | Bir ayrılma geçişi tetiklenir tetiklenmez eklenir ve bir kare sonrası kaldırılır. |
-| `:leave-end` | Bir ayrılma geçişi tetiklendikten bir kare sonrasında eklenir (aynı anda `leave-start` kaldırılır), geçiş/animasyon bittiğinde kaldırılır.
-
----
-
-### `x-spread`
-**Örnek:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Menüyü aç</button>
-
-    <span x-spread="dialogue">Menü içeriği</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` direktifi, bir elementin Alpine bağlamalarını yeniden kullanılabilir bir nesneye çıkarmanızı sağlar.
-
-Bu nesne anahtarları birer direktiflerdir (Belirteçler içeren herhangi bir direktif olabilir) ve değerleri Alpine tarafından çalıştırlabilecek geri çağırma fonksiyonlarıdır.
-
-> Not: x-spread için dikkat etmeniz gereken birkaç nokta var:
-> - "spread" edilecek direktif `x-for` olduğu zaman, fonksiyondan düz bir string ifade döndürmeniz gerekir. Örneğin: `['x-for']() { return 'item in items' }`
-> - `x-data` ve `x-init` ise bir "spread" nesnesinde kullanılamaz.
-
----
-
-### `x-cloak`
-**Örnek:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` özellikleri, Alpine başlatılır başlatılmaz elementlerden kaldırılır. Bu önceden yüklenmiş DOM 'u gizlemek için kullanışlıdır. attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. Bunun çalışması için yaygın kullanım, aşağıdaki global stili eklemektir.
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### Sihirli Özellikler
-
-> `$el` hariç diğer sihirli özellikler, bileşen henüz başlatılmadığı için **`x-data` içinde kullanılamaz**.
-
----
-
-### `$el`
-**Örnek:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Beni "foo" ile yer değiştir</button>
-</div>
-```
-
-`$el`, kök DOM düğümünü getirmek için kullanılan bir sihirli özelliktir.
-
-### `$refs`
-**Örnek:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` bileşen içinde `x-ref` ile işaretlenmiş DOM elementlerini getirmek için kullanılan sihirli bir özelliktir. Bu, DOM elementlerini manuel olarak işlemeniz gerektiğinde kullanışlıdır.
-
----
-
-### `$event`
-**Örnek:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` tarayıcının kendi "Event" nesnesini getirmek için bir olay dinleyici içinde kullanılabilir.
-
-> Not: $event özelliği yalnızca DOM ifadelerinde kullanılabilir.
-
-Eğer $event 'a bir JavaScript fonksiyonu içinde erişmek istiyorsanız doğrudan parametre olarak verebilirsiniz:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**Örnek:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- Tıklandığında console.log "bar" durumuna dönüşecek -->
-</div>
-```
-
-**Olay yayılımı üzerine notlar**
-
-[olay köpürme](https://en.wikipedia.org/wiki/Event_bubbling) 'den dolayı dikkat edin; aynı hiyerarşik seviyeden dağıtılan olayları yakalamanız gerektiğinde, [`.window`](https://github.com/alpinejs/alpine#x-on) belirtecini kullanmanız gerekir.
-
-**Örnek:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> Yukarıdaki örnek çalışmayacaktır; çünkü `custom-event` event dağıtıldığında ortak ataları olan `div` 'e yayılacak.
-
-**Bileşenlere Dağıtmak**
-
-Bileşenleri birbiriyle konuşturmak için bir önceki teknikten de faydalanabilirsiniz.
-
-**Örnek:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- Tıklandığında console.log "Hello World!" durumuna dönüşecek. -->
-```
-
-`$dispatch`, bir `CustomEvent` oluşturmanın ve dahili olan `dispatchEvent()` fonksiyonunu kullanarak onu iletmenin kısa yoludur. Özel olayları kullanarak bileşenlerde ve birbirleri arasında veri göndermenin birçok yararlı kullanım durumları vardır. Tarayıcılardaki `CustomEvent` sisteminin altında yatan daha fazla bilgi için [Bakınız](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events).
-
-Dikkat edeceğiniz nokta; `$dispatch('some-event', { some: 'data' })` için ikinci parametre olarak verdiğiniz herhangi bir data, yeni bir olayın "detail" özelliğiyle erişilebilir hale gelir:`$event.detail.some`. Özel olay verisinin `detail` özelliğine eklenmesi tarayıcılardaki `CustomEvent` 'lar için standart bir uygulamadır. Daha fazla bilgi için [Bakınız](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)
-
-Ayrıca `x-model` bağlamaları için veri güncellemelerini tetiklemekte `$dispatch()` 'i kullanabilirsiniz. Örneğin:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- Butona tıklandığında, `x-model` köpüren "input" olayını yakalar ve foo 'yu "baz" olarak günceller. -->
-    </span>
-</div>
-```
-
-> Not: Bu $dispatch özelliği yalnızca DOM ifadelerinde kullanılabilir.
-
-Eğer $dispatch 'a bir JavaScript fonksiyonu içinde erişmek istiyorsanız doğrudan parametre olarak verebilirsiniz:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**Örnek:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick`, verilen bir ifadeyi sadece, Alpine 'nın kendi reaktif DOM güncellemelerini yaptıktan SONRA çalıştırmanıza olanak sağlayan sihirli bir özelliktir. Bu, yaptığınız herhangi bir güncellemenin yansıltılmasından sonraki DOM durumuyla iletişim kurmak istediğinizde kullanışlıdır.
-
----
-
-### `$watch`
-**Örnek:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Aç Kapa</button>
-</div>
-```
-
-`$watch` sihirli metoduyla bir bileşen özelliğini "izleye" bilirsiniz. Yukarıdaki örnekte, butona tıklanıp `open` değiştiğinde, verilen geri çağırma fonksiyonu ateşlenir ve yeni değer `console.log` ile basılır.
-
-## Güvenlik
-Eğer güvenlik zaafları bulursanız lütfen [calebporzio@gmail.com]() adresine gönderin.
-
-Alpine kendi direktiflerini çalıştırmak için `Function` nesnesinin özel bir uygulamasına dayanır. `eval()` fonksiyonundan daha güvenli olmasına rağmen, Google Chrome App gibi sınırlandırılmış İçerik Güvenliği Politikası (İGP) kullanan bazı ortamlarda kullanımı yasaktır.
-
-Eğer Alpine 'ı hassas verilerle ilgilenen ve [CSP](https://csp.withgoogle.com/docs/strict-csp.html) gerektiren bir sitede kullanırsanız, politikanıza `unsafe-eval` 'i dahil etmeniz gerekir. Doğru şekilde yapılandırılmış sağlam bir politika, kişisel veya finansal verileri kullanırken kullanıcılarınızın korunmasına yardımcı olacaktır.
-
-Bu politika, sayfanızdaki tüm kodlara uygulanacağından, sitenize eklediğiniz diğer dış kütüphanelerin güvenilir olduklarını ve sayfanıza ya `eval()` fonksiyonunu kullanarak ya da zararlı kod enjekte edip DOM 'u yöneterek Siteler Arası Betik Çalıştırma zaafını uygulamadığından emin olmak için söz konusu bu kütüphaneleri dikkatlice gözden geçirmek önemlidir.
-
-## V3 Yol Haritası
-* Vue benzerliği için "x-ref" ten "ref" e geçilsin mi?
-* `Alpine.directive()` Eklemek
-* `Alpine.component('foo', {...})` Eklemek (Sihirli `__init()` metoduyla birlikte)
-* "loaded", "transition-start" vb. için Alpine olaylarını iletmek... ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* `x-bind:class="{ 'foo': true }"` 'dan "object" (ve array) sentaksını kaldırmak ([#236](https://github.com/alpinejs/alpine/pull/236) `style` özelliği için nesne sentaksını desteklemek)
-* `x-for` reaktif değişimi geliştirmek ([#165](https://github.com/alpinejs/alpine/pull/165))
-* V3 'te "derin izleme" desteği eklemek ([#294](https://github.com/alpinejs/alpine/pull/294))
-* `$el` kısayolu eklemek
-* `@click.away` 'i `@click.outside` olarak değiştirmek?
-
-## Lisans
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-MIT lisansı altında lisanslanmıştır, detaylar için [LICENSE.md](LICENSE.md) 'e bakınız.

+ 0 - 783
README.zh-CN.md

@@ -1,783 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js 通过很低的成本提供了与 Vue 或 React 这类大型框架相近的响应式和声明式特性。
-
-你可以继续操作 DOM,并在需要的时候使用 Alpine.js。
-
-可以理解为 JavaScript 版本的 [Tailwind](https://tailwindcss.com/)。
-
-> 备注:Alpine.js 的语法几乎完全借用自 [Vue](https://vuejs.org/) (并用 [Angular](https://angularjs.org/) 的语法做了些扩展)。在此由衷感谢他们对 Web 世界的贡献。
-
-## 安装 Install
-
-**使用 CDN:** 把以下脚本加入到你的 `<head>` 尾部.
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-就是这样,Alpine.js 会自行初始化。
-
-生产环境中,建议在链接中锁定特定版本号,以此避免新版本中的变更造成问题。
-例如,锁定版本为 `2.8.2` (最新版本):
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**使用 npm:** 从 npm 安装依赖包。
-```js
-npm i alpinejs
-```
-
-并在你的脚本中引入它。
-```js
-import 'alpinejs'
-```
-
-**需要 IE11 支持的场景** 改用这段脚本。
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-这一写法使用了 [module/nomodule 模式(英文)](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) ,这样的写法可以让现代浏览器自动加载模块版本依赖,而在 IE11 或其他早期浏览器中自动加载专属兼容版本。
-
-## 使用 Use
-
-*下拉菜单(Dropdown)/模态弹窗(Modal)*
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">Open Dropdown</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        Dropdown Body
-    </ul>
-</div>
-```
-
-*标签页 Tabs*
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">Tab Foo</div>
-    <div x-show="tab === 'bar'">Tab Bar</div>
-</div>
-```
-
-这样的写法也可以用在其他地方:
-*鼠标悬停时从服务器预加载下拉菜单中的 HTML 内容。*
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >Show Dropdown</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        Loading Spinner...
-    </div>
-</div>
-```
-
-## 学习 Learn
-
-当前共有 14 个指令可用,如下所示:
-
-| 指令 | 描述 |
-| --- | --- |
-| [`x-data`](#x-data) | 定义一个新的组件作用域。 |
-| [`x-init`](#x-init) | 组件初始化时运行其中的表达式。 |
-| [`x-show`](#x-show) | 根据表达式结果(true 或 false)控制元素的 `display: none;`(译者注:控制模块显示/隐藏) |
-| [`x-bind`](#x-bind) | 将当前属性的值设定为指令中表达式的结果。 |
-| [`x-on`](#x-on) | 向元素上挂载事件监听器。当事件触发时执行其中的表达式。 |
-| [`x-model`](#x-model) | 向当前元素新增「双向数据绑定」。保持输入元素与组件数据同步。 |
-| [`x-text`](#x-text) | 和 `x-bind` 类似,但更新的是元素的 `innerText`。 |
-| [`x-html`](#x-html) | 和 `x-bind` 类似,但更新的是元素的 `innerHTML`。 |
-| [`x-ref`](#x-ref) | 在组件外获取原始 DOM 元素的简便方法。 |
-| [`x-if`](#x-if) | 值为 false 时将从 DOM 中完全移除元素。需要在 `<template>` 标签中使用。 |
-| [`x-for`](#x-for) | 为数组中的每一项创建一个新的 DOM 节点。需要在 `<template>` 标签中使用。 |
-| [`x-transition`](#x-transition) | 用于在过渡(CSS Translation)的各个阶段中为元素添加 class 的指令。 |
-| [`x-spread`](#x-spread) | 为了更好的复用,可以绑定一个带有 Alpine 指令(作为 key)的对象到元素上。 |
-| [`x-cloak`](#x-cloak) | 这一属性会在 Alpine 初始化完成后被移除,可以用来隐藏未初始化的 DOM。 |
-
-以及 6 个魔法属性:
-
-| 魔法属性 | 描述 |
-| --- | --- |
-| [`$el`](#el) | 获取根元素的 DOM 节点。 |
-| [`$refs`](#refs) | 获取组件中标记有 `x-ref` 的 DOM 元素。 |
-| [`$event`](#event) | 在事件监听器中获取浏览器原生的「Event」对象。 |
-| [`$dispatch`](#dispatch) | 创建一个「CustomEvent」并使用其内部的 `.dispatchEvent()` 方法进行分发。 |
-| [`$nextTick`](#nexttick) | 在 Alpine 做出响应式 DOM 更新后,执行一个给出的表达式。 |
-| [`$watch`](#watch) | 当监听的组件属性发生变化时,触发给定的回调函数。 |
-
-
-## 赞助商 Sponsors
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**想让你的 Logo 也出现在这? [到 Twitter 发送 DM](https://twitter.com/calebporzio)**
-
-## 社区相关项目 Community Projects
-
-* [AlpineJS 周报(英文)](https://alpinejs.codewithhugo.com/newsletter/)
-* [Spruce (状态管理框架/英文)](https://github.com/ryangjchandler/spruce)
-* [Turbolinks Adapter(英文)](https://github.com/SimoTod/alpine-turbolinks-adapter)
-* [Alpine Magic Helpers(英文)](https://github.com/KevinBatdorf/alpine-magic-helpers)
-* [Awesome Alpine(英文)](https://github.com/ryangjchandler/awesome-alpine)
-
-### 指令 Directives
-
----
-
-### `x-data`
-
-**例如:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**结构:** `<div x-data="[可迭代对象]">...</div>`
-
-`x-data` 将定义一个新的组件作用域。它将通知框架初始化带有传入数据的一个新组件。
-
-类似 Vue 组件中的 data 属性。
-
-**抽离组件逻辑**
-
-你可以把数据(以及行为)通过一个可复用的函数抽离出来:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">Open</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // Dropdown
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **各位 Bundler 使用者**,注意 Alpine.js 操作的函数都在全局作用域(`window`),你需要把 `x-data` 使用的函数声明到 `window` 上,例如 `window.dropdown = function () {}` (因为在 Webpack, Rollup, Parcel 等工具中,`function` 默认会被挂载模块作用域,而非 `window`).
-
-你也可以通过对象解构语法,把多个数据对象混合起来:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**例如:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**结构:** `<div x-data="..." x-init="[表达式]"></div>`
-
-`x-init` 将在组件初始化时运行给定的表达式。
-
-如果你希望代码在 Alpine 对 DOM 进行初始化更新后再调用(类似 VueJS 中的 `mounted()` 钩子),你可以传入一个回调函数,它将在 DOM 操作完成后被调用,例如:
-
-`x-init="() => { // we have access to the post-dom-initialization state here // }"`
-
----
-
-### `x-show`
-**例如:** `<div x-show="open"></div>`
-
-**结构:** `<div x-show="[表达式]"></div>`
-
-`x-show` 将根据表达式结果(true 或 false)控制元素的 `display: none;`(译者注:控制模块显示/隐藏)
-
-**x-show.transition**
-
-`x-show.transition` 是一个可以让你在使用 `x-show` 操作 CSS 过渡(Transition)时更爽的简便 API。
-
-```html
-<div x-show.transition="open">
-    这段内容会在过渡中滑入/滑出。
-</div>
-```
-
-| 指令 | 描述 |
-| --- | --- |
-| `x-show.transition` | 同时滑入/滑出并缩放(默认值:opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | 仅滑入 |
-| `x-show.transition.out` | 仅滑出 |
-| `x-show.transition.opacity` | 仅使用淡入淡出 |
-| `x-show.transition.scale` | 仅使用缩放 |
-| `x-show.transition.scale.75` | 自定义 CSS 缩放转换为 `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | 设定 "in" 的的过渡时间为 200ms。出动作("out")将是它的一半 (100ms). |
-| `x-show.transition.origin.top.right` | 自定义 CSS 转换起始位置为 `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | 为 "in" 和 "out" 设定不同的过渡时间。 |
-
-> 备注: 所有的过渡修饰符都可组合使用。也就是说可以这么用(虽然真这么用过于粗暴23333): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> 备注: `x-show` 将等待子元素完成 out。如果你希望跳过这一行为,可以添加 `.immediate` 修饰符:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> 备注:可以用 ":" 简写语法替代,例如: `:type="..."`.
-
-**例如:** `<input x-bind:type="inputType">`
-
-**结构:** `<input x-bind:[HTML属性]="[表达式]">`
-
-`x-bind` 将当前属性的值设定为指令中表达式的结果。 这一表达式可以访问组件数据对象中的所有 key,并在每次数据更新时重算结果。
-
-> 备注: 属性数据绑定只会在依赖的值更新时被重算。框架足够智能,可以观测数据变化并检测绑定是否关心这些变化。
-
-**`x-bind` 到 class 属性**
-
-`x-bind` 在完成到 `class` 属性的绑定时,行为略有不同。
-
-对于 class,你可以传入一个对象,key 为 class 名,值为布尔量,用来表示对应 class 是否应该生效。
-
-例如:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-在这一例子中,"hidden" 这一 class 将只会在 foo 数据属性为 `true` 时有效。
-
-**`x-bind` 到布尔值属性**
-
-`x-bind` 支持布尔值属性,与其他 value 属性一样,使用变量或者其他结果为 `true` 或 `false` 的表达式作为其条件。
-
-例如:
-```html
-<!-- 给定值: -->
-<button x-bind:disabled="myVar">Click me</button>
-
-<!-- 当 myVar == true: -->
-<button disabled="disabled">Click me</button>
-
-<!-- 当 myVar == false: -->
-<button>Click me</button>
-```
-
-这将在 `myVar` 为 true 或 false 时分别新增或删除 `disabled` 属性。
-
-[HTML specification 文档(英文)](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute)中列出的布尔值属性都被支持,例如: `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open` 等等。
-
-> 备注:如果你需要一个 false 状态来展示你的属性,如:`aria-*`,要用对绑定值使用链式的 `.toString()`。例如: `:aria-expanded="isOpen.toString()"` 将在 `isOpen` 为 `true` 或 `false` 时都能保持属性存在。
-
-**`.camel` 修饰符**
-**例如:** `<svg x-bind:view-box.camel="viewBox">`
-
-`camel` 修饰符用来绑定等效驼峰写法的属性名。如上面的例子,`viewBox` 的值将被绑定到 `viewBox` 属性,他被表示为 `view-box`。
-
----
-
-### `x-on`
-
-> 备注:你可以直接使用简化的 "@" 语法,例如:`@click="..."`。
-
-**例如:** `<button x-on:click="foo = 'bar'"></button>`
-
-**结构:** `<button x-on:[事件]="[表达式]"></button>`
-
-`x-on` 挂载一个事件监听器到声明的元素昂,当事件触发后,传入的表达式将被执行。你可以在指令所在元素可用的任何事件上使用 `x-on`,完整的事件列表,可以参考 [MDN 上的事件参考文档](https://developer.mozilla.org/en-US/docs/Web/Events)。
-
-如果表达式中的进行了任何数据变动,其他绑定到这些数据的元素属性将被更新。
-
-> 备注:你也可以直接使用 JavaScript 函数名。
-
-**例如:** `<button x-on:click="myFunction"></button>`
-
-这等效于:`<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` 修饰符**
-
-**例如:** `<input type="text" x-on:keydown.escape="open = false">`
-
-你可以通过向 `x-on:keydown` 指令增加 keydown 修饰符来指定特定需要监听的按钮。注意修饰符是 `Event.key` 值的短横线隔开写法(kebab-cased)版本。
-
-例如:`enter`, `escape`, `arrow-up`, `arrow-down`
-
-> 备注:你也可以这样监听混合的系统修饰符: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` 修饰符**
-
-**例如:** `<div x-on:click.away="showModal = false"></div>`
-
-当 `.away` 修饰符存在时,事件处理器将在源头不是他们自己或他们的子元素时被触发。
-
-这对下拉菜单或模态框中处理用户点击其外部的位置关闭的交互动作非常有用。
-
-**`.prevent` 修饰符**
-**例如:** `<input type="checkbox" x-on:click.prevent>`
-
-增加 `.prevent` 到事件监听器上,将会调用触发事件的 `preventDefault` 方法。在上面的例子中,这意味着这个 checkbox 在用户点击时不会真的被选中。
-
-**`.stop` 修饰符**
-**例如:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-增加 `.stop` 到事件监听器上,将会调用触发事件的 `stopPropagation` 方法。在上面的例子中,这意味着点击事件不会从这个按钮冒泡到其他 div 上。换句话说,用户点击按钮时 `foo` 并不会被置为 `bar`。
-
-**`.self` 修饰符**
-**例如:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-增加 `.self` 到事件监听器上,将会使得处理器只在 `$event.target` 为元素自己的时候被调用。在上面的例子中,这意味着按钮的点击事件会冒泡的上层的 `<div>` 时,将 **不会** 调用处理器函数。
-
-**`.window` 修饰符**
-**例如:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-增加 `.window` 到事件监听器上,将会安装监听器到全局的 window 对象而不是实际声明的 DOM 节点。当你需要在 window 上的属性变化(如 resize 事件)时修改自己组件的状态,这会非常有用。在例子中,当窗口宽度扩大到 768 像素以上时我们就会关闭模态框/下拉菜单,否则保持已有状态。
-
->备注:你也可以使用 `.document` 修饰符来挂载监听器到`document` 而不是 `window`
-
-**`.once` 修饰符**
-**例如:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-增加 `.once` 修饰符到事件监听器上,将会确保监听器只被调用一次。这对于那些你只想调一次的事件来说超有用,比如请求 HTML 片段之类的。
-
-**`.passive` 修饰符**
-**例如:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-增加 `.passive` 修饰符到事件监听器上,将会使监听器为 passive 状态,这意味着 `preventDefault()`不能工作。这可以帮助处理触摸设备上的滑动性能问题。
-
-**`.debounce` 修饰符**
-**例如:** `<input x-on:input.debounce="fetchSomething()">`
-
-`debounce` 修饰符允许你对事件处理器进行「防抖」。换句话说,事件处理器将会在上次触发完成后等待一段时间才会再次触发。当处理器准备好后再处理上一个调用。
-
-默认的防抖「等待」时间是 250 毫秒。
-
-如果你打算自定义它,可以这样指定:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` 修饰符**
-**例如:** `<input x-on:event-name.camel="doSomething()">`
-
-`camel` 修饰符用来挂载等效驼峰写法的事件监听器。如上面的例子,表达式将在 `eventName` 事件触发时被执行。
-
----
-
-### `x-model`
-**例如:** `<input type="text" x-model="foo">`
-
-**结构:** `<input type="text" x-model="[data item]">`
-
-`x-model` 新增「双向数据绑定」到一个元素上。换句话说,输入元素的 value 值将于组件中数据项的值维持同步。
-
-> 备注:`x-model` 可以智能地检测文字输入框(input)、多选框(checkbox)、单选框(radio button)、文本输入区(textarea)、下拉选择(select)、下拉多选(multi selects)。他的行为及使用场景和 [Vue](https://vuejs.org/v2/guide/forms.html) 别无二致。
-
-**`.number` 修饰符**
-**例如:** `<input x-model.number="age">`
-
-`number` 修饰符将转换输入的值为数据为数字类型,如果不能被成功转换,将返回原始值。
-
-**`.debounce` 修饰符**
-**例如:** `<input x-model.debounce="search">`
-
-`debounce` 修饰符允许你对值的更新进行「防抖」。换句话说,事件处理器将会在上次触发完成后等待一段时间才会再次触发。当处理器准备好后再处理上一个调用。
-
-默认的防抖「等待」时间是 250 毫秒。
-
-如果你打算自定义它,可以这样指定:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**例如:** `<span x-text="foo"></span>`
-
-**结构:** `<span x-text="[表达式]"`
-
-`x-text` 与 `x-bind` 十分相似,只不过当属性中的值更新时,他会更新元素的 `innerText`。
-
----
-
-### `x-html`
-**例如:** `<span x-html="foo"></span>`
-
-**结构:** `<span x-html="[表达式]"`
-
-`x-html` 与 `x-bind` 十分相似,只不过当属性中的值更新时,他会更新元素的 `innerHTML`。
-
-> :warning: **只能用在可信内容上,绝不要直接展示用户的内容** :warning:
->
-> 动态渲染第三方来源的 HTML 会非常容易造成 [XSS 漏洞(英文)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)。
-
----
-
-### `x-ref`
-**例如:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**结构:** `<div x-ref="[ref 名称]"></div><button x-on:click="$refs.[ref 名称].innerText = 'bar'"></button>`
-
-`x-ref` 提供了一种在组件外获取原始 DOM 元素的简便方法。通过设置元素上的 `x-ref` 属性,你可在任何事件处理中通过内置对象(魔法属性) `$refs` 和标记的 refName 拿到 DOM。
-
-它可以帮助你在任何地方替代设置id再通过 `document.querySelector` 取值的做法。
-
-> 备注:如果你需要,也可以绑个动态值到 x-ref `<span :x-ref="item.id"></span>`。
-
----
-
-### `x-if`
-**例如:** `<template x-if="true"><div>Some Element</div></template>`
-
-**结构:** `<template x-if="[表达式]"><div>Some Element</div></template>`
-
-有的时候,`x-show` 可能会不太好用(它会在值为 false 时为元素增加 `display: none` 样式),`x-if` 可以真实的完整的把元素从 DOM 中删除。
-
-但要注意,`x-if` 只能在 `<template></template>` 标签中使用,因为 Alpine 没有使用虚拟 DOM。这一实现允许 Alpine 保持简洁,直接使用真实的 DOM 来完成动态部分(magic)。
-
-> 备注:`x-if` 要求在 `<template></template>` 标签中有单一的根元素。
-
-> 备注:当在 `svg` 标签中使用 `template` 的时候,你需要增加 [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) 在初始化 Alpine 之前运行它。
-
----
-
-### `x-for`
-**例如:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> 备注:`:key` 绑定时可选的,但是强烈推荐,使用它在列表渲染中是必要的。
-
-`x-for` 可以用于为数组中的每一项创建一个新的 DOM 节点。这一特性与 Vue 中的 `v-for` 非常类似,他也需要在 `template` 标签上使用,不能是普通的 DOM 元素。
-
-如果需要使用当前迭代中的索引,可以这样写:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- 你可以在需要时直接使用索引值 index。 -->
-    <div x-text="index"></div>
-</template>
-```
-
-若果你需要在迭代中访问原始数组对象,可以这样写:
-
-```html
-<template x-for="(item, index, collection) in items" :key="index">
-    <div>
-        <!-- 你可以在需要时直接使用数组原始值 collection。 -->
-        <!-- 当前项 -->
-        <div x-text="item"></div>
-        <!-- 和上一行效果一致 -->
-        <div x-text="collection[index]"></div>
-        <!-- 上一项 -->
-        <div x-text="collection[index - 1]"></div>
-    </div>
-</template>
-```
-
-> 备注:`x-for` 要求在 `<template></template>` 标签中有单一的根元素。
-
-> 备注:当在 `svg` 标签中使用 `template` 的时候,你需要增加 [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538) 在初始化 Alpine 之前运行它。
-
-#### 嵌套 `x-for`
-可以嵌套使用 `x-for` 循环,但是你必须为每个循环外面都包裹一个元素,如下:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
-#### 范围内迭代
-
-Alpine 支持 `i in n` 语法,当 n 是整数时,就可以完成在一个固定范围内迭代的目标了。
-
-```html
-<template x-for="i in 10">
-    <span x-text="i"></span>
-</template>
-```
-
----
-
-### `x-transition`
-**例如:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> 这个例子使用了 [Tailwind CSS](https://tailwindcss.com) 中提供的 class。
-
-Alpine 提供了 6 个不同的过渡指令用来在元素过渡(Transition)的显示/隐藏状态下不同阶段生效不同的 class。这些指令都能和 `x-show` 还有 `x-if` 一起使用。
-
-这些行为与 VueJS 的过渡指令完全一致。只是用了更清晰的命名。
-
-| 指令 | 描述 |
-| --- | --- |
-| `:enter` | 在整个 Enter 阶段都生效 |
-| `:enter-start` | 在元素被插入前生效,在元素被插入的后1帧被删除 |
-| `:enter-end` | 在元素被插入后1帧(`enter-start` 被移除的同时)生效,在过渡/动画结束后被删除 |
-| `:leave` | 在整个 Leave 阶段都生效 |
-| `:leave-start` | 在 Leave 过渡触发后立即生效,1帧即被删除 |
-| `:leave-end` | 在 Leave 过渡触发后(`leave-start` 删除的同时)1 帧新增,并在过渡/动画结束时删除。|
-
----
-
-### `x-spread`
-**例如:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">Open Dropdown</button>
-
-    <span x-spread="dialogue">Dropdown Contents</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` 允许你展开一个可以复用的对象,其中包括元素的 Alpine 绑定。
-
-这一对象的 key 是指令(当然也可以包括修饰符),value 是可被 Alpine 执行的回调。
-
-> 备注: x-spread 有以下两点需要注意
-> - 当被展开的指令是 `x-for` 时,你需要在回调中返回一个表达式字符串,如:`['x-for']() { return 'item in items' }`.
-> - `x-data` 和 `x-init` 不能在「spread」对象中使用。
-
----
-
-### `x-cloak`
-**例如:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` 属性将在 Alpine 初始化后被移除。这对于隐藏未初始化完毕的 DOM 非常有效,一种典型的通过全局样式的工作方式如下:
-
-```html
-<style>
-    [x-cloak] {
-        display: none !important;
-    }
-</style>
-```
-
-### 魔法属性 Magic Properties
-
-> 除 `$el` 外,魔法属性 **在 `x-data` 中的无法使用**,因为那时组件还没初始化。
-
----
-
-### `$el`
-**例如:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
-</div>
-```
-
-`$el` 是一个用来获取根组件 DOM 节点的魔法属性。
-
-### `$refs`
-**例如:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` 是一个用来在组件中获取原生 DOM 元素的魔法属性。这可以帮助你在需要时手动拿到原始的 DOM 元素。
-
----
-
-### `$event`
-**例如:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` 是一个用来在事件监听器中接受浏览器原生「Event」对象的魔法属性。
-
-> 备注: $event 属性只在 DOM 表达式中有效。
-
-如果你需要在一个 JavaScript 函数中使用 $event,可以直接这么干:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**例如:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- 点击时,将触发 console.log -->
-</div>
-```
-
-**有关事件传播 (Event Propagation)**
-
-请注意,因为 [事件冒泡机制](https://en.wikipedia.org/wiki/Event_bubbling) 的存在,当你需要从相同层级节点上拦截已触发的事件时,需要增加 [`.window`](https://github.com/alpinejs/alpine#x-on) 修饰符:
-
-**例如:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> 上面的例子是错误示范,不能正常工作,因为 `custom-event` 被触发时,他只会传播到共同的祖先,上级的 `div` 元素。
-
-**分发到组件**
-
-也可以刚才这一技巧在组件之间通信使用:
-
-**例如:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- 当点击发生时,将会 console.log "Hello World!". -->
-```
-
-`$dispatch` 是一个创建 `CustomEvent` 并使用其内部的 `.dispatchEvent()` 进行分发的快捷方式。有很多使用自定义事件在组件间传递数据的优秀用例。[参考这篇文档](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) 来获取更多关于浏览器中 `CustomEvent` 的信息。
-
-可以注意到,放在 `$dispatch('some-event', { some: 'data' })` 第二个参数的数据,在新事件上可通过「detail」属性来拿到:`$event.detail.some`。将自定义事件的数据附加到 .detail 属性是在浏览器中 `CustomEvent` 的标准实践。更多信息参阅 [这篇文档(英文)](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)。
-
-你也可以使用 `$dispatch()` 来触发 `x-model` 绑定的数据更新。例如:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- 按钮被点击后,`x-model` 将获得冒泡的 「input」事件,并更新 foo 为 「baz」。 -->
-    </span>
-</div>
-```
-
-> 备注:$dispatch 属性只在 DOM 表达式中有效。
-
-如果你需要在一个 JavaScript 函数中使用 $dispatch,可以直接这么干:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**例如:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-`$nextTick` 是一个运行你在 Alpine 做出响应式 DOM 更新后,执行一个给定表达式的指令。这在你需要在完成数据更新后用 DOM 状态做交互时非常有用。
-
----
-
-### `$watch`
-**例如:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">Toggle Open</button>
-</div>
-```
-
-你可以通过 `$watch` 魔法方法「监听」一个组件属性。在上面的例子中,当按钮被点击且 open 被改变时,你提供的回调函数会被调用,`console.log` 新的 value。
-
-## 安全相关 Security
-如果你发现了安全漏洞,请发邮件到 [calebporzio@gmail.com]().
-
-Alpine 依赖对 `Function` 对象的自定义实现来运行指令。虽然比 `eval()` 安全一,但在某些环境下这一方法也不可用,例如 Google Chrome App 使用的限制性内容安全策略(Content Security Policy/CSP).
-
-如果你在使用 Alpin 的网站上处理敏感数据,就需要设置 [CSP](https://csp.withgoogle.com/docs/strict-csp.html) 使之包括 `unsafe-eval`。正确设置安全的策略有助于保护用户的个人隐私数据。
-
-由于策略设置会适用于页面中所有脚本,务必要检查页面引入的其他外部依赖,避免它们引发 XSS 漏洞、通过 `eval()` 修改 DOM 注入恶意代码。
-
-## V3 路线图 Roadmap
-* 从`x-ref` 迁移到 `ref` 以与 Vue 保持一致?
-* 新增 `Alpine.directive()`
-* 新增 `Alpine.component('foo', {...})` (通过 `__init()` 魔法方法)
-* 分发 Alpine 的 "loaded", "transition-start" 等多个事件 ([#299](https://github.com/alpinejs/alpine/pull/299)) ?
-* 移除 `x-bind:class="{ 'foo': true }"` 中的使用对象(以及数组)的语法 ([#236](https://github.com/alpinejs/alpine/pull/236) 并增加在 `style` 中使用对象的支持
-* 优化 `x-for` 的响应式效果 ([#165](https://github.com/alpinejs/alpine/pull/165))
-* 增加 "deep watching" 支持 ([#294](https://github.com/alpinejs/alpine/pull/294))
-* 增加 `$el` 快捷方式
-* 修改 `@click.away` 为 `@click.outside`?
-
-## 许可证 License
-
-Copyright © 2019-2021 Caleb Porzio 与仓库所有贡献者 版权所有
-
-基于 MIT 许可证开源,查看 [LICENSE.md](LICENSE.md) 获取详情。

+ 0 - 750
README.zh-TW.md

@@ -1,750 +0,0 @@
-# Alpine.js
-
-![npm bundle size](https://img.shields.io/bundlephobia/minzip/alpinejs)
-![npm version](https://img.shields.io/npm/v/alpinejs)
-[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://alpinejs.codewithhugo.com/chat/)
-
-Alpine.js 提供了 Vue 與 React 等大框架的互動式與宣告式的功能,而不需花費太多成本。
-
-有了 Alpine.js 就可以繼續使用 DOM,並在有需要的時候通過 Alpine.js 增加功能。
-
-可以想像成是 JavaScript 版的 [Tailwind](https://tailwindcss.com/)。
-
-> 備註:Alpine.js 的格式幾乎都是從 [Vue](https://vuejs.org/) 參考而來 (以及擴充了 [Angular](https://angularjs.org/))。本人在此由衷感謝這些套件為 Web 環境帶來的貢獻。
-
-## 安裝  
-
-**使用 CDN:** 將下列腳本新增至 `<head>` 末端。
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
-```
-
-就這樣。Alpine.js 會自行初始化。
-
-在正式環境中,建議在連結中固定特定版本,以避免新版本使功能無法使用。
-如,要使用 `2.8.2` 版則可以這樣寫:
-```html
-<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
-```
-
-**使用 npm:** 從 npm 安裝套件。
-```js
-npm i alpinejs
-```
-
-在腳本中引入。
-```js
-import 'alpinejs'
-```
-
-**若要支援 IE11** 請改用下列腳本。
-```html
-<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
-<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine-ie11.min.js" defer></script>
-```
-
-上述寫法使用了 [module/nomodule 模式 (英文)](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) ,這樣寫可以讓現代瀏覽器自動載入模組套件組合,而 IE11 以及其他舊瀏覽器中則會自動載入 IE11 模組套件。
-
-## 開始使用
-
-**下拉選單 Dropdown、強制回應視窗 Modal**
-```html
-<div x-data="{ open: false }">
-    <button @click="open = true">展開下拉選單</button>
-
-    <ul
-        x-show="open"
-        @click.away="open = false"
-    >
-        下拉選單內容
-    </ul>
-</div>
-```
-
-**索引標籤 Tab**
-```html
-<div x-data="{ tab: 'foo' }">
-    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
-    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>
-
-    <div x-show="tab === 'foo'">索引標籤 Foo</div>
-    <div x-show="tab === 'bar'">索引標籤 Bar</div>
-</div>
-```
-
-也可以用在更多地方:
-
-**遊標停留時預先截取下拉選單的 HTML**
-```html
-<div x-data="{ open: false }">
-    <button
-        @mouseenter.once="
-            fetch('/dropdown-partial.html')
-                .then(response => response.text())
-                .then(html => { $refs.dropdown.innerHTML = html })
-        "
-        @click="open = true"
-    >顯示下拉選單</button>
-
-    <div x-ref="dropdown" x-show="open" @click.away="open = false">
-        載入中進度環...
-    </div>
-</div>
-```
-
-## 學習
-
-總共有 14 種可用的指示詞 (Directive):
-
-| 指示詞 | 說明 |
-| --- | --- |
-| [`x-data`](#x-data) | 宣告新元件定義範圍。 |
-| [`x-init`](#x-init) | 模組初始化後執行運算式。 |
-| [`x-show`](#x-show) | 依據運算式 (true 或 false) 新增或移除元素的 `display: none;`。 |
-| [`x-bind`](#x-bind) | 將屬性的值設為 JS 運算式的執行結果。 |
-| [`x-on`](#x-on) | 將事件監聽器附加至元素上。當事件發出後執行 JS 運算式。 |
-| [`x-model`](#x-model) | 為元素新增「雙向資料繫結」。保持輸入元素與元件資料間的同步。 |
-| [`x-text`](#x-text) | 與 `x-bind` 的運作方式類似,但更新的是元素的 `innerText`。 |
-| [`x-html`](#x-html) | 與 `x-bind` 的運作方式類似,但更新的是元素的 `innerHTML`。 |
-| [`x-ref`](#x-ref) |從元素中取得原始 DOM 元素的簡便方法。 |
-| [`x-if`](#x-if) | 從 DOM 中完全移除元素。必須在 `<template>` 標籤上使用。 |
-| [`x-for`](#x-for) | 為陣列中的每個項目建立新 DOM 節點。必須在 `<template>` 標籤上使用。 |
-| [`x-transition`](#x-transition) | 用於在轉場的各個階段為元素設定 Class 的指示詞。 |
-| [`x-spread`](#x-spread) | 為了更佳的可複用性,可將包含 Alpine 指示詞的物件繫結至元素上。 |
-| [`x-cloak`](#x-cloak) | 該屬性會在 Alpine 初始化後移除。適合用來隱藏還未初始化的 DOM。 |
-
-以及 6 個魔法屬性:
-
-| 魔法屬性 | 說明 |
-| --- | --- |
-| [`$el`](#el) |  截取根元素的 DOM 節點。 |
-| [`$refs`](#refs) | 截取元素中以 `x-ref` 標記的 DOM 元素。 |
-| [`$event`](#event) | 在事件監聽器中截取瀏覽器的原生「Event」物件。  |
-| [`$dispatch`](#dispatch) | 建立 `CustomEvent` 並在內部以其 `.dispatchEvent()` 發送該 `CustomEvent`。 |
-| [`$nextTick`](#nexttick) | 在 Alpine 處理好 DOM 更新 **之後** 執行給定的運算式。 |
-| [`$watch`](#watch) | 當正在「監聽 - watch」的屬性發生改動後,觸發給定的回呼函式。 |
-
-
-## 贊助
-
-<img width="33%" src="https://refactoringui.nyc3.cdn.digitaloceanspaces.com/tailwind-logo.svg" alt="Tailwind CSS">
-
-**想在這裡顯示你的 Logo 嗎? [在 Twitter 上傳送 DM](https://twitter.com/calebporzio)**
-
-## VIP 參與者
-
-<table>
-  <tr>
-    <td align="center"><a href="http://calebporzio.com"><img src="https://avatars2.githubusercontent.com/u/3670578?v=4" width="100px;" alt="Caleb Porzio"/><br /><sub><b>Caleb Porzio</b></sub></a><br /><sub>(作者)</sub></td>
-    <td align="center"><a href="https://github.com/HugoDF"><img src="https://avatars2.githubusercontent.com/u/6459679?v=4" width="100px;" alt="Hugo"/><br /><sub><b>Hugo</b></sub></a></td>
-    <td align="center"><a href="https://github.com/ryangjchandler"><img src="https://avatars2.githubusercontent.com/u/41837763?v=4" width="100px;" alt="Ryan Chandler"/><br /><sub><b>Ryan Chandler</b></sub></a></td>
-    <td align="center"><a href="https://github.com/SimoTod"><img src="https://avatars2.githubusercontent.com/u/8427737?v=4" width="100px;" alt="Simone Todaro"/><br /><sub><b>Simone Todaro</b></sub></a></td>
-  </tr>
-</table>
-
-### 指示詞
-
----
-
-### `x-data`
-
-**範例:** `<div x-data="{ foo: 'bar' }">...</div>`
-
-**結構:** `<div x-data="[JSON 資料物件]">...</div>`
-
-`x-data` 宣告新的元件定義範圍。使用 x-data 會告知 Alpine 以給定的資料物件來初始化新的元件。
-
-可想像成 Vue 元件中的 `data` 屬性。
-
-**抽出元素邏輯**
-
-可以將資料 (與行為) 抽出成可重複使用的函式:
-
-```html
-<div x-data="dropdown()">
-    <button x-on:click="open">開啟</button>
-
-    <div x-show="isOpen()" x-on:click.away="close">
-        // 下拉選單
-    </div>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            show: false,
-            open() { this.show = true },
-            close() { this.show = false },
-            isOpen() { return this.show === true },
-        }
-    }
-</script>
-```
-
-> **各位 Bundler 使用者**,請注意,Alpine.js 存取的函式都在全域範圍 (`window`),要在 `x-data` 中使用函式時必須要顯式將函式指派至 `window` 上。如 `window.dropdown = function () {}` (因為 Webpack, Rollup, Parcel …等中,定義的 `function` 預設都在模組範圍內而不是 `window`)。
-
-也可以使用物件解構來將多個資料物件混合在一起:
-
-```html
-<div x-data="{...dropdown(), ...tabs()}">
-```
-
----
-
-### `x-init`
-**範例:** `<div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>`
-
-**結構:** `<div x-data="..." x-init="[運算式]"></div>`
-
-`x-init` 會在元素初始化後執行運算式。
-
-若想在 Alpine 將更新套用至 DOM **之後** 才執行程式碼的話 (類似 VueJS 中的 `mounted()` Hook),可以從 `x-init` 中回傳一個回呼函式,該函式會在出套用至 DOM 後才執行:
-
-`x-init="() => { // 此處可存取 DOM 初始化完畢後的狀態 // }"`
-
----
-
-### `x-show`
-**範例:** `<div x-show="open"></div>`
-
-**結構:** `<div x-show="[運算式]"></div>`
-
-`x-show` 會依據運算式為 `true` 或 `false` 來在元素上會新增或移除 `display: none;` 樣式。
-
-**x-show.transition**
-
-`x-show.transition` 是一個很方便的 API,可使 `x-show` 更與 CSS Transition 配合地更佳完美。
-
-```html
-<div x-show.transition="open">
-    這裡的內容會轉換入、轉換出。
-</div>
-```
-
-| 指示詞 | 說明 |
-| --- | --- |
-| `x-show.transition` | 同時淡入淡出並縮放。 (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
-| `x-show.transition.in` | 僅轉換入。 |
-| `x-show.transition.out` | 僅轉換出。 |
-| `x-show.transition.opacity` | 僅使用淡入淡出。 |
-| `x-show.transition.scale` | 僅使用縮放。 |
-| `x-show.transition.scale.75` | 自定 CSS 縮放變換 `transform: scale(.75)`. |
-| `x-show.transition.duration.200ms` | 設定「轉換入」的變換為 200ms。轉換出將設定為該值的一半 (100ms). |
-| `x-show.transition.origin.top.right` | 自定 CSS 變換的起始 `transform-origin: top right`. |
-| `x-show.transition.in.duration.200ms.out.duration.50ms` | 為「轉換入」與「轉換出」設定不同的持續時間。 |
-
-> 備註:所有的轉換修飾詞都可以互相組合使用。可以這樣用 (雖然很故意XD): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
-
-> 備註:`x-show` 會等待所有子節點都完成轉換後。若想跳過這個行為,請加上 `.immediate` 修飾詞:
-```html
-<div x-show.immediate="open">
-    <div x-show.transition="open">
-</div>
-```
----
-
-### `x-bind`
-
-> 備註:也可以使用較短的「:」語法: `:type="..."`
-
-**範例:** `<input x-bind:type="inputType">`
-
-**結構:** `<input x-bind:[屬性]="[運算式]">`
-
-`x-bind` 將屬性值設為 JavaScript 運算式的結果。運算式中可以存取元件資料物件中的所有索引鍵,且每次資料有更新時都更新。
-
-> 備註:屬性繫結 **僅會** 在其相依的值更新時才更新。Alpine 框架會觀察資料的更改,並偵測哪個繫結與該資料有關。
-
-**將 `x-bind` 用在 Class 屬性**
-
-當繫結在 `class` 屬性時,`x-bind` 的運作模式會有點不同。
-
-對於 Class,需要傳入一個物件,其中物件的索引鍵為 Class 的名稱,而值則為布林運算式,用來判斷是否要套用該 Class 名稱。
-
-如:
-`<div x-bind:class="{ 'hidden': foo }"></div>`
-
-在該例中,「hidden」class 只會在 `foo` 資料屬性的值為 `true` 時套用。
-
-**將 `x-bind` 用在布林屬性**
-
-`x-bind` 支援以與數值屬性相同的方式來繫結布林屬性,只需使用作為判斷條件的變數或是任意可以解為 `true` 或 `false` 的 JavaScript 運算式即可。
-
-如:
-```html
-<!-- 如下程式: -->
-<button x-bind:disabled="myVar">點擊此處</button>
-
-<!-- 當 myVar == true: -->
-<button disabled="disabled">點擊此處</button>
-
-<!-- 當 myVar == false: -->
-<button>點擊此處</button>
-```
-
-該範例中的程式會依據 `myVar` 為 true 或 false 來新增或移除 disabled 屬性。
-
-布林屬性的支援係依據 [HTML 規格 (英文)](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute),如 `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open` …等。
-
-**`.camel` 修飾詞**
-
-**範例:** `<svg x-bind:view-box.camel="viewBox">`
-
-使用 `camel` 修飾詞會繫結到對應駝峰命名法的屬性上。在上述例子中, `viewBox` 的值會被繫結到 `view-box` 所對應的 `viewBox` 屬性上。
-
----
-
-### `x-on`
-
-> 備註:也可以使用較短的「@」語法:`@click="..."`
-
-**範例:** `<button x-on:click="foo = 'bar'"></button>`
-
-**結構:** `<button x-on:[事件]="[運算式]"></button>`
-
-`x-on` 將事件監聽器附加至宣告 `x-on` 的元素上。當發出該事件後,執行設定為該事件值的對應 JavaScript 運算式。
-
-若在該運算式中有修改任何資料,則其他「繫結 Bind」該資料元素屬性也會一併更新。
-
-> 備註:也可以指定一個 JavaScript 函式名稱
-
-**範例:** `<button x-on:click="myFunction"></button>`
-
-與該程式碼相同: `<button x-on:click="myFunction($event)"></button>`
-
-**`keydown` 修飾詞**
-
-**範例:** `<input type="text" x-on:keydown.escape="open = false">`
-
-可以將按鍵附加到 `x-on:keydown` 指示詞後面來指定要監聽的按鍵。請注意,該修飾詞使用的是 `-` 號分隔命名 (kebab-cased) 版本的 `Event.key` 值。
-
-如: `enter`, `escape`, `arrow-up`, `arrow-down`
-
-> 備註:也可以監聽使用系統修飾詞的按鍵組合,如: `x-on:keydown.cmd.enter="foo"`
-
-**`.away` 修飾詞**
-
-**範例:** `<div x-on:click.away="showModal = false"></div>`
-
-當有 `.away` 修飾詞時,將只會在由非該元素或該元素子節點的其他元素發出事件時執行事件處理常式。
-
-適合用在讓使用者點擊元件外面來關閉下拉選單與強制回應視窗時隱藏這些元件等情況。
-
-**`.prevent` 修飾詞**
-
-**範例:** `<input type="checkbox" x-on:click.prevent>`
-
-在事件監聽器加上 `.prevent` 會在觸發的事件上呼叫 `preventDefault`。在上述範例中,使用 `.prevent` 則代表該多選框在使用者點擊後不會被實際選中。
-
-**`.stop` 修飾詞**
-
-**範例:** `<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>`
-
-在事件監聽器加上 `.stop` 會在觸發的事件上呼叫 `stopPropagation`。在上述範例中,使用 `.stop` 則代表「click」事件觸發之後不會從底部 Bubble 到外層的 `<div>` 。換句話來說,使用者點擊按鈕 (Button) 後, `foo` 的值不會被設為 `'bar'`。
-
-**`.self` 修飾詞**
-
-**範例:** `<div x-on:click.self="foo = 'bar'"><button></button></div>`
-
-在事件監聽器加上 `.self` 則只會在 `$event.target` 是該元素的時候才觸發監聽器。在上述範例中,則表示從按鈕 Bubble 到外層 `<div>` 上來的「click」事件 **不會** 執行監聽器。
-
-**`.window` 修飾詞**
-
-**範例:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
-
-在事件監聽器加上 `.window` 會將監聽器安裝到全域的 window 物件中,而不是宣告該監聽器的 DOM 物件上。適合用在當有其他東西修改了 window 而需要修改元件狀態的時候,如縮放事件。在本例中,當視窗調整為大於 768 像素寬時,程式會關閉強制回應視窗或下拉選單,否則會繼續維持原本的狀態。
-
->備註:也可以使用 `.document` 修飾詞來將監聽器附加到 `document` 而不是 `window` 上
-
-**`.once` 修飾詞**
-
-**範例:** `<button x-on:mouseenter.once="fetchSomething()"></button>`
-
-在事件監聽器加上 `.onece` 則可以確保只會呼叫一次事件監聽器。適合用來做一些只需要做一次就好的事,如取得 HTML 部分等。
-
-**`.passive` 修飾詞**
-
-**範例:** `<button x-on:mousedown.passive="interactive = true"></button>`
-
-在事件監聽器加上 `.passive` 修飾詞則可讓監聽器成為被動,也就表示在所有處理的事件上 `preventDefault()` 都將不會有任何作用。可以用在如提升觸控裝置上的滾動效能等目的。 
-
-**`.debounce` 修飾詞**
-
-**範例:** `<input x-on:input.debounce="fetchSomething()">`
-
-`.debounce` 修飾詞可以試事件監聽器「消除彈跳 (Debouce)」。也就是說,該處理常式會等到上一個事件觸發後的一段時間後才執行。當處理常式準備好可執行後,則會執行上一個處理常式呼叫。
-
-預設的消除彈跳「等待」時間為 250 毫秒。
-
-若要自定等待事件,則可使用如下方法指定:
-
-```
-<input x-on:input.debounce.750="fetchSomething()">
-<input x-on:input.debounce.750ms="fetchSomething()">
-```
-
-**`.camel` 修飾詞**
-
-**範例:** `<input x-on:event-name.camel="doSomething()">`
-
-使用 `.camel` 修飾詞來監聽以駝峰命名法命名的事件。在上述例子中,元素觸發 `eventName` 事件後會執行該運算式。
-
----
-
-### `x-model`
-**範例:** `<input type="text" x-model="foo">`
-
-**結構:** `<input type="text" x-model="[資料項目]">`
-
-`x-model` 可用來在元素加上「雙向資料繫結 (Two-way Data Binding)」。也就是說,輸入元素的值會保持與元件資料項目的值同步。
-
-> 備註:`x-model` 很聰明,會偵測文字輸入框、多選框、單選框、Textarea、下拉選單與多重選取區域等。`x-model` 的運作方式在各個情況下應該都[與 Vue 相同](https://vuejs.org/v2/guide/forms.html)。
-
-**`.debounce` 修飾詞**
-
-**範例:** `<input x-model.debounce="search">`
-
-`debounce` 修飾詞可以在數值更新上加上「消除彈跳 (Debounce)」。也就是說,從上一次事件觸發之後的一段時間之後才會呼叫事件處理常式。當處理常式可呼叫後,才會執行上一個處理常式呼叫。
-
-預設的消除彈跳「等待」時間為 250 毫秒。
-
-若要自定等待時間,則可用下列方式指定:
-
-```
-<input x-model.debounce.750="search">
-<input x-model.debounce.750ms="search">
-```
-
----
-
-### `x-text`
-**範例:** `<span x-text="foo"></span>`
-
-**結構:** `<span x-text="[運算式]"`
-
-`x-text` 類似 `x-bind` ,但更新的不是元素的屬性,而是 `innerText`。
-
----
-
-### `x-html`
-**範例:** `<span x-html="foo"></span>`
-
-**結構:** `<span x-html="[運算式]"`
-
-`x-text` 類似 `x-bind` ,但更新的不是元素的屬性,而是 `innerHTML`。
-
-> :warning: **絕對不要用在使用者輸入的內容,且請只用在可信任的內容上。** :warning:
->
-> 從第三方來源動態呈現 HTML 可能會導致 [XSS (英文)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) 漏洞。
-
----
-
-### `x-ref`
-**範例:** `<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>`
-
-**結構:** `<div x-ref="[參照名稱]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>`
-
-`x-ref` 提供從元件上取得原始 DOM 元素的簡便方法。只要在元素上設定 `x-ref` 屬性,就可以在所有事件處理常式中通過 `$refs` 物件來取得該元素。
-
-除了設定 ID 並在各個地方使用 `document.querySelector`,使用 `x-ref` 可作為替代方法。
-
-> 備註:若有需要也可以在 `x-ref` 上繫結動態數值:`<span :x-ref="item.id"></span>`。
-
----
-
-### `x-if`
-**範例:** `<template x-if="true"><div>一些元素</div></template>`
-
-**結構:** `<template x-if="[運算式]"><div>一些元素</div></template>`
-
-但遇到一些 `x-show` 不合用的情況 (`x-show` 會在表達式為 false 時將元素設為 `display: none`),則可以使用 `x-if` 來將元素完全從 DOM 中移除。
-
-但要注意,`x-if` 必須要用在 `<template></template>` 標籤上,因為 Alpine 不使用虛擬 DOM。這種實作方式可保持 Alpine 簡陋,並使用真的 DOM 來處理動態 (Magic) 的部分。
-
-> 備註:使用 `x-if` 時 `<template></template>` 標籤中必須只能有單一根元素。
-
-> 備註:如果要在 `svg` 標籤中使用 `template`,則需要在 Alpine.js 初始化前執行一段 [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)。
-
----
-
-### `x-for`
-**範例:**
-```html
-<template x-for="item in items" :key="item">
-    <div x-text="item"></div>
-</template>
-```
-
-> 備註:`:key` 繫結為非必填。但「強烈」建議要加上。
-
-`x-for` 適用於需要為陣列中每個項目建立新 DOM 節點的情況。用法看起來應該跟 Vue 中的 `v-for` 類似,但唯一不同的地方就是要放在 `template` 標籤上而不是一般的 DOM 元素。
-
-若需要存取目前迭代的索引,則可使用下列語法:
-
-```html
-<template x-for="(item, index) in items" :key="index">
-    <!-- 若有需要也可以在迭代中參照「index」。 -->
-    <div x-text="index"></div>
-</template>
-```
-
-> 備註:使用 `x-for` 時 `<template></template>` 標籤中必須只能有單一根元素。
-
-> 備註:如果要在 `svg` 標籤中使用 `template`,則需要在 Alpine.js 初始化前執行一段 [polyfill](https://github.com/alpinejs/alpine/issues/637#issuecomment-654856538)。
-
-#### 巢狀嵌套 `x-for`
-可以嵌套多層 `x-for` 迴圈,但每個迴圈都 **必須** 放在一個元素內,如:
-
-```html
-<template x-for="item in items">
-    <div>
-        <template x-for="subItem in item.subItems">
-            <div x-text="subItem"></div>
-        </template>
-    </div>
-</template>
-```
-
----
-
-### `x-transition`
-**範例:**
-```html
-<div
-    x-show="open"
-    x-transition:enter="transition ease-out duration-300"
-    x-transition:enter-start="opacity-0 transform scale-90"
-    x-transition:enter-end="opacity-100 transform scale-100"
-    x-transition:leave="transition ease-in duration-300"
-    x-transition:leave-start="opacity-100 transform scale-100"
-    x-transition:leave-end="opacity-0 transform scale-90"
->...</div>
-```
-
-```html
-<template x-if="open">
-    <div
-        x-transition:enter="transition ease-out duration-300"
-        x-transition:enter-start="opacity-0 transform scale-90"
-        x-transition:enter-end="opacity-100 transform scale-100"
-        x-transition:leave="transition ease-in duration-300"
-        x-transition:leave-start="opacity-100 transform scale-100"
-        x-transition:leave-end="opacity-0 transform scale-90"
-    >...</div>
-</template>
-```
-
-> 上述範例使用了 [Tailwind CSS](https://tailwindcss.com) 的 Class
-
-Alpine 中提供了 6 種不同的變換指示詞,可用於在元素變換的「hidden 隱藏」與「shown 顯示」狀態間的各個階段套用 Class。這些指示詞可用在 `x-show` **與** `x-if` 上。
-
-這些行為都與 VueJS 的 transition 指示詞很類似,但不同的地方則是使用了不同的名稱:
-
-| 指示詞 | 說明 |
-| --- | --- |
-| `:enter` | 套用於整個 Enter 階段。 |
-| `:enter-start` | 在元素插入前新增,並在元素插入的 1 幀後刪除。 |
-| `:enter-end` | 在元素插入後 (與 `enter-start` 刪除同時) 1 幀時新增,變換或動畫結束時刪除。 |
-| `:leave` | 套用於整個 Leave 階段。 |
-| `:leave-start` | 在 Leave 變換觸發後立刻新增、並在 1 幀後刪除。 |
-| `:leave-end` | 在 Leave 變換觸發後 (與 `leave-start` 刪除同時) 1 幀新增,並在變換或動畫結束時刪除。 |
-
----
-
-### `x-spread`
-**範例:**
-```html
-<div x-data="dropdown()">
-    <button x-spread="trigger">開啟下拉選單</button>
-
-    <span x-spread="dialogue">下拉選單內容</span>
-</div>
-
-<script>
-    function dropdown() {
-        return {
-            open: false,
-            trigger: {
-                ['@click']() {
-                    this.open = true
-                },
-            },
-            dialogue: {
-                ['x-show']() {
-                    return this.open
-                },
-                ['@click.away']() {
-                    this.open = false
-                },
-            }
-        }
-    }
-</script>
-```
-
-`x-spread` 可用來將元素的 Alpine 繫結截取到可重複使用的元素中。
-
-元素的索引鍵為指示詞 (可以是任何指示詞,包含修飾詞),而元素值則為由 Alpine 取值的回呼函式。
-
-> 備註:x-spread 唯一要注意的就是與 `x-for` 搭配使用的情況。當被「spread」的指示詞是 `x-for`,則回呼內回傳的應該要是運算式字串。如: `['x-for']() { return 'item in items' }`.
-
----
-
-### `x-cloak`
-**範例:** `<div x-data="{}" x-cloak></div>`
-
-`x-cloak` 屬性會在 Alpine 初始化後從元素上移除。可以用來隱藏還未初始化的 DOM 元素。通常使用下列全域樣式:
-
-```html
-<style>
-    [x-cloak] { display: none; }
-</style>
-```
-
-### 魔法屬性
-
-> 除了 `$el` 是例外,所有的魔法屬性 **在 `x-data` 中都無法使用**,因為元素還未初始化。
-
----
-
-### `$el`
-**範例:**
-```html
-<div x-data>
-    <button @click="$el.innerHTML = 'foo'">這裡的內容會取代為「foo」</button>
-</div>
-```
-
-`$el` 是可用來取得元件根 DOM 節點的魔法屬性。
-
-### `$refs`
-**範例:**
-```html
-<span x-ref="foo"></span>
-
-<button x-on:click="$refs.foo.innerText = 'bar'"></button>
-```
-
-`$refs` 是可用來取得元件內以 `x-ref` 標記的 DOM 元素之魔法屬性。適合用在要手動操作 DOM 元素的情況。
-
----
-
-### `$event`
-**範例:**
-```html
-<input x-on:input="alert($event.target.value)">
-```
-
-`$event` 是可在事件監聽器內取得瀏覽器原生「Event」物件的魔法屬性。
-
-> 備註:$event 屬性只可在 DOM 運算式中使用。
-
-若有需要在 JavaScript 函式中存取 $event,則可以直接將 $event 傳入:
-
-`<button x-on:click="myFunction($event)"></button>`
-
----
-
-### `$dispatch`
-**範例:**
-```html
-<div @custom-event="console.log($event.detail.foo)">
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-    <!-- 點擊後會 console.log "bar" -->
-</div>
-```
-
-**有關事件傳播 (Event Propagation)**
-
-請注意,由於 [Event Bubbling (英語)](https://en.wikipedia.org/wiki/Event_bubbling),當有需要截取從相同層級節點觸發的事件時,則需要加上 [`.window`](#x-on) 修飾詞:
-
-**範例:**
-
-```html
-<div x-data>
-    <span @custom-event="console.log($event.detail.foo)"></span>
-    <button @click="$dispatch('custom-event', { foo: 'bar' })">
-<div>
-```
-
-> 上述範例無效,因為 `custom-event` 觸發的時候,會傳播到共同母級節點,即 `div`。
-
-**分派至元件**
-
-也可以通過剛才那個技巧來在元件間互相溝通:
-
-**範例:**
-
-```html
-<div x-data @custom-event.window="console.log($event.detail)"></div>
-
-<button x-data @click="$dispatch('custom-event', 'Hello World!')">
-<!-- 點擊後會 console.log "Hello World!". -->
-```
-
-`$dispatch` 是建立 `CustomEvent` 並在內部使用 `.dispatchEvent()` 分派的捷徑方法。還有其他許多通過自定事件來在元件間傳遞資料的例子。請 [參考此處 (英文)](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) 以瞭解更多有關不同瀏覽器中的 `CustomEvent` 資訊。
-
-可以注意到放在第二個參數的資料 `$dispatch('some-event', { some: 'data' })`,在新事件上可通過「detail」屬性來取得:`$event.detail.some`。將自定事件資料附加到 `.detail` 屬性是在瀏覽器中 `CustomEvent` 的標準實踐。更多資訊請 [參考此處 (英文)](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)。
-
-也可以使用 `$dispatch()` 來觸發 `x-model` 繫結的資料更新。如:
-
-```html
-<div x-data="{ foo: 'bar' }">
-    <span x-model="foo">
-        <button @click="$dispatch('input', 'baz')">
-        <!-- 點擊按鈕後,`x-model` 會抓到 Bubbing 的「input」事件,並將 foo 更新為「baz」 -->
-    </span>
-</div>
-```
-
-> 備註:$dispatch 屬性只可在 DOM 運算式中使用。
-
-若有需要在 JavaScript 函式中存取 $dispatch,則可以直接將 $dispatch 傳入:
-
-`<button x-on:click="myFunction($dispatch)"></button>`
-
----
-
-### `$nextTick`
-**範例:**
-```html
-<div x-data="{ fruit: 'apple' }">
-    <button
-        x-on:click="
-            fruit = 'pear';
-            $nextTick(() => { console.log($event.target.innerText) });
-        "
-        x-text="fruit"
-    ></button>
-</div>
-```
-
-通過 `$nextTick` 魔法屬性則可以在 Alpine 做出 DOM 更新 **之後** 才執行指定的運算式。適用於需要在資料反應到 DOM 上後才要與 DOM 互動的情況。
-
----
-
-### `$watch`
-**範例:**
-```html
-<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
-    <button @click="open = ! open">開啟/關閉</button>
-</div>
-```
-
-可通過 `$watch` 魔法方法來「監聽 (Watch)」元件屬性。在上述例子中,當按鈕點擊後 `open` 會該表,接著會指定給定的回呼並以新的值來執行 `console.log`。
-
-## 安全性 Security
-若你發現安全性漏洞,請傳送電子郵件至 [calebporzio@gmail.com]()。
-
-Alpine 仰賴與使用 `Function` 物件來自定實作以對指示詞取值。雖然比 `eval()` 來的安全,但這個做法依然在一些環境下被禁止,如 Google Chrome App 使用了限制性的 CSP (Content Security Policy,內容安全性原則)。
-
-若在需要處理機敏資料的網站上使用 Alpine,且需要設定 [CSP (英語)](https://csp.withgoogle.com/docs/strict-csp.html),則必須在 CSP 設定中加上 `unsafe-eval`。設定正確且堅固的原則有助於保護使用者在處理個人資料或財務資料上的安全。
-
-由於原則設定會套用至頁面中的所有腳本,所以也應注意要小心審閱網站中引入的其他外部函式庫,以確保能信任這些函式庫,並避免這些函式庫引發 XSS 漏洞或使用 `eval()` 函式來調整 DOM 或在頁面中注入惡意程式碼。
-
-## 授權條款 License
-
-Copyright © 2019-2021 Caleb Porzio and contributors
-
-Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.
-透過 MIT 授權條款授權,詳情請參閱 [LICENSE.md](LICENSE.md)。

+ 0 - 13
babel.config.js

@@ -1,13 +0,0 @@
-module.exports = {
-    presets: [
-        [
-            '@babel/preset-env',
-            {
-                targets: {
-                    node: 'current',
-                    edge: '18'
-                },
-            },
-        ],
-    ],
-};

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1579 - 0
benchmarks/giant.html


+ 22142 - 0
benchmarks/init.html

@@ -0,0 +1,22142 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <title>Alpine-3-keyed</title>
+    <link href="/css/currentStyle.css" rel="stylesheet" />
+    <script src="http://alpine-next.test/packages/alpinejs/dist/cdn.js" defer></script>
+    <script>
+        window.start = performance.now()
+        document.addEventListener('alpine:initialized', () => {
+            setTimeout(() => {
+                console.log(performance.now() - window.start);
+            })
+        })
+    </script>
+  </head>
+  <body>
+    <div class="container" id="main" x-data="app">
+      <div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                  @click="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                  @click="runLots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                  @click="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                  @click="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                  @click="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                  @click="swapRows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <table class="table table-hover table-striped test-data">
+        <tbody>
+          <template x-for="item in data" :key="item.id">
+            <tr :class="item.id === selected ? 'danger' : ''">
+              <td class="col-md-1" x-text="item.id"></td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label"></a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)" >x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr>
+          </template>
+        </tbody>
+      </table>
+      <table class="table table-hover table-striped test-data">
+        <tbody x-data="{ item: { id: 999999, label: 'yoyoyo' }}">
+          <tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">5</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">6</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">7</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">8</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">9</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">10</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">11</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">12</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">13</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">14</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">15</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">16</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">17</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">18</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">19</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">20</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">21</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">22</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">23</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">24</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">25</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">26</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">27</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">28</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">29</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">30</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">31</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">32</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">33</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">34</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant green desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">35</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">36</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">37</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">38</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">39</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">40</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">41</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">42</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">43</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">44</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">45</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">46</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">47</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">48</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">49</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">50</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">51</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable pink desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">52</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">53</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">54</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">55</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">56</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain red pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">57</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">58</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">59</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">60</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">61</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">62</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">63</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">64</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">65</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">66</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">67</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">68</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">69</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important blue table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr>
+            <div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+                <div class="row">
+                  <div class="col-md-6">
+                    <h1>Alpine-3-keyed</h1>
+                  </div>
+                  <div class="col-md-6">
+                    <div class="row">
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="run"
+                          @click="run"
+                        >
+                          Create 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="runlots"
+                          @click="runLots"
+                        >
+                          Create 10,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="add"
+                          @click="add"
+                        >
+                          Append 1,000 rows
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="update"
+                          @click="update"
+                        >
+                          Update every 10th row
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="clear"
+                          @click="clear"
+                        >
+                          Clear
+                        </button>
+                      </div>
+                      <div class="col-sm-6 smallpad">
+                        <button
+                          type="button"
+                          class="btn btn-primary btn-block"
+                          id="swaprows"
+                          @click="swapRows"
+                        >
+                          Swap Rows
+                        </button>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                  @click="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                  @click="runLots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                  @click="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                  @click="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                  @click="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                  @click="swapRows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div><div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+            <tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">70</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">71</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">72</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">73</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly yellow pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">74</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">75</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">76</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">77</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">78</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">79</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">80</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">81</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">82</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">83</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">84</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">85</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">86</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">87</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap yellow burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">88</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">89</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">90</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean green desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">91</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">92</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">93</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive white pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">94</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">95</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">96</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">97</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">98</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">99</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">100</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">101</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">102</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">103</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">104</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">105</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">106</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">107</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">108</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">109</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">110</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">111</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">112</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">113</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">114</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">115</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">116</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">117</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">118</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">119</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">120</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">121</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">122</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">123</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">124</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">125</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">126</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome yellow sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">127</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">128</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">129</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">130</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">131</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">132</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">133</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">134</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">135</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">136</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">137</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">138</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">139</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">140</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">141</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">142</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">143</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">144</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">145</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short white pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">146</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">147</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">148</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">149</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">150</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">151</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">152</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">153</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">154</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">155</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">156</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">157</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">158</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">159</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">160</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">161</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">162</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">163</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">164</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">165</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">166</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">167</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">168</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">169</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">170</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">171</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">172</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">173</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">174</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">175</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">176</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">177</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">178</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">179</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">180</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">181</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">182</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">183</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">184</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">185</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy green desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">186</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">187</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">188</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">189</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">190</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">191</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">192</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">193</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">194</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">195</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">196</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">197</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">198</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">199</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">200</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">201</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">202</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">203</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">204</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">205</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">206</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">207</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">208</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">209</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">210</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">211</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">212</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">213</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">214</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">215</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">216</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd red car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">217</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">218</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">219</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">220</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">221</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">222</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">223</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">224</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">225</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">226</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">227</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">228</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">229</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">230</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">231</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">232</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">233</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">234</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">235</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">236</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">237</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">238</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">239</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">240</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long yellow burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">241</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">242</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">243</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">244</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">245</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">246</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">247</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">248</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short black pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">249</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">250</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">251</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">252</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">253</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">254</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">255</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">256</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">257</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">258</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap yellow pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">259</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">260</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">261</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">262</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">263</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">264</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">265</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">266</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">267</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">268</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">269</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">270</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">271</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">272</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">273</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">274</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">275</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">276</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">277</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">278</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">279</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">280</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">281</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">282</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd yellow sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">283</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">284</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">285</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">286</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">287</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">288</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">289</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">290</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive yellow desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">291</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">292</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">293</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">294</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">295</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">296</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">297</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">298</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">299</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">300</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">301</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">302</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty black keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">303</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">304</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">305</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">306</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">307</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">308</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">309</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">310</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">311</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">312</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome blue pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">313</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">314</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain black house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">315</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">316</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">317</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">318</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">319</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">320</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">321</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">322</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">323</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">324</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy yellow bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">325</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">326</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">327</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">328</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">329</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">330</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">331</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">332</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">333</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">334</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">335</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy yellow burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">336</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">337</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">338</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">339</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">340</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">341</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">342</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">343</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">344</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">345</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">346</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">347</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">348</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">349</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful red pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">350</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">351</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">352</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">353</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">354</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">355</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">356</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">357</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">358</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">359</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">360</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly white pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">361</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">362</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">363</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">364</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">365</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">366</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">367</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">368</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">369</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">370</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">371</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">372</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">373</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy yellow pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">374</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">375</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">376</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">377</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">378</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">379</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">380</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">381</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">382</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">383</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">384</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">385</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">386</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">387</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">388</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">389</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">390</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">391</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">392</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">393</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large green cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">394</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">395</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">396</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">397</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">398</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">399</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short green desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">400</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">401</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">402</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">403</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">404</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">405</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">406</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">407</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short green pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">408</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">409</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">410</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">411</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">412</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">413</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">414</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">415</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">416</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy yellow pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">417</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">418</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">419</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">420</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">421</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">422</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">423</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">424</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean pink mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">425</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint white pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">426</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">427</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">428</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">429</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">430</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint red pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">431</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">432</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">433</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">434</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive black house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">435</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">436</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">437</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">438</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">439</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">440</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">441</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">442</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy purple pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">443</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">444</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">445</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">446</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">447</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">448</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty yellow burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">449</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">450</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">451</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">452</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">453</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">454</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">455</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">456</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">457</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long pink desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">458</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">459</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">460</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">461</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">462</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">463</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">464</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">465</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">466</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">467</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">468</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">469</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">470</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">471</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">472</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">473</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">474</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long black sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">475</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">476</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">477</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">478</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">479</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">480</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">481</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">482</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">483</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">484</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable black pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">485</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">486</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">487</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">488</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">489</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy black house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">490</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">491</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">492</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">493</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly red car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">494</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">495</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">496</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">497</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">498</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy white burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">499</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">500</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">501</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">502</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">503</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">504</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">505</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">506</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">507</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">508</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">509</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">510</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big yellow bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">511</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large orange desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">512</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">513</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">514</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important pink mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">515</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">516</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty brown table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">517</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd white pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">518</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">519</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">520</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long green keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">521</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">522</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">523</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">524</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">525</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">526</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">527</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">528</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">529</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">530</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">531</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">532</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">533</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">534</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap white pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">535</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">536</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">537</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">538</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">539</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">540</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly pink table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">541</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful black burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">542</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">543</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">544</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">545</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">546</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">547</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">548</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">549</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">550</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">551</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">552</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">553</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">554</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">555</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy purple mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">556</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain yellow bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">557</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall purple house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">558</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive red pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">559</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">560</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">561</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">562</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">563</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">564</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">565</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">566</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">567</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">568</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">569</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">570</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry black house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">571</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">572</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">573</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">574</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">575</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">576</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">577</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">578</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">579</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">580</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">581</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">582</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">583</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">584</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">585</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">586</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">587</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">588</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">589</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">590</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">591</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">592</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">593</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">594</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">595</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean pink desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">596</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">597</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">598</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">599</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">600</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">601</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">602</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">603</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">604</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">605</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">606</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">607</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">608</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">609</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">610</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">611</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">612</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly black keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">613</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">614</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">615</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy orange table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">616</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">617</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">618</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short yellow desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">619</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">620</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">621</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">622</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">623</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">624</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">625</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy black sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">626</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">627</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable red sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">628</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">629</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">630</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">631</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">632</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">633</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">634</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">635</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive pink sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">636</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">637</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">638</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">639</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">640</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean orange house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">641</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">642</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">643</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">644</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">645</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">646</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">647</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">648</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">649</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">650</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">651</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">652</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">653</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">654</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">655</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">656</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall purple house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">657</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly black sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">658</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">659</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">660</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">661</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty green bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">662</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important blue pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">663</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy pink sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">664</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">665</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">666</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">667</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">668</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">669</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">670</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">671</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">672</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important green bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">673</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">674</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">675</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">676</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">677</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">678</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">679</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">680</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">681</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">682</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">683</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">684</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">685</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">686</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">687</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">688</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">689</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">690</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">691</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">692</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">693</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">694</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">695</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">696</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">697</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">698</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">699</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry blue pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">700</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">701</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">702</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important red pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">703</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">704</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">705</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly pink cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">706</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">707</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">708</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">709</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy pink sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">710</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry pink burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">711</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">712</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">713</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">714</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty white burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">715</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">716</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">717</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">718</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">719</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">720</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">721</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">722</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">723</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">724</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty purple house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">725</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">726</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">727</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd green cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">728</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean green desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">729</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">730</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">731</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">732</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">733</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">734</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">735</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">736</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">737</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint orange cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">738</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable black sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">739</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">740</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful yellow pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">741</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">742</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">743</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful blue bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">744</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">745</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">746</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">747</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">748</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">749</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">750</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">751</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">752</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry pink mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">753</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">754</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">755</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">756</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">757</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">758</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">759</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">760</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">761</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">762</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">763</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">764</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">765</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">766</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">767</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall white desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">768</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">769</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome green car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">770</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">771</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">772</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">773</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">774</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">775</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">776</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">777</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">778</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">779</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">780</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">781</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">782</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">783</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">784</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">785</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">786</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">787</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important white pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">788</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">789</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">790</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">791</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">792</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">793</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">794</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">795</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">796</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant green sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">797</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">798</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">799</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">800</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy blue pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">801</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">802</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">803</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">804</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">805</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">806</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">807</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">808</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">809</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">810</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">811</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall black bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">812</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large blue house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">813</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">814</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">815</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">816</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">817</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean orange house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">818</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">819</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">820</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">821</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd pink bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">822</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">823</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">824</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">825</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint purple pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">826</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">827</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">828</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">829</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint blue pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">830</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">831</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">832</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">833</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">834</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">835</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">836</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">837</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">838</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">839</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">840</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">841</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">842</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">843</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">844</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">845</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain pink pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">846</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">847</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive purple pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">848</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">849</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">850</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy green cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">851</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">852</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short green pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">853</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big red keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">854</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">855</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">856</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">857</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">858</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">859</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">860</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">861</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy blue car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">862</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">863</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">864</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive yellow house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">865</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">866</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">867</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">868</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small pink car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">869</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">870</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">871</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">872</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant orange pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">873</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">874</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">875</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">876</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">877</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">878</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">879</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">880</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">881</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy blue desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">882</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">883</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly brown pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">884</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy white cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">885</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small white house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">886</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">887</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean purple chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">888</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">889</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important white burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">890</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">891</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">892</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">893</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">894</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">895</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big brown burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">896</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome red house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">897</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap green bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">898</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean orange mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">899</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly orange house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">900</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">901</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long red mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">902</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">903</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint orange pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">904</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">905</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">906</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd orange mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">907</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty red desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">908</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">909</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">910</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small purple burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">911</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">912</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big white keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">913</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable pink sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">914</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">915</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">916</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy pink bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">917</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint orange chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">918</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">919</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry yellow table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">920</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable yellow keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">921</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important white mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">922</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">923</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small orange keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">924</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">925</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">926</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly yellow chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">927</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">928</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">inexpensive white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">929</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">930</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">931</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant white bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">932</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">933</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">934</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">935</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful white table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">936</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long red cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">937</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">938</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd purple pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">939</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall purple desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">940</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">941</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall orange sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">942</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big blue burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">943</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful blue pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">944</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important brown sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">945</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">946</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small purple keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">947</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">948</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy green burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">949</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">950</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">951</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">952</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">953</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small blue cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">954</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large pink keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">955</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy brown cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">956</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome pink bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">957</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short purple mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">958</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy yellow car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">959</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">angry black burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">960</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">quaint black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">961</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">962</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large black desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">963</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">964</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful orange desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">965</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">large red table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">966</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">important pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">967</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall green mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">968</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">mushy yellow mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">969</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful brown chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">970</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful purple bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">971</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">easy yellow desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">972</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">small green pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">973</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable brown bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">974</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">tall red bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">975</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">976</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap purple sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">977</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">clean green pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">978</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">elegant pink house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">979</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">short purple car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">980</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">adorable white chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">981</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap blue mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">982</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long white car</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">983</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">crazy red burger</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">984</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">odd black cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">985</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">handsome black mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">986</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty yellow cookie</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">987</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">988</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly yellow pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">989</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">expensive black pizza</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">990</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">long green table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">991</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap orange mouse</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">992</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">pretty orange bbq</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">993</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">fancy purple house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">994</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly blue chair</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">995</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">cheap brown desk</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">996</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful pink pony</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">997</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">plain blue sandwich</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">998</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">helpful purple table</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">999</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">unsightly blue keyboard</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr><tr :class="item.id === selected ? 'danger' : ''" class="">
+              <td class="col-md-1" x-text="item.id">1000</td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label">big green house</a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)">x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr>
+        </tbody>
+      </table>
+
+      <span
+        class="preloadicon glyphicon glyphicon-remove"
+        aria-hidden="true"
+      ></span>
+    </div>
+
+    <script>
+        document.addEventListener('alpine:initializing', () => {
+            let idCounter = 1;
+            const adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"],
+            colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"],
+            nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
+
+            function _random (max) { return Math.round(Math.random() * 1000) % max; };
+
+            function buildData(count) {
+            let data = new Array(count);
+            for (let i = 0; i < count; i++) {
+                data[i] = {
+                id: idCounter++,
+                label: `${adjectives[_random(adjectives.length)]} ${colours[_random(colours.length)]} ${nouns[_random(nouns.length)]}`
+                }
+            }
+            return data;
+            }
+
+            Alpine.data('app', function() {
+                return {
+                    data: [],
+                    selected: undefined,
+
+                    add() { this.data = this.data.concat(buildData(1000)) },
+                    clear() {
+                        let start = performance.now()
+                        this.data = [];
+                        this.selected = undefined;
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    update() {
+                        let start = performance.now()
+                        for (let i = 0; i < this.data.length; i += 10) {
+                            this.data[i].label += ' !!!';
+                        }
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    remove(id) {
+                        let start = performance.now()
+                        const idx = this.data.findIndex(d => d.id === id);
+                        this.data.splice(idx, 1);
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    run() {
+                        let start = performance.now()
+                        this.data = buildData(1000);
+                        this.selected = undefined;
+                        setTimeout(() => {
+
+                        }, 0)
+                    },
+                    runLots() {
+                        let start = performance.now()
+                        this.data = buildData(10000);
+                        this.selected = undefined;
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    select(id) { this.selected = id },
+                    swapRows() {
+                        const d = this.data;
+                        if (d.length > 998) {
+                            const tmp = d[998];
+                            d[998] = d[1];
+                            d[1] = tmp;
+                        }
+                    }
+                }
+            })
+        })
+    </script>
+  </body>
+</html>

+ 201 - 0
benchmarks/loop.html

@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <title>Alpine-3-keyed</title>
+    <link href="/css/currentStyle.css" rel="stylesheet" />
+    <script src="http://alpine-next.test/packages/alpinejs/dist/cdn.js" defer></script>
+    <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
+  </head>
+  <body>
+    <div class="container" id="main" x-data="{ data: []}">
+      <div class="jumbotron">
+        <div class="row">
+          <div class="col-md-6">
+            <h1>Alpine-3-keyed</h1>
+          </div>
+          <div class="col-md-6">
+            <div class="row">
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="run"
+                  @click="run"
+                >
+                  Create 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="runlots"
+                  @click="runLots"
+                >
+                  Create 10,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="add"
+                  @click="add"
+                >
+                  Append 1,000 rows
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="update"
+                  @click="update"
+                >
+                  Update every 10th row
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="clear"
+                  @click="clear"
+                >
+                  Clear
+                </button>
+              </div>
+              <div class="col-sm-6 smallpad">
+                <button
+                  type="button"
+                  class="btn btn-primary btn-block"
+                  id="swaprows"
+                  @click="swapRows"
+                >
+                  Swap Rows
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <table class="table table-hover table-striped test-data">
+        <tbody>
+          <template x-for="item in data" :key="item.id">
+            <tr :class="item.id === selected ? 'danger' : ''">
+              <td class="col-md-1" x-text="item.id"></td>
+              <td class="col-md-4">
+                <a @click="select(item.id)" x-text="item.label"></a>
+              </td>
+              <td class="col-md-1">
+                <a @click="remove(item.id)" >x</a>
+              </td>
+              <td class="col-md-6"></td>
+            </tr>
+          </template>
+        </tbody>
+      </table>
+
+      <span
+        class="preloadicon glyphicon glyphicon-remove"
+        aria-hidden="true"
+      ></span>
+    </div>
+
+    <script>
+            let idCounter = 1;
+            const adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"],
+            colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"],
+            nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
+
+            function _random (max) { return Math.round(Math.random() * 1000) % max; };
+
+            function buildData(count) {
+            let data = new Array(count);
+            for (let i = 0; i < count; i++) {
+                data[i] = {
+                id: idCounter++,
+                label: `${adjectives[_random(adjectives.length)]} ${colours[_random(colours.length)]} ${nouns[_random(nouns.length)]}`
+                }
+            }
+            return data;
+            }
+
+            function app() {
+                return {
+                    data: [],
+                    selected: undefined,
+
+                    add() {
+                        let start = performance.now()
+                        this.data = this.data.concat(buildData(1000))
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    clear() {
+                        let start = performance.now()
+                        this.data = [];
+                        this.selected = undefined;
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    update() {
+                        let start = performance.now()
+                        for (let i = 0; i < this.data.length; i += 10) {
+                            this.data[i].label += ' !!!';
+                        }
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    remove(id) {
+                        let start = performance.now()
+                        const idx = this.data.findIndex(d => d.id === id);
+                        this.data.splice(idx, 1);
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    run() {
+                        let start = performance.now()
+                        this.data = buildData(100);
+                        this.selected = undefined;
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    runLots() {
+                        let start = performance.now()
+                        this.data = buildData(10000);
+                        this.selected = undefined;
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    select(id) {
+                        let start = performance.now()
+                        this.selected = id
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    },
+                    swapRows() {
+                        let start = performance.now()
+                        const d = this.data;
+                        if (d.length > 998) {
+                            const tmp = d[998];
+                            d[998] = d[1];
+                            d[1] = tmp;
+                        }
+                        setTimeout(() => {
+                            console.log(performance.now() - start);
+                        }, 0)
+                    }
+                }
+            }
+    </script>
+  </body>
+</html>

+ 17 - 0
benchmarks/memory.html

@@ -0,0 +1,17 @@
+<html>
+    <script src="http://alpine-next.test/packages/alpinejs/dist/cdn.js" defer></script>
+
+    <div x-data="{ items: [] }">
+        <template x-for="item in items">
+            <h1>hi</h1>
+        </template>
+
+        <button @click="items.length === 0 ? items.push('ggoo') : items = []" x-text="'ghjghj'">delete</button>
+    </div>
+
+    <script>
+        function remove() {
+            document.querySelector('span').remove()
+        }
+    </script>
+</html>

+ 65 - 0
benchmarks/mutation_observer.html

@@ -0,0 +1,65 @@
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+    <script>
+        let mutations = []
+
+        let pauseCollection = false
+
+        function reverseMutation(mutation) {
+            let table = {
+                characterData: () => {
+                    mutation.target.textContent = mutation.oldValue
+                },
+                attributes: () => {
+                    if (! mutation.oldValue) {
+                        mutation.target.removeAttribute(mutation.attributeName)
+                        return
+                    }
+
+                    mutation.target.setAttribute(mutation.attributeName, mutation.oldValue)
+                },
+                childList: () => {
+                    if (mutation.removedNodes) {
+                        let parent = mutation.target
+                    }
+                }
+            }
+
+            console.log(mutation);
+            table[mutation.type]()
+        }
+
+        function reverse() {
+            pauseCollection = true
+
+            while (mutations.length > 0) reverseMutation(mutations.pop())
+
+            pauseCollection = false
+        }
+
+        document.addEventListener('DOMContentLoaded', () => {
+            let observer = new MutationObserver(imutations => {
+                if (pauseCollection) return
+
+                imutations.forEach(i => mutations.push(i))
+
+                console.log(imutations);
+            })
+
+            observer.observe(document.body, { characterData: true, attributeOldValue: true, characterDataOldValue: true, childList: true, subtree: true, attributes: true })
+        })
+    </script>
+</head>
+<body>
+    <div>
+        <h1 foo="bar">yo</h1>
+        <h1>there</h1>
+
+        <button>this is cool</button>
+    </div>
+</body>
+</html>

+ 11 - 0
cypress.json

@@ -0,0 +1,11 @@
+{
+    "ignoreTestFiles": "*.html",
+    "screenshotOnRunFailure": false,
+    "video": false,
+    "fixturesFolder": "tests/cypress/fixtures",
+    "integrationFolder": "tests/cypress/integration",
+    "pluginsFile": "tests/cypress/plugins/index.js",
+    "screenshotsFolder": "tests/cypress/screenshots",
+    "videosFolder": "tests/cypress/videos",
+    "supportFile": "tests/cypress/support/index.js"
+}

+ 0 - 8042
dist/alpine-ie11.js

@@ -1,8042 +0,0 @@
-(function (factory) {
-  typeof define === 'function' && define.amd ? define(factory) :
-  factory();
-}((function () { 'use strict';
-
-  (function() {
-
-    var select = HTMLSelectElement.prototype;
-    if (select.hasOwnProperty("selectedOptions")) return
-
-    Object.defineProperty(select, "selectedOptions", {
-      get: function() {
-        return this.querySelectorAll(":checked")
-      },
-      enumerable: true,
-      configurable: true,
-    });
-  })();
-
-  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
-
-  function createCommonjsModule(fn, module) {
-  	return module = { exports: {} }, fn(module, module.exports), module.exports;
-  }
-
-  (function(){function n(){function v(){return null}function l(a){return a?"object"===typeof a||"function"===typeof a:!1}function p(a){if(null!==a&&!l(a))throw new TypeError("Object prototype may only be an Object or null: "+a);}var q=null,e=Object,w=!!e.create||!({__proto__:null}instanceof e),A=e.create||(w?function(a){p(a);return {__proto__:a}}:function(a){function c(){}p(a);if(null===a)throw new SyntaxError("Native Object.create is required to create objects with null prototype");c.prototype=a;return new c}),
-  B=e.getPrototypeOf||([].__proto__===Array.prototype?function(a){a=a.__proto__;return l(a)?a:null}:v);var m=function(a,c){function k(){}if(void 0===(this&&this instanceof m?this.constructor:void 0))throw new TypeError("Constructor Proxy requires 'new'");if(!l(a)||!l(c))throw new TypeError("Cannot create proxy with a non-object as target or handler");q=function(){a=null;k=function(b){throw new TypeError("Cannot perform '"+b+"' on a proxy that has been revoked");};};setTimeout(function(){q=null;},0);var g=
-  c;c={get:null,set:null,apply:null,construct:null};for(var h in g){if(!(h in c))throw new TypeError("Proxy polyfill does not support trap '"+h+"'");c[h]=g[h];}"function"===typeof g&&(c.apply=g.apply.bind(g));g=B(a);var r=!1,t=!1;if("function"===typeof a){var f=function(){var b=this&&this.constructor===f,d=Array.prototype.slice.call(arguments);k(b?"construct":"apply");return b&&c.construct?c.construct.call(this,a,d):!b&&c.apply?c.apply(a,this,d):b?(d.unshift(a),new (a.bind.apply(a,d))):a.apply(this,
-  d)};r=!0;}else a instanceof Array?(f=[],t=!0):f=w||null!==g?A(g):{};var x=c.get?function(b){k("get");return c.get(this,b,f)}:function(b){k("get");return this[b]},C=c.set?function(b,d){k("set");c.set(this,b,d,f);}:function(b,d){k("set");this[b]=d;},y={};e.getOwnPropertyNames(a).forEach(function(b){if(!((r||t)&&b in f)){var d=e.getOwnPropertyDescriptor(a,b);e.defineProperty(f,b,{enumerable:!!d.enumerable,get:x.bind(a,b),set:C.bind(a,b)});y[b]=!0;}});h=!0;if(r||t){var D=e.setPrototypeOf||([].__proto__===
-  Array.prototype?function(b,d){p(d);b.__proto__=d;return b}:v);g&&D(f,g)||(h=!1);}if(c.get||!h)for(var u in a)y[u]||e.defineProperty(f,u,{get:x.bind(a,u)});e.seal(a);e.seal(f);return f};m.revocable=function(a,c){return {proxy:new m(a,c),revoke:q}};return m}var z="undefined"!==typeof process&&"[object process]"==={}.toString.call(process)||"undefined"!==typeof navigator&&"ReactNative"===navigator.product?commonjsGlobal:self;z.Proxy||(z.Proxy=n(),z.Proxy.revocable=z.Proxy.revocable);})();
-
-  !function(e){var t=e.Element.prototype;"function"!=typeof t.matches&&(t.matches=t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||function(e){for(var t=(this.document||this.ownerDocument).querySelectorAll(e),o=0;t[o]&&t[o]!==this;)++o;return Boolean(t[o])}),"function"!=typeof t.closest&&(t.closest=function(e){for(var t=this;t&&1===t.nodeType;){if(t.matches(e))return t;t=t.parentNode;}return null});}(window);
-
-  (function (arr) {
-    arr.forEach(function (item) {
-      if (item.hasOwnProperty('remove')) {
-        return;
-      }
-      Object.defineProperty(item, 'remove', {
-        configurable: true,
-        enumerable: true,
-        writable: true,
-        value: function remove() {
-          this.parentNode && this.parentNode.removeChild(this);
-        }
-      });
-    });
-  })([Element.prototype, CharacterData.prototype, DocumentType.prototype].filter(Boolean));
-
-  /*
-   * classList.js: Cross-browser full element.classList implementation.
-   * 1.1.20170427
-   *
-   * By Eli Grey, http://eligrey.com
-   * License: Dedicated to the public domain.
-   *   See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
-   */
-
-  /*global self, document, DOMException */
-
-  /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
-
-  if ("document" in window.self) {
-
-  // Full polyfill for browsers with no classList support
-  // Including IE < Edge missing SVGElement.classList
-  if (!("classList" in document.createElement("_")) 
-  	|| document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {
-
-  (function (view) {
-
-  if (!('Element' in view)) return;
-
-  var
-  	  classListProp = "classList"
-  	, protoProp = "prototype"
-  	, elemCtrProto = view.Element[protoProp]
-  	, objCtr = Object
-  	, strTrim = String[protoProp].trim || function () {
-  		return this.replace(/^\s+|\s+$/g, "");
-  	}
-  	, arrIndexOf = Array[protoProp].indexOf || function (item) {
-  		var
-  			  i = 0
-  			, len = this.length
-  		;
-  		for (; i < len; i++) {
-  			if (i in this && this[i] === item) {
-  				return i;
-  			}
-  		}
-  		return -1;
-  	}
-  	// Vendors: please allow content code to instantiate DOMExceptions
-  	, DOMEx = function (type, message) {
-  		this.name = type;
-  		this.code = DOMException[type];
-  		this.message = message;
-  	}
-  	, checkTokenAndGetIndex = function (classList, token) {
-  		if (token === "") {
-  			throw new DOMEx(
-  				  "SYNTAX_ERR"
-  				, "An invalid or illegal string was specified"
-  			);
-  		}
-  		if (/\s/.test(token)) {
-  			throw new DOMEx(
-  				  "INVALID_CHARACTER_ERR"
-  				, "String contains an invalid character"
-  			);
-  		}
-  		return arrIndexOf.call(classList, token);
-  	}
-  	, ClassList = function (elem) {
-  		var
-  			  trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
-  			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
-  			, i = 0
-  			, len = classes.length
-  		;
-  		for (; i < len; i++) {
-  			this.push(classes[i]);
-  		}
-  		this._updateClassName = function () {
-  			elem.setAttribute("class", this.toString());
-  		};
-  	}
-  	, classListProto = ClassList[protoProp] = []
-  	, classListGetter = function () {
-  		return new ClassList(this);
-  	}
-  ;
-  // Most DOMException implementations don't allow calling DOMException's toString()
-  // on non-DOMExceptions. Error's toString() is sufficient here.
-  DOMEx[protoProp] = Error[protoProp];
-  classListProto.item = function (i) {
-  	return this[i] || null;
-  };
-  classListProto.contains = function (token) {
-  	token += "";
-  	return checkTokenAndGetIndex(this, token) !== -1;
-  };
-  classListProto.add = function () {
-  	var
-  		  tokens = arguments
-  		, i = 0
-  		, l = tokens.length
-  		, token
-  		, updated = false
-  	;
-  	do {
-  		token = tokens[i] + "";
-  		if (checkTokenAndGetIndex(this, token) === -1) {
-  			this.push(token);
-  			updated = true;
-  		}
-  	}
-  	while (++i < l);
-
-  	if (updated) {
-  		this._updateClassName();
-  	}
-  };
-  classListProto.remove = function () {
-  	var
-  		  tokens = arguments
-  		, i = 0
-  		, l = tokens.length
-  		, token
-  		, updated = false
-  		, index
-  	;
-  	do {
-  		token = tokens[i] + "";
-  		index = checkTokenAndGetIndex(this, token);
-  		while (index !== -1) {
-  			this.splice(index, 1);
-  			updated = true;
-  			index = checkTokenAndGetIndex(this, token);
-  		}
-  	}
-  	while (++i < l);
-
-  	if (updated) {
-  		this._updateClassName();
-  	}
-  };
-  classListProto.toggle = function (token, force) {
-  	token += "";
-
-  	var
-  		  result = this.contains(token)
-  		, method = result ?
-  			force !== true && "remove"
-  		:
-  			force !== false && "add"
-  	;
-
-  	if (method) {
-  		this[method](token);
-  	}
-
-  	if (force === true || force === false) {
-  		return force;
-  	} else {
-  		return !result;
-  	}
-  };
-  classListProto.toString = function () {
-  	return this.join(" ");
-  };
-
-  if (objCtr.defineProperty) {
-  	var classListPropDesc = {
-  		  get: classListGetter
-  		, enumerable: true
-  		, configurable: true
-  	};
-  	try {
-  		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
-  	} catch (ex) { // IE 8 doesn't support enumerable:true
-  		// adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36
-  		// modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected
-  		if (ex.number === undefined || ex.number === -0x7FF5EC54) {
-  			classListPropDesc.enumerable = false;
-  			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
-  		}
-  	}
-  } else if (objCtr[protoProp].__defineGetter__) {
-  	elemCtrProto.__defineGetter__(classListProp, classListGetter);
-  }
-
-  }(window.self));
-
-  }
-
-  // There is full or partial native classList support, so just check if we need
-  // to normalize the add/remove and toggle APIs.
-
-  (function () {
-
-  	var testElement = document.createElement("_");
-
-  	testElement.classList.add("c1", "c2");
-
-  	// Polyfill for IE 10/11 and Firefox <26, where classList.add and
-  	// classList.remove exist but support only one argument at a time.
-  	if (!testElement.classList.contains("c2")) {
-  		var createMethod = function(method) {
-  			var original = DOMTokenList.prototype[method];
-
-  			DOMTokenList.prototype[method] = function(token) {
-  				var i, len = arguments.length;
-
-  				for (i = 0; i < len; i++) {
-  					token = arguments[i];
-  					original.call(this, token);
-  				}
-  			};
-  		};
-  		createMethod('add');
-  		createMethod('remove');
-  	}
-
-  	testElement.classList.toggle("c3", false);
-
-  	// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
-  	// support the second argument.
-  	if (testElement.classList.contains("c3")) {
-  		var _toggle = DOMTokenList.prototype.toggle;
-
-  		DOMTokenList.prototype.toggle = function(token, force) {
-  			if (1 in arguments && !this.contains(token) === !force) {
-  				return force;
-  			} else {
-  				return _toggle.call(this, token);
-  			}
-  		};
-
-  	}
-
-  	testElement = null;
-  }());
-
-  }
-
-  /**
-   * @license
-   * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
-   * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-   * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-   * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-   * Code distributed by Google as part of the polymer project is also
-   * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-   */
-
-  // minimal template polyfill
-  (function() {
-
-    var needsTemplate = (typeof HTMLTemplateElement === 'undefined');
-    var brokenDocFragment = !(document.createDocumentFragment().cloneNode() instanceof DocumentFragment);
-    var needsDocFrag = false;
-
-    // NOTE: Replace DocumentFragment to work around IE11 bug that
-    // causes children of a document fragment modified while
-    // there is a mutation observer to not have a parentNode, or
-    // have a broken parentNode (!?!)
-    if (/Trident/.test(navigator.userAgent)) {
-      (function() {
-
-        needsDocFrag = true;
-
-        var origCloneNode = Node.prototype.cloneNode;
-        Node.prototype.cloneNode = function cloneNode(deep) {
-          var newDom = origCloneNode.call(this, deep);
-          if (this instanceof DocumentFragment) {
-            newDom.__proto__ = DocumentFragment.prototype;
-          }
-          return newDom;
-        };
-
-        // IE's DocumentFragment querySelector code doesn't work when
-        // called on an element instance
-        DocumentFragment.prototype.querySelectorAll = HTMLElement.prototype.querySelectorAll;
-        DocumentFragment.prototype.querySelector = HTMLElement.prototype.querySelector;
-
-        Object.defineProperties(DocumentFragment.prototype, {
-          'nodeType': {
-            get: function () {
-              return Node.DOCUMENT_FRAGMENT_NODE;
-            },
-            configurable: true
-          },
-
-          'localName': {
-            get: function () {
-              return undefined;
-            },
-            configurable: true
-          },
-
-          'nodeName': {
-            get: function () {
-              return '#document-fragment';
-            },
-            configurable: true
-          }
-        });
-
-        var origInsertBefore = Node.prototype.insertBefore;
-        function insertBefore(newNode, refNode) {
-          if (newNode instanceof DocumentFragment) {
-            var child;
-            while ((child = newNode.firstChild)) {
-              origInsertBefore.call(this, child, refNode);
-            }
-          } else {
-            origInsertBefore.call(this, newNode, refNode);
-          }
-          return newNode;
-        }
-        Node.prototype.insertBefore = insertBefore;
-
-        var origAppendChild = Node.prototype.appendChild;
-        Node.prototype.appendChild = function appendChild(child) {
-          if (child instanceof DocumentFragment) {
-            insertBefore.call(this, child, null);
-          } else {
-            origAppendChild.call(this, child);
-          }
-          return child;
-        };
-
-        var origRemoveChild = Node.prototype.removeChild;
-        var origReplaceChild = Node.prototype.replaceChild;
-        Node.prototype.replaceChild = function replaceChild(newChild, oldChild) {
-          if (newChild instanceof DocumentFragment) {
-            insertBefore.call(this, newChild, oldChild);
-            origRemoveChild.call(this, oldChild);
-          } else {
-            origReplaceChild.call(this, newChild, oldChild);
-          }
-          return oldChild;
-        };
-
-        Document.prototype.createDocumentFragment = function createDocumentFragment() {
-          var frag = this.createElement('df');
-          frag.__proto__ = DocumentFragment.prototype;
-          return frag;
-        };
-
-        var origImportNode = Document.prototype.importNode;
-        Document.prototype.importNode = function importNode(impNode, deep) {
-          deep = deep || false;
-          var newNode = origImportNode.call(this, impNode, deep);
-          if (impNode instanceof DocumentFragment) {
-            newNode.__proto__ = DocumentFragment.prototype;
-          }
-          return newNode;
-        };
-      })();
-    }
-
-    // NOTE: we rely on this cloneNode not causing element upgrade.
-    // This means this polyfill must load before the CE polyfill and
-    // this would need to be re-worked if a browser supports native CE
-    // but not <template>.
-    var capturedCloneNode = Node.prototype.cloneNode;
-    var capturedCreateElement = Document.prototype.createElement;
-    var capturedImportNode = Document.prototype.importNode;
-    var capturedRemoveChild = Node.prototype.removeChild;
-    var capturedAppendChild = Node.prototype.appendChild;
-    var capturedReplaceChild = Node.prototype.replaceChild;
-    var capturedParseFromString = DOMParser.prototype.parseFromString;
-    var capturedHTMLElementInnerHTML = Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML') || {
-      /**
-       * @this {!HTMLElement}
-       * @return {string}
-       */
-      get: function() {
-        return this.innerHTML;
-      },
-      /**
-       * @this {!HTMLElement}
-       * @param {string}
-       */
-      set: function(text) {
-        this.innerHTML = text;
-      }
-    };
-    var capturedChildNodes = Object.getOwnPropertyDescriptor(window.Node.prototype, 'childNodes') || {
-      /**
-       * @this {!Node}
-       * @return {!NodeList}
-       */
-      get: function() {
-        return this.childNodes;
-      }
-    };
-
-    var elementQuerySelectorAll = Element.prototype.querySelectorAll;
-    var docQuerySelectorAll = Document.prototype.querySelectorAll;
-    var fragQuerySelectorAll = DocumentFragment.prototype.querySelectorAll;
-
-    var scriptSelector = 'script:not([type]),script[type="application/javascript"],script[type="text/javascript"]';
-
-    function QSA(node, selector) {
-      // IE 11 throws a SyntaxError with `scriptSelector` if the node has no children due to the `:not([type])` syntax
-      if (!node.childNodes.length) {
-        return [];
-      }
-      switch (node.nodeType) {
-        case Node.DOCUMENT_NODE:
-          return docQuerySelectorAll.call(node, selector);
-        case Node.DOCUMENT_FRAGMENT_NODE:
-          return fragQuerySelectorAll.call(node, selector);
-        default:
-          return elementQuerySelectorAll.call(node, selector);
-      }
-    }
-
-    // returns true if nested templates cannot be cloned (they cannot be on
-    // some impl's like Safari 8 and Edge)
-    // OR if cloning a document fragment does not result in a document fragment
-    var needsCloning = (function() {
-      if (!needsTemplate) {
-        var t = document.createElement('template');
-        var t2 = document.createElement('template');
-        t2.content.appendChild(document.createElement('div'));
-        t.content.appendChild(t2);
-        var clone = t.cloneNode(true);
-        return (clone.content.childNodes.length === 0 || clone.content.firstChild.content.childNodes.length === 0
-          || brokenDocFragment);
-      }
-    })();
-
-    var TEMPLATE_TAG = 'template';
-    var PolyfilledHTMLTemplateElement = function() {};
-
-    if (needsTemplate) {
-
-      var contentDoc = document.implementation.createHTMLDocument('template');
-      var canDecorate = true;
-
-      var templateStyle = document.createElement('style');
-      templateStyle.textContent = TEMPLATE_TAG + '{display:none;}';
-
-      var head = document.head;
-      head.insertBefore(templateStyle, head.firstElementChild);
-
-      /**
-        Provides a minimal shim for the <template> element.
-      */
-      PolyfilledHTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
-
-
-      // if elements do not have `innerHTML` on instances, then
-      // templates can be patched by swizzling their prototypes.
-      var canProtoPatch =
-        !(document.createElement('div').hasOwnProperty('innerHTML'));
-
-      /**
-        The `decorate` method moves element children to the template's `content`.
-        NOTE: there is no support for dynamically adding elements to templates.
-      */
-      PolyfilledHTMLTemplateElement.decorate = function(template) {
-        // if the template is decorated or not in HTML namespace, return fast
-        if (template.content ||
-            template.namespaceURI !== document.documentElement.namespaceURI) {
-          return;
-        }
-        template.content = contentDoc.createDocumentFragment();
-        var child;
-        while ((child = template.firstChild)) {
-          capturedAppendChild.call(template.content, child);
-        }
-        // NOTE: prefer prototype patching for performance and
-        // because on some browsers (IE11), re-defining `innerHTML`
-        // can result in intermittent errors.
-        if (canProtoPatch) {
-          template.__proto__ = PolyfilledHTMLTemplateElement.prototype;
-        } else {
-          template.cloneNode = function(deep) {
-            return PolyfilledHTMLTemplateElement._cloneNode(this, deep);
-          };
-          // add innerHTML to template, if possible
-          // Note: this throws on Safari 7
-          if (canDecorate) {
-            try {
-              defineInnerHTML(template);
-              defineOuterHTML(template);
-            } catch (err) {
-              canDecorate = false;
-            }
-          }
-        }
-        // bootstrap recursively
-        PolyfilledHTMLTemplateElement.bootstrap(template.content);
-      };
-
-      // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js
-      var topLevelWrappingMap = {
-        'option': ['select'],
-        'thead': ['table'],
-        'col': ['colgroup', 'table'],
-        'tr': ['tbody', 'table'],
-        'th': ['tr', 'tbody', 'table'],
-        'td': ['tr', 'tbody', 'table']
-      };
-
-      var getTagName = function(text) {
-        // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/var/rtagName.js
-        return ( /<([a-z][^/\0>\x20\t\r\n\f]+)/i.exec(text) || ['', ''])[1].toLowerCase();
-      };
-
-      var defineInnerHTML = function defineInnerHTML(obj) {
-        Object.defineProperty(obj, 'innerHTML', {
-          get: function() {
-            return getInnerHTML(this);
-          },
-          set: function(text) {
-            // For IE11, wrap the text in the correct (table) context
-            var wrap = topLevelWrappingMap[getTagName(text)];
-            if (wrap) {
-              for (var i = 0; i < wrap.length; i++) {
-                text = '<' + wrap[i] + '>' + text + '</' + wrap[i] + '>';
-              }
-            }
-            contentDoc.body.innerHTML = text;
-            PolyfilledHTMLTemplateElement.bootstrap(contentDoc);
-            while (this.content.firstChild) {
-              capturedRemoveChild.call(this.content, this.content.firstChild);
-            }
-            var body = contentDoc.body;
-            // If we had wrapped, get back to the original node
-            if (wrap) {
-              for (var j = 0; j < wrap.length; j++) {
-                body = body.lastChild;
-              }
-            }
-            while (body.firstChild) {
-              capturedAppendChild.call(this.content, body.firstChild);
-            }
-          },
-          configurable: true
-        });
-      };
-
-      var defineOuterHTML = function defineOuterHTML(obj) {
-        Object.defineProperty(obj, 'outerHTML', {
-          get: function() {
-            return '<' + TEMPLATE_TAG + '>' + this.innerHTML + '</' + TEMPLATE_TAG + '>';
-          },
-          set: function(innerHTML) {
-            if (this.parentNode) {
-              contentDoc.body.innerHTML = innerHTML;
-              var docFrag = this.ownerDocument.createDocumentFragment();
-              while (contentDoc.body.firstChild) {
-                capturedAppendChild.call(docFrag, contentDoc.body.firstChild);
-              }
-              capturedReplaceChild.call(this.parentNode, docFrag, this);
-            } else {
-              throw new Error("Failed to set the 'outerHTML' property on 'Element': This element has no parent node.");
-            }
-          },
-          configurable: true
-        });
-      };
-
-      defineInnerHTML(PolyfilledHTMLTemplateElement.prototype);
-      defineOuterHTML(PolyfilledHTMLTemplateElement.prototype);
-
-      /**
-        The `bootstrap` method is called automatically and "fixes" all
-        <template> elements in the document referenced by the `doc` argument.
-      */
-      PolyfilledHTMLTemplateElement.bootstrap = function bootstrap(doc) {
-        var templates = QSA(doc, TEMPLATE_TAG);
-        for (var i=0, l=templates.length, t; (i<l) && (t=templates[i]); i++) {
-          PolyfilledHTMLTemplateElement.decorate(t);
-        }
-      };
-
-      // auto-bootstrapping for main document
-      document.addEventListener('DOMContentLoaded', function() {
-        PolyfilledHTMLTemplateElement.bootstrap(document);
-      });
-
-      // Patch document.createElement to ensure newly created templates have content
-      Document.prototype.createElement = function createElement() {
-        var el = capturedCreateElement.apply(this, arguments);
-        if (el.localName === 'template') {
-          PolyfilledHTMLTemplateElement.decorate(el);
-        }
-        return el;
-      };
-
-      DOMParser.prototype.parseFromString = function() {
-        var el = capturedParseFromString.apply(this, arguments);
-        PolyfilledHTMLTemplateElement.bootstrap(el);
-        return el;
-      };
-
-      Object.defineProperty(HTMLElement.prototype, 'innerHTML', {
-        get: function() {
-          return getInnerHTML(this);
-        },
-        set: function(text) {
-          capturedHTMLElementInnerHTML.set.call(this, text);
-          PolyfilledHTMLTemplateElement.bootstrap(this);
-        },
-        configurable: true,
-        enumerable: true
-      });
-
-      // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
-      var escapeAttrRegExp = /[&\u00A0"]/g;
-      var escapeDataRegExp = /[&\u00A0<>]/g;
-
-      var escapeReplace = function(c) {
-        switch (c) {
-          case '&':
-            return '&amp;';
-          case '<':
-            return '&lt;';
-          case '>':
-            return '&gt;';
-          case '"':
-            return '&quot;';
-          case '\u00A0':
-            return '&nbsp;';
-        }
-      };
-
-      var escapeAttr = function(s) {
-        return s.replace(escapeAttrRegExp, escapeReplace);
-      };
-
-      var escapeData = function(s) {
-        return s.replace(escapeDataRegExp, escapeReplace);
-      };
-
-      var makeSet = function(arr) {
-        var set = {};
-        for (var i = 0; i < arr.length; i++) {
-          set[arr[i]] = true;
-        }
-        return set;
-      };
-
-      // http://www.whatwg.org/specs/web-apps/current-work/#void-elements
-      var voidElements = makeSet([
-        'area',
-        'base',
-        'br',
-        'col',
-        'command',
-        'embed',
-        'hr',
-        'img',
-        'input',
-        'keygen',
-        'link',
-        'meta',
-        'param',
-        'source',
-        'track',
-        'wbr'
-      ]);
-
-      var plaintextParents = makeSet([
-        'style',
-        'script',
-        'xmp',
-        'iframe',
-        'noembed',
-        'noframes',
-        'plaintext',
-        'noscript'
-      ]);
-
-      /**
-       * @param {Node} node
-       * @param {Node} parentNode
-       * @param {Function=} callback
-       */
-      var getOuterHTML = function(node, parentNode, callback) {
-        switch (node.nodeType) {
-          case Node.ELEMENT_NODE: {
-            var tagName = node.localName;
-            var s = '<' + tagName;
-            var attrs = node.attributes;
-            for (var i = 0, attr; (attr = attrs[i]); i++) {
-              s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
-            }
-            s += '>';
-            if (voidElements[tagName]) {
-              return s;
-            }
-            return s + getInnerHTML(node, callback) + '</' + tagName + '>';
-          }
-          case Node.TEXT_NODE: {
-            var data = /** @type {Text} */ (node).data;
-            if (parentNode && plaintextParents[parentNode.localName]) {
-              return data;
-            }
-            return escapeData(data);
-          }
-          case Node.COMMENT_NODE: {
-            return '<!--' + /** @type {Comment} */ (node).data + '-->';
-          }
-          default: {
-            window.console.error(node);
-            throw new Error('not implemented');
-          }
-        }
-      };
-
-      /**
-       * @param {Node} node
-       * @param {Function=} callback
-       */
-      var getInnerHTML = function(node, callback) {
-        if (node.localName === 'template') {
-          node =  /** @type {HTMLTemplateElement} */ (node).content;
-        }
-        var s = '';
-        var c$ = callback ? callback(node) : capturedChildNodes.get.call(node);
-        for (var i=0, l=c$.length, child; (i<l) && (child=c$[i]); i++) {
-          s += getOuterHTML(child, node, callback);
-        }
-        return s;
-      };
-
-    }
-
-    // make cloning/importing work!
-    if (needsTemplate || needsCloning) {
-
-      PolyfilledHTMLTemplateElement._cloneNode = function _cloneNode(template, deep) {
-        var clone = capturedCloneNode.call(template, false);
-        // NOTE: decorate doesn't auto-fix children because they are already
-        // decorated so they need special clone fixup.
-        if (this.decorate) {
-          this.decorate(clone);
-        }
-        if (deep) {
-          // NOTE: use native clone node to make sure CE's wrapped
-          // cloneNode does not cause elements to upgrade.
-          capturedAppendChild.call(clone.content, capturedCloneNode.call(template.content, true));
-          // now ensure nested templates are cloned correctly.
-          fixClonedDom(clone.content, template.content);
-        }
-        return clone;
-      };
-
-      // Given a source and cloned subtree, find <template>'s in the cloned
-      // subtree and replace them with cloned <template>'s from source.
-      // We must do this because only the source templates have proper .content.
-      var fixClonedDom = function fixClonedDom(clone, source) {
-        // do nothing if cloned node is not an element
-        if (!source.querySelectorAll) return;
-        // these two lists should be coincident
-        var s$ = QSA(source, TEMPLATE_TAG);
-        if (s$.length === 0) {
-          return;
-        }
-        var t$ = QSA(clone, TEMPLATE_TAG);
-        for (var i=0, l=t$.length, t, s; i<l; i++) {
-          s = s$[i];
-          t = t$[i];
-          if (PolyfilledHTMLTemplateElement && PolyfilledHTMLTemplateElement.decorate) {
-            PolyfilledHTMLTemplateElement.decorate(s);
-          }
-          capturedReplaceChild.call(t.parentNode, cloneNode.call(s, true), t);
-        }
-      };
-
-      // make sure scripts inside of a cloned template are executable
-      var fixClonedScripts = function fixClonedScripts(fragment) {
-        var scripts = QSA(fragment, scriptSelector);
-        for (var ns, s, i = 0; i < scripts.length; i++) {
-          s = scripts[i];
-          ns = capturedCreateElement.call(document, 'script');
-          ns.textContent = s.textContent;
-          var attrs = s.attributes;
-          for (var ai = 0, a; ai < attrs.length; ai++) {
-            a = attrs[ai];
-            ns.setAttribute(a.name, a.value);
-          }
-          capturedReplaceChild.call(s.parentNode, ns, s);
-        }
-      };
-
-      // override all cloning to fix the cloned subtree to contain properly
-      // cloned templates.
-      var cloneNode = Node.prototype.cloneNode = function cloneNode(deep) {
-        var dom;
-        // workaround for Edge bug cloning documentFragments
-        // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8619646/
-        if (!needsDocFrag && brokenDocFragment && this instanceof DocumentFragment) {
-          if (!deep) {
-            return this.ownerDocument.createDocumentFragment();
-          } else {
-            dom = importNode.call(this.ownerDocument, this, true);
-          }
-        } else if (this.nodeType === Node.ELEMENT_NODE &&
-                   this.localName === TEMPLATE_TAG &&
-                   this.namespaceURI == document.documentElement.namespaceURI) {
-          dom = PolyfilledHTMLTemplateElement._cloneNode(this, deep);
-        } else {
-          dom = capturedCloneNode.call(this, deep);
-        }
-        // template.content is cloned iff `deep`.
-        if (deep) {
-          fixClonedDom(dom, this);
-        }
-        return dom;
-      };
-
-      // NOTE: we are cloning instead of importing <template>'s.
-      // However, the ownerDocument of the cloned template will be correct!
-      // This is because the native import node creates the right document owned
-      // subtree and `fixClonedDom` inserts cloned templates into this subtree,
-      // thus updating the owner doc.
-      var importNode = Document.prototype.importNode = function importNode(element, deep) {
-        deep = deep || false;
-        if (element.localName === TEMPLATE_TAG) {
-          return PolyfilledHTMLTemplateElement._cloneNode(element, deep);
-        } else {
-          var dom = capturedImportNode.call(this, element, deep);
-          if (deep) {
-            fixClonedDom(dom, element);
-            fixClonedScripts(dom);
-          }
-          return dom;
-        }
-      };
-    }
-
-    if (needsTemplate) {
-      window.HTMLTemplateElement = PolyfilledHTMLTemplateElement;
-    }
-
-  })();
-
-  var ApplyThisPrototype = (function() {
-    return function ApplyThisPrototype(event, target) {
-      if ((typeof target === 'object') && (target !== null)) {
-        var proto = Object.getPrototypeOf(target);
-        var property;
-
-        for (property in proto) {
-          if (!(property in event)) {
-            var descriptor = Object.getOwnPropertyDescriptor(proto, property);
-            if (descriptor) {
-              Object.defineProperty(event, property, descriptor);
-            }
-          }
-        }
-
-        for (property in target) {
-          if (!(property in event)) {
-            event[property] = target[property];
-          }
-        }
-      }
-    }
-  })();
-
-  (function(ApplyThisPrototype) {
-    /**
-     * Polyfill CustomEvent
-     */
-    try {
-      var event = new window.CustomEvent('event', { bubbles: true, cancelable: true });
-    } catch (error) {
-      var CustomEventOriginal = window.CustomEvent || window.Event;
-      var CustomEvent = function(eventName, params) {
-        params = params || {};
-        var event = document.createEvent('CustomEvent');
-        event.initCustomEvent(
-          eventName,
-          (params.bubbles === void 0) ? false : params.bubbles,
-          (params.cancelable === void 0) ? false : params.cancelable,
-          (params.detail === void 0) ? {} : params.detail
-        );
-        ApplyThisPrototype(event, this);
-        return event;
-      };
-      CustomEvent.prototype = CustomEventOriginal.prototype;
-      window.CustomEvent = CustomEvent;
-    }
-  })(ApplyThisPrototype);
-
-  var EventListenerInterceptor = (function() {
-
-    if(typeof EventTarget === 'undefined') {
-      window.EventTarget = Node;
-    }
-
-    /**
-     * Event listener interceptor
-     */
-
-    var EventListenerInterceptor = {
-      interceptors: [] // { target: EventTarget, interceptors: [{ add: Function, remove: Function }, ...] }
-    };
-
-
-    /**
-     * Returns if exists a previously registered listener from a target and the normalized arguments
-     * @param target
-     * @param normalizedArguments
-     * @return {*}
-     */
-    EventListenerInterceptor.getRegisteredEventListener = function(target, normalizedArguments) {
-      var key = normalizedArguments.type + '-' + (normalizedArguments.options.capture ? '1' : '0');
-      if(
-        (target.__eventListeners !== void 0) &&
-        (target.__eventListeners[key] !== void 0)
-      ) {
-        var map = target.__eventListeners[key];
-        for(var i = 0; i < map.length; i++) {
-          if(map[i].listener === normalizedArguments.listener) {
-            return map[i];
-          }
-        }
-      }
-      return null;
-    };
-
-    /**
-     * Registers a listener on a target with some options
-     * @param target
-     * @param normalizedArguments
-     */
-    EventListenerInterceptor.registerEventListener = function(target, normalizedArguments) {
-      var key = normalizedArguments.type + '-' + (normalizedArguments.options.capture ? '1' : '0');
-
-      if(target.__eventListeners === void 0) {
-        target.__eventListeners = {};
-      }
-
-      if(target.__eventListeners[key] === void 0) {
-        target.__eventListeners[key] = [];
-      }
-
-      target.__eventListeners[key].push(normalizedArguments);
-    };
-
-    /**
-     * Unregisters a listener on a target with some options
-     * @param target
-     * @param normalizedArguments
-     */
-    EventListenerInterceptor.unregisterEventListener = function(target, normalizedArguments) {
-      var key = normalizedArguments.type + '-' + (normalizedArguments.options.capture ? '1' : '0');
-      if(
-        (target.__eventListeners !==  void 0) &&
-        (target.__eventListeners[key] !== void 0)
-      ) {
-        var map = target.__eventListeners[key];
-        for(var i = 0; i < map.length; i++) {
-          if(map[i].listener === normalizedArguments.listener) {
-            map.splice(i, 1);
-          }
-        }
-
-        if(map.length === 0) {
-          delete target.__eventListeners[key];
-        }
-      }
-    };
-
-
-
-    EventListenerInterceptor.normalizeListenerCallback = function(listener) {
-      if((typeof listener === 'function') || (listener === null) || (listener === void 0)) {
-        return listener;
-      } else if((typeof listener === 'object') && (typeof listener.handleEvent === 'function')) {
-        return listener.handleEvent;
-      } else {
-        // to support Symbol
-        return function(event) {
-          listener(event);
-        };
-      }
-    };
-
-    EventListenerInterceptor.normalizeListenerOptions = function(options) {
-      switch(typeof options) {
-        case 'boolean':
-          options = { capture: options };
-          break;
-        case 'undefined':
-          options = { capture: false };
-          break;
-        case 'object':
-          if (options === null) {
-            options = { capture: false };
-          }
-          break;
-        default:
-          throw new Error('Unsupported options type for addEventListener');
-      }
-
-      options.once      = Boolean(options.once);
-      options.passive   = Boolean(options.passive);
-      options.capture   = Boolean(options.capture);
-
-      return options;
-    };
-
-    EventListenerInterceptor.normalizeListenerArguments = function(type, listener, options) {
-      return {
-        type: type,
-        listener: this.normalizeListenerCallback(listener),
-        options: this.normalizeListenerOptions(options)
-      };
-    };
-
-
-
-    EventListenerInterceptor.intercept = function(target, interceptors) {
-      // get an interceptor with this target or null
-      var interceptor = null;
-      for (var i = 0; i < this.interceptors.length; i++) {
-        if(this.interceptors[i].target === target) {
-          interceptor = this.interceptors[i];
-        }
-      }
-
-      // if no interceptor already set
-      if (interceptor === null) {
-        interceptor = { target: target, interceptors: [interceptors] };
-        this.interceptors.push(interceptor);
-
-        this.interceptAddEventListener(target, interceptor);
-        this.interceptRemoveEventListener(target, interceptor);
-      } else { // if an interceptor already set, simply add interceptors to the list
-        interceptor.interceptors.push(interceptors);
-      }
-
-      // var release = function() {
-      //   target.prototype.addEventListener = addEventListener;
-      //   target.prototype.removeEventListener = removeEventListener;
-      // };
-      // this.interceptors.push(release);
-      // return release;
-    };
-
-    EventListenerInterceptor.interceptAddEventListener = function(target, interceptor) {
-      var _this = this;
-
-      var addEventListener = target.prototype.addEventListener;
-      target.prototype.addEventListener = function(type, listener, options) {
-        var normalizedArguments = _this.normalizeListenerArguments(type, listener, options);
-        var registeredEventListener = _this.getRegisteredEventListener(this, normalizedArguments);
-
-        if (!registeredEventListener) {
-
-          normalizedArguments.polyfilled = {
-            type: normalizedArguments.type,
-            listener: normalizedArguments.listener,
-            options: {
-              capture: normalizedArguments.options.capture,
-              once: normalizedArguments.options.once,
-              passive: normalizedArguments.options.passive
-            }
-          };
-
-          for (var i = 0; i < interceptor.interceptors.length; i++) {
-            var interceptors = interceptor.interceptors[i];
-            if (typeof interceptors.add === 'function') {
-              interceptors.add(normalizedArguments);
-            }
-          }
-
-          // console.log('normalizedArguments', normalizedArguments.polyfilled);
-
-          _this.registerEventListener(this, normalizedArguments);
-
-          addEventListener.call(
-            this,
-            normalizedArguments.polyfilled.type,
-            normalizedArguments.polyfilled.listener,
-            normalizedArguments.polyfilled.options
-          );
-        }
-      };
-
-      return function() {
-        target.prototype.addEventListener = addEventListener;
-      };
-    };
-
-    EventListenerInterceptor.interceptRemoveEventListener = function(target, interceptor) {
-      var _this = this;
-
-      var removeEventListener = target.prototype.removeEventListener;
-      target.prototype.removeEventListener = function(type, listener, options) {
-        var normalizedArguments = _this.normalizeListenerArguments(type, listener, options);
-        var registeredEventListener = _this.getRegisteredEventListener(this, normalizedArguments);
-
-        if (registeredEventListener) {
-          _this.unregisterEventListener(this, normalizedArguments);
-          removeEventListener.call(
-            this,
-            registeredEventListener.polyfilled.type,
-            registeredEventListener.polyfilled.listener,
-            registeredEventListener.polyfilled.options
-          );
-        } else {
-          removeEventListener.call(this, type, listener, options);
-        }
-      };
-
-      return function() {
-        target.prototype.removeEventListener = removeEventListener;
-      };
-    };
-
-    EventListenerInterceptor.interceptAll = function(interceptors) {
-      this.intercept(EventTarget, interceptors);
-      if(!(window instanceof EventTarget)) {
-        this.intercept(Window, interceptors);
-      }
-    };
-
-    EventListenerInterceptor.releaseAll = function() {
-      for(var i = 0, l = this.interceptors.length; i < l; i++) {
-        this.interceptors();
-      }
-    };
-
-
-    EventListenerInterceptor.error = function(error) {
-      // throw error;
-      console.error(error);
-    };
-
-    return EventListenerInterceptor;
-  })();
-
-  (function(EventListenerInterceptor) {
-    /**
-     * Event listener options support
-     */
-
-    EventListenerInterceptor.detectSupportedOptions = function() {
-      var _this = this;
-
-      this.supportedOptions = {
-        once: false,
-        passive: false,
-        capture: false,
-
-        all: false,
-        some: false
-      };
-
-      document.createDocumentFragment().addEventListener('test', function() {}, {
-        get once() {
-          _this.supportedOptions.once = true;
-          return false;
-        },
-        get passive() {
-          _this.supportedOptions.passive = true;
-          return false;
-        },
-        get capture() {
-          _this.supportedOptions.capture = true;
-          return false;
-        }
-      });
-
-      // useful shortcuts to detect if options are all/some supported
-      this.supportedOptions.all  = this.supportedOptions.once && this.supportedOptions.passive && this.supportedOptions.capture;
-      this.supportedOptions.some = this.supportedOptions.once || this.supportedOptions.passive || this.supportedOptions.capture;
-    };
-
-    EventListenerInterceptor.polyfillListenerOptions = function() {
-      this.detectSupportedOptions();
-      if (!this.supportedOptions.all) {
-        var _this = this;
-
-        this.interceptAll({
-          add: function(normalizedArguments) {
-            // console.log('intercepted', normalizedArguments);
-
-            var once = normalizedArguments.options.once && !_this.supportedOptions.once;
-            var passive = normalizedArguments.options.passive && !_this.supportedOptions.passive;
-
-            if (once || passive) {
-              var listener = normalizedArguments.polyfilled.listener;
-
-              normalizedArguments.polyfilled.listener = function(event) {
-                if(once) {
-                  this.removeEventListener(normalizedArguments.type, normalizedArguments.listener, normalizedArguments.options);
-                }
-
-                if(passive) {
-                  event.preventDefault = function() {
-                    throw new Error('Unable to preventDefault inside passive event listener invocation.');
-                  };
-                }
-
-                return listener.call(this, event);
-              };
-            }
-
-            if (!_this.supportedOptions.some) {
-              normalizedArguments.polyfilled.options = normalizedArguments.options.capture;
-            }
-          }
-        });
-      }
-    };
-
-
-    EventListenerInterceptor.polyfillListenerOptions();
-
-
-    // var onclick = function() {
-    //   console.log('click');
-    // };
-
-    // document.body.addEventListener('click', onclick, false);
-    // document.body.addEventListener('click', onclick, { once: true });
-    // document.body.addEventListener('click', onclick, { once: true });
-    // document.body.addEventListener('click', onclick, false);
-    // document.body.addEventListener('click', onclick, false);
-
-  })(EventListenerInterceptor);
-
-  // For the IE11 build.
-  SVGElement.prototype.contains = SVGElement.prototype.contains || HTMLElement.prototype.contains // .childElementCount polyfill
-  // from https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/childElementCount#Polyfill_for_IE8_IE9_Safari
-  ;
-
-  (function (constructor) {
-    if (constructor && constructor.prototype && constructor.prototype.childElementCount == null) {
-      Object.defineProperty(constructor.prototype, 'childElementCount', {
-        get: function get() {
-          var i = 0,
-              count = 0,
-              node,
-              nodes = this.childNodes;
-
-          while (node = nodes[i++]) {
-            if (node.nodeType === 1) count++;
-          }
-
-          return count;
-        }
-      });
-    }
-  })(window.Node || window.Element);
-
-  var check = function (it) {
-    return it && it.Math == Math && it;
-  };
-
-  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
-  var global_1 =
-    // eslint-disable-next-line no-undef
-    check(typeof globalThis == 'object' && globalThis) ||
-    check(typeof window == 'object' && window) ||
-    check(typeof self == 'object' && self) ||
-    check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
-    // eslint-disable-next-line no-new-func
-    (function () { return this; })() || Function('return this')();
-
-  var fails = function (exec) {
-    try {
-      return !!exec();
-    } catch (error) {
-      return true;
-    }
-  };
-
-  // Detect IE8's incomplete defineProperty implementation
-  var descriptors = !fails(function () {
-    return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
-  });
-
-  var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
-  var getOwnPropertyDescriptor$4 = Object.getOwnPropertyDescriptor;
-
-  // Nashorn ~ JDK8 bug
-  var NASHORN_BUG = getOwnPropertyDescriptor$4 && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
-
-  // `Object.prototype.propertyIsEnumerable` method implementation
-  // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
-  var f$5 = NASHORN_BUG ? function propertyIsEnumerable(V) {
-    var descriptor = getOwnPropertyDescriptor$4(this, V);
-    return !!descriptor && descriptor.enumerable;
-  } : nativePropertyIsEnumerable;
-
-  var objectPropertyIsEnumerable = {
-  	f: f$5
-  };
-
-  var createPropertyDescriptor = function (bitmap, value) {
-    return {
-      enumerable: !(bitmap & 1),
-      configurable: !(bitmap & 2),
-      writable: !(bitmap & 4),
-      value: value
-    };
-  };
-
-  var toString = {}.toString;
-
-  var classofRaw = function (it) {
-    return toString.call(it).slice(8, -1);
-  };
-
-  var split = ''.split;
-
-  // fallback for non-array-like ES3 and non-enumerable old V8 strings
-  var indexedObject = fails(function () {
-    // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
-    // eslint-disable-next-line no-prototype-builtins
-    return !Object('z').propertyIsEnumerable(0);
-  }) ? function (it) {
-    return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
-  } : Object;
-
-  // `RequireObjectCoercible` abstract operation
-  // https://tc39.es/ecma262/#sec-requireobjectcoercible
-  var requireObjectCoercible = function (it) {
-    if (it == undefined) throw TypeError("Can't call method on " + it);
-    return it;
-  };
-
-  // toObject with fallback for non-array-like ES3 strings
-
-
-
-  var toIndexedObject = function (it) {
-    return indexedObject(requireObjectCoercible(it));
-  };
-
-  var isObject = function (it) {
-    return typeof it === 'object' ? it !== null : typeof it === 'function';
-  };
-
-  // `ToPrimitive` abstract operation
-  // https://tc39.es/ecma262/#sec-toprimitive
-  // instead of the ES6 spec version, we didn't implement @@toPrimitive case
-  // and the second argument - flag - preferred type is a string
-  var toPrimitive = function (input, PREFERRED_STRING) {
-    if (!isObject(input)) return input;
-    var fn, val;
-    if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
-    if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
-    if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
-    throw TypeError("Can't convert object to primitive value");
-  };
-
-  var hasOwnProperty = {}.hasOwnProperty;
-
-  var has$1 = function (it, key) {
-    return hasOwnProperty.call(it, key);
-  };
-
-  var document$3 = global_1.document;
-  // typeof document.createElement is 'object' in old IE
-  var EXISTS = isObject(document$3) && isObject(document$3.createElement);
-
-  var documentCreateElement = function (it) {
-    return EXISTS ? document$3.createElement(it) : {};
-  };
-
-  // Thank's IE8 for his funny defineProperty
-  var ie8DomDefine = !descriptors && !fails(function () {
-    return Object.defineProperty(documentCreateElement('div'), 'a', {
-      get: function () { return 7; }
-    }).a != 7;
-  });
-
-  var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-
-  // `Object.getOwnPropertyDescriptor` method
-  // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
-  var f$4 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
-    O = toIndexedObject(O);
-    P = toPrimitive(P, true);
-    if (ie8DomDefine) try {
-      return nativeGetOwnPropertyDescriptor(O, P);
-    } catch (error) { /* empty */ }
-    if (has$1(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
-  };
-
-  var objectGetOwnPropertyDescriptor = {
-  	f: f$4
-  };
-
-  var anObject = function (it) {
-    if (!isObject(it)) {
-      throw TypeError(String(it) + ' is not an object');
-    } return it;
-  };
-
-  var nativeDefineProperty = Object.defineProperty;
-
-  // `Object.defineProperty` method
-  // https://tc39.es/ecma262/#sec-object.defineproperty
-  var f$3 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
-    anObject(O);
-    P = toPrimitive(P, true);
-    anObject(Attributes);
-    if (ie8DomDefine) try {
-      return nativeDefineProperty(O, P, Attributes);
-    } catch (error) { /* empty */ }
-    if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
-    if ('value' in Attributes) O[P] = Attributes.value;
-    return O;
-  };
-
-  var objectDefineProperty = {
-  	f: f$3
-  };
-
-  var createNonEnumerableProperty = descriptors ? function (object, key, value) {
-    return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
-  } : function (object, key, value) {
-    object[key] = value;
-    return object;
-  };
-
-  var setGlobal = function (key, value) {
-    try {
-      createNonEnumerableProperty(global_1, key, value);
-    } catch (error) {
-      global_1[key] = value;
-    } return value;
-  };
-
-  var SHARED = '__core-js_shared__';
-  var store$1 = global_1[SHARED] || setGlobal(SHARED, {});
-
-  var sharedStore = store$1;
-
-  var functionToString = Function.toString;
-
-  // this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
-  if (typeof sharedStore.inspectSource != 'function') {
-    sharedStore.inspectSource = function (it) {
-      return functionToString.call(it);
-    };
-  }
-
-  var inspectSource = sharedStore.inspectSource;
-
-  var WeakMap$1 = global_1.WeakMap;
-
-  var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource(WeakMap$1));
-
-  var shared = createCommonjsModule(function (module) {
-  (module.exports = function (key, value) {
-    return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
-  })('versions', []).push({
-    version: '3.8.3',
-    mode: 'global',
-    copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
-  });
-  });
-
-  var id = 0;
-  var postfix = Math.random();
-
-  var uid = function (key) {
-    return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
-  };
-
-  var keys$1 = shared('keys');
-
-  var sharedKey = function (key) {
-    return keys$1[key] || (keys$1[key] = uid(key));
-  };
-
-  var hiddenKeys$1 = {};
-
-  var WeakMap = global_1.WeakMap;
-  var set$2, get, has;
-
-  var enforce = function (it) {
-    return has(it) ? get(it) : set$2(it, {});
-  };
-
-  var getterFor = function (TYPE) {
-    return function (it) {
-      var state;
-      if (!isObject(it) || (state = get(it)).type !== TYPE) {
-        throw TypeError('Incompatible receiver, ' + TYPE + ' required');
-      } return state;
-    };
-  };
-
-  if (nativeWeakMap) {
-    var store = sharedStore.state || (sharedStore.state = new WeakMap());
-    var wmget = store.get;
-    var wmhas = store.has;
-    var wmset = store.set;
-    set$2 = function (it, metadata) {
-      metadata.facade = it;
-      wmset.call(store, it, metadata);
-      return metadata;
-    };
-    get = function (it) {
-      return wmget.call(store, it) || {};
-    };
-    has = function (it) {
-      return wmhas.call(store, it);
-    };
-  } else {
-    var STATE = sharedKey('state');
-    hiddenKeys$1[STATE] = true;
-    set$2 = function (it, metadata) {
-      metadata.facade = it;
-      createNonEnumerableProperty(it, STATE, metadata);
-      return metadata;
-    };
-    get = function (it) {
-      return has$1(it, STATE) ? it[STATE] : {};
-    };
-    has = function (it) {
-      return has$1(it, STATE);
-    };
-  }
-
-  var internalState = {
-    set: set$2,
-    get: get,
-    has: has,
-    enforce: enforce,
-    getterFor: getterFor
-  };
-
-  var redefine = createCommonjsModule(function (module) {
-  var getInternalState = internalState.get;
-  var enforceInternalState = internalState.enforce;
-  var TEMPLATE = String(String).split('String');
-
-  (module.exports = function (O, key, value, options) {
-    var unsafe = options ? !!options.unsafe : false;
-    var simple = options ? !!options.enumerable : false;
-    var noTargetGet = options ? !!options.noTargetGet : false;
-    var state;
-    if (typeof value == 'function') {
-      if (typeof key == 'string' && !has$1(value, 'name')) {
-        createNonEnumerableProperty(value, 'name', key);
-      }
-      state = enforceInternalState(value);
-      if (!state.source) {
-        state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
-      }
-    }
-    if (O === global_1) {
-      if (simple) O[key] = value;
-      else setGlobal(key, value);
-      return;
-    } else if (!unsafe) {
-      delete O[key];
-    } else if (!noTargetGet && O[key]) {
-      simple = true;
-    }
-    if (simple) O[key] = value;
-    else createNonEnumerableProperty(O, key, value);
-  // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
-  })(Function.prototype, 'toString', function toString() {
-    return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
-  });
-  });
-
-  var path = global_1;
-
-  var aFunction$1 = function (variable) {
-    return typeof variable == 'function' ? variable : undefined;
-  };
-
-  var getBuiltIn = function (namespace, method) {
-    return arguments.length < 2 ? aFunction$1(path[namespace]) || aFunction$1(global_1[namespace])
-      : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
-  };
-
-  var ceil = Math.ceil;
-  var floor$1 = Math.floor;
-
-  // `ToInteger` abstract operation
-  // https://tc39.es/ecma262/#sec-tointeger
-  var toInteger = function (argument) {
-    return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor$1 : ceil)(argument);
-  };
-
-  var min$5 = Math.min;
-
-  // `ToLength` abstract operation
-  // https://tc39.es/ecma262/#sec-tolength
-  var toLength = function (argument) {
-    return argument > 0 ? min$5(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
-  };
-
-  var max$2 = Math.max;
-  var min$4 = Math.min;
-
-  // Helper for a popular repeating case of the spec:
-  // Let integer be ? ToInteger(index).
-  // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
-  var toAbsoluteIndex = function (index, length) {
-    var integer = toInteger(index);
-    return integer < 0 ? max$2(integer + length, 0) : min$4(integer, length);
-  };
-
-  // `Array.prototype.{ indexOf, includes }` methods implementation
-  var createMethod$5 = function (IS_INCLUDES) {
-    return function ($this, el, fromIndex) {
-      var O = toIndexedObject($this);
-      var length = toLength(O.length);
-      var index = toAbsoluteIndex(fromIndex, length);
-      var value;
-      // Array#includes uses SameValueZero equality algorithm
-      // eslint-disable-next-line no-self-compare
-      if (IS_INCLUDES && el != el) while (length > index) {
-        value = O[index++];
-        // eslint-disable-next-line no-self-compare
-        if (value != value) return true;
-      // Array#indexOf ignores holes, Array#includes - not
-      } else for (;length > index; index++) {
-        if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
-      } return !IS_INCLUDES && -1;
-    };
-  };
-
-  var arrayIncludes = {
-    // `Array.prototype.includes` method
-    // https://tc39.es/ecma262/#sec-array.prototype.includes
-    includes: createMethod$5(true),
-    // `Array.prototype.indexOf` method
-    // https://tc39.es/ecma262/#sec-array.prototype.indexof
-    indexOf: createMethod$5(false)
-  };
-
-  var indexOf = arrayIncludes.indexOf;
-
-
-  var objectKeysInternal = function (object, names) {
-    var O = toIndexedObject(object);
-    var i = 0;
-    var result = [];
-    var key;
-    for (key in O) !has$1(hiddenKeys$1, key) && has$1(O, key) && result.push(key);
-    // Don't enum bug & hidden keys
-    while (names.length > i) if (has$1(O, key = names[i++])) {
-      ~indexOf(result, key) || result.push(key);
-    }
-    return result;
-  };
-
-  // IE8- don't enum bug keys
-  var enumBugKeys = [
-    'constructor',
-    'hasOwnProperty',
-    'isPrototypeOf',
-    'propertyIsEnumerable',
-    'toLocaleString',
-    'toString',
-    'valueOf'
-  ];
-
-  var hiddenKeys = enumBugKeys.concat('length', 'prototype');
-
-  // `Object.getOwnPropertyNames` method
-  // https://tc39.es/ecma262/#sec-object.getownpropertynames
-  var f$2 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
-    return objectKeysInternal(O, hiddenKeys);
-  };
-
-  var objectGetOwnPropertyNames = {
-  	f: f$2
-  };
-
-  var f$1 = Object.getOwnPropertySymbols;
-
-  var objectGetOwnPropertySymbols = {
-  	f: f$1
-  };
-
-  // all object keys, includes non-enumerable and symbols
-  var ownKeys$1 = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
-    var keys = objectGetOwnPropertyNames.f(anObject(it));
-    var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
-    return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
-  };
-
-  var copyConstructorProperties = function (target, source) {
-    var keys = ownKeys$1(source);
-    var defineProperty = objectDefineProperty.f;
-    var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
-    for (var i = 0; i < keys.length; i++) {
-      var key = keys[i];
-      if (!has$1(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
-    }
-  };
-
-  var replacement = /#|\.prototype\./;
-
-  var isForced = function (feature, detection) {
-    var value = data[normalize(feature)];
-    return value == POLYFILL ? true
-      : value == NATIVE ? false
-      : typeof detection == 'function' ? fails(detection)
-      : !!detection;
-  };
-
-  var normalize = isForced.normalize = function (string) {
-    return String(string).replace(replacement, '.').toLowerCase();
-  };
-
-  var data = isForced.data = {};
-  var NATIVE = isForced.NATIVE = 'N';
-  var POLYFILL = isForced.POLYFILL = 'P';
-
-  var isForced_1 = isForced;
-
-  var getOwnPropertyDescriptor$3 = objectGetOwnPropertyDescriptor.f;
-
-
-
-
-
-
-  /*
-    options.target      - name of the target object
-    options.global      - target is the global object
-    options.stat        - export as static methods of target
-    options.proto       - export as prototype methods of target
-    options.real        - real prototype method for the `pure` version
-    options.forced      - export even if the native feature is available
-    options.bind        - bind methods to the target, required for the `pure` version
-    options.wrap        - wrap constructors to preventing global pollution, required for the `pure` version
-    options.unsafe      - use the simple assignment of property instead of delete + defineProperty
-    options.sham        - add a flag to not completely full polyfills
-    options.enumerable  - export as enumerable property
-    options.noTargetGet - prevent calling a getter on target
-  */
-  var _export = function (options, source) {
-    var TARGET = options.target;
-    var GLOBAL = options.global;
-    var STATIC = options.stat;
-    var FORCED, target, key, targetProperty, sourceProperty, descriptor;
-    if (GLOBAL) {
-      target = global_1;
-    } else if (STATIC) {
-      target = global_1[TARGET] || setGlobal(TARGET, {});
-    } else {
-      target = (global_1[TARGET] || {}).prototype;
-    }
-    if (target) for (key in source) {
-      sourceProperty = source[key];
-      if (options.noTargetGet) {
-        descriptor = getOwnPropertyDescriptor$3(target, key);
-        targetProperty = descriptor && descriptor.value;
-      } else targetProperty = target[key];
-      FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
-      // contained in target
-      if (!FORCED && targetProperty !== undefined) {
-        if (typeof sourceProperty === typeof targetProperty) continue;
-        copyConstructorProperties(sourceProperty, targetProperty);
-      }
-      // add a flag to not completely full polyfills
-      if (options.sham || (targetProperty && targetProperty.sham)) {
-        createNonEnumerableProperty(sourceProperty, 'sham', true);
-      }
-      // extend global
-      redefine(target, key, sourceProperty, options);
-    }
-  };
-
-  var aFunction = function (it) {
-    if (typeof it != 'function') {
-      throw TypeError(String(it) + ' is not a function');
-    } return it;
-  };
-
-  // optional / simple context binding
-  var functionBindContext = function (fn, that, length) {
-    aFunction(fn);
-    if (that === undefined) return fn;
-    switch (length) {
-      case 0: return function () {
-        return fn.call(that);
-      };
-      case 1: return function (a) {
-        return fn.call(that, a);
-      };
-      case 2: return function (a, b) {
-        return fn.call(that, a, b);
-      };
-      case 3: return function (a, b, c) {
-        return fn.call(that, a, b, c);
-      };
-    }
-    return function (/* ...args */) {
-      return fn.apply(that, arguments);
-    };
-  };
-
-  // `ToObject` abstract operation
-  // https://tc39.es/ecma262/#sec-toobject
-  var toObject = function (argument) {
-    return Object(requireObjectCoercible(argument));
-  };
-
-  // `IsArray` abstract operation
-  // https://tc39.es/ecma262/#sec-isarray
-  var isArray = Array.isArray || function isArray(arg) {
-    return classofRaw(arg) == 'Array';
-  };
-
-  var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
-    // Chrome 38 Symbol has incorrect toString conversion
-    // eslint-disable-next-line no-undef
-    return !String(Symbol());
-  });
-
-  var useSymbolAsUid = nativeSymbol
-    // eslint-disable-next-line no-undef
-    && !Symbol.sham
-    // eslint-disable-next-line no-undef
-    && typeof Symbol.iterator == 'symbol';
-
-  var WellKnownSymbolsStore = shared('wks');
-  var Symbol$1 = global_1.Symbol;
-  var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
-
-  var wellKnownSymbol = function (name) {
-    if (!has$1(WellKnownSymbolsStore, name)) {
-      if (nativeSymbol && has$1(Symbol$1, name)) WellKnownSymbolsStore[name] = Symbol$1[name];
-      else WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
-    } return WellKnownSymbolsStore[name];
-  };
-
-  var SPECIES$5 = wellKnownSymbol('species');
-
-  // `ArraySpeciesCreate` abstract operation
-  // https://tc39.es/ecma262/#sec-arrayspeciescreate
-  var arraySpeciesCreate = function (originalArray, length) {
-    var C;
-    if (isArray(originalArray)) {
-      C = originalArray.constructor;
-      // cross-realm fallback
-      if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
-      else if (isObject(C)) {
-        C = C[SPECIES$5];
-        if (C === null) C = undefined;
-      }
-    } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
-  };
-
-  var push = [].push;
-
-  // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
-  var createMethod$4 = function (TYPE) {
-    var IS_MAP = TYPE == 1;
-    var IS_FILTER = TYPE == 2;
-    var IS_SOME = TYPE == 3;
-    var IS_EVERY = TYPE == 4;
-    var IS_FIND_INDEX = TYPE == 6;
-    var IS_FILTER_OUT = TYPE == 7;
-    var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
-    return function ($this, callbackfn, that, specificCreate) {
-      var O = toObject($this);
-      var self = indexedObject(O);
-      var boundFunction = functionBindContext(callbackfn, that, 3);
-      var length = toLength(self.length);
-      var index = 0;
-      var create = specificCreate || arraySpeciesCreate;
-      var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
-      var value, result;
-      for (;length > index; index++) if (NO_HOLES || index in self) {
-        value = self[index];
-        result = boundFunction(value, index, O);
-        if (TYPE) {
-          if (IS_MAP) target[index] = result; // map
-          else if (result) switch (TYPE) {
-            case 3: return true;              // some
-            case 5: return value;             // find
-            case 6: return index;             // findIndex
-            case 2: push.call(target, value); // filter
-          } else switch (TYPE) {
-            case 4: return false;             // every
-            case 7: push.call(target, value); // filterOut
-          }
-        }
-      }
-      return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
-    };
-  };
-
-  var arrayIteration = {
-    // `Array.prototype.forEach` method
-    // https://tc39.es/ecma262/#sec-array.prototype.foreach
-    forEach: createMethod$4(0),
-    // `Array.prototype.map` method
-    // https://tc39.es/ecma262/#sec-array.prototype.map
-    map: createMethod$4(1),
-    // `Array.prototype.filter` method
-    // https://tc39.es/ecma262/#sec-array.prototype.filter
-    filter: createMethod$4(2),
-    // `Array.prototype.some` method
-    // https://tc39.es/ecma262/#sec-array.prototype.some
-    some: createMethod$4(3),
-    // `Array.prototype.every` method
-    // https://tc39.es/ecma262/#sec-array.prototype.every
-    every: createMethod$4(4),
-    // `Array.prototype.find` method
-    // https://tc39.es/ecma262/#sec-array.prototype.find
-    find: createMethod$4(5),
-    // `Array.prototype.findIndex` method
-    // https://tc39.es/ecma262/#sec-array.prototype.findIndex
-    findIndex: createMethod$4(6),
-    // `Array.prototype.filterOut` method
-    // https://github.com/tc39/proposal-array-filtering
-    filterOut: createMethod$4(7)
-  };
-
-  var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
-
-  var process$4 = global_1.process;
-  var versions = process$4 && process$4.versions;
-  var v8 = versions && versions.v8;
-  var match, version;
-
-  if (v8) {
-    match = v8.split('.');
-    version = match[0] + match[1];
-  } else if (engineUserAgent) {
-    match = engineUserAgent.match(/Edge\/(\d+)/);
-    if (!match || match[1] >= 74) {
-      match = engineUserAgent.match(/Chrome\/(\d+)/);
-      if (match) version = match[1];
-    }
-  }
-
-  var engineV8Version = version && +version;
-
-  var SPECIES$4 = wellKnownSymbol('species');
-
-  var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
-    // We can't use this feature detection in V8 since it causes
-    // deoptimization and serious performance degradation
-    // https://github.com/zloirock/core-js/issues/677
-    return engineV8Version >= 51 || !fails(function () {
-      var array = [];
-      var constructor = array.constructor = {};
-      constructor[SPECIES$4] = function () {
-        return { foo: 1 };
-      };
-      return array[METHOD_NAME](Boolean).foo !== 1;
-    });
-  };
-
-  var defineProperty$5 = Object.defineProperty;
-  var cache = {};
-
-  var thrower = function (it) { throw it; };
-
-  var arrayMethodUsesToLength = function (METHOD_NAME, options) {
-    if (has$1(cache, METHOD_NAME)) return cache[METHOD_NAME];
-    if (!options) options = {};
-    var method = [][METHOD_NAME];
-    var ACCESSORS = has$1(options, 'ACCESSORS') ? options.ACCESSORS : false;
-    var argument0 = has$1(options, 0) ? options[0] : thrower;
-    var argument1 = has$1(options, 1) ? options[1] : undefined;
-
-    return cache[METHOD_NAME] = !!method && !fails(function () {
-      if (ACCESSORS && !descriptors) return true;
-      var O = { length: -1 };
-
-      if (ACCESSORS) defineProperty$5(O, 1, { enumerable: true, get: thrower });
-      else O[1] = 1;
-
-      method.call(O, argument0, argument1);
-    });
-  };
-
-  var $filter = arrayIteration.filter;
-
-
-
-  var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport('filter');
-  // Edge 14- issue
-  var USES_TO_LENGTH$8 = arrayMethodUsesToLength('filter');
-
-  // `Array.prototype.filter` method
-  // https://tc39.es/ecma262/#sec-array.prototype.filter
-  // with adding support of @@species
-  _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 || !USES_TO_LENGTH$8 }, {
-    filter: function filter(callbackfn /* , thisArg */) {
-      return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  var arrayMethodIsStrict = function (METHOD_NAME, argument) {
-    var method = [][METHOD_NAME];
-    return !!method && fails(function () {
-      // eslint-disable-next-line no-useless-call,no-throw-literal
-      method.call(null, argument || function () { throw 1; }, 1);
-    });
-  };
-
-  var $forEach = arrayIteration.forEach;
-
-
-
-  var STRICT_METHOD$4 = arrayMethodIsStrict('forEach');
-  var USES_TO_LENGTH$7 = arrayMethodUsesToLength('forEach');
-
-  // `Array.prototype.forEach` method implementation
-  // https://tc39.es/ecma262/#sec-array.prototype.foreach
-  var arrayForEach = (!STRICT_METHOD$4 || !USES_TO_LENGTH$7) ? function forEach(callbackfn /* , thisArg */) {
-    return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
-  } : [].forEach;
-
-  // `Array.prototype.forEach` method
-  // https://tc39.es/ecma262/#sec-array.prototype.foreach
-  _export({ target: 'Array', proto: true, forced: [].forEach != arrayForEach }, {
-    forEach: arrayForEach
-  });
-
-  var iteratorClose = function (iterator) {
-    var returnMethod = iterator['return'];
-    if (returnMethod !== undefined) {
-      return anObject(returnMethod.call(iterator)).value;
-    }
-  };
-
-  // call something on iterator step with safe closing on error
-  var callWithSafeIterationClosing = function (iterator, fn, value, ENTRIES) {
-    try {
-      return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
-    // 7.4.6 IteratorClose(iterator, completion)
-    } catch (error) {
-      iteratorClose(iterator);
-      throw error;
-    }
-  };
-
-  var iterators = {};
-
-  var ITERATOR$5 = wellKnownSymbol('iterator');
-  var ArrayPrototype$1 = Array.prototype;
-
-  // check on default Array iterator
-  var isArrayIteratorMethod = function (it) {
-    return it !== undefined && (iterators.Array === it || ArrayPrototype$1[ITERATOR$5] === it);
-  };
-
-  var createProperty = function (object, key, value) {
-    var propertyKey = toPrimitive(key);
-    if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
-    else object[propertyKey] = value;
-  };
-
-  var TO_STRING_TAG$3 = wellKnownSymbol('toStringTag');
-  var test = {};
-
-  test[TO_STRING_TAG$3] = 'z';
-
-  var toStringTagSupport = String(test) === '[object z]';
-
-  var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag');
-  // ES3 wrong here
-  var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
-
-  // fallback for IE11 Script Access Denied error
-  var tryGet = function (it, key) {
-    try {
-      return it[key];
-    } catch (error) { /* empty */ }
-  };
-
-  // getting tag from ES6+ `Object.prototype.toString`
-  var classof = toStringTagSupport ? classofRaw : function (it) {
-    var O, tag, result;
-    return it === undefined ? 'Undefined' : it === null ? 'Null'
-      // @@toStringTag case
-      : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$2)) == 'string' ? tag
-      // builtinTag case
-      : CORRECT_ARGUMENTS ? classofRaw(O)
-      // ES3 arguments fallback
-      : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
-  };
-
-  var ITERATOR$4 = wellKnownSymbol('iterator');
-
-  var getIteratorMethod = function (it) {
-    if (it != undefined) return it[ITERATOR$4]
-      || it['@@iterator']
-      || iterators[classof(it)];
-  };
-
-  // `Array.from` method implementation
-  // https://tc39.es/ecma262/#sec-array.from
-  var arrayFrom = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
-    var O = toObject(arrayLike);
-    var C = typeof this == 'function' ? this : Array;
-    var argumentsLength = arguments.length;
-    var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
-    var mapping = mapfn !== undefined;
-    var iteratorMethod = getIteratorMethod(O);
-    var index = 0;
-    var length, result, step, iterator, next, value;
-    if (mapping) mapfn = functionBindContext(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);
-    // if the target is not iterable or it's an array with the default iterator - use a simple case
-    if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {
-      iterator = iteratorMethod.call(O);
-      next = iterator.next;
-      result = new C();
-      for (;!(step = next.call(iterator)).done; index++) {
-        value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value;
-        createProperty(result, index, value);
-      }
-    } else {
-      length = toLength(O.length);
-      result = new C(length);
-      for (;length > index; index++) {
-        value = mapping ? mapfn(O[index], index) : O[index];
-        createProperty(result, index, value);
-      }
-    }
-    result.length = index;
-    return result;
-  };
-
-  var ITERATOR$3 = wellKnownSymbol('iterator');
-  var SAFE_CLOSING = false;
-
-  try {
-    var called = 0;
-    var iteratorWithReturn = {
-      next: function () {
-        return { done: !!called++ };
-      },
-      'return': function () {
-        SAFE_CLOSING = true;
-      }
-    };
-    iteratorWithReturn[ITERATOR$3] = function () {
-      return this;
-    };
-    // eslint-disable-next-line no-throw-literal
-    Array.from(iteratorWithReturn, function () { throw 2; });
-  } catch (error) { /* empty */ }
-
-  var checkCorrectnessOfIteration = function (exec, SKIP_CLOSING) {
-    if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
-    var ITERATION_SUPPORT = false;
-    try {
-      var object = {};
-      object[ITERATOR$3] = function () {
-        return {
-          next: function () {
-            return { done: ITERATION_SUPPORT = true };
-          }
-        };
-      };
-      exec(object);
-    } catch (error) { /* empty */ }
-    return ITERATION_SUPPORT;
-  };
-
-  var INCORRECT_ITERATION$1 = !checkCorrectnessOfIteration(function (iterable) {
-    Array.from(iterable);
-  });
-
-  // `Array.from` method
-  // https://tc39.es/ecma262/#sec-array.from
-  _export({ target: 'Array', stat: true, forced: INCORRECT_ITERATION$1 }, {
-    from: arrayFrom
-  });
-
-  // `String.prototype.{ codePointAt, at }` methods implementation
-  var createMethod$3 = function (CONVERT_TO_STRING) {
-    return function ($this, pos) {
-      var S = String(requireObjectCoercible($this));
-      var position = toInteger(pos);
-      var size = S.length;
-      var first, second;
-      if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
-      first = S.charCodeAt(position);
-      return first < 0xD800 || first > 0xDBFF || position + 1 === size
-        || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
-          ? CONVERT_TO_STRING ? S.charAt(position) : first
-          : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
-    };
-  };
-
-  var stringMultibyte = {
-    // `String.prototype.codePointAt` method
-    // https://tc39.es/ecma262/#sec-string.prototype.codepointat
-    codeAt: createMethod$3(false),
-    // `String.prototype.at` method
-    // https://github.com/mathiasbynens/String.prototype.at
-    charAt: createMethod$3(true)
-  };
-
-  var correctPrototypeGetter = !fails(function () {
-    function F() { /* empty */ }
-    F.prototype.constructor = null;
-    return Object.getPrototypeOf(new F()) !== F.prototype;
-  });
-
-  var IE_PROTO$1 = sharedKey('IE_PROTO');
-  var ObjectPrototype = Object.prototype;
-
-  // `Object.getPrototypeOf` method
-  // https://tc39.es/ecma262/#sec-object.getprototypeof
-  var objectGetPrototypeOf = correctPrototypeGetter ? Object.getPrototypeOf : function (O) {
-    O = toObject(O);
-    if (has$1(O, IE_PROTO$1)) return O[IE_PROTO$1];
-    if (typeof O.constructor == 'function' && O instanceof O.constructor) {
-      return O.constructor.prototype;
-    } return O instanceof Object ? ObjectPrototype : null;
-  };
-
-  var ITERATOR$2 = wellKnownSymbol('iterator');
-  var BUGGY_SAFARI_ITERATORS$1 = false;
-
-  var returnThis$2 = function () { return this; };
-
-  // `%IteratorPrototype%` object
-  // https://tc39.es/ecma262/#sec-%iteratorprototype%-object
-  var IteratorPrototype$2, PrototypeOfArrayIteratorPrototype, arrayIterator;
-
-  if ([].keys) {
-    arrayIterator = [].keys();
-    // Safari 8 has buggy iterators w/o `next`
-    if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS$1 = true;
-    else {
-      PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator));
-      if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype$2 = PrototypeOfArrayIteratorPrototype;
-    }
-  }
-
-  var NEW_ITERATOR_PROTOTYPE = IteratorPrototype$2 == undefined || fails(function () {
-    var test = {};
-    // FF44- legacy iterators case
-    return IteratorPrototype$2[ITERATOR$2].call(test) !== test;
-  });
-
-  if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype$2 = {};
-
-  // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
-  if (!has$1(IteratorPrototype$2, ITERATOR$2)) {
-    createNonEnumerableProperty(IteratorPrototype$2, ITERATOR$2, returnThis$2);
-  }
-
-  var iteratorsCore = {
-    IteratorPrototype: IteratorPrototype$2,
-    BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS$1
-  };
-
-  // `Object.keys` method
-  // https://tc39.es/ecma262/#sec-object.keys
-  var objectKeys = Object.keys || function keys(O) {
-    return objectKeysInternal(O, enumBugKeys);
-  };
-
-  // `Object.defineProperties` method
-  // https://tc39.es/ecma262/#sec-object.defineproperties
-  var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
-    anObject(O);
-    var keys = objectKeys(Properties);
-    var length = keys.length;
-    var index = 0;
-    var key;
-    while (length > index) objectDefineProperty.f(O, key = keys[index++], Properties[key]);
-    return O;
-  };
-
-  var html = getBuiltIn('document', 'documentElement');
-
-  var GT = '>';
-  var LT = '<';
-  var PROTOTYPE = 'prototype';
-  var SCRIPT = 'script';
-  var IE_PROTO = sharedKey('IE_PROTO');
-
-  var EmptyConstructor = function () { /* empty */ };
-
-  var scriptTag = function (content) {
-    return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
-  };
-
-  // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
-  var NullProtoObjectViaActiveX = function (activeXDocument) {
-    activeXDocument.write(scriptTag(''));
-    activeXDocument.close();
-    var temp = activeXDocument.parentWindow.Object;
-    activeXDocument = null; // avoid memory leak
-    return temp;
-  };
-
-  // Create object with fake `null` prototype: use iframe Object with cleared prototype
-  var NullProtoObjectViaIFrame = function () {
-    // Thrash, waste and sodomy: IE GC bug
-    var iframe = documentCreateElement('iframe');
-    var JS = 'java' + SCRIPT + ':';
-    var iframeDocument;
-    iframe.style.display = 'none';
-    html.appendChild(iframe);
-    // https://github.com/zloirock/core-js/issues/475
-    iframe.src = String(JS);
-    iframeDocument = iframe.contentWindow.document;
-    iframeDocument.open();
-    iframeDocument.write(scriptTag('document.F=Object'));
-    iframeDocument.close();
-    return iframeDocument.F;
-  };
-
-  // Check for document.domain and active x support
-  // No need to use active x approach when document.domain is not set
-  // see https://github.com/es-shims/es5-shim/issues/150
-  // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
-  // avoid IE GC bug
-  var activeXDocument;
-  var NullProtoObject = function () {
-    try {
-      /* global ActiveXObject */
-      activeXDocument = document.domain && new ActiveXObject('htmlfile');
-    } catch (error) { /* ignore */ }
-    NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
-    var length = enumBugKeys.length;
-    while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
-    return NullProtoObject();
-  };
-
-  hiddenKeys$1[IE_PROTO] = true;
-
-  // `Object.create` method
-  // https://tc39.es/ecma262/#sec-object.create
-  var objectCreate = Object.create || function create(O, Properties) {
-    var result;
-    if (O !== null) {
-      EmptyConstructor[PROTOTYPE] = anObject(O);
-      result = new EmptyConstructor();
-      EmptyConstructor[PROTOTYPE] = null;
-      // add "__proto__" for Object.getPrototypeOf polyfill
-      result[IE_PROTO] = O;
-    } else result = NullProtoObject();
-    return Properties === undefined ? result : objectDefineProperties(result, Properties);
-  };
-
-  var defineProperty$4 = objectDefineProperty.f;
-
-
-
-  var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
-
-  var setToStringTag = function (it, TAG, STATIC) {
-    if (it && !has$1(it = STATIC ? it : it.prototype, TO_STRING_TAG$1)) {
-      defineProperty$4(it, TO_STRING_TAG$1, { configurable: true, value: TAG });
-    }
-  };
-
-  var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
-
-
-
-
-
-  var returnThis$1 = function () { return this; };
-
-  var createIteratorConstructor = function (IteratorConstructor, NAME, next) {
-    var TO_STRING_TAG = NAME + ' Iterator';
-    IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(1, next) });
-    setToStringTag(IteratorConstructor, TO_STRING_TAG, false);
-    iterators[TO_STRING_TAG] = returnThis$1;
-    return IteratorConstructor;
-  };
-
-  var aPossiblePrototype = function (it) {
-    if (!isObject(it) && it !== null) {
-      throw TypeError("Can't set " + String(it) + ' as a prototype');
-    } return it;
-  };
-
-  // `Object.setPrototypeOf` method
-  // https://tc39.es/ecma262/#sec-object.setprototypeof
-  // Works with __proto__ only. Old v8 can't work with null proto objects.
-  /* eslint-disable no-proto */
-  var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
-    var CORRECT_SETTER = false;
-    var test = {};
-    var setter;
-    try {
-      setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
-      setter.call(test, []);
-      CORRECT_SETTER = test instanceof Array;
-    } catch (error) { /* empty */ }
-    return function setPrototypeOf(O, proto) {
-      anObject(O);
-      aPossiblePrototype(proto);
-      if (CORRECT_SETTER) setter.call(O, proto);
-      else O.__proto__ = proto;
-      return O;
-    };
-  }() : undefined);
-
-  var IteratorPrototype = iteratorsCore.IteratorPrototype;
-  var BUGGY_SAFARI_ITERATORS = iteratorsCore.BUGGY_SAFARI_ITERATORS;
-  var ITERATOR$1 = wellKnownSymbol('iterator');
-  var KEYS = 'keys';
-  var VALUES = 'values';
-  var ENTRIES = 'entries';
-
-  var returnThis = function () { return this; };
-
-  var defineIterator = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
-    createIteratorConstructor(IteratorConstructor, NAME, next);
-
-    var getIterationMethod = function (KIND) {
-      if (KIND === DEFAULT && defaultIterator) return defaultIterator;
-      if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];
-      switch (KIND) {
-        case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
-        case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
-        case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
-      } return function () { return new IteratorConstructor(this); };
-    };
-
-    var TO_STRING_TAG = NAME + ' Iterator';
-    var INCORRECT_VALUES_NAME = false;
-    var IterablePrototype = Iterable.prototype;
-    var nativeIterator = IterablePrototype[ITERATOR$1]
-      || IterablePrototype['@@iterator']
-      || DEFAULT && IterablePrototype[DEFAULT];
-    var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
-    var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
-    var CurrentIteratorPrototype, methods, KEY;
-
-    // fix native
-    if (anyNativeIterator) {
-      CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable()));
-      if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
-        if (objectGetPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {
-          if (objectSetPrototypeOf) {
-            objectSetPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);
-          } else if (typeof CurrentIteratorPrototype[ITERATOR$1] != 'function') {
-            createNonEnumerableProperty(CurrentIteratorPrototype, ITERATOR$1, returnThis);
-          }
-        }
-        // Set @@toStringTag to native iterators
-        setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true);
-      }
-    }
-
-    // fix Array#{values, @@iterator}.name in V8 / FF
-    if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
-      INCORRECT_VALUES_NAME = true;
-      defaultIterator = function values() { return nativeIterator.call(this); };
-    }
-
-    // define iterator
-    if (IterablePrototype[ITERATOR$1] !== defaultIterator) {
-      createNonEnumerableProperty(IterablePrototype, ITERATOR$1, defaultIterator);
-    }
-    iterators[NAME] = defaultIterator;
-
-    // export additional methods
-    if (DEFAULT) {
-      methods = {
-        values: getIterationMethod(VALUES),
-        keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
-        entries: getIterationMethod(ENTRIES)
-      };
-      if (FORCED) for (KEY in methods) {
-        if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
-          redefine(IterablePrototype, KEY, methods[KEY]);
-        }
-      } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
-    }
-
-    return methods;
-  };
-
-  var charAt$1 = stringMultibyte.charAt;
-
-
-
-  var STRING_ITERATOR = 'String Iterator';
-  var setInternalState$3 = internalState.set;
-  var getInternalState$2 = internalState.getterFor(STRING_ITERATOR);
-
-  // `String.prototype[@@iterator]` method
-  // https://tc39.es/ecma262/#sec-string.prototype-@@iterator
-  defineIterator(String, 'String', function (iterated) {
-    setInternalState$3(this, {
-      type: STRING_ITERATOR,
-      string: String(iterated),
-      index: 0
-    });
-  // `%StringIteratorPrototype%.next` method
-  // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next
-  }, function next() {
-    var state = getInternalState$2(this);
-    var string = state.string;
-    var index = state.index;
-    var point;
-    if (index >= string.length) return { value: undefined, done: true };
-    point = charAt$1(string, index);
-    state.index += point.length;
-    return { value: point, done: false };
-  });
-
-  // iterable DOM collections
-  // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
-  var domIterables = {
-    CSSRuleList: 0,
-    CSSStyleDeclaration: 0,
-    CSSValueList: 0,
-    ClientRectList: 0,
-    DOMRectList: 0,
-    DOMStringList: 0,
-    DOMTokenList: 1,
-    DataTransferItemList: 0,
-    FileList: 0,
-    HTMLAllCollection: 0,
-    HTMLCollection: 0,
-    HTMLFormElement: 0,
-    HTMLSelectElement: 0,
-    MediaList: 0,
-    MimeTypeArray: 0,
-    NamedNodeMap: 0,
-    NodeList: 1,
-    PaintRequestList: 0,
-    Plugin: 0,
-    PluginArray: 0,
-    SVGLengthList: 0,
-    SVGNumberList: 0,
-    SVGPathSegList: 0,
-    SVGPointList: 0,
-    SVGStringList: 0,
-    SVGTransformList: 0,
-    SourceBufferList: 0,
-    StyleSheetList: 0,
-    TextTrackCueList: 0,
-    TextTrackList: 0,
-    TouchList: 0
-  };
-
-  for (var COLLECTION_NAME$1 in domIterables) {
-    var Collection$1 = global_1[COLLECTION_NAME$1];
-    var CollectionPrototype$1 = Collection$1 && Collection$1.prototype;
-    // some Chrome versions have non-configurable methods on DOMTokenList
-    if (CollectionPrototype$1 && CollectionPrototype$1.forEach !== arrayForEach) try {
-      createNonEnumerableProperty(CollectionPrototype$1, 'forEach', arrayForEach);
-    } catch (error) {
-      CollectionPrototype$1.forEach = arrayForEach;
-    }
-  }
-
-  function _typeof(obj) {
-    "@babel/helpers - typeof";
-
-    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
-      _typeof = function (obj) {
-        return typeof obj;
-      };
-    } else {
-      _typeof = function (obj) {
-        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
-      };
-    }
-
-    return _typeof(obj);
-  }
-
-  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
-    try {
-      var info = gen[key](arg);
-      var value = info.value;
-    } catch (error) {
-      reject(error);
-      return;
-    }
-
-    if (info.done) {
-      resolve(value);
-    } else {
-      Promise.resolve(value).then(_next, _throw);
-    }
-  }
-
-  function _asyncToGenerator(fn) {
-    return function () {
-      var self = this,
-          args = arguments;
-      return new Promise(function (resolve, reject) {
-        var gen = fn.apply(self, args);
-
-        function _next(value) {
-          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
-        }
-
-        function _throw(err) {
-          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
-        }
-
-        _next(undefined);
-      });
-    };
-  }
-
-  function _classCallCheck(instance, Constructor) {
-    if (!(instance instanceof Constructor)) {
-      throw new TypeError("Cannot call a class as a function");
-    }
-  }
-
-  function _defineProperties(target, props) {
-    for (var i = 0; i < props.length; i++) {
-      var descriptor = props[i];
-      descriptor.enumerable = descriptor.enumerable || false;
-      descriptor.configurable = true;
-      if ("value" in descriptor) descriptor.writable = true;
-      Object.defineProperty(target, descriptor.key, descriptor);
-    }
-  }
-
-  function _createClass(Constructor, protoProps, staticProps) {
-    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
-    if (staticProps) _defineProperties(Constructor, staticProps);
-    return Constructor;
-  }
-
-  function _defineProperty(obj, key, value) {
-    if (key in obj) {
-      Object.defineProperty(obj, key, {
-        value: value,
-        enumerable: true,
-        configurable: true,
-        writable: true
-      });
-    } else {
-      obj[key] = value;
-    }
-
-    return obj;
-  }
-
-  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 _objectSpread2(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) {
-          _defineProperty(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;
-  }
-
-  function _newArrowCheck(innerThis, boundThis) {
-    if (innerThis !== boundThis) {
-      throw new TypeError("Cannot instantiate an arrow function");
-    }
-  }
-
-  function _slicedToArray(arr, i) {
-    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
-  }
-
-  function _toConsumableArray(arr) {
-    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
-  }
-
-  function _arrayWithoutHoles(arr) {
-    if (Array.isArray(arr)) return _arrayLikeToArray(arr);
-  }
-
-  function _arrayWithHoles(arr) {
-    if (Array.isArray(arr)) return arr;
-  }
-
-  function _iterableToArray(iter) {
-    if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
-  }
-
-  function _iterableToArrayLimit(arr, i) {
-    if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
-    var _arr = [];
-    var _n = true;
-    var _d = false;
-    var _e = undefined;
-
-    try {
-      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
-        _arr.push(_s.value);
-
-        if (i && _arr.length === i) break;
-      }
-    } catch (err) {
-      _d = true;
-      _e = err;
-    } finally {
-      try {
-        if (!_n && _i["return"] != null) _i["return"]();
-      } finally {
-        if (_d) throw _e;
-      }
-    }
-
-    return _arr;
-  }
-
-  function _unsupportedIterableToArray(o, minLen) {
-    if (!o) return;
-    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
-    var n = Object.prototype.toString.call(o).slice(8, -1);
-    if (n === "Object" && o.constructor) n = o.constructor.name;
-    if (n === "Map" || n === "Set") return Array.from(o);
-    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
-  }
-
-  function _arrayLikeToArray(arr, len) {
-    if (len == null || len > arr.length) len = arr.length;
-
-    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
-
-    return arr2;
-  }
-
-  function _nonIterableSpread() {
-    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
-  }
-
-  function _nonIterableRest() {
-    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
-  }
-
-  createCommonjsModule(function (module) {
-  /**
-   * Copyright (c) 2014-present, Facebook, Inc.
-   *
-   * This source code is licensed under the MIT license found in the
-   * LICENSE file in the root directory of this source tree.
-   */
-
-  var runtime = (function (exports) {
-
-    var Op = Object.prototype;
-    var hasOwn = Op.hasOwnProperty;
-    var undefined$1; // More compressible than void 0.
-    var $Symbol = typeof Symbol === "function" ? Symbol : {};
-    var iteratorSymbol = $Symbol.iterator || "@@iterator";
-    var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
-    var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
-
-    function wrap(innerFn, outerFn, self, tryLocsList) {
-      // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
-      var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
-      var generator = Object.create(protoGenerator.prototype);
-      var context = new Context(tryLocsList || []);
-
-      // The ._invoke method unifies the implementations of the .next,
-      // .throw, and .return methods.
-      generator._invoke = makeInvokeMethod(innerFn, self, context);
-
-      return generator;
-    }
-    exports.wrap = wrap;
-
-    // Try/catch helper to minimize deoptimizations. Returns a completion
-    // record like context.tryEntries[i].completion. This interface could
-    // have been (and was previously) designed to take a closure to be
-    // invoked without arguments, but in all the cases we care about we
-    // already have an existing method we want to call, so there's no need
-    // to create a new function object. We can even get away with assuming
-    // the method takes exactly one argument, since that happens to be true
-    // in every case, so we don't have to touch the arguments object. The
-    // only additional allocation required is the completion record, which
-    // has a stable shape and so hopefully should be cheap to allocate.
-    function tryCatch(fn, obj, arg) {
-      try {
-        return { type: "normal", arg: fn.call(obj, arg) };
-      } catch (err) {
-        return { type: "throw", arg: err };
-      }
-    }
-
-    var GenStateSuspendedStart = "suspendedStart";
-    var GenStateSuspendedYield = "suspendedYield";
-    var GenStateExecuting = "executing";
-    var GenStateCompleted = "completed";
-
-    // Returning this object from the innerFn has the same effect as
-    // breaking out of the dispatch switch statement.
-    var ContinueSentinel = {};
-
-    // Dummy constructor functions that we use as the .constructor and
-    // .constructor.prototype properties for functions that return Generator
-    // objects. For full spec compliance, you may wish to configure your
-    // minifier not to mangle the names of these two functions.
-    function Generator() {}
-    function GeneratorFunction() {}
-    function GeneratorFunctionPrototype() {}
-
-    // This is a polyfill for %IteratorPrototype% for environments that
-    // don't natively support it.
-    var IteratorPrototype = {};
-    IteratorPrototype[iteratorSymbol] = function () {
-      return this;
-    };
-
-    var getProto = Object.getPrototypeOf;
-    var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
-    if (NativeIteratorPrototype &&
-        NativeIteratorPrototype !== Op &&
-        hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
-      // This environment has a native %IteratorPrototype%; use it instead
-      // of the polyfill.
-      IteratorPrototype = NativeIteratorPrototype;
-    }
-
-    var Gp = GeneratorFunctionPrototype.prototype =
-      Generator.prototype = Object.create(IteratorPrototype);
-    GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
-    GeneratorFunctionPrototype.constructor = GeneratorFunction;
-    GeneratorFunctionPrototype[toStringTagSymbol] =
-      GeneratorFunction.displayName = "GeneratorFunction";
-
-    // Helper for defining the .next, .throw, and .return methods of the
-    // Iterator interface in terms of a single ._invoke method.
-    function defineIteratorMethods(prototype) {
-      ["next", "throw", "return"].forEach(function(method) {
-        prototype[method] = function(arg) {
-          return this._invoke(method, arg);
-        };
-      });
-    }
-
-    exports.isGeneratorFunction = function(genFun) {
-      var ctor = typeof genFun === "function" && genFun.constructor;
-      return ctor
-        ? ctor === GeneratorFunction ||
-          // For the native GeneratorFunction constructor, the best we can
-          // do is to check its .name property.
-          (ctor.displayName || ctor.name) === "GeneratorFunction"
-        : false;
-    };
-
-    exports.mark = function(genFun) {
-      if (Object.setPrototypeOf) {
-        Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
-      } else {
-        genFun.__proto__ = GeneratorFunctionPrototype;
-        if (!(toStringTagSymbol in genFun)) {
-          genFun[toStringTagSymbol] = "GeneratorFunction";
-        }
-      }
-      genFun.prototype = Object.create(Gp);
-      return genFun;
-    };
-
-    // Within the body of any async function, `await x` is transformed to
-    // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
-    // `hasOwn.call(value, "__await")` to determine if the yielded value is
-    // meant to be awaited.
-    exports.awrap = function(arg) {
-      return { __await: arg };
-    };
-
-    function AsyncIterator(generator, PromiseImpl) {
-      function invoke(method, arg, resolve, reject) {
-        var record = tryCatch(generator[method], generator, arg);
-        if (record.type === "throw") {
-          reject(record.arg);
-        } else {
-          var result = record.arg;
-          var value = result.value;
-          if (value &&
-              typeof value === "object" &&
-              hasOwn.call(value, "__await")) {
-            return PromiseImpl.resolve(value.__await).then(function(value) {
-              invoke("next", value, resolve, reject);
-            }, function(err) {
-              invoke("throw", err, resolve, reject);
-            });
-          }
-
-          return PromiseImpl.resolve(value).then(function(unwrapped) {
-            // When a yielded Promise is resolved, its final value becomes
-            // the .value of the Promise<{value,done}> result for the
-            // current iteration.
-            result.value = unwrapped;
-            resolve(result);
-          }, function(error) {
-            // If a rejected Promise was yielded, throw the rejection back
-            // into the async generator function so it can be handled there.
-            return invoke("throw", error, resolve, reject);
-          });
-        }
-      }
-
-      var previousPromise;
-
-      function enqueue(method, arg) {
-        function callInvokeWithMethodAndArg() {
-          return new PromiseImpl(function(resolve, reject) {
-            invoke(method, arg, resolve, reject);
-          });
-        }
-
-        return previousPromise =
-          // If enqueue has been called before, then we want to wait until
-          // all previous Promises have been resolved before calling invoke,
-          // so that results are always delivered in the correct order. If
-          // enqueue has not been called before, then it is important to
-          // call invoke immediately, without waiting on a callback to fire,
-          // so that the async generator function has the opportunity to do
-          // any necessary setup in a predictable way. This predictability
-          // is why the Promise constructor synchronously invokes its
-          // executor callback, and why async functions synchronously
-          // execute code before the first await. Since we implement simple
-          // async functions in terms of async generators, it is especially
-          // important to get this right, even though it requires care.
-          previousPromise ? previousPromise.then(
-            callInvokeWithMethodAndArg,
-            // Avoid propagating failures to Promises returned by later
-            // invocations of the iterator.
-            callInvokeWithMethodAndArg
-          ) : callInvokeWithMethodAndArg();
-      }
-
-      // Define the unified helper method that is used to implement .next,
-      // .throw, and .return (see defineIteratorMethods).
-      this._invoke = enqueue;
-    }
-
-    defineIteratorMethods(AsyncIterator.prototype);
-    AsyncIterator.prototype[asyncIteratorSymbol] = function () {
-      return this;
-    };
-    exports.AsyncIterator = AsyncIterator;
-
-    // Note that simple async functions are implemented on top of
-    // AsyncIterator objects; they just return a Promise for the value of
-    // the final result produced by the iterator.
-    exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
-      if (PromiseImpl === void 0) PromiseImpl = Promise;
-
-      var iter = new AsyncIterator(
-        wrap(innerFn, outerFn, self, tryLocsList),
-        PromiseImpl
-      );
-
-      return exports.isGeneratorFunction(outerFn)
-        ? iter // If outerFn is a generator, return the full iterator.
-        : iter.next().then(function(result) {
-            return result.done ? result.value : iter.next();
-          });
-    };
-
-    function makeInvokeMethod(innerFn, self, context) {
-      var state = GenStateSuspendedStart;
-
-      return function invoke(method, arg) {
-        if (state === GenStateExecuting) {
-          throw new Error("Generator is already running");
-        }
-
-        if (state === GenStateCompleted) {
-          if (method === "throw") {
-            throw arg;
-          }
-
-          // Be forgiving, per 25.3.3.3.3 of the spec:
-          // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
-          return doneResult();
-        }
-
-        context.method = method;
-        context.arg = arg;
-
-        while (true) {
-          var delegate = context.delegate;
-          if (delegate) {
-            var delegateResult = maybeInvokeDelegate(delegate, context);
-            if (delegateResult) {
-              if (delegateResult === ContinueSentinel) continue;
-              return delegateResult;
-            }
-          }
-
-          if (context.method === "next") {
-            // Setting context._sent for legacy support of Babel's
-            // function.sent implementation.
-            context.sent = context._sent = context.arg;
-
-          } else if (context.method === "throw") {
-            if (state === GenStateSuspendedStart) {
-              state = GenStateCompleted;
-              throw context.arg;
-            }
-
-            context.dispatchException(context.arg);
-
-          } else if (context.method === "return") {
-            context.abrupt("return", context.arg);
-          }
-
-          state = GenStateExecuting;
-
-          var record = tryCatch(innerFn, self, context);
-          if (record.type === "normal") {
-            // If an exception is thrown from innerFn, we leave state ===
-            // GenStateExecuting and loop back for another invocation.
-            state = context.done
-              ? GenStateCompleted
-              : GenStateSuspendedYield;
-
-            if (record.arg === ContinueSentinel) {
-              continue;
-            }
-
-            return {
-              value: record.arg,
-              done: context.done
-            };
-
-          } else if (record.type === "throw") {
-            state = GenStateCompleted;
-            // Dispatch the exception by looping back around to the
-            // context.dispatchException(context.arg) call above.
-            context.method = "throw";
-            context.arg = record.arg;
-          }
-        }
-      };
-    }
-
-    // Call delegate.iterator[context.method](context.arg) and handle the
-    // result, either by returning a { value, done } result from the
-    // delegate iterator, or by modifying context.method and context.arg,
-    // setting context.delegate to null, and returning the ContinueSentinel.
-    function maybeInvokeDelegate(delegate, context) {
-      var method = delegate.iterator[context.method];
-      if (method === undefined$1) {
-        // A .throw or .return when the delegate iterator has no .throw
-        // method always terminates the yield* loop.
-        context.delegate = null;
-
-        if (context.method === "throw") {
-          // Note: ["return"] must be used for ES3 parsing compatibility.
-          if (delegate.iterator["return"]) {
-            // If the delegate iterator has a return method, give it a
-            // chance to clean up.
-            context.method = "return";
-            context.arg = undefined$1;
-            maybeInvokeDelegate(delegate, context);
-
-            if (context.method === "throw") {
-              // If maybeInvokeDelegate(context) changed context.method from
-              // "return" to "throw", let that override the TypeError below.
-              return ContinueSentinel;
-            }
-          }
-
-          context.method = "throw";
-          context.arg = new TypeError(
-            "The iterator does not provide a 'throw' method");
-        }
-
-        return ContinueSentinel;
-      }
-
-      var record = tryCatch(method, delegate.iterator, context.arg);
-
-      if (record.type === "throw") {
-        context.method = "throw";
-        context.arg = record.arg;
-        context.delegate = null;
-        return ContinueSentinel;
-      }
-
-      var info = record.arg;
-
-      if (! info) {
-        context.method = "throw";
-        context.arg = new TypeError("iterator result is not an object");
-        context.delegate = null;
-        return ContinueSentinel;
-      }
-
-      if (info.done) {
-        // Assign the result of the finished delegate to the temporary
-        // variable specified by delegate.resultName (see delegateYield).
-        context[delegate.resultName] = info.value;
-
-        // Resume execution at the desired location (see delegateYield).
-        context.next = delegate.nextLoc;
-
-        // If context.method was "throw" but the delegate handled the
-        // exception, let the outer generator proceed normally. If
-        // context.method was "next", forget context.arg since it has been
-        // "consumed" by the delegate iterator. If context.method was
-        // "return", allow the original .return call to continue in the
-        // outer generator.
-        if (context.method !== "return") {
-          context.method = "next";
-          context.arg = undefined$1;
-        }
-
-      } else {
-        // Re-yield the result returned by the delegate method.
-        return info;
-      }
-
-      // The delegate iterator is finished, so forget it and continue with
-      // the outer generator.
-      context.delegate = null;
-      return ContinueSentinel;
-    }
-
-    // Define Generator.prototype.{next,throw,return} in terms of the
-    // unified ._invoke helper method.
-    defineIteratorMethods(Gp);
-
-    Gp[toStringTagSymbol] = "Generator";
-
-    // A Generator should always return itself as the iterator object when the
-    // @@iterator function is called on it. Some browsers' implementations of the
-    // iterator prototype chain incorrectly implement this, causing the Generator
-    // object to not be returned from this call. This ensures that doesn't happen.
-    // See https://github.com/facebook/regenerator/issues/274 for more details.
-    Gp[iteratorSymbol] = function() {
-      return this;
-    };
-
-    Gp.toString = function() {
-      return "[object Generator]";
-    };
-
-    function pushTryEntry(locs) {
-      var entry = { tryLoc: locs[0] };
-
-      if (1 in locs) {
-        entry.catchLoc = locs[1];
-      }
-
-      if (2 in locs) {
-        entry.finallyLoc = locs[2];
-        entry.afterLoc = locs[3];
-      }
-
-      this.tryEntries.push(entry);
-    }
-
-    function resetTryEntry(entry) {
-      var record = entry.completion || {};
-      record.type = "normal";
-      delete record.arg;
-      entry.completion = record;
-    }
-
-    function Context(tryLocsList) {
-      // The root entry object (effectively a try statement without a catch
-      // or a finally block) gives us a place to store values thrown from
-      // locations where there is no enclosing try statement.
-      this.tryEntries = [{ tryLoc: "root" }];
-      tryLocsList.forEach(pushTryEntry, this);
-      this.reset(true);
-    }
-
-    exports.keys = function(object) {
-      var keys = [];
-      for (var key in object) {
-        keys.push(key);
-      }
-      keys.reverse();
-
-      // Rather than returning an object with a next method, we keep
-      // things simple and return the next function itself.
-      return function next() {
-        while (keys.length) {
-          var key = keys.pop();
-          if (key in object) {
-            next.value = key;
-            next.done = false;
-            return next;
-          }
-        }
-
-        // To avoid creating an additional object, we just hang the .value
-        // and .done properties off the next function object itself. This
-        // also ensures that the minifier will not anonymize the function.
-        next.done = true;
-        return next;
-      };
-    };
-
-    function values(iterable) {
-      if (iterable) {
-        var iteratorMethod = iterable[iteratorSymbol];
-        if (iteratorMethod) {
-          return iteratorMethod.call(iterable);
-        }
-
-        if (typeof iterable.next === "function") {
-          return iterable;
-        }
-
-        if (!isNaN(iterable.length)) {
-          var i = -1, next = function next() {
-            while (++i < iterable.length) {
-              if (hasOwn.call(iterable, i)) {
-                next.value = iterable[i];
-                next.done = false;
-                return next;
-              }
-            }
-
-            next.value = undefined$1;
-            next.done = true;
-
-            return next;
-          };
-
-          return next.next = next;
-        }
-      }
-
-      // Return an iterator with no values.
-      return { next: doneResult };
-    }
-    exports.values = values;
-
-    function doneResult() {
-      return { value: undefined$1, done: true };
-    }
-
-    Context.prototype = {
-      constructor: Context,
-
-      reset: function(skipTempReset) {
-        this.prev = 0;
-        this.next = 0;
-        // Resetting context._sent for legacy support of Babel's
-        // function.sent implementation.
-        this.sent = this._sent = undefined$1;
-        this.done = false;
-        this.delegate = null;
-
-        this.method = "next";
-        this.arg = undefined$1;
-
-        this.tryEntries.forEach(resetTryEntry);
-
-        if (!skipTempReset) {
-          for (var name in this) {
-            // Not sure about the optimal order of these conditions:
-            if (name.charAt(0) === "t" &&
-                hasOwn.call(this, name) &&
-                !isNaN(+name.slice(1))) {
-              this[name] = undefined$1;
-            }
-          }
-        }
-      },
-
-      stop: function() {
-        this.done = true;
-
-        var rootEntry = this.tryEntries[0];
-        var rootRecord = rootEntry.completion;
-        if (rootRecord.type === "throw") {
-          throw rootRecord.arg;
-        }
-
-        return this.rval;
-      },
-
-      dispatchException: function(exception) {
-        if (this.done) {
-          throw exception;
-        }
-
-        var context = this;
-        function handle(loc, caught) {
-          record.type = "throw";
-          record.arg = exception;
-          context.next = loc;
-
-          if (caught) {
-            // If the dispatched exception was caught by a catch block,
-            // then let that catch block handle the exception normally.
-            context.method = "next";
-            context.arg = undefined$1;
-          }
-
-          return !! caught;
-        }
-
-        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-          var entry = this.tryEntries[i];
-          var record = entry.completion;
-
-          if (entry.tryLoc === "root") {
-            // Exception thrown outside of any try block that could handle
-            // it, so set the completion value of the entire function to
-            // throw the exception.
-            return handle("end");
-          }
-
-          if (entry.tryLoc <= this.prev) {
-            var hasCatch = hasOwn.call(entry, "catchLoc");
-            var hasFinally = hasOwn.call(entry, "finallyLoc");
-
-            if (hasCatch && hasFinally) {
-              if (this.prev < entry.catchLoc) {
-                return handle(entry.catchLoc, true);
-              } else if (this.prev < entry.finallyLoc) {
-                return handle(entry.finallyLoc);
-              }
-
-            } else if (hasCatch) {
-              if (this.prev < entry.catchLoc) {
-                return handle(entry.catchLoc, true);
-              }
-
-            } else if (hasFinally) {
-              if (this.prev < entry.finallyLoc) {
-                return handle(entry.finallyLoc);
-              }
-
-            } else {
-              throw new Error("try statement without catch or finally");
-            }
-          }
-        }
-      },
-
-      abrupt: function(type, arg) {
-        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-          var entry = this.tryEntries[i];
-          if (entry.tryLoc <= this.prev &&
-              hasOwn.call(entry, "finallyLoc") &&
-              this.prev < entry.finallyLoc) {
-            var finallyEntry = entry;
-            break;
-          }
-        }
-
-        if (finallyEntry &&
-            (type === "break" ||
-             type === "continue") &&
-            finallyEntry.tryLoc <= arg &&
-            arg <= finallyEntry.finallyLoc) {
-          // Ignore the finally entry if control is not jumping to a
-          // location outside the try/catch block.
-          finallyEntry = null;
-        }
-
-        var record = finallyEntry ? finallyEntry.completion : {};
-        record.type = type;
-        record.arg = arg;
-
-        if (finallyEntry) {
-          this.method = "next";
-          this.next = finallyEntry.finallyLoc;
-          return ContinueSentinel;
-        }
-
-        return this.complete(record);
-      },
-
-      complete: function(record, afterLoc) {
-        if (record.type === "throw") {
-          throw record.arg;
-        }
-
-        if (record.type === "break" ||
-            record.type === "continue") {
-          this.next = record.arg;
-        } else if (record.type === "return") {
-          this.rval = this.arg = record.arg;
-          this.method = "return";
-          this.next = "end";
-        } else if (record.type === "normal" && afterLoc) {
-          this.next = afterLoc;
-        }
-
-        return ContinueSentinel;
-      },
-
-      finish: function(finallyLoc) {
-        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-          var entry = this.tryEntries[i];
-          if (entry.finallyLoc === finallyLoc) {
-            this.complete(entry.completion, entry.afterLoc);
-            resetTryEntry(entry);
-            return ContinueSentinel;
-          }
-        }
-      },
-
-      "catch": function(tryLoc) {
-        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-          var entry = this.tryEntries[i];
-          if (entry.tryLoc === tryLoc) {
-            var record = entry.completion;
-            if (record.type === "throw") {
-              var thrown = record.arg;
-              resetTryEntry(entry);
-            }
-            return thrown;
-          }
-        }
-
-        // The context.catch method must only be called with a location
-        // argument that corresponds to a known catch block.
-        throw new Error("illegal catch attempt");
-      },
-
-      delegateYield: function(iterable, resultName, nextLoc) {
-        this.delegate = {
-          iterator: values(iterable),
-          resultName: resultName,
-          nextLoc: nextLoc
-        };
-
-        if (this.method === "next") {
-          // Deliberately forget the last sent value so that we don't
-          // accidentally pass it on to the delegate.
-          this.arg = undefined$1;
-        }
-
-        return ContinueSentinel;
-      }
-    };
-
-    // Regardless of whether this script is executing as a CommonJS module
-    // or not, return the runtime object so that we can declare the variable
-    // regeneratorRuntime in the outer scope, which allows this module to be
-    // injected easily by `bin/regenerator --include-runtime script.js`.
-    return exports;
-
-  }(
-    // If this script is executing as a CommonJS module, use module.exports
-    // as the regeneratorRuntime namespace. Otherwise create a new empty
-    // object. Either way, the resulting object will be used to initialize
-    // the regeneratorRuntime variable at the top of this file.
-    module.exports 
-  ));
-
-  try {
-    regeneratorRuntime = runtime;
-  } catch (accidentalStrictMode) {
-    // This module should not be running in strict mode, so the above
-    // assignment should always work unless something is misconfigured. Just
-    // in case runtime.js accidentally runs in strict mode, we can escape
-    // strict mode using a global Function call. This could conceivably fail
-    // if a Content Security Policy forbids using Function, but in that case
-    // the proper solution is to fix the accidental strict mode problem. If
-    // you've misconfigured your bundler to force strict mode and applied a
-    // CSP to forbid Function, and you're not willing to fix either of those
-    // problems, please detail your unique predicament in a GitHub issue.
-    Function("r", "regeneratorRuntime = r")(runtime);
-  }
-  });
-
-  var UNSCOPABLES = wellKnownSymbol('unscopables');
-  var ArrayPrototype = Array.prototype;
-
-  // Array.prototype[@@unscopables]
-  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
-  if (ArrayPrototype[UNSCOPABLES] == undefined) {
-    objectDefineProperty.f(ArrayPrototype, UNSCOPABLES, {
-      configurable: true,
-      value: objectCreate(null)
-    });
-  }
-
-  // add a key to Array.prototype[@@unscopables]
-  var addToUnscopables = function (key) {
-    ArrayPrototype[UNSCOPABLES][key] = true;
-  };
-
-  var $includes = arrayIncludes.includes;
-
-
-
-  var USES_TO_LENGTH$6 = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });
-
-  // `Array.prototype.includes` method
-  // https://tc39.es/ecma262/#sec-array.prototype.includes
-  _export({ target: 'Array', proto: true, forced: !USES_TO_LENGTH$6 }, {
-    includes: function includes(el /* , fromIndex = 0 */) {
-      return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
-  addToUnscopables('includes');
-
-  var $map = arrayIteration.map;
-
-
-
-  var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('map');
-  // FF49- issue
-  var USES_TO_LENGTH$5 = arrayMethodUsesToLength('map');
-
-  // `Array.prototype.map` method
-  // https://tc39.es/ecma262/#sec-array.prototype.map
-  // with adding support of @@species
-  _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 || !USES_TO_LENGTH$5 }, {
-    map: function map(callbackfn /* , thisArg */) {
-      return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  // `Array.prototype.{ reduce, reduceRight }` methods implementation
-  var createMethod$2 = function (IS_RIGHT) {
-    return function (that, callbackfn, argumentsLength, memo) {
-      aFunction(callbackfn);
-      var O = toObject(that);
-      var self = indexedObject(O);
-      var length = toLength(O.length);
-      var index = IS_RIGHT ? length - 1 : 0;
-      var i = IS_RIGHT ? -1 : 1;
-      if (argumentsLength < 2) while (true) {
-        if (index in self) {
-          memo = self[index];
-          index += i;
-          break;
-        }
-        index += i;
-        if (IS_RIGHT ? index < 0 : length <= index) {
-          throw TypeError('Reduce of empty array with no initial value');
-        }
-      }
-      for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
-        memo = callbackfn(memo, self[index], index, O);
-      }
-      return memo;
-    };
-  };
-
-  var arrayReduce = {
-    // `Array.prototype.reduce` method
-    // https://tc39.es/ecma262/#sec-array.prototype.reduce
-    left: createMethod$2(false),
-    // `Array.prototype.reduceRight` method
-    // https://tc39.es/ecma262/#sec-array.prototype.reduceright
-    right: createMethod$2(true)
-  };
-
-  var engineIsNode = classofRaw(global_1.process) == 'process';
-
-  var $reduce = arrayReduce.left;
-
-
-
-
-
-  var STRICT_METHOD$3 = arrayMethodIsStrict('reduce');
-  var USES_TO_LENGTH$4 = arrayMethodUsesToLength('reduce', { 1: 0 });
-  // Chrome 80-82 has a critical bug
-  // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
-  var CHROME_BUG = !engineIsNode && engineV8Version > 79 && engineV8Version < 83;
-
-  // `Array.prototype.reduce` method
-  // https://tc39.es/ecma262/#sec-array.prototype.reduce
-  _export({ target: 'Array', proto: true, forced: !STRICT_METHOD$3 || !USES_TO_LENGTH$4 || CHROME_BUG }, {
-    reduce: function reduce(callbackfn /* , initialValue */) {
-      return $reduce(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  var $some = arrayIteration.some;
-
-
-
-  var STRICT_METHOD$2 = arrayMethodIsStrict('some');
-  var USES_TO_LENGTH$3 = arrayMethodUsesToLength('some');
-
-  // `Array.prototype.some` method
-  // https://tc39.es/ecma262/#sec-array.prototype.some
-  _export({ target: 'Array', proto: true, forced: !STRICT_METHOD$2 || !USES_TO_LENGTH$3 }, {
-    some: function some(callbackfn /* , thisArg */) {
-      return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  var propertyIsEnumerable = objectPropertyIsEnumerable.f;
-
-  // `Object.{ entries, values }` methods implementation
-  var createMethod$1 = function (TO_ENTRIES) {
-    return function (it) {
-      var O = toIndexedObject(it);
-      var keys = objectKeys(O);
-      var length = keys.length;
-      var i = 0;
-      var result = [];
-      var key;
-      while (length > i) {
-        key = keys[i++];
-        if (!descriptors || propertyIsEnumerable.call(O, key)) {
-          result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
-        }
-      }
-      return result;
-    };
-  };
-
-  var objectToArray = {
-    // `Object.entries` method
-    // https://tc39.es/ecma262/#sec-object.entries
-    entries: createMethod$1(true),
-    // `Object.values` method
-    // https://tc39.es/ecma262/#sec-object.values
-    values: createMethod$1(false)
-  };
-
-  var $entries = objectToArray.entries;
-
-  // `Object.entries` method
-  // https://tc39.es/ecma262/#sec-object.entries
-  _export({ target: 'Object', stat: true }, {
-    entries: function entries(O) {
-      return $entries(O);
-    }
-  });
-
-  // `SameValue` abstract operation
-  // https://tc39.es/ecma262/#sec-samevalue
-  var sameValue = Object.is || function is(x, y) {
-    // eslint-disable-next-line no-self-compare
-    return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
-  };
-
-  // `Object.is` method
-  // https://tc39.es/ecma262/#sec-object.is
-  _export({ target: 'Object', stat: true }, {
-    is: sameValue
-  });
-
-  var FAILS_ON_PRIMITIVES = fails(function () { objectKeys(1); });
-
-  // `Object.keys` method
-  // https://tc39.es/ecma262/#sec-object.keys
-  _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {
-    keys: function keys(it) {
-      return objectKeys(toObject(it));
-    }
-  });
-
-  // `Object.prototype.toString` method implementation
-  // https://tc39.es/ecma262/#sec-object.prototype.tostring
-  var objectToString = toStringTagSupport ? {}.toString : function toString() {
-    return '[object ' + classof(this) + ']';
-  };
-
-  // `Object.prototype.toString` method
-  // https://tc39.es/ecma262/#sec-object.prototype.tostring
-  if (!toStringTagSupport) {
-    redefine(Object.prototype, 'toString', objectToString, { unsafe: true });
-  }
-
-  var nativePromiseConstructor = global_1.Promise;
-
-  var redefineAll = function (target, src, options) {
-    for (var key in src) redefine(target, key, src[key], options);
-    return target;
-  };
-
-  var SPECIES$3 = wellKnownSymbol('species');
-
-  var setSpecies = function (CONSTRUCTOR_NAME) {
-    var Constructor = getBuiltIn(CONSTRUCTOR_NAME);
-    var defineProperty = objectDefineProperty.f;
-
-    if (descriptors && Constructor && !Constructor[SPECIES$3]) {
-      defineProperty(Constructor, SPECIES$3, {
-        configurable: true,
-        get: function () { return this; }
-      });
-    }
-  };
-
-  var anInstance = function (it, Constructor, name) {
-    if (!(it instanceof Constructor)) {
-      throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
-    } return it;
-  };
-
-  var Result = function (stopped, result) {
-    this.stopped = stopped;
-    this.result = result;
-  };
-
-  var iterate = function (iterable, unboundFunction, options) {
-    var that = options && options.that;
-    var AS_ENTRIES = !!(options && options.AS_ENTRIES);
-    var IS_ITERATOR = !!(options && options.IS_ITERATOR);
-    var INTERRUPTED = !!(options && options.INTERRUPTED);
-    var fn = functionBindContext(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED);
-    var iterator, iterFn, index, length, result, next, step;
-
-    var stop = function (condition) {
-      if (iterator) iteratorClose(iterator);
-      return new Result(true, condition);
-    };
-
-    var callFn = function (value) {
-      if (AS_ENTRIES) {
-        anObject(value);
-        return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
-      } return INTERRUPTED ? fn(value, stop) : fn(value);
-    };
-
-    if (IS_ITERATOR) {
-      iterator = iterable;
-    } else {
-      iterFn = getIteratorMethod(iterable);
-      if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
-      // optimisation for array iterators
-      if (isArrayIteratorMethod(iterFn)) {
-        for (index = 0, length = toLength(iterable.length); length > index; index++) {
-          result = callFn(iterable[index]);
-          if (result && result instanceof Result) return result;
-        } return new Result(false);
-      }
-      iterator = iterFn.call(iterable);
-    }
-
-    next = iterator.next;
-    while (!(step = next.call(iterator)).done) {
-      try {
-        result = callFn(step.value);
-      } catch (error) {
-        iteratorClose(iterator);
-        throw error;
-      }
-      if (typeof result == 'object' && result && result instanceof Result) return result;
-    } return new Result(false);
-  };
-
-  var SPECIES$2 = wellKnownSymbol('species');
-
-  // `SpeciesConstructor` abstract operation
-  // https://tc39.es/ecma262/#sec-speciesconstructor
-  var speciesConstructor = function (O, defaultConstructor) {
-    var C = anObject(O).constructor;
-    var S;
-    return C === undefined || (S = anObject(C)[SPECIES$2]) == undefined ? defaultConstructor : aFunction(S);
-  };
-
-  var engineIsIos = /(iphone|ipod|ipad).*applewebkit/i.test(engineUserAgent);
-
-  var location = global_1.location;
-  var set$1 = global_1.setImmediate;
-  var clear = global_1.clearImmediate;
-  var process$3 = global_1.process;
-  var MessageChannel = global_1.MessageChannel;
-  var Dispatch = global_1.Dispatch;
-  var counter = 0;
-  var queue = {};
-  var ONREADYSTATECHANGE = 'onreadystatechange';
-  var defer, channel, port;
-
-  var run = function (id) {
-    // eslint-disable-next-line no-prototype-builtins
-    if (queue.hasOwnProperty(id)) {
-      var fn = queue[id];
-      delete queue[id];
-      fn();
-    }
-  };
-
-  var runner = function (id) {
-    return function () {
-      run(id);
-    };
-  };
-
-  var listener = function (event) {
-    run(event.data);
-  };
-
-  var post = function (id) {
-    // old engines have not location.origin
-    global_1.postMessage(id + '', location.protocol + '//' + location.host);
-  };
-
-  // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
-  if (!set$1 || !clear) {
-    set$1 = function setImmediate(fn) {
-      var args = [];
-      var i = 1;
-      while (arguments.length > i) args.push(arguments[i++]);
-      queue[++counter] = function () {
-        // eslint-disable-next-line no-new-func
-        (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
-      };
-      defer(counter);
-      return counter;
-    };
-    clear = function clearImmediate(id) {
-      delete queue[id];
-    };
-    // Node.js 0.8-
-    if (engineIsNode) {
-      defer = function (id) {
-        process$3.nextTick(runner(id));
-      };
-    // Sphere (JS game engine) Dispatch API
-    } else if (Dispatch && Dispatch.now) {
-      defer = function (id) {
-        Dispatch.now(runner(id));
-      };
-    // Browsers with MessageChannel, includes WebWorkers
-    // except iOS - https://github.com/zloirock/core-js/issues/624
-    } else if (MessageChannel && !engineIsIos) {
-      channel = new MessageChannel();
-      port = channel.port2;
-      channel.port1.onmessage = listener;
-      defer = functionBindContext(port.postMessage, port, 1);
-    // Browsers with postMessage, skip WebWorkers
-    // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
-    } else if (
-      global_1.addEventListener &&
-      typeof postMessage == 'function' &&
-      !global_1.importScripts &&
-      location && location.protocol !== 'file:' &&
-      !fails(post)
-    ) {
-      defer = post;
-      global_1.addEventListener('message', listener, false);
-    // IE8-
-    } else if (ONREADYSTATECHANGE in documentCreateElement('script')) {
-      defer = function (id) {
-        html.appendChild(documentCreateElement('script'))[ONREADYSTATECHANGE] = function () {
-          html.removeChild(this);
-          run(id);
-        };
-      };
-    // Rest old browsers
-    } else {
-      defer = function (id) {
-        setTimeout(runner(id), 0);
-      };
-    }
-  }
-
-  var task$1 = {
-    set: set$1,
-    clear: clear
-  };
-
-  var engineIsWebosWebkit = /web0s(?!.*chrome)/i.test(engineUserAgent);
-
-  var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
-  var macrotask = task$1.set;
-
-
-
-
-  var MutationObserver$1 = global_1.MutationObserver || global_1.WebKitMutationObserver;
-  var document$2 = global_1.document;
-  var process$2 = global_1.process;
-  var Promise$1 = global_1.Promise;
-  // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`
-  var queueMicrotaskDescriptor = getOwnPropertyDescriptor$2(global_1, 'queueMicrotask');
-  var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;
-
-  var flush, head, last, notify$1, toggle, node, promise, then;
-
-  // modern engines have queueMicrotask method
-  if (!queueMicrotask) {
-    flush = function () {
-      var parent, fn;
-      if (engineIsNode && (parent = process$2.domain)) parent.exit();
-      while (head) {
-        fn = head.fn;
-        head = head.next;
-        try {
-          fn();
-        } catch (error) {
-          if (head) notify$1();
-          else last = undefined;
-          throw error;
-        }
-      } last = undefined;
-      if (parent) parent.enter();
-    };
-
-    // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339
-    // also except WebOS Webkit https://github.com/zloirock/core-js/issues/898
-    if (!engineIsIos && !engineIsNode && !engineIsWebosWebkit && MutationObserver$1 && document$2) {
-      toggle = true;
-      node = document$2.createTextNode('');
-      new MutationObserver$1(flush).observe(node, { characterData: true });
-      notify$1 = function () {
-        node.data = toggle = !toggle;
-      };
-    // environments with maybe non-completely correct, but existent Promise
-    } else if (Promise$1 && Promise$1.resolve) {
-      // Promise.resolve without an argument throws an error in LG WebOS 2
-      promise = Promise$1.resolve(undefined);
-      then = promise.then;
-      notify$1 = function () {
-        then.call(promise, flush);
-      };
-    // Node.js without promises
-    } else if (engineIsNode) {
-      notify$1 = function () {
-        process$2.nextTick(flush);
-      };
-    // for other environments - macrotask based on:
-    // - setImmediate
-    // - MessageChannel
-    // - window.postMessag
-    // - onreadystatechange
-    // - setTimeout
-    } else {
-      notify$1 = function () {
-        // strange IE + webpack dev server bug - use .call(global)
-        macrotask.call(global_1, flush);
-      };
-    }
-  }
-
-  var microtask = queueMicrotask || function (fn) {
-    var task = { fn: fn, next: undefined };
-    if (last) last.next = task;
-    if (!head) {
-      head = task;
-      notify$1();
-    } last = task;
-  };
-
-  var PromiseCapability = function (C) {
-    var resolve, reject;
-    this.promise = new C(function ($$resolve, $$reject) {
-      if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
-      resolve = $$resolve;
-      reject = $$reject;
-    });
-    this.resolve = aFunction(resolve);
-    this.reject = aFunction(reject);
-  };
-
-  // 25.4.1.5 NewPromiseCapability(C)
-  var f = function (C) {
-    return new PromiseCapability(C);
-  };
-
-  var newPromiseCapability$1 = {
-  	f: f
-  };
-
-  var promiseResolve = function (C, x) {
-    anObject(C);
-    if (isObject(x) && x.constructor === C) return x;
-    var promiseCapability = newPromiseCapability$1.f(C);
-    var resolve = promiseCapability.resolve;
-    resolve(x);
-    return promiseCapability.promise;
-  };
-
-  var hostReportErrors = function (a, b) {
-    var console = global_1.console;
-    if (console && console.error) {
-      arguments.length === 1 ? console.error(a) : console.error(a, b);
-    }
-  };
-
-  var perform = function (exec) {
-    try {
-      return { error: false, value: exec() };
-    } catch (error) {
-      return { error: true, value: error };
-    }
-  };
-
-  var task = task$1.set;
-
-
-
-
-
-
-
-
-
-
-
-  var SPECIES$1 = wellKnownSymbol('species');
-  var PROMISE = 'Promise';
-  var getInternalState$1 = internalState.get;
-  var setInternalState$2 = internalState.set;
-  var getInternalPromiseState = internalState.getterFor(PROMISE);
-  var PromiseConstructor = nativePromiseConstructor;
-  var TypeError$1 = global_1.TypeError;
-  var document$1 = global_1.document;
-  var process$1 = global_1.process;
-  var $fetch = getBuiltIn('fetch');
-  var newPromiseCapability = newPromiseCapability$1.f;
-  var newGenericPromiseCapability = newPromiseCapability;
-  var DISPATCH_EVENT = !!(document$1 && document$1.createEvent && global_1.dispatchEvent);
-  var NATIVE_REJECTION_EVENT = typeof PromiseRejectionEvent == 'function';
-  var UNHANDLED_REJECTION = 'unhandledrejection';
-  var REJECTION_HANDLED = 'rejectionhandled';
-  var PENDING = 0;
-  var FULFILLED = 1;
-  var REJECTED = 2;
-  var HANDLED = 1;
-  var UNHANDLED = 2;
-  var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
-
-  var FORCED$1 = isForced_1(PROMISE, function () {
-    var GLOBAL_CORE_JS_PROMISE = inspectSource(PromiseConstructor) !== String(PromiseConstructor);
-    if (!GLOBAL_CORE_JS_PROMISE) {
-      // V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
-      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565
-      // We can't detect it synchronously, so just check versions
-      if (engineV8Version === 66) return true;
-      // Unhandled rejections tracking support, NodeJS Promise without it fails @@species test
-      if (!engineIsNode && !NATIVE_REJECTION_EVENT) return true;
-    }
-    // We can't use @@species feature detection in V8 since it causes
-    // deoptimization and performance degradation
-    // https://github.com/zloirock/core-js/issues/679
-    if (engineV8Version >= 51 && /native code/.test(PromiseConstructor)) return false;
-    // Detect correctness of subclassing with @@species support
-    var promise = PromiseConstructor.resolve(1);
-    var FakePromise = function (exec) {
-      exec(function () { /* empty */ }, function () { /* empty */ });
-    };
-    var constructor = promise.constructor = {};
-    constructor[SPECIES$1] = FakePromise;
-    return !(promise.then(function () { /* empty */ }) instanceof FakePromise);
-  });
-
-  var INCORRECT_ITERATION = FORCED$1 || !checkCorrectnessOfIteration(function (iterable) {
-    PromiseConstructor.all(iterable)['catch'](function () { /* empty */ });
-  });
-
-  // helpers
-  var isThenable = function (it) {
-    var then;
-    return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
-  };
-
-  var notify = function (state, isReject) {
-    if (state.notified) return;
-    state.notified = true;
-    var chain = state.reactions;
-    microtask(function () {
-      var value = state.value;
-      var ok = state.state == FULFILLED;
-      var index = 0;
-      // variable length - can't use forEach
-      while (chain.length > index) {
-        var reaction = chain[index++];
-        var handler = ok ? reaction.ok : reaction.fail;
-        var resolve = reaction.resolve;
-        var reject = reaction.reject;
-        var domain = reaction.domain;
-        var result, then, exited;
-        try {
-          if (handler) {
-            if (!ok) {
-              if (state.rejection === UNHANDLED) onHandleUnhandled(state);
-              state.rejection = HANDLED;
-            }
-            if (handler === true) result = value;
-            else {
-              if (domain) domain.enter();
-              result = handler(value); // can throw
-              if (domain) {
-                domain.exit();
-                exited = true;
-              }
-            }
-            if (result === reaction.promise) {
-              reject(TypeError$1('Promise-chain cycle'));
-            } else if (then = isThenable(result)) {
-              then.call(result, resolve, reject);
-            } else resolve(result);
-          } else reject(value);
-        } catch (error) {
-          if (domain && !exited) domain.exit();
-          reject(error);
-        }
-      }
-      state.reactions = [];
-      state.notified = false;
-      if (isReject && !state.rejection) onUnhandled(state);
-    });
-  };
-
-  var dispatchEvent = function (name, promise, reason) {
-    var event, handler;
-    if (DISPATCH_EVENT) {
-      event = document$1.createEvent('Event');
-      event.promise = promise;
-      event.reason = reason;
-      event.initEvent(name, false, true);
-      global_1.dispatchEvent(event);
-    } else event = { promise: promise, reason: reason };
-    if (!NATIVE_REJECTION_EVENT && (handler = global_1['on' + name])) handler(event);
-    else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
-  };
-
-  var onUnhandled = function (state) {
-    task.call(global_1, function () {
-      var promise = state.facade;
-      var value = state.value;
-      var IS_UNHANDLED = isUnhandled(state);
-      var result;
-      if (IS_UNHANDLED) {
-        result = perform(function () {
-          if (engineIsNode) {
-            process$1.emit('unhandledRejection', value, promise);
-          } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
-        });
-        // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
-        state.rejection = engineIsNode || isUnhandled(state) ? UNHANDLED : HANDLED;
-        if (result.error) throw result.value;
-      }
-    });
-  };
-
-  var isUnhandled = function (state) {
-    return state.rejection !== HANDLED && !state.parent;
-  };
-
-  var onHandleUnhandled = function (state) {
-    task.call(global_1, function () {
-      var promise = state.facade;
-      if (engineIsNode) {
-        process$1.emit('rejectionHandled', promise);
-      } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
-    });
-  };
-
-  var bind = function (fn, state, unwrap) {
-    return function (value) {
-      fn(state, value, unwrap);
-    };
-  };
-
-  var internalReject = function (state, value, unwrap) {
-    if (state.done) return;
-    state.done = true;
-    if (unwrap) state = unwrap;
-    state.value = value;
-    state.state = REJECTED;
-    notify(state, true);
-  };
-
-  var internalResolve = function (state, value, unwrap) {
-    if (state.done) return;
-    state.done = true;
-    if (unwrap) state = unwrap;
-    try {
-      if (state.facade === value) throw TypeError$1("Promise can't be resolved itself");
-      var then = isThenable(value);
-      if (then) {
-        microtask(function () {
-          var wrapper = { done: false };
-          try {
-            then.call(value,
-              bind(internalResolve, wrapper, state),
-              bind(internalReject, wrapper, state)
-            );
-          } catch (error) {
-            internalReject(wrapper, error, state);
-          }
-        });
-      } else {
-        state.value = value;
-        state.state = FULFILLED;
-        notify(state, false);
-      }
-    } catch (error) {
-      internalReject({ done: false }, error, state);
-    }
-  };
-
-  // constructor polyfill
-  if (FORCED$1) {
-    // 25.4.3.1 Promise(executor)
-    PromiseConstructor = function Promise(executor) {
-      anInstance(this, PromiseConstructor, PROMISE);
-      aFunction(executor);
-      Internal.call(this);
-      var state = getInternalState$1(this);
-      try {
-        executor(bind(internalResolve, state), bind(internalReject, state));
-      } catch (error) {
-        internalReject(state, error);
-      }
-    };
-    // eslint-disable-next-line no-unused-vars
-    Internal = function Promise(executor) {
-      setInternalState$2(this, {
-        type: PROMISE,
-        done: false,
-        notified: false,
-        parent: false,
-        reactions: [],
-        rejection: false,
-        state: PENDING,
-        value: undefined
-      });
-    };
-    Internal.prototype = redefineAll(PromiseConstructor.prototype, {
-      // `Promise.prototype.then` method
-      // https://tc39.es/ecma262/#sec-promise.prototype.then
-      then: function then(onFulfilled, onRejected) {
-        var state = getInternalPromiseState(this);
-        var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));
-        reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
-        reaction.fail = typeof onRejected == 'function' && onRejected;
-        reaction.domain = engineIsNode ? process$1.domain : undefined;
-        state.parent = true;
-        state.reactions.push(reaction);
-        if (state.state != PENDING) notify(state, false);
-        return reaction.promise;
-      },
-      // `Promise.prototype.catch` method
-      // https://tc39.es/ecma262/#sec-promise.prototype.catch
-      'catch': function (onRejected) {
-        return this.then(undefined, onRejected);
-      }
-    });
-    OwnPromiseCapability = function () {
-      var promise = new Internal();
-      var state = getInternalState$1(promise);
-      this.promise = promise;
-      this.resolve = bind(internalResolve, state);
-      this.reject = bind(internalReject, state);
-    };
-    newPromiseCapability$1.f = newPromiseCapability = function (C) {
-      return C === PromiseConstructor || C === PromiseWrapper
-        ? new OwnPromiseCapability(C)
-        : newGenericPromiseCapability(C);
-    };
-
-    if (typeof nativePromiseConstructor == 'function') {
-      nativeThen = nativePromiseConstructor.prototype.then;
-
-      // wrap native Promise#then for native async functions
-      redefine(nativePromiseConstructor.prototype, 'then', function then(onFulfilled, onRejected) {
-        var that = this;
-        return new PromiseConstructor(function (resolve, reject) {
-          nativeThen.call(that, resolve, reject);
-        }).then(onFulfilled, onRejected);
-      // https://github.com/zloirock/core-js/issues/640
-      }, { unsafe: true });
-
-      // wrap fetch result
-      if (typeof $fetch == 'function') _export({ global: true, enumerable: true, forced: true }, {
-        // eslint-disable-next-line no-unused-vars
-        fetch: function fetch(input /* , init */) {
-          return promiseResolve(PromiseConstructor, $fetch.apply(global_1, arguments));
-        }
-      });
-    }
-  }
-
-  _export({ global: true, wrap: true, forced: FORCED$1 }, {
-    Promise: PromiseConstructor
-  });
-
-  setToStringTag(PromiseConstructor, PROMISE, false);
-  setSpecies(PROMISE);
-
-  PromiseWrapper = getBuiltIn(PROMISE);
-
-  // statics
-  _export({ target: PROMISE, stat: true, forced: FORCED$1 }, {
-    // `Promise.reject` method
-    // https://tc39.es/ecma262/#sec-promise.reject
-    reject: function reject(r) {
-      var capability = newPromiseCapability(this);
-      capability.reject.call(undefined, r);
-      return capability.promise;
-    }
-  });
-
-  _export({ target: PROMISE, stat: true, forced: FORCED$1 }, {
-    // `Promise.resolve` method
-    // https://tc39.es/ecma262/#sec-promise.resolve
-    resolve: function resolve(x) {
-      return promiseResolve(this, x);
-    }
-  });
-
-  _export({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION }, {
-    // `Promise.all` method
-    // https://tc39.es/ecma262/#sec-promise.all
-    all: function all(iterable) {
-      var C = this;
-      var capability = newPromiseCapability(C);
-      var resolve = capability.resolve;
-      var reject = capability.reject;
-      var result = perform(function () {
-        var $promiseResolve = aFunction(C.resolve);
-        var values = [];
-        var counter = 0;
-        var remaining = 1;
-        iterate(iterable, function (promise) {
-          var index = counter++;
-          var alreadyCalled = false;
-          values.push(undefined);
-          remaining++;
-          $promiseResolve.call(C, promise).then(function (value) {
-            if (alreadyCalled) return;
-            alreadyCalled = true;
-            values[index] = value;
-            --remaining || resolve(values);
-          }, reject);
-        });
-        --remaining || resolve(values);
-      });
-      if (result.error) reject(result.value);
-      return capability.promise;
-    },
-    // `Promise.race` method
-    // https://tc39.es/ecma262/#sec-promise.race
-    race: function race(iterable) {
-      var C = this;
-      var capability = newPromiseCapability(C);
-      var reject = capability.reject;
-      var result = perform(function () {
-        var $promiseResolve = aFunction(C.resolve);
-        iterate(iterable, function (promise) {
-          $promiseResolve.call(C, promise).then(capability.resolve, reject);
-        });
-      });
-      if (result.error) reject(result.value);
-      return capability.promise;
-    }
-  });
-
-  // `RegExp.prototype.flags` getter implementation
-  // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
-  var regexpFlags = function () {
-    var that = anObject(this);
-    var result = '';
-    if (that.global) result += 'g';
-    if (that.ignoreCase) result += 'i';
-    if (that.multiline) result += 'm';
-    if (that.dotAll) result += 's';
-    if (that.unicode) result += 'u';
-    if (that.sticky) result += 'y';
-    return result;
-  };
-
-  // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError,
-  // so we use an intermediate function.
-  function RE(s, f) {
-    return RegExp(s, f);
-  }
-
-  var UNSUPPORTED_Y$1 = fails(function () {
-    // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
-    var re = RE('a', 'y');
-    re.lastIndex = 2;
-    return re.exec('abcd') != null;
-  });
-
-  var BROKEN_CARET = fails(function () {
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
-    var re = RE('^r', 'gy');
-    re.lastIndex = 2;
-    return re.exec('str') != null;
-  });
-
-  var regexpStickyHelpers = {
-  	UNSUPPORTED_Y: UNSUPPORTED_Y$1,
-  	BROKEN_CARET: BROKEN_CARET
-  };
-
-  var nativeExec = RegExp.prototype.exec;
-  // This always refers to the native implementation, because the
-  // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
-  // which loads this file before patching the method.
-  var nativeReplace = String.prototype.replace;
-
-  var patchedExec = nativeExec;
-
-  var UPDATES_LAST_INDEX_WRONG = (function () {
-    var re1 = /a/;
-    var re2 = /b*/g;
-    nativeExec.call(re1, 'a');
-    nativeExec.call(re2, 'a');
-    return re1.lastIndex !== 0 || re2.lastIndex !== 0;
-  })();
-
-  var UNSUPPORTED_Y = regexpStickyHelpers.UNSUPPORTED_Y || regexpStickyHelpers.BROKEN_CARET;
-
-  // nonparticipating capturing group, copied from es5-shim's String#split patch.
-  var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
-
-  var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y;
-
-  if (PATCH) {
-    patchedExec = function exec(str) {
-      var re = this;
-      var lastIndex, reCopy, match, i;
-      var sticky = UNSUPPORTED_Y && re.sticky;
-      var flags = regexpFlags.call(re);
-      var source = re.source;
-      var charsAdded = 0;
-      var strCopy = str;
-
-      if (sticky) {
-        flags = flags.replace('y', '');
-        if (flags.indexOf('g') === -1) {
-          flags += 'g';
-        }
-
-        strCopy = String(str).slice(re.lastIndex);
-        // Support anchored sticky behavior.
-        if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\n')) {
-          source = '(?: ' + source + ')';
-          strCopy = ' ' + strCopy;
-          charsAdded++;
-        }
-        // ^(? + rx + ) is needed, in combination with some str slicing, to
-        // simulate the 'y' flag.
-        reCopy = new RegExp('^(?:' + source + ')', flags);
-      }
-
-      if (NPCG_INCLUDED) {
-        reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
-      }
-      if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
-
-      match = nativeExec.call(sticky ? reCopy : re, strCopy);
-
-      if (sticky) {
-        if (match) {
-          match.input = match.input.slice(charsAdded);
-          match[0] = match[0].slice(charsAdded);
-          match.index = re.lastIndex;
-          re.lastIndex += match[0].length;
-        } else re.lastIndex = 0;
-      } else if (UPDATES_LAST_INDEX_WRONG && match) {
-        re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
-      }
-      if (NPCG_INCLUDED && match && match.length > 1) {
-        // Fix browsers whose `exec` methods don't consistently return `undefined`
-        // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
-        nativeReplace.call(match[0], reCopy, function () {
-          for (i = 1; i < arguments.length - 2; i++) {
-            if (arguments[i] === undefined) match[i] = undefined;
-          }
-        });
-      }
-
-      return match;
-    };
-  }
-
-  var regexpExec = patchedExec;
-
-  // `RegExp.prototype.exec` method
-  // https://tc39.es/ecma262/#sec-regexp.prototype.exec
-  _export({ target: 'RegExp', proto: true, forced: /./.exec !== regexpExec }, {
-    exec: regexpExec
-  });
-
-  var MATCH$1 = wellKnownSymbol('match');
-
-  // `IsRegExp` abstract operation
-  // https://tc39.es/ecma262/#sec-isregexp
-  var isRegexp = function (it) {
-    var isRegExp;
-    return isObject(it) && ((isRegExp = it[MATCH$1]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
-  };
-
-  var notARegexp = function (it) {
-    if (isRegexp(it)) {
-      throw TypeError("The method doesn't accept regular expressions");
-    } return it;
-  };
-
-  var MATCH = wellKnownSymbol('match');
-
-  var correctIsRegexpLogic = function (METHOD_NAME) {
-    var regexp = /./;
-    try {
-      '/./'[METHOD_NAME](regexp);
-    } catch (error1) {
-      try {
-        regexp[MATCH] = false;
-        return '/./'[METHOD_NAME](regexp);
-      } catch (error2) { /* empty */ }
-    } return false;
-  };
-
-  // `String.prototype.includes` method
-  // https://tc39.es/ecma262/#sec-string.prototype.includes
-  _export({ target: 'String', proto: true, forced: !correctIsRegexpLogic('includes') }, {
-    includes: function includes(searchString /* , position = 0 */) {
-      return !!~String(requireObjectCoercible(this))
-        .indexOf(notARegexp(searchString), arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  // TODO: Remove from `core-js@4` since it's moved to entry points
-
-
-
-
-
-
-
-  var SPECIES = wellKnownSymbol('species');
-
-  var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
-    // #replace needs built-in support for named groups.
-    // #match works fine because it just return the exec results, even if it has
-    // a "grops" property.
-    var re = /./;
-    re.exec = function () {
-      var result = [];
-      result.groups = { a: '7' };
-      return result;
-    };
-    return ''.replace(re, '$<a>') !== '7';
-  });
-
-  // IE <= 11 replaces $0 with the whole match, as if it was $&
-  // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
-  var REPLACE_KEEPS_$0 = (function () {
-    return 'a'.replace(/./, '$0') === '$0';
-  })();
-
-  var REPLACE = wellKnownSymbol('replace');
-  // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
-  var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
-    if (/./[REPLACE]) {
-      return /./[REPLACE]('a', '$0') === '';
-    }
-    return false;
-  })();
-
-  // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
-  // Weex JS has frozen built-in prototypes, so use try / catch wrapper
-  var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
-    var re = /(?:)/;
-    var originalExec = re.exec;
-    re.exec = function () { return originalExec.apply(this, arguments); };
-    var result = 'ab'.split(re);
-    return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
-  });
-
-  var fixRegexpWellKnownSymbolLogic = function (KEY, length, exec, sham) {
-    var SYMBOL = wellKnownSymbol(KEY);
-
-    var DELEGATES_TO_SYMBOL = !fails(function () {
-      // String methods call symbol-named RegEp methods
-      var O = {};
-      O[SYMBOL] = function () { return 7; };
-      return ''[KEY](O) != 7;
-    });
-
-    var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
-      // Symbol-named RegExp methods call .exec
-      var execCalled = false;
-      var re = /a/;
-
-      if (KEY === 'split') {
-        // We can't use real regex here since it causes deoptimization
-        // and serious performance degradation in V8
-        // https://github.com/zloirock/core-js/issues/306
-        re = {};
-        // RegExp[@@split] doesn't call the regex's exec method, but first creates
-        // a new one. We need to return the patched regex when creating the new one.
-        re.constructor = {};
-        re.constructor[SPECIES] = function () { return re; };
-        re.flags = '';
-        re[SYMBOL] = /./[SYMBOL];
-      }
-
-      re.exec = function () { execCalled = true; return null; };
-
-      re[SYMBOL]('');
-      return !execCalled;
-    });
-
-    if (
-      !DELEGATES_TO_SYMBOL ||
-      !DELEGATES_TO_EXEC ||
-      (KEY === 'replace' && !(
-        REPLACE_SUPPORTS_NAMED_GROUPS &&
-        REPLACE_KEEPS_$0 &&
-        !REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
-      )) ||
-      (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
-    ) {
-      var nativeRegExpMethod = /./[SYMBOL];
-      var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
-        if (regexp.exec === regexpExec) {
-          if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
-            // The native String method already delegates to @@method (this
-            // polyfilled function), leasing to infinite recursion.
-            // We avoid it by directly calling the native @@method method.
-            return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
-          }
-          return { done: true, value: nativeMethod.call(str, regexp, arg2) };
-        }
-        return { done: false };
-      }, {
-        REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,
-        REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
-      });
-      var stringMethod = methods[0];
-      var regexMethod = methods[1];
-
-      redefine(String.prototype, KEY, stringMethod);
-      redefine(RegExp.prototype, SYMBOL, length == 2
-        // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
-        // 21.2.5.11 RegExp.prototype[@@split](string, limit)
-        ? function (string, arg) { return regexMethod.call(string, this, arg); }
-        // 21.2.5.6 RegExp.prototype[@@match](string)
-        // 21.2.5.9 RegExp.prototype[@@search](string)
-        : function (string) { return regexMethod.call(string, this); }
-      );
-    }
-
-    if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);
-  };
-
-  var charAt = stringMultibyte.charAt;
-
-  // `AdvanceStringIndex` abstract operation
-  // https://tc39.es/ecma262/#sec-advancestringindex
-  var advanceStringIndex = function (S, index, unicode) {
-    return index + (unicode ? charAt(S, index).length : 1);
-  };
-
-  // `RegExpExec` abstract operation
-  // https://tc39.es/ecma262/#sec-regexpexec
-  var regexpExecAbstract = function (R, S) {
-    var exec = R.exec;
-    if (typeof exec === 'function') {
-      var result = exec.call(R, S);
-      if (typeof result !== 'object') {
-        throw TypeError('RegExp exec method returned something other than an Object or null');
-      }
-      return result;
-    }
-
-    if (classofRaw(R) !== 'RegExp') {
-      throw TypeError('RegExp#exec called on incompatible receiver');
-    }
-
-    return regexpExec.call(R, S);
-  };
-
-  var arrayPush = [].push;
-  var min$3 = Math.min;
-  var MAX_UINT32 = 0xFFFFFFFF;
-
-  // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
-  var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });
-
-  // @@split logic
-  fixRegexpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
-    var internalSplit;
-    if (
-      'abbc'.split(/(b)*/)[1] == 'c' ||
-      'test'.split(/(?:)/, -1).length != 4 ||
-      'ab'.split(/(?:ab)*/).length != 2 ||
-      '.'.split(/(.?)(.?)/).length != 4 ||
-      '.'.split(/()()/).length > 1 ||
-      ''.split(/.?/).length
-    ) {
-      // based on es5-shim implementation, need to rework it
-      internalSplit = function (separator, limit) {
-        var string = String(requireObjectCoercible(this));
-        var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
-        if (lim === 0) return [];
-        if (separator === undefined) return [string];
-        // If `separator` is not a regex, use native split
-        if (!isRegexp(separator)) {
-          return nativeSplit.call(string, separator, lim);
-        }
-        var output = [];
-        var flags = (separator.ignoreCase ? 'i' : '') +
-                    (separator.multiline ? 'm' : '') +
-                    (separator.unicode ? 'u' : '') +
-                    (separator.sticky ? 'y' : '');
-        var lastLastIndex = 0;
-        // Make `global` and avoid `lastIndex` issues by working with a copy
-        var separatorCopy = new RegExp(separator.source, flags + 'g');
-        var match, lastIndex, lastLength;
-        while (match = regexpExec.call(separatorCopy, string)) {
-          lastIndex = separatorCopy.lastIndex;
-          if (lastIndex > lastLastIndex) {
-            output.push(string.slice(lastLastIndex, match.index));
-            if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
-            lastLength = match[0].length;
-            lastLastIndex = lastIndex;
-            if (output.length >= lim) break;
-          }
-          if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
-        }
-        if (lastLastIndex === string.length) {
-          if (lastLength || !separatorCopy.test('')) output.push('');
-        } else output.push(string.slice(lastLastIndex));
-        return output.length > lim ? output.slice(0, lim) : output;
-      };
-    // Chakra, V8
-    } else if ('0'.split(undefined, 0).length) {
-      internalSplit = function (separator, limit) {
-        return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
-      };
-    } else internalSplit = nativeSplit;
-
-    return [
-      // `String.prototype.split` method
-      // https://tc39.es/ecma262/#sec-string.prototype.split
-      function split(separator, limit) {
-        var O = requireObjectCoercible(this);
-        var splitter = separator == undefined ? undefined : separator[SPLIT];
-        return splitter !== undefined
-          ? splitter.call(separator, O, limit)
-          : internalSplit.call(String(O), separator, limit);
-      },
-      // `RegExp.prototype[@@split]` method
-      // https://tc39.es/ecma262/#sec-regexp.prototype-@@split
-      //
-      // NOTE: This cannot be properly polyfilled in engines that don't support
-      // the 'y' flag.
-      function (regexp, limit) {
-        var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
-        if (res.done) return res.value;
-
-        var rx = anObject(regexp);
-        var S = String(this);
-        var C = speciesConstructor(rx, RegExp);
-
-        var unicodeMatching = rx.unicode;
-        var flags = (rx.ignoreCase ? 'i' : '') +
-                    (rx.multiline ? 'm' : '') +
-                    (rx.unicode ? 'u' : '') +
-                    (SUPPORTS_Y ? 'y' : 'g');
-
-        // ^(? + rx + ) is needed, in combination with some S slicing, to
-        // simulate the 'y' flag.
-        var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
-        var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
-        if (lim === 0) return [];
-        if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
-        var p = 0;
-        var q = 0;
-        var A = [];
-        while (q < S.length) {
-          splitter.lastIndex = SUPPORTS_Y ? q : 0;
-          var z = regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
-          var e;
-          if (
-            z === null ||
-            (e = min$3(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
-          ) {
-            q = advanceStringIndex(S, q, unicodeMatching);
-          } else {
-            A.push(S.slice(p, q));
-            if (A.length === lim) return A;
-            for (var i = 1; i <= z.length - 1; i++) {
-              A.push(z[i]);
-              if (A.length === lim) return A;
-            }
-            q = p = e;
-          }
-        }
-        A.push(S.slice(p));
-        return A;
-      }
-    ];
-  }, !SUPPORTS_Y);
-
-  var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
-  var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
-  var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
-
-  // We can't use this feature detection in V8 since it causes
-  // deoptimization and serious performance degradation
-  // https://github.com/zloirock/core-js/issues/679
-  var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
-    var array = [];
-    array[IS_CONCAT_SPREADABLE] = false;
-    return array.concat()[0] !== array;
-  });
-
-  var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
-
-  var isConcatSpreadable = function (O) {
-    if (!isObject(O)) return false;
-    var spreadable = O[IS_CONCAT_SPREADABLE];
-    return spreadable !== undefined ? !!spreadable : isArray(O);
-  };
-
-  var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
-
-  // `Array.prototype.concat` method
-  // https://tc39.es/ecma262/#sec-array.prototype.concat
-  // with adding support of @@isConcatSpreadable and @@species
-  _export({ target: 'Array', proto: true, forced: FORCED }, {
-    concat: function concat(arg) { // eslint-disable-line no-unused-vars
-      var O = toObject(this);
-      var A = arraySpeciesCreate(O, 0);
-      var n = 0;
-      var i, k, length, len, E;
-      for (i = -1, length = arguments.length; i < length; i++) {
-        E = i === -1 ? O : arguments[i];
-        if (isConcatSpreadable(E)) {
-          len = toLength(E.length);
-          if (n + len > MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
-          for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
-        } else {
-          if (n >= MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
-          createProperty(A, n++, E);
-        }
-      }
-      A.length = n;
-      return A;
-    }
-  });
-
-  var $find = arrayIteration.find;
-
-
-
-  var FIND = 'find';
-  var SKIPS_HOLES = true;
-
-  var USES_TO_LENGTH$2 = arrayMethodUsesToLength(FIND);
-
-  // Shouldn't skip holes
-  if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });
-
-  // `Array.prototype.find` method
-  // https://tc39.es/ecma262/#sec-array.prototype.find
-  _export({ target: 'Array', proto: true, forced: SKIPS_HOLES || !USES_TO_LENGTH$2 }, {
-    find: function find(callbackfn /* , that = undefined */) {
-      return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
-  addToUnscopables(FIND);
-
-  var $indexOf = arrayIncludes.indexOf;
-
-
-
-  var nativeIndexOf = [].indexOf;
-
-  var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
-  var STRICT_METHOD$1 = arrayMethodIsStrict('indexOf');
-  var USES_TO_LENGTH$1 = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });
-
-  // `Array.prototype.indexOf` method
-  // https://tc39.es/ecma262/#sec-array.prototype.indexof
-  _export({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || !STRICT_METHOD$1 || !USES_TO_LENGTH$1 }, {
-    indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
-      return NEGATIVE_ZERO
-        // convert -0 to +0
-        ? nativeIndexOf.apply(this, arguments) || 0
-        : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);
-    }
-  });
-
-  var ARRAY_ITERATOR = 'Array Iterator';
-  var setInternalState$1 = internalState.set;
-  var getInternalState = internalState.getterFor(ARRAY_ITERATOR);
-
-  // `Array.prototype.entries` method
-  // https://tc39.es/ecma262/#sec-array.prototype.entries
-  // `Array.prototype.keys` method
-  // https://tc39.es/ecma262/#sec-array.prototype.keys
-  // `Array.prototype.values` method
-  // https://tc39.es/ecma262/#sec-array.prototype.values
-  // `Array.prototype[@@iterator]` method
-  // https://tc39.es/ecma262/#sec-array.prototype-@@iterator
-  // `CreateArrayIterator` internal method
-  // https://tc39.es/ecma262/#sec-createarrayiterator
-  var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) {
-    setInternalState$1(this, {
-      type: ARRAY_ITERATOR,
-      target: toIndexedObject(iterated), // target
-      index: 0,                          // next index
-      kind: kind                         // kind
-    });
-  // `%ArrayIteratorPrototype%.next` method
-  // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
-  }, function () {
-    var state = getInternalState(this);
-    var target = state.target;
-    var kind = state.kind;
-    var index = state.index++;
-    if (!target || index >= target.length) {
-      state.target = undefined;
-      return { value: undefined, done: true };
-    }
-    if (kind == 'keys') return { value: index, done: false };
-    if (kind == 'values') return { value: target[index], done: false };
-    return { value: [index, target[index]], done: false };
-  }, 'values');
-
-  // argumentsList[@@iterator] is %ArrayProto_values%
-  // https://tc39.es/ecma262/#sec-createunmappedargumentsobject
-  // https://tc39.es/ecma262/#sec-createmappedargumentsobject
-  iterators.Arguments = iterators.Array;
-
-  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
-  addToUnscopables('keys');
-  addToUnscopables('values');
-  addToUnscopables('entries');
-
-  var nativeJoin = [].join;
-
-  var ES3_STRINGS = indexedObject != Object;
-  var STRICT_METHOD = arrayMethodIsStrict('join', ',');
-
-  // `Array.prototype.join` method
-  // https://tc39.es/ecma262/#sec-array.prototype.join
-  _export({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD }, {
-    join: function join(separator) {
-      return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
-    }
-  });
-
-  var defineProperty$3 = objectDefineProperty.f;
-
-  var FunctionPrototype = Function.prototype;
-  var FunctionPrototypeToString = FunctionPrototype.toString;
-  var nameRE = /^\s*function ([^ (]*)/;
-  var NAME = 'name';
-
-  // Function instances `.name` property
-  // https://tc39.es/ecma262/#sec-function-instances-name
-  if (descriptors && !(NAME in FunctionPrototype)) {
-    defineProperty$3(FunctionPrototype, NAME, {
-      configurable: true,
-      get: function () {
-        try {
-          return FunctionPrototypeToString.call(this).match(nameRE)[1];
-        } catch (error) {
-          return '';
-        }
-      }
-    });
-  }
-
-  // makes subclassing work correct for wrapped built-ins
-  var inheritIfRequired = function ($this, dummy, Wrapper) {
-    var NewTarget, NewTargetPrototype;
-    if (
-      // it can work only with native `setPrototypeOf`
-      objectSetPrototypeOf &&
-      // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
-      typeof (NewTarget = dummy.constructor) == 'function' &&
-      NewTarget !== Wrapper &&
-      isObject(NewTargetPrototype = NewTarget.prototype) &&
-      NewTargetPrototype !== Wrapper.prototype
-    ) objectSetPrototypeOf($this, NewTargetPrototype);
-    return $this;
-  };
-
-  // a string of all valid unicode whitespaces
-  // eslint-disable-next-line max-len
-  var whitespaces = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
-
-  var whitespace = '[' + whitespaces + ']';
-  var ltrim = RegExp('^' + whitespace + whitespace + '*');
-  var rtrim = RegExp(whitespace + whitespace + '*$');
-
-  // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
-  var createMethod = function (TYPE) {
-    return function ($this) {
-      var string = String(requireObjectCoercible($this));
-      if (TYPE & 1) string = string.replace(ltrim, '');
-      if (TYPE & 2) string = string.replace(rtrim, '');
-      return string;
-    };
-  };
-
-  var stringTrim = {
-    // `String.prototype.{ trimLeft, trimStart }` methods
-    // https://tc39.es/ecma262/#sec-string.prototype.trimstart
-    start: createMethod(1),
-    // `String.prototype.{ trimRight, trimEnd }` methods
-    // https://tc39.es/ecma262/#sec-string.prototype.trimend
-    end: createMethod(2),
-    // `String.prototype.trim` method
-    // https://tc39.es/ecma262/#sec-string.prototype.trim
-    trim: createMethod(3)
-  };
-
-  var getOwnPropertyNames = objectGetOwnPropertyNames.f;
-  var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
-  var defineProperty$2 = objectDefineProperty.f;
-  var trim = stringTrim.trim;
-
-  var NUMBER = 'Number';
-  var NativeNumber = global_1[NUMBER];
-  var NumberPrototype = NativeNumber.prototype;
-
-  // Opera ~12 has broken Object#toString
-  var BROKEN_CLASSOF = classofRaw(objectCreate(NumberPrototype)) == NUMBER;
-
-  // `ToNumber` abstract operation
-  // https://tc39.es/ecma262/#sec-tonumber
-  var toNumber = function (argument) {
-    var it = toPrimitive(argument, false);
-    var first, third, radix, maxCode, digits, length, index, code;
-    if (typeof it == 'string' && it.length > 2) {
-      it = trim(it);
-      first = it.charCodeAt(0);
-      if (first === 43 || first === 45) {
-        third = it.charCodeAt(2);
-        if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
-      } else if (first === 48) {
-        switch (it.charCodeAt(1)) {
-          case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i
-          case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i
-          default: return +it;
-        }
-        digits = it.slice(2);
-        length = digits.length;
-        for (index = 0; index < length; index++) {
-          code = digits.charCodeAt(index);
-          // parseInt parses a string to a first unavailable symbol
-          // but ToNumber should return NaN if a string contains unavailable symbols
-          if (code < 48 || code > maxCode) return NaN;
-        } return parseInt(digits, radix);
-      }
-    } return +it;
-  };
-
-  // `Number` constructor
-  // https://tc39.es/ecma262/#sec-number-constructor
-  if (isForced_1(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {
-    var NumberWrapper = function Number(value) {
-      var it = arguments.length < 1 ? 0 : value;
-      var dummy = this;
-      return dummy instanceof NumberWrapper
-        // check on 1..constructor(foo) case
-        && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(dummy); }) : classofRaw(dummy) != NUMBER)
-          ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);
-    };
-    for (var keys = descriptors ? getOwnPropertyNames(NativeNumber) : (
-      // ES3:
-      'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
-      // ES2015 (in case, if modules with ES2015 Number statics required before):
-      'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
-      'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger,' +
-      // ESNext
-      'fromString,range'
-    ).split(','), j = 0, key; keys.length > j; j++) {
-      if (has$1(NativeNumber, key = keys[j]) && !has$1(NumberWrapper, key)) {
-        defineProperty$2(NumberWrapper, key, getOwnPropertyDescriptor$1(NativeNumber, key));
-      }
-    }
-    NumberWrapper.prototype = NumberPrototype;
-    NumberPrototype.constructor = NumberWrapper;
-    redefine(global_1, NUMBER, NumberWrapper);
-  }
-
-  var nativeAssign = Object.assign;
-  var defineProperty$1 = Object.defineProperty;
-
-  // `Object.assign` method
-  // https://tc39.es/ecma262/#sec-object.assign
-  var objectAssign = !nativeAssign || fails(function () {
-    // should have correct order of operations (Edge bug)
-    if (descriptors && nativeAssign({ b: 1 }, nativeAssign(defineProperty$1({}, 'a', {
-      enumerable: true,
-      get: function () {
-        defineProperty$1(this, 'b', {
-          value: 3,
-          enumerable: false
-        });
-      }
-    }), { b: 2 })).b !== 1) return true;
-    // should work with symbols and should have deterministic property order (V8 bug)
-    var A = {};
-    var B = {};
-    // eslint-disable-next-line no-undef
-    var symbol = Symbol();
-    var alphabet = 'abcdefghijklmnopqrst';
-    A[symbol] = 7;
-    alphabet.split('').forEach(function (chr) { B[chr] = chr; });
-    return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
-  }) ? function assign(target, source) { // eslint-disable-line no-unused-vars
-    var T = toObject(target);
-    var argumentsLength = arguments.length;
-    var index = 1;
-    var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
-    var propertyIsEnumerable = objectPropertyIsEnumerable.f;
-    while (argumentsLength > index) {
-      var S = indexedObject(arguments[index++]);
-      var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
-      var length = keys.length;
-      var j = 0;
-      var key;
-      while (length > j) {
-        key = keys[j++];
-        if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
-      }
-    } return T;
-  } : nativeAssign;
-
-  // `Object.assign` method
-  // https://tc39.es/ecma262/#sec-object.assign
-  _export({ target: 'Object', stat: true, forced: Object.assign !== objectAssign }, {
-    assign: objectAssign
-  });
-
-  var $values = objectToArray.values;
-
-  // `Object.values` method
-  // https://tc39.es/ecma262/#sec-object.values
-  _export({ target: 'Object', stat: true }, {
-    values: function values(O) {
-      return $values(O);
-    }
-  });
-
-  var freezing = !fails(function () {
-    return Object.isExtensible(Object.preventExtensions({}));
-  });
-
-  var internalMetadata = createCommonjsModule(function (module) {
-  var defineProperty = objectDefineProperty.f;
-
-
-
-  var METADATA = uid('meta');
-  var id = 0;
-
-  var isExtensible = Object.isExtensible || function () {
-    return true;
-  };
-
-  var setMetadata = function (it) {
-    defineProperty(it, METADATA, { value: {
-      objectID: 'O' + ++id, // object ID
-      weakData: {}          // weak collections IDs
-    } });
-  };
-
-  var fastKey = function (it, create) {
-    // return a primitive with prefix
-    if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
-    if (!has$1(it, METADATA)) {
-      // can't set metadata to uncaught frozen object
-      if (!isExtensible(it)) return 'F';
-      // not necessary to add metadata
-      if (!create) return 'E';
-      // add missing metadata
-      setMetadata(it);
-    // return object ID
-    } return it[METADATA].objectID;
-  };
-
-  var getWeakData = function (it, create) {
-    if (!has$1(it, METADATA)) {
-      // can't set metadata to uncaught frozen object
-      if (!isExtensible(it)) return true;
-      // not necessary to add metadata
-      if (!create) return false;
-      // add missing metadata
-      setMetadata(it);
-    // return the store of weak collections IDs
-    } return it[METADATA].weakData;
-  };
-
-  // add metadata on freeze-family methods calling
-  var onFreeze = function (it) {
-    if (freezing && meta.REQUIRED && isExtensible(it) && !has$1(it, METADATA)) setMetadata(it);
-    return it;
-  };
-
-  var meta = module.exports = {
-    REQUIRED: false,
-    fastKey: fastKey,
-    getWeakData: getWeakData,
-    onFreeze: onFreeze
-  };
-
-  hiddenKeys$1[METADATA] = true;
-  });
-  internalMetadata.REQUIRED;
-  internalMetadata.fastKey;
-  internalMetadata.getWeakData;
-  internalMetadata.onFreeze;
-
-  var collection = function (CONSTRUCTOR_NAME, wrapper, common) {
-    var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1;
-    var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1;
-    var ADDER = IS_MAP ? 'set' : 'add';
-    var NativeConstructor = global_1[CONSTRUCTOR_NAME];
-    var NativePrototype = NativeConstructor && NativeConstructor.prototype;
-    var Constructor = NativeConstructor;
-    var exported = {};
-
-    var fixMethod = function (KEY) {
-      var nativeMethod = NativePrototype[KEY];
-      redefine(NativePrototype, KEY,
-        KEY == 'add' ? function add(value) {
-          nativeMethod.call(this, value === 0 ? 0 : value);
-          return this;
-        } : KEY == 'delete' ? function (key) {
-          return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
-        } : KEY == 'get' ? function get(key) {
-          return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);
-        } : KEY == 'has' ? function has(key) {
-          return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
-        } : function set(key, value) {
-          nativeMethod.call(this, key === 0 ? 0 : key, value);
-          return this;
-        }
-      );
-    };
-
-    // eslint-disable-next-line max-len
-    if (isForced_1(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
-      new NativeConstructor().entries().next();
-    })))) {
-      // create collection constructor
-      Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
-      internalMetadata.REQUIRED = true;
-    } else if (isForced_1(CONSTRUCTOR_NAME, true)) {
-      var instance = new Constructor();
-      // early implementations not supports chaining
-      var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
-      // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
-      var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
-      // most early implementations doesn't supports iterables, most modern - not close it correctly
-      // eslint-disable-next-line no-new
-      var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
-      // for early implementations -0 and +0 not the same
-      var BUGGY_ZERO = !IS_WEAK && fails(function () {
-        // V8 ~ Chromium 42- fails only with 5+ elements
-        var $instance = new NativeConstructor();
-        var index = 5;
-        while (index--) $instance[ADDER](index, index);
-        return !$instance.has(-0);
-      });
-
-      if (!ACCEPT_ITERABLES) {
-        Constructor = wrapper(function (dummy, iterable) {
-          anInstance(dummy, Constructor, CONSTRUCTOR_NAME);
-          var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
-          if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
-          return that;
-        });
-        Constructor.prototype = NativePrototype;
-        NativePrototype.constructor = Constructor;
-      }
-
-      if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
-        fixMethod('delete');
-        fixMethod('has');
-        IS_MAP && fixMethod('get');
-      }
-
-      if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
-
-      // weak collections should not contains .clear method
-      if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
-    }
-
-    exported[CONSTRUCTOR_NAME] = Constructor;
-    _export({ global: true, forced: Constructor != NativeConstructor }, exported);
-
-    setToStringTag(Constructor, CONSTRUCTOR_NAME);
-
-    if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
-
-    return Constructor;
-  };
-
-  var defineProperty = objectDefineProperty.f;
-
-
-
-
-
-
-
-
-  var fastKey = internalMetadata.fastKey;
-
-
-  var setInternalState = internalState.set;
-  var internalStateGetterFor = internalState.getterFor;
-
-  var collectionStrong = {
-    getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
-      var C = wrapper(function (that, iterable) {
-        anInstance(that, C, CONSTRUCTOR_NAME);
-        setInternalState(that, {
-          type: CONSTRUCTOR_NAME,
-          index: objectCreate(null),
-          first: undefined,
-          last: undefined,
-          size: 0
-        });
-        if (!descriptors) that.size = 0;
-        if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
-      });
-
-      var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
-
-      var define = function (that, key, value) {
-        var state = getInternalState(that);
-        var entry = getEntry(that, key);
-        var previous, index;
-        // change existing entry
-        if (entry) {
-          entry.value = value;
-        // create new entry
-        } else {
-          state.last = entry = {
-            index: index = fastKey(key, true),
-            key: key,
-            value: value,
-            previous: previous = state.last,
-            next: undefined,
-            removed: false
-          };
-          if (!state.first) state.first = entry;
-          if (previous) previous.next = entry;
-          if (descriptors) state.size++;
-          else that.size++;
-          // add to index
-          if (index !== 'F') state.index[index] = entry;
-        } return that;
-      };
-
-      var getEntry = function (that, key) {
-        var state = getInternalState(that);
-        // fast case
-        var index = fastKey(key);
-        var entry;
-        if (index !== 'F') return state.index[index];
-        // frozen object case
-        for (entry = state.first; entry; entry = entry.next) {
-          if (entry.key == key) return entry;
-        }
-      };
-
-      redefineAll(C.prototype, {
-        // 23.1.3.1 Map.prototype.clear()
-        // 23.2.3.2 Set.prototype.clear()
-        clear: function clear() {
-          var that = this;
-          var state = getInternalState(that);
-          var data = state.index;
-          var entry = state.first;
-          while (entry) {
-            entry.removed = true;
-            if (entry.previous) entry.previous = entry.previous.next = undefined;
-            delete data[entry.index];
-            entry = entry.next;
-          }
-          state.first = state.last = undefined;
-          if (descriptors) state.size = 0;
-          else that.size = 0;
-        },
-        // 23.1.3.3 Map.prototype.delete(key)
-        // 23.2.3.4 Set.prototype.delete(value)
-        'delete': function (key) {
-          var that = this;
-          var state = getInternalState(that);
-          var entry = getEntry(that, key);
-          if (entry) {
-            var next = entry.next;
-            var prev = entry.previous;
-            delete state.index[entry.index];
-            entry.removed = true;
-            if (prev) prev.next = next;
-            if (next) next.previous = prev;
-            if (state.first == entry) state.first = next;
-            if (state.last == entry) state.last = prev;
-            if (descriptors) state.size--;
-            else that.size--;
-          } return !!entry;
-        },
-        // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
-        // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
-        forEach: function forEach(callbackfn /* , that = undefined */) {
-          var state = getInternalState(this);
-          var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
-          var entry;
-          while (entry = entry ? entry.next : state.first) {
-            boundFunction(entry.value, entry.key, this);
-            // revert to the last existing entry
-            while (entry && entry.removed) entry = entry.previous;
-          }
-        },
-        // 23.1.3.7 Map.prototype.has(key)
-        // 23.2.3.7 Set.prototype.has(value)
-        has: function has(key) {
-          return !!getEntry(this, key);
-        }
-      });
-
-      redefineAll(C.prototype, IS_MAP ? {
-        // 23.1.3.6 Map.prototype.get(key)
-        get: function get(key) {
-          var entry = getEntry(this, key);
-          return entry && entry.value;
-        },
-        // 23.1.3.9 Map.prototype.set(key, value)
-        set: function set(key, value) {
-          return define(this, key === 0 ? 0 : key, value);
-        }
-      } : {
-        // 23.2.3.1 Set.prototype.add(value)
-        add: function add(value) {
-          return define(this, value = value === 0 ? 0 : value, value);
-        }
-      });
-      if (descriptors) defineProperty(C.prototype, 'size', {
-        get: function () {
-          return getInternalState(this).size;
-        }
-      });
-      return C;
-    },
-    setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {
-      var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';
-      var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME);
-      var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME);
-      // add .keys, .values, .entries, [@@iterator]
-      // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
-      defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {
-        setInternalState(this, {
-          type: ITERATOR_NAME,
-          target: iterated,
-          state: getInternalCollectionState(iterated),
-          kind: kind,
-          last: undefined
-        });
-      }, function () {
-        var state = getInternalIteratorState(this);
-        var kind = state.kind;
-        var entry = state.last;
-        // revert to the last existing entry
-        while (entry && entry.removed) entry = entry.previous;
-        // get next entry
-        if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {
-          // or finish the iteration
-          state.target = undefined;
-          return { value: undefined, done: true };
-        }
-        // return step by kind
-        if (kind == 'keys') return { value: entry.key, done: false };
-        if (kind == 'values') return { value: entry.value, done: false };
-        return { value: [entry.key, entry.value], done: false };
-      }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
-
-      // add [@@species], 23.1.2.2, 23.2.2.2
-      setSpecies(CONSTRUCTOR_NAME);
-    }
-  };
-
-  // `Set` constructor
-  // https://tc39.es/ecma262/#sec-set-objects
-  collection('Set', function (init) {
-    return function Set() { return init(this, arguments.length ? arguments[0] : undefined); };
-  }, collectionStrong);
-
-  // @@match logic
-  fixRegexpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
-    return [
-      // `String.prototype.match` method
-      // https://tc39.es/ecma262/#sec-string.prototype.match
-      function match(regexp) {
-        var O = requireObjectCoercible(this);
-        var matcher = regexp == undefined ? undefined : regexp[MATCH];
-        return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
-      },
-      // `RegExp.prototype[@@match]` method
-      // https://tc39.es/ecma262/#sec-regexp.prototype-@@match
-      function (regexp) {
-        var res = maybeCallNative(nativeMatch, regexp, this);
-        if (res.done) return res.value;
-
-        var rx = anObject(regexp);
-        var S = String(this);
-
-        if (!rx.global) return regexpExecAbstract(rx, S);
-
-        var fullUnicode = rx.unicode;
-        rx.lastIndex = 0;
-        var A = [];
-        var n = 0;
-        var result;
-        while ((result = regexpExecAbstract(rx, S)) !== null) {
-          var matchStr = String(result[0]);
-          A[n] = matchStr;
-          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
-          n++;
-        }
-        return n === 0 ? null : A;
-      }
-    ];
-  });
-
-  var floor = Math.floor;
-  var replace = ''.replace;
-  var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
-  var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g;
-
-  // https://tc39.es/ecma262/#sec-getsubstitution
-  var getSubstitution = function (matched, str, position, captures, namedCaptures, replacement) {
-    var tailPos = position + matched.length;
-    var m = captures.length;
-    var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
-    if (namedCaptures !== undefined) {
-      namedCaptures = toObject(namedCaptures);
-      symbols = SUBSTITUTION_SYMBOLS;
-    }
-    return replace.call(replacement, symbols, function (match, ch) {
-      var capture;
-      switch (ch.charAt(0)) {
-        case '$': return '$';
-        case '&': return matched;
-        case '`': return str.slice(0, position);
-        case "'": return str.slice(tailPos);
-        case '<':
-          capture = namedCaptures[ch.slice(1, -1)];
-          break;
-        default: // \d\d?
-          var n = +ch;
-          if (n === 0) return match;
-          if (n > m) {
-            var f = floor(n / 10);
-            if (f === 0) return match;
-            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
-            return match;
-          }
-          capture = captures[n - 1];
-      }
-      return capture === undefined ? '' : capture;
-    });
-  };
-
-  var max$1 = Math.max;
-  var min$2 = Math.min;
-
-  var maybeToString = function (it) {
-    return it === undefined ? it : String(it);
-  };
-
-  // @@replace logic
-  fixRegexpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
-    var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
-    var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
-    var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';
-
-    return [
-      // `String.prototype.replace` method
-      // https://tc39.es/ecma262/#sec-string.prototype.replace
-      function replace(searchValue, replaceValue) {
-        var O = requireObjectCoercible(this);
-        var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
-        return replacer !== undefined
-          ? replacer.call(searchValue, O, replaceValue)
-          : nativeReplace.call(String(O), searchValue, replaceValue);
-      },
-      // `RegExp.prototype[@@replace]` method
-      // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
-      function (regexp, replaceValue) {
-        if (
-          (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0) ||
-          (typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1)
-        ) {
-          var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
-          if (res.done) return res.value;
-        }
-
-        var rx = anObject(regexp);
-        var S = String(this);
-
-        var functionalReplace = typeof replaceValue === 'function';
-        if (!functionalReplace) replaceValue = String(replaceValue);
-
-        var global = rx.global;
-        if (global) {
-          var fullUnicode = rx.unicode;
-          rx.lastIndex = 0;
-        }
-        var results = [];
-        while (true) {
-          var result = regexpExecAbstract(rx, S);
-          if (result === null) break;
-
-          results.push(result);
-          if (!global) break;
-
-          var matchStr = String(result[0]);
-          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
-        }
-
-        var accumulatedResult = '';
-        var nextSourcePosition = 0;
-        for (var i = 0; i < results.length; i++) {
-          result = results[i];
-
-          var matched = String(result[0]);
-          var position = max$1(min$2(toInteger(result.index), S.length), 0);
-          var captures = [];
-          // NOTE: This is equivalent to
-          //   captures = result.slice(1).map(maybeToString)
-          // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
-          // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
-          // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
-          for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
-          var namedCaptures = result.groups;
-          if (functionalReplace) {
-            var replacerArgs = [matched].concat(captures, position, S);
-            if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
-            var replacement = String(replaceValue.apply(undefined, replacerArgs));
-          } else {
-            replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
-          }
-          if (position >= nextSourcePosition) {
-            accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
-            nextSourcePosition = position + matched.length;
-          }
-        }
-        return accumulatedResult + S.slice(nextSourcePosition);
-      }
-    ];
-  });
-
-  var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
-
-
-
-
-
-
-  var nativeStartsWith = ''.startsWith;
-  var min$1 = Math.min;
-
-  var CORRECT_IS_REGEXP_LOGIC = correctIsRegexpLogic('startsWith');
-  // https://github.com/zloirock/core-js/pull/702
-  var MDN_POLYFILL_BUG = !CORRECT_IS_REGEXP_LOGIC && !!function () {
-    var descriptor = getOwnPropertyDescriptor(String.prototype, 'startsWith');
-    return descriptor && !descriptor.writable;
-  }();
-
-  // `String.prototype.startsWith` method
-  // https://tc39.es/ecma262/#sec-string.prototype.startswith
-  _export({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG && !CORRECT_IS_REGEXP_LOGIC }, {
-    startsWith: function startsWith(searchString /* , position = 0 */) {
-      var that = String(requireObjectCoercible(this));
-      notARegexp(searchString);
-      var index = toLength(min$1(arguments.length > 1 ? arguments[1] : undefined, that.length));
-      var search = String(searchString);
-      return nativeStartsWith
-        ? nativeStartsWith.call(that, search, index)
-        : that.slice(index, index + search.length) === search;
-    }
-  });
-
-  var non = '\u200B\u0085\u180E';
-
-  // check that a method works with the correct list
-  // of whitespaces and has a correct name
-  var stringTrimForced = function (METHOD_NAME) {
-    return fails(function () {
-      return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;
-    });
-  };
-
-  var $trim = stringTrim.trim;
-
-
-  // `String.prototype.trim` method
-  // https://tc39.es/ecma262/#sec-string.prototype.trim
-  _export({ target: 'String', proto: true, forced: stringTrimForced('trim') }, {
-    trim: function trim() {
-      return $trim(this);
-    }
-  });
-
-  var ITERATOR = wellKnownSymbol('iterator');
-  var TO_STRING_TAG = wellKnownSymbol('toStringTag');
-  var ArrayValues = es_array_iterator.values;
-
-  for (var COLLECTION_NAME in domIterables) {
-    var Collection = global_1[COLLECTION_NAME];
-    var CollectionPrototype = Collection && Collection.prototype;
-    if (CollectionPrototype) {
-      // some Chrome versions have non-configurable methods on DOMTokenList
-      if (CollectionPrototype[ITERATOR] !== ArrayValues) try {
-        createNonEnumerableProperty(CollectionPrototype, ITERATOR, ArrayValues);
-      } catch (error) {
-        CollectionPrototype[ITERATOR] = ArrayValues;
-      }
-      if (!CollectionPrototype[TO_STRING_TAG]) {
-        createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);
-      }
-      if (domIterables[COLLECTION_NAME]) for (var METHOD_NAME in es_array_iterator) {
-        // some Chrome versions have non-configurable methods on DOMTokenList
-        if (CollectionPrototype[METHOD_NAME] !== es_array_iterator[METHOD_NAME]) try {
-          createNonEnumerableProperty(CollectionPrototype, METHOD_NAME, es_array_iterator[METHOD_NAME]);
-        } catch (error) {
-          CollectionPrototype[METHOD_NAME] = es_array_iterator[METHOD_NAME];
-        }
-      }
-    }
-  }
-
-  var _this3 = undefined;
-
-  // Thanks @stimulus:
-  // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts
-  function domReady() {
-    var _this = this;
-
-    return new Promise(function (resolve) {
-      _newArrowCheck(this, _this);
-
-      if (document.readyState == "loading") {
-        document.addEventListener("DOMContentLoaded", resolve);
-      } else {
-        resolve();
-      }
-    }.bind(this));
-  }
-  function arrayUnique(array) {
-    return Array.from(new Set(array));
-  }
-  function isTesting() {
-    return navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom");
-  }
-  function checkedAttrLooseCompare(valueA, valueB) {
-    return valueA == valueB;
-  }
-  function warnIfMalformedTemplate(el, directive) {
-    if (el.tagName.toLowerCase() !== 'template') {
-      console.warn("Alpine: [".concat(directive, "] directive should only be added to <template> tags. See https://github.com/alpinejs/alpine#").concat(directive));
-    } else if (el.content.childElementCount !== 1) {
-      console.warn("Alpine: <template> tag with [".concat(directive, "] encountered with an unexpected number of root elements. Make sure <template> has a single root element. "));
-    }
-  }
-  function kebabCase(subject) {
-    return subject.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[_\s]/, '-').toLowerCase();
-  }
-  function camelCase(subject) {
-    var _this2 = this;
-
-    return subject.toLowerCase().replace(/-(\w)/g, function (match, _char) {
-      _newArrowCheck(this, _this2);
-
-      return _char.toUpperCase();
-    }.bind(this));
-  }
-  function walk(el, callback) {
-    if (callback(el) === false) return;
-    var node = el.firstElementChild;
-
-    while (node) {
-      walk(node, callback);
-      node = node.nextElementSibling;
-    }
-  }
-  function debounce(func, wait) {
-    var timeout;
-    return function () {
-      var context = this,
-          args = arguments;
-
-      var later = function later() {
-        timeout = null;
-        func.apply(context, args);
-      };
-
-      clearTimeout(timeout);
-      timeout = setTimeout(later, wait);
-    };
-  }
-
-  var handleError = function handleError(el, expression, error) {
-    _newArrowCheck(this, _this3);
-
-    console.warn("Alpine Error: \"".concat(error, "\"\n\nExpression: \"").concat(expression, "\"\nElement:"), el);
-
-    if (!isTesting()) {
-      Object.assign(error, {
-        el: el,
-        expression: expression
-      });
-      throw error;
-    }
-  }.bind(undefined);
-
-  function tryCatch(cb, _ref) {
-    var _this4 = this;
-
-    var el = _ref.el,
-        expression = _ref.expression;
-
-    try {
-      var value = cb();
-      return value instanceof Promise ? value["catch"](function (e) {
-        _newArrowCheck(this, _this4);
-
-        return handleError(el, expression, e);
-      }.bind(this)) : value;
-    } catch (e) {
-      handleError(el, expression, e);
-    }
-  }
-
-  function saferEval(el, expression, dataContext) {
-    var _this5 = this;
-
-    var additionalHelperVariables = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-    return tryCatch(function () {
-      _newArrowCheck(this, _this5);
-
-      if (typeof expression === 'function') {
-        return expression.call(dataContext);
-      }
-
-      return new Function(['$data'].concat(_toConsumableArray(Object.keys(additionalHelperVariables))), "var __alpine_result; with($data) { __alpine_result = ".concat(expression, " }; return __alpine_result")).apply(void 0, [dataContext].concat(_toConsumableArray(Object.values(additionalHelperVariables))));
-    }.bind(this), {
-      el: el,
-      expression: expression
-    });
-  }
-  function saferEvalNoReturn(el, expression, dataContext) {
-    var _this6 = this;
-
-    var additionalHelperVariables = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-    return tryCatch(function () {
-      _newArrowCheck(this, _this6);
-
-      if (typeof expression === 'function') {
-        return Promise.resolve(expression.call(dataContext, additionalHelperVariables['$event']));
-      }
-
-      var AsyncFunction = Function; // For the cases when users pass only a function reference to the caller: `x-on:click="foo"`
-      // Where "foo" is a function. Also, we'll pass the function the event instance when we call it.
-
-      if (Object.keys(dataContext).includes(expression)) {
-        var methodReference = new Function(['dataContext'].concat(_toConsumableArray(Object.keys(additionalHelperVariables))), "with(dataContext) { return ".concat(expression, " }")).apply(void 0, [dataContext].concat(_toConsumableArray(Object.values(additionalHelperVariables))));
-
-        if (typeof methodReference === 'function') {
-          return Promise.resolve(methodReference.call(dataContext, additionalHelperVariables['$event']));
-        } else {
-          return Promise.resolve();
-        }
-      }
-
-      return Promise.resolve(new AsyncFunction(['dataContext'].concat(_toConsumableArray(Object.keys(additionalHelperVariables))), "with(dataContext) { ".concat(expression, " }")).apply(void 0, [dataContext].concat(_toConsumableArray(Object.values(additionalHelperVariables)))));
-    }.bind(this), {
-      el: el,
-      expression: expression
-    });
-  }
-  var xAttrRE = /^x-(on|bind|data|text|html|model|if|for|show|cloak|transition|ref|spread)\b/;
-  function isXAttr(attr) {
-    var name = replaceAtAndColonWithStandardSyntax(attr.name);
-    return xAttrRE.test(name);
-  }
-  function getXAttrs(el, component, type) {
-    var _this7 = this;
-
-    var directives = Array.from(el.attributes).filter(isXAttr).map(parseHtmlAttribute); // Get an object of directives from x-spread.
-
-    var spreadDirective = directives.filter(function (directive) {
-      _newArrowCheck(this, _this7);
-
-      return directive.type === 'spread';
-    }.bind(this))[0];
-
-    if (spreadDirective) {
-      var spreadObject = saferEval(el, spreadDirective.expression, component.$data); // Add x-spread directives to the pile of existing directives.
-
-      directives = directives.concat(Object.entries(spreadObject).map(function (_ref2) {
-        _newArrowCheck(this, _this7);
-
-        var _ref3 = _slicedToArray(_ref2, 2),
-            name = _ref3[0],
-            value = _ref3[1];
-
-        return parseHtmlAttribute({
-          name: name,
-          value: value
-        });
-      }.bind(this)));
-    }
-
-    if (type) return directives.filter(function (i) {
-      _newArrowCheck(this, _this7);
-
-      return i.type === type;
-    }.bind(this));
-    return sortDirectives(directives);
-  }
-
-  function sortDirectives(directives) {
-    var _this8 = this;
-
-    var directiveOrder = ['bind', 'model', 'show', 'catch-all'];
-    return directives.sort(function (a, b) {
-      _newArrowCheck(this, _this8);
-
-      var typeA = directiveOrder.indexOf(a.type) === -1 ? 'catch-all' : a.type;
-      var typeB = directiveOrder.indexOf(b.type) === -1 ? 'catch-all' : b.type;
-      return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB);
-    }.bind(this));
-  }
-
-  function parseHtmlAttribute(_ref4) {
-    var _this9 = this;
-
-    var name = _ref4.name,
-        value = _ref4.value;
-    var normalizedName = replaceAtAndColonWithStandardSyntax(name);
-    var typeMatch = normalizedName.match(xAttrRE);
-    var valueMatch = normalizedName.match(/:([a-zA-Z0-9\-:]+)/);
-    var modifiers = normalizedName.match(/\.[^.\]]+(?=[^\]]*$)/g) || [];
-    return {
-      type: typeMatch ? typeMatch[1] : null,
-      value: valueMatch ? valueMatch[1] : null,
-      modifiers: modifiers.map(function (i) {
-        _newArrowCheck(this, _this9);
-
-        return i.replace('.', '');
-      }.bind(this)),
-      expression: value
-    };
-  }
-  function isBooleanAttr(attrName) {
-    // As per HTML spec table https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute
-    // Array roughly ordered by estimated usage
-    var booleanAttributes = ['disabled', 'checked', 'required', 'readonly', 'hidden', 'open', 'selected', 'autofocus', 'itemscope', 'multiple', 'novalidate', 'allowfullscreen', 'allowpaymentrequest', 'formnovalidate', 'autoplay', 'controls', 'loop', 'muted', 'playsinline', 'default', 'ismap', 'reversed', 'async', 'defer', 'nomodule'];
-    return booleanAttributes.includes(attrName);
-  }
-  function replaceAtAndColonWithStandardSyntax(name) {
-    if (name.startsWith('@')) {
-      return name.replace('@', 'x-on:');
-    } else if (name.startsWith(':')) {
-      return name.replace(':', 'x-bind:');
-    }
-
-    return name;
-  }
-  function convertClassStringToArray(classList) {
-    var filterFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Boolean;
-    return classList.split(' ').filter(filterFn);
-  }
-  var TRANSITION_TYPE_IN = 'in';
-  var TRANSITION_TYPE_OUT = 'out';
-  var TRANSITION_CANCELLED = 'cancelled';
-  function transitionIn(el, show, reject, component) {
-    var _this10 = this;
-
-    var forceSkip = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
-    // We don't want to transition on the initial page load.
-    if (forceSkip) return show();
-
-    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_IN) {
-      // there is already a similar transition going on, this was probably triggered by
-      // a change in a different property, let's just leave the previous one doing its job
-      return;
-    }
-
-    var attrs = getXAttrs(el, component, 'transition');
-    var showAttr = getXAttrs(el, component, 'show')[0]; // If this is triggered by a x-show.transition.
-
-    if (showAttr && showAttr.modifiers.includes('transition')) {
-      var modifiers = showAttr.modifiers; // If x-show.transition.out, we'll skip the "in" transition.
-
-      if (modifiers.includes('out') && !modifiers.includes('in')) return show();
-      var settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out'); // If x-show.transition.in...out... only use "in" related modifiers for this transition.
-
-      modifiers = settingBothSidesOfTransition ? modifiers.filter(function (i, index) {
-        _newArrowCheck(this, _this10);
-
-        return index < modifiers.indexOf('out');
-      }.bind(this)) : modifiers;
-      transitionHelperIn(el, modifiers, show, reject); // Otherwise, we can assume x-transition:enter.
-    } else if (attrs.some(function (attr) {
-      _newArrowCheck(this, _this10);
-
-      return ['enter', 'enter-start', 'enter-end'].includes(attr.value);
-    }.bind(this))) {
-      transitionClassesIn(el, component, attrs, show, reject);
-    } else {
-      // If neither, just show that damn thing.
-      show();
-    }
-  }
-  function transitionOut(el, hide, reject, component) {
-    var _this11 = this;
-
-    var forceSkip = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
-    // We don't want to transition on the initial page load.
-    if (forceSkip) return hide();
-
-    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_OUT) {
-      // there is already a similar transition going on, this was probably triggered by
-      // a change in a different property, let's just leave the previous one doing its job
-      return;
-    }
-
-    var attrs = getXAttrs(el, component, 'transition');
-    var showAttr = getXAttrs(el, component, 'show')[0];
-
-    if (showAttr && showAttr.modifiers.includes('transition')) {
-      var modifiers = showAttr.modifiers;
-      if (modifiers.includes('in') && !modifiers.includes('out')) return hide();
-      var settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out');
-      modifiers = settingBothSidesOfTransition ? modifiers.filter(function (i, index) {
-        _newArrowCheck(this, _this11);
-
-        return index > modifiers.indexOf('out');
-      }.bind(this)) : modifiers;
-      transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hide, reject);
-    } else if (attrs.some(function (attr) {
-      _newArrowCheck(this, _this11);
-
-      return ['leave', 'leave-start', 'leave-end'].includes(attr.value);
-    }.bind(this))) {
-      transitionClassesOut(el, component, attrs, hide, reject);
-    } else {
-      hide();
-    }
-  }
-  function transitionHelperIn(el, modifiers, showCallback, reject) {
-    var _this12 = this;
-
-    // Default values inspired by: https://material.io/design/motion/speed.html#duration
-    var styleValues = {
-      duration: modifierValue(modifiers, 'duration', 150),
-      origin: modifierValue(modifiers, 'origin', 'center'),
-      first: {
-        opacity: 0,
-        scale: modifierValue(modifiers, 'scale', 95)
-      },
-      second: {
-        opacity: 1,
-        scale: 100
-      }
-    };
-    transitionHelper(el, modifiers, showCallback, function () {
-      _newArrowCheck(this, _this12);
-    }.bind(this), reject, styleValues, TRANSITION_TYPE_IN);
-  }
-  function transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hideCallback, reject) {
-    var _this13 = this;
-
-    // Make the "out" transition .5x slower than the "in". (Visually better)
-    // HOWEVER, if they explicitly set a duration for the "out" transition,
-    // use that.
-    var duration = settingBothSidesOfTransition ? modifierValue(modifiers, 'duration', 150) : modifierValue(modifiers, 'duration', 150) / 2;
-    var styleValues = {
-      duration: duration,
-      origin: modifierValue(modifiers, 'origin', 'center'),
-      first: {
-        opacity: 1,
-        scale: 100
-      },
-      second: {
-        opacity: 0,
-        scale: modifierValue(modifiers, 'scale', 95)
-      }
-    };
-    transitionHelper(el, modifiers, function () {
-      _newArrowCheck(this, _this13);
-    }.bind(this), hideCallback, reject, styleValues, TRANSITION_TYPE_OUT);
-  }
-
-  function modifierValue(modifiers, key, fallback) {
-    // If the modifier isn't present, use the default.
-    if (modifiers.indexOf(key) === -1) return fallback; // If it IS present, grab the value after it: x-show.transition.duration.500ms
-
-    var rawValue = modifiers[modifiers.indexOf(key) + 1];
-    if (!rawValue) return fallback;
-
-    if (key === 'scale') {
-      // Check if the very next value is NOT a number and return the fallback.
-      // If x-show.transition.scale, we'll use the default scale value.
-      // That is how a user opts out of the opacity transition.
-      if (!isNumeric(rawValue)) return fallback;
-    }
-
-    if (key === 'duration') {
-      // Support x-show.transition.duration.500ms && duration.500
-      var match = rawValue.match(/([0-9]+)ms/);
-      if (match) return match[1];
-    }
-
-    if (key === 'origin') {
-      // Support chaining origin directions: x-show.transition.top.right
-      if (['top', 'right', 'left', 'center', 'bottom'].includes(modifiers[modifiers.indexOf(key) + 2])) {
-        return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(' ');
-      }
-    }
-
-    return rawValue;
-  }
-
-  function transitionHelper(el, modifiers, hook1, hook2, reject, styleValues, type) {
-    // clear the previous transition if exists to avoid caching the wrong styles
-    if (el.__x_transition) {
-      el.__x_transition.cancel && el.__x_transition.cancel();
-    } // If the user set these style values, we'll put them back when we're done with them.
-
-
-    var opacityCache = el.style.opacity;
-    var transformCache = el.style.transform;
-    var transformOriginCache = el.style.transformOrigin; // If no modifiers are present: x-show.transition, we'll default to both opacity and scale.
-
-    var noModifiers = !modifiers.includes('opacity') && !modifiers.includes('scale');
-    var transitionOpacity = noModifiers || modifiers.includes('opacity');
-    var transitionScale = noModifiers || modifiers.includes('scale'); // These are the explicit stages of a transition (same stages for in and for out).
-    // This way you can get a birds eye view of the hooks, and the differences
-    // between them.
-
-    var stages = {
-      start: function start() {
-        if (transitionOpacity) el.style.opacity = styleValues.first.opacity;
-        if (transitionScale) el.style.transform = "scale(".concat(styleValues.first.scale / 100, ")");
-      },
-      during: function during() {
-        if (transitionScale) el.style.transformOrigin = styleValues.origin;
-        el.style.transitionProperty = [transitionOpacity ? "opacity" : "", transitionScale ? "transform" : ""].join(' ').trim();
-        el.style.transitionDuration = "".concat(styleValues.duration / 1000, "s");
-        el.style.transitionTimingFunction = "cubic-bezier(0.4, 0.0, 0.2, 1)";
-      },
-      show: function show() {
-        hook1();
-      },
-      end: function end() {
-        if (transitionOpacity) el.style.opacity = styleValues.second.opacity;
-        if (transitionScale) el.style.transform = "scale(".concat(styleValues.second.scale / 100, ")");
-      },
-      hide: function hide() {
-        hook2();
-      },
-      cleanup: function cleanup() {
-        if (transitionOpacity) el.style.opacity = opacityCache;
-        if (transitionScale) el.style.transform = transformCache;
-        if (transitionScale) el.style.transformOrigin = transformOriginCache;
-        el.style.transitionProperty = null;
-        el.style.transitionDuration = null;
-        el.style.transitionTimingFunction = null;
-      }
-    };
-    transition(el, stages, type, reject);
-  }
-
-  var ensureStringExpression = function ensureStringExpression(expression, el, component) {
-    _newArrowCheck(this, _this3);
-
-    return typeof expression === 'function' ? component.evaluateReturnExpression(el, expression) : expression;
-  }.bind(undefined);
-
-  function transitionClassesIn(el, component, directives, showCallback, reject) {
-    var _this14 = this;
-
-    var enter = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this14);
-
-      return i.value === 'enter';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    var enterStart = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this14);
-
-      return i.value === 'enter-start';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    var enterEnd = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this14);
-
-      return i.value === 'enter-end';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    transitionClasses(el, enter, enterStart, enterEnd, showCallback, function () {
-      _newArrowCheck(this, _this14);
-    }.bind(this), TRANSITION_TYPE_IN, reject);
-  }
-  function transitionClassesOut(el, component, directives, hideCallback, reject) {
-    var _this15 = this;
-
-    var leave = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this15);
-
-      return i.value === 'leave';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    var leaveStart = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this15);
-
-      return i.value === 'leave-start';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    var leaveEnd = convertClassStringToArray(ensureStringExpression((directives.find(function (i) {
-      _newArrowCheck(this, _this15);
-
-      return i.value === 'leave-end';
-    }.bind(this)) || {
-      expression: ''
-    }).expression, el, component));
-    transitionClasses(el, leave, leaveStart, leaveEnd, function () {
-      _newArrowCheck(this, _this15);
-    }.bind(this), hideCallback, TRANSITION_TYPE_OUT, reject);
-  }
-  function transitionClasses(el, classesDuring, classesStart, classesEnd, hook1, hook2, type, reject) {
-    // clear the previous transition if exists to avoid caching the wrong classes
-    if (el.__x_transition) {
-      el.__x_transition.cancel && el.__x_transition.cancel();
-    }
-
-    var originalClasses = el.__x_original_classes || [];
-    var stages = {
-      start: function start() {
-        var _el$classList;
-
-        (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classesStart));
-      },
-      during: function during() {
-        var _el$classList2;
-
-        (_el$classList2 = el.classList).add.apply(_el$classList2, _toConsumableArray(classesDuring));
-      },
-      show: function show() {
-        hook1();
-      },
-      end: function end() {
-        var _el$classList3,
-            _this16 = this,
-            _el$classList4;
-
-        // Don't remove classes that were in the original class attribute.
-        (_el$classList3 = el.classList).remove.apply(_el$classList3, _toConsumableArray(classesStart.filter(function (i) {
-          _newArrowCheck(this, _this16);
-
-          return !originalClasses.includes(i);
-        }.bind(this))));
-
-        (_el$classList4 = el.classList).add.apply(_el$classList4, _toConsumableArray(classesEnd));
-      },
-      hide: function hide() {
-        hook2();
-      },
-      cleanup: function cleanup() {
-        var _el$classList5,
-            _this17 = this,
-            _el$classList6;
-
-        (_el$classList5 = el.classList).remove.apply(_el$classList5, _toConsumableArray(classesDuring.filter(function (i) {
-          _newArrowCheck(this, _this17);
-
-          return !originalClasses.includes(i);
-        }.bind(this))));
-
-        (_el$classList6 = el.classList).remove.apply(_el$classList6, _toConsumableArray(classesEnd.filter(function (i) {
-          _newArrowCheck(this, _this17);
-
-          return !originalClasses.includes(i);
-        }.bind(this))));
-      }
-    };
-    transition(el, stages, type, reject);
-  }
-  function transition(el, stages, type, reject) {
-    var _this18 = this;
-
-    var finish = once(function () {
-      _newArrowCheck(this, _this18);
-
-      stages.hide(); // Adding an "isConnected" check, in case the callback
-      // removed the element from the DOM.
-
-      if (el.isConnected) {
-        stages.cleanup();
-      }
-
-      delete el.__x_transition;
-    }.bind(this));
-    el.__x_transition = {
-      // Set transition type so we can avoid clearing transition if the direction is the same
-      type: type,
-      // create a callback for the last stages of the transition so we can call it
-      // from different point and early terminate it. Once will ensure that function
-      // is only called one time.
-      cancel: once(function () {
-        _newArrowCheck(this, _this18);
-
-        reject(TRANSITION_CANCELLED);
-        finish();
-      }.bind(this)),
-      finish: finish,
-      // This store the next animation frame so we can cancel it
-      nextFrame: null
-    };
-    stages.start();
-    stages.during();
-    el.__x_transition.nextFrame = requestAnimationFrame(function () {
-      var _this19 = this;
-
-      _newArrowCheck(this, _this18);
-
-      // Note: Safari's transitionDuration property will list out comma separated transition durations
-      // for every single transition property. Let's grab the first one and call it a day.
-      var duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, '').replace('s', '')) * 1000;
-
-      if (duration === 0) {
-        duration = Number(getComputedStyle(el).animationDuration.replace('s', '')) * 1000;
-      }
-
-      stages.show();
-      el.__x_transition.nextFrame = requestAnimationFrame(function () {
-        _newArrowCheck(this, _this19);
-
-        stages.end();
-        setTimeout(el.__x_transition.finish, duration);
-      }.bind(this));
-    }.bind(this));
-  }
-  function isNumeric(subject) {
-    return !Array.isArray(subject) && !isNaN(subject);
-  } // Thanks @vuejs
-  // https://github.com/vuejs/vue/blob/4de4649d9637262a9b007720b59f80ac72a5620c/src/shared/util.js
-
-  function once(callback) {
-    var called = false;
-    return function () {
-      if (!called) {
-        called = true;
-        callback.apply(this, arguments);
-      }
-    };
-  }
-
-  function handleForDirective(component, templateEl, expression, initialUpdate, extraVars) {
-    var _this = this;
-
-    warnIfMalformedTemplate(templateEl, 'x-for');
-    var iteratorNames = typeof expression === 'function' ? parseForExpression(component.evaluateReturnExpression(templateEl, expression)) : parseForExpression(expression);
-    var items = evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, templateEl, iteratorNames, extraVars); // As we walk the array, we'll also walk the DOM (updating/creating as we go).
-
-    var currentEl = templateEl;
-    items.forEach(function (item, index) {
-      var _this2 = this;
-
-      _newArrowCheck(this, _this);
-
-      var iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
-      var currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
-      var nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
-
-      if (!nextEl) {
-        nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl); // And transition it in if it's not the first page load.
-
-        transitionIn(nextEl, function () {
-          _newArrowCheck(this, _this2);
-        }.bind(this), function () {
-          _newArrowCheck(this, _this2);
-        }.bind(this), component, initialUpdate);
-        nextEl.__x_for = iterationScopeVariables;
-        component.initializeElements(nextEl, function () {
-          _newArrowCheck(this, _this2);
-
-          return nextEl.__x_for;
-        }.bind(this)); // Otherwise update the element we found.
-      } else {
-        // Temporarily remove the key indicator to allow the normal "updateElements" to work.
-        delete nextEl.__x_for_key;
-        nextEl.__x_for = iterationScopeVariables;
-        component.updateElements(nextEl, function () {
-          _newArrowCheck(this, _this2);
-
-          return nextEl.__x_for;
-        }.bind(this));
-      }
-
-      currentEl = nextEl;
-      currentEl.__x_for_key = currentKey;
-    }.bind(this));
-    removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component);
-  } // This was taken from VueJS 2.* core. Thanks Vue!
-
-  function parseForExpression(expression) {
-    var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
-    var stripParensRE = /^\(|\)$/g;
-    var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
-    var inMatch = String(expression).match(forAliasRE);
-    if (!inMatch) return;
-    var res = {};
-    res.items = inMatch[2].trim();
-    var item = inMatch[1].trim().replace(stripParensRE, '');
-    var iteratorMatch = item.match(forIteratorRE);
-
-    if (iteratorMatch) {
-      res.item = item.replace(forIteratorRE, '').trim();
-      res.index = iteratorMatch[1].trim();
-
-      if (iteratorMatch[2]) {
-        res.collection = iteratorMatch[2].trim();
-      }
-    } else {
-      res.item = item;
-    }
-
-    return res;
-  }
-
-  function getIterationScopeVariables(iteratorNames, item, index, items, extraVars) {
-    // We must create a new object, so each iteration has a new scope
-    var scopeVariables = extraVars ? _objectSpread2({}, extraVars) : {};
-    scopeVariables[iteratorNames.item] = item;
-    if (iteratorNames.index) scopeVariables[iteratorNames.index] = index;
-    if (iteratorNames.collection) scopeVariables[iteratorNames.collection] = items;
-    return scopeVariables;
-  }
-
-  function generateKeyForIteration(component, el, index, iterationScopeVariables) {
-    var _this3 = this;
-
-    var bindKeyAttribute = getXAttrs(el, component, 'bind').filter(function (attr) {
-      _newArrowCheck(this, _this3);
-
-      return attr.value === 'key';
-    }.bind(this))[0]; // If the dev hasn't specified a key, just return the index of the iteration.
-
-    if (!bindKeyAttribute) return index;
-    return component.evaluateReturnExpression(el, bindKeyAttribute.expression, function () {
-      _newArrowCheck(this, _this3);
-
-      return iterationScopeVariables;
-    }.bind(this));
-  }
-
-  function evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, el, iteratorNames, extraVars) {
-    var _this4 = this;
-
-    var ifAttribute = getXAttrs(el, component, 'if')[0];
-
-    if (ifAttribute && !component.evaluateReturnExpression(el, ifAttribute.expression)) {
-      return [];
-    }
-
-    var items = component.evaluateReturnExpression(el, iteratorNames.items, extraVars); // This adds support for the `i in n` syntax.
-
-    if (isNumeric(items) && items >= 0) {
-      items = Array.from(Array(items).keys(), function (i) {
-        _newArrowCheck(this, _this4);
-
-        return i + 1;
-      }.bind(this));
-    }
-
-    return items;
-  }
-
-  function addElementInLoopAfterCurrentEl(templateEl, currentEl) {
-    var clone = document.importNode(templateEl.content, true);
-    currentEl.parentElement.insertBefore(clone, currentEl.nextElementSibling);
-    return currentEl.nextElementSibling;
-  }
-
-  function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
-    if (!nextEl) return; // If we are already past the x-for generated elements, we don't need to look ahead.
-
-    if (nextEl.__x_for_key === undefined) return; // If the the key's DO match, no need to look ahead.
-
-    if (nextEl.__x_for_key === currentKey) return nextEl; // If they don't, we'll look ahead for a match.
-    // If we find it, we'll move it to the current position in the loop.
-
-    var tmpNextEl = nextEl;
-
-    while (tmpNextEl) {
-      if (tmpNextEl.__x_for_key === currentKey) {
-        return tmpNextEl.parentElement.insertBefore(tmpNextEl, nextEl);
-      }
-
-      tmpNextEl = tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined ? tmpNextEl.nextElementSibling : false;
-    }
-  }
-
-  function removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component) {
-    var nextElementFromOldLoop = currentEl.nextElementSibling && currentEl.nextElementSibling.__x_for_key !== undefined ? currentEl.nextElementSibling : false;
-
-    var _loop = function _loop() {
-      var _this5 = this;
-
-      var nextElementFromOldLoopImmutable = nextElementFromOldLoop;
-      var nextSibling = nextElementFromOldLoop.nextElementSibling;
-      transitionOut(nextElementFromOldLoop, function () {
-        _newArrowCheck(this, _this5);
-
-        nextElementFromOldLoopImmutable.remove();
-      }.bind(this), function () {
-        _newArrowCheck(this, _this5);
-      }.bind(this), component);
-      nextElementFromOldLoop = nextSibling && nextSibling.__x_for_key !== undefined ? nextSibling : false;
-    };
-
-    while (nextElementFromOldLoop) {
-      _loop();
-    }
-  }
-
-  function handleAttributeBindingDirective(component, el, attrName, expression, extraVars, attrType, modifiers) {
-    var _this = this;
-
-    var value = component.evaluateReturnExpression(el, expression, extraVars);
-
-    if (attrName === 'value') {
-      if (Alpine.ignoreFocusedForValueBinding && document.activeElement.isSameNode(el)) return; // If nested model key is undefined, set the default value to empty string.
-
-      if (value === undefined && String(expression).match(/\./)) {
-        value = '';
-      }
-
-      if (el.type === 'radio') {
-        // Set radio value from x-bind:value, if no "value" attribute exists.
-        // If there are any initial state values, radio will have a correct
-        // "checked" value since x-bind:value is processed before x-model.
-        if (el.attributes.value === undefined && attrType === 'bind') {
-          el.value = value;
-        } else if (attrType !== 'bind') {
-          el.checked = checkedAttrLooseCompare(el.value, value);
-        }
-      } else if (el.type === 'checkbox') {
-        // If we are explicitly binding a string to the :value, set the string,
-        // If the value is a boolean, leave it alone, it will be set to "on"
-        // automatically.
-        if (typeof value !== 'boolean' && ![null, undefined].includes(value) && attrType === 'bind') {
-          el.value = String(value);
-        } else if (attrType !== 'bind') {
-          if (Array.isArray(value)) {
-            // I'm purposely not using Array.includes here because it's
-            // strict, and because of Numeric/String mis-casting, I
-            // want the "includes" to be "fuzzy".
-            el.checked = value.some(function (val) {
-              _newArrowCheck(this, _this);
-
-              return checkedAttrLooseCompare(val, el.value);
-            }.bind(this));
-          } else {
-            el.checked = !!value;
-          }
-        }
-      } else if (el.tagName === 'SELECT') {
-        updateSelect(el, value);
-      } else {
-        if (el.value === value) return;
-        el.value = value;
-      }
-    } else if (attrName === 'class') {
-      if (Array.isArray(value)) {
-        var originalClasses = el.__x_original_classes || [];
-        el.setAttribute('class', arrayUnique(originalClasses.concat(value)).join(' '));
-      } else if (_typeof(value) === 'object') {
-        // Sorting the keys / class names by their boolean value will ensure that
-        // anything that evaluates to `false` and needs to remove classes is run first.
-        var keysSortedByBooleanValue = Object.keys(value).sort(function (a, b) {
-          _newArrowCheck(this, _this);
-
-          return value[a] - value[b];
-        }.bind(this));
-        keysSortedByBooleanValue.forEach(function (classNames) {
-          var _this2 = this;
-
-          _newArrowCheck(this, _this);
-
-          if (value[classNames]) {
-            convertClassStringToArray(classNames).forEach(function (className) {
-              _newArrowCheck(this, _this2);
-
-              return el.classList.add(className);
-            }.bind(this));
-          } else {
-            convertClassStringToArray(classNames).forEach(function (className) {
-              _newArrowCheck(this, _this2);
-
-              return el.classList.remove(className);
-            }.bind(this));
-          }
-        }.bind(this));
-      } else {
-        var _originalClasses = el.__x_original_classes || [];
-
-        var newClasses = value ? convertClassStringToArray(value) : [];
-        el.setAttribute('class', arrayUnique(_originalClasses.concat(newClasses)).join(' '));
-      }
-    } else {
-      attrName = modifiers.includes('camel') ? camelCase(attrName) : attrName; // If an attribute's bound value is null, undefined or false, remove the attribute
-
-      if ([null, undefined, false].includes(value)) {
-        el.removeAttribute(attrName);
-      } else {
-        isBooleanAttr(attrName) ? setIfChanged(el, attrName, attrName) : setIfChanged(el, attrName, value);
-      }
-    }
-  }
-
-  function setIfChanged(el, attrName, value) {
-    if (el.getAttribute(attrName) != value) {
-      el.setAttribute(attrName, value);
-    }
-  }
-
-  function updateSelect(el, value) {
-    var _this3 = this;
-
-    var arrayWrappedValue = [].concat(value).map(function (value) {
-      _newArrowCheck(this, _this3);
-
-      return value + '';
-    }.bind(this));
-    Array.from(el.options).forEach(function (option) {
-      _newArrowCheck(this, _this3);
-
-      option.selected = arrayWrappedValue.includes(option.value);
-    }.bind(this));
-  }
-
-  function handleTextDirective(el, output, expression) {
-    // If nested model key is undefined, set the default value to empty string.
-    if (output === undefined && String(expression).match(/\./)) {
-      output = '';
-    }
-
-    el.textContent = output;
-  }
-
-  function handleHtmlDirective(component, el, expression, extraVars) {
-    el.innerHTML = component.evaluateReturnExpression(el, expression, extraVars);
-  }
-
-  function handleShowDirective(component, el, value, modifiers) {
-    var _this = this;
-
-    var initialUpdate = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
-
-    var hide = function hide() {
-      _newArrowCheck(this, _this);
-
-      el.style.display = 'none';
-      el.__x_is_shown = false;
-    }.bind(this);
-
-    var show = function show() {
-      _newArrowCheck(this, _this);
-
-      if (el.style.length === 1 && el.style.display === 'none') {
-        el.removeAttribute('style');
-      } else {
-        el.style.removeProperty('display');
-      }
-
-      el.__x_is_shown = true;
-    }.bind(this);
-
-    if (initialUpdate === true) {
-      if (value) {
-        show();
-      } else {
-        hide();
-      }
-
-      return;
-    }
-
-    var handle = function handle(resolve, reject) {
-      var _this2 = this;
-
-      _newArrowCheck(this, _this);
-
-      if (value) {
-        if (el.style.display === 'none' || el.__x_transition) {
-          transitionIn(el, function () {
-            _newArrowCheck(this, _this2);
-
-            show();
-          }.bind(this), reject, component);
-        }
-
-        resolve(function () {
-          _newArrowCheck(this, _this2);
-        }.bind(this));
-      } else {
-        if (el.style.display !== 'none') {
-          transitionOut(el, function () {
-            var _this3 = this;
-
-            _newArrowCheck(this, _this2);
-
-            resolve(function () {
-              _newArrowCheck(this, _this3);
-
-              hide();
-            }.bind(this));
-          }.bind(this), reject, component);
-        } else {
-          resolve(function () {
-            _newArrowCheck(this, _this2);
-          }.bind(this));
-        }
-      }
-    }.bind(this); // The working of x-show is a bit complex because we need to
-    // wait for any child transitions to finish before hiding
-    // some element. Also, this has to be done recursively.
-    // If x-show.immediate, foregoe the waiting.
-
-
-    if (modifiers.includes('immediate')) {
-      handle(function (finish) {
-        _newArrowCheck(this, _this);
-
-        return finish();
-      }.bind(this), function () {
-        _newArrowCheck(this, _this);
-      }.bind(this));
-      return;
-    } // x-show is encountered during a DOM tree walk. If an element
-    // we encounter is NOT a child of another x-show element we
-    // can execute the previous x-show stack (if one exists).
-
-
-    if (component.showDirectiveLastElement && !component.showDirectiveLastElement.contains(el)) {
-      component.executeAndClearRemainingShowDirectiveStack();
-    }
-
-    component.showDirectiveStack.push(handle);
-    component.showDirectiveLastElement = el;
-  }
-
-  function handleIfDirective(component, el, expressionResult, initialUpdate, extraVars) {
-    var _this = this;
-
-    warnIfMalformedTemplate(el, 'x-if');
-    var elementHasAlreadyBeenAdded = el.nextElementSibling && el.nextElementSibling.__x_inserted_me === true;
-
-    if (expressionResult && (!elementHasAlreadyBeenAdded || el.__x_transition)) {
-      var clone = document.importNode(el.content, true);
-      el.parentElement.insertBefore(clone, el.nextElementSibling);
-      transitionIn(el.nextElementSibling, function () {
-        _newArrowCheck(this, _this);
-      }.bind(this), function () {
-        _newArrowCheck(this, _this);
-      }.bind(this), component, initialUpdate);
-      component.initializeElements(el.nextElementSibling, extraVars);
-      el.nextElementSibling.__x_inserted_me = true;
-    } else if (!expressionResult && elementHasAlreadyBeenAdded) {
-      transitionOut(el.nextElementSibling, function () {
-        _newArrowCheck(this, _this);
-
-        el.nextElementSibling.remove();
-      }.bind(this), function () {
-        _newArrowCheck(this, _this);
-      }.bind(this), component, initialUpdate);
-    }
-  }
-
-  var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('splice');
-  var USES_TO_LENGTH = arrayMethodUsesToLength('splice', { ACCESSORS: true, 0: 0, 1: 2 });
-
-  var max = Math.max;
-  var min = Math.min;
-  var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
-  var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
-
-  // `Array.prototype.splice` method
-  // https://tc39.es/ecma262/#sec-array.prototype.splice
-  // with adding support of @@species
-  _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {
-    splice: function splice(start, deleteCount /* , ...items */) {
-      var O = toObject(this);
-      var len = toLength(O.length);
-      var actualStart = toAbsoluteIndex(start, len);
-      var argumentsLength = arguments.length;
-      var insertCount, actualDeleteCount, A, k, from, to;
-      if (argumentsLength === 0) {
-        insertCount = actualDeleteCount = 0;
-      } else if (argumentsLength === 1) {
-        insertCount = 0;
-        actualDeleteCount = len - actualStart;
-      } else {
-        insertCount = argumentsLength - 2;
-        actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
-      }
-      if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
-        throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
-      }
-      A = arraySpeciesCreate(O, actualDeleteCount);
-      for (k = 0; k < actualDeleteCount; k++) {
-        from = actualStart + k;
-        if (from in O) createProperty(A, k, O[from]);
-      }
-      A.length = actualDeleteCount;
-      if (insertCount < actualDeleteCount) {
-        for (k = actualStart; k < len - actualDeleteCount; k++) {
-          from = k + actualDeleteCount;
-          to = k + insertCount;
-          if (from in O) O[to] = O[from];
-          else delete O[to];
-        }
-        for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
-      } else if (insertCount > actualDeleteCount) {
-        for (k = len - actualDeleteCount; k > actualStart; k--) {
-          from = k + actualDeleteCount - 1;
-          to = k + insertCount - 1;
-          if (from in O) O[to] = O[from];
-          else delete O[to];
-        }
-      }
-      for (k = 0; k < insertCount; k++) {
-        O[k + actualStart] = arguments[k + 2];
-      }
-      O.length = len - actualDeleteCount + insertCount;
-      return A;
-    }
-  });
-
-  function registerListener(component, el, event, modifiers, expression) {
-    var _this = this;
-
-    var extraVars = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
-    var options = {
-      passive: modifiers.includes('passive')
-    };
-
-    if (modifiers.includes('camel')) {
-      event = camelCase(event);
-    }
-
-    var node_add_count = el.__x_node_add_count;
-
-    var _handler2, listenerTarget;
-
-    if (modifiers.includes('away')) {
-      listenerTarget = document;
-
-      _handler2 = function handler(e) {
-        _newArrowCheck(this, _this);
-
-        // Don't do anything if the click came from the element or within it.
-        if (el.contains(e.target)) return; // Don't do anything if this element isn't currently visible.
-
-        if (el.offsetWidth < 1 && el.offsetHeight < 1) return; // Now that we are sure the element is visible, AND the click
-        // is from outside it, let's run the expression.
-
-        runListenerHandler(component, expression, e, extraVars);
-
-        if (modifiers.includes('once')) {
-          document.removeEventListener(event, _handler2, options);
-        }
-      }.bind(this);
-    } else {
-      listenerTarget = modifiers.includes('window') ? window : modifiers.includes('document') ? document : el;
-
-      _handler2 = function _handler(e) {
-        var _this2 = this;
-
-        _newArrowCheck(this, _this);
-
-        // Remove this global event handler if the element that declared it
-        // has been removed. It's now stale.
-        if (listenerTarget === window || listenerTarget === document) {
-          if (!document.body.contains(el)) {
-            listenerTarget.removeEventListener(event, _handler2, options);
-            return;
-          }
-        }
-
-        if (el.__x_node_add_count !== node_add_count) {
-          listenerTarget.removeEventListener(event, _handler2, options);
-          return;
-        }
-
-        if (isKeyEvent(event)) {
-          if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {
-            return;
-          }
-        }
-
-        if (modifiers.includes('prevent')) e.preventDefault();
-        if (modifiers.includes('stop')) e.stopPropagation(); // If the .self modifier isn't present, or if it is present and
-        // the target element matches the element we are registering the
-        // event on, run the handler
-
-        if (!modifiers.includes('self') || e.target === el) {
-          var returnValue = runListenerHandler(component, expression, e, extraVars);
-          returnValue.then(function (value) {
-            _newArrowCheck(this, _this2);
-
-            if (value === false) {
-              e.preventDefault();
-            } else {
-              if (modifiers.includes('once')) {
-                listenerTarget.removeEventListener(event, _handler2, options);
-              }
-            }
-          }.bind(this));
-        }
-      }.bind(this);
-    }
-
-    if (modifiers.includes('debounce')) {
-      var nextModifier = modifiers[modifiers.indexOf('debounce') + 1] || 'invalid-wait';
-      var wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250;
-      _handler2 = debounce(_handler2, wait);
-    }
-
-    listenerTarget.addEventListener(event, _handler2, options);
-  }
-
-  function runListenerHandler(component, expression, e, extraVars) {
-    var _this3 = this;
-
-    return component.evaluateCommandExpression(e.target, expression, function () {
-      _newArrowCheck(this, _this3);
-
-      return _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        '$event': e
-      });
-    }.bind(this));
-  }
-
-  function isKeyEvent(event) {
-    return ['keydown', 'keyup'].includes(event);
-  }
-
-  function isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {
-    var _this4 = this;
-
-    var keyModifiers = modifiers.filter(function (i) {
-      _newArrowCheck(this, _this4);
-
-      return !['window', 'document', 'prevent', 'stop'].includes(i);
-    }.bind(this));
-
-    if (keyModifiers.includes('debounce')) {
-      var debounceIndex = keyModifiers.indexOf('debounce');
-      keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || 'invalid-wait').split('ms')[0]) ? 2 : 1);
-    } // If no modifier is specified, we'll call it a press.
-
-
-    if (keyModifiers.length === 0) return false; // If one is passed, AND it matches the key pressed, we'll call it a press.
-
-    if (keyModifiers.length === 1 && keyModifiers[0] === keyToModifier(e.key)) return false; // The user is listening for key combinations.
-
-    var systemKeyModifiers = ['ctrl', 'shift', 'alt', 'meta', 'cmd', 'super'];
-    var selectedSystemKeyModifiers = systemKeyModifiers.filter(function (modifier) {
-      _newArrowCheck(this, _this4);
-
-      return keyModifiers.includes(modifier);
-    }.bind(this));
-    keyModifiers = keyModifiers.filter(function (i) {
-      _newArrowCheck(this, _this4);
-
-      return !selectedSystemKeyModifiers.includes(i);
-    }.bind(this));
-
-    if (selectedSystemKeyModifiers.length > 0) {
-      var activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter(function (modifier) {
-        _newArrowCheck(this, _this4);
-
-        // Alias "cmd" and "super" to "meta"
-        if (modifier === 'cmd' || modifier === 'super') modifier = 'meta';
-        return e["".concat(modifier, "Key")];
-      }.bind(this)); // If all the modifiers selected are pressed, ...
-
-      if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
-        // AND the remaining key is pressed as well. It's a press.
-        if (keyModifiers[0] === keyToModifier(e.key)) return false;
-      }
-    } // We'll call it NOT a valid keypress.
-
-
-    return true;
-  }
-
-  function keyToModifier(key) {
-    switch (key) {
-      case '/':
-        return 'slash';
-
-      case ' ':
-      case 'Spacebar':
-        return 'space';
-
-      default:
-        return key && kebabCase(key);
-    }
-  }
-
-  function registerModelListener(component, el, modifiers, expression, extraVars) {
-    var _this = this;
-
-    // If the element we are binding to is a select, a radio, or checkbox
-    // we'll listen for the change event instead of the "input" event.
-    var event = el.tagName.toLowerCase() === 'select' || ['checkbox', 'radio'].includes(el.type) || modifiers.includes('lazy') ? 'change' : 'input';
-    var listenerExpression = "".concat(expression, " = rightSideOfExpression($event, ").concat(expression, ")");
-    registerListener(component, el, event, modifiers, listenerExpression, function () {
-      _newArrowCheck(this, _this);
-
-      return _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        rightSideOfExpression: generateModelAssignmentFunction(el, modifiers, expression)
-      });
-    }.bind(this));
-  }
-
-  function generateModelAssignmentFunction(el, modifiers, expression) {
-    var _this2 = this;
-
-    if (el.type === 'radio') {
-      // Radio buttons only work properly when they share a name attribute.
-      // People might assume we take care of that for them, because
-      // they already set a shared "x-model" attribute.
-      if (!el.hasAttribute('name')) el.setAttribute('name', expression);
-    }
-
-    return function (event, currentValue) {
-      var _this3 = this;
-
-      _newArrowCheck(this, _this2);
-
-      // Check for event.detail due to an issue where IE11 handles other events as a CustomEvent.
-      if (event instanceof CustomEvent && event.detail) {
-        return event.detail;
-      } else if (el.type === 'checkbox') {
-        // If the data we are binding to is an array, toggle its value inside the array.
-        if (Array.isArray(currentValue)) {
-          var newValue = modifiers.includes('number') ? safeParseNumber(event.target.value) : event.target.value;
-          return event.target.checked ? currentValue.concat([newValue]) : currentValue.filter(function (el) {
-            _newArrowCheck(this, _this3);
-
-            return !checkedAttrLooseCompare(el, newValue);
-          }.bind(this));
-        } else {
-          return event.target.checked;
-        }
-      } else if (el.tagName.toLowerCase() === 'select' && el.multiple) {
-        return modifiers.includes('number') ? Array.from(event.target.selectedOptions).map(function (option) {
-          _newArrowCheck(this, _this3);
-
-          var rawValue = option.value || option.text;
-          return safeParseNumber(rawValue);
-        }.bind(this)) : Array.from(event.target.selectedOptions).map(function (option) {
-          _newArrowCheck(this, _this3);
-
-          return option.value || option.text;
-        }.bind(this));
-      } else {
-        var rawValue = event.target.value;
-        return modifiers.includes('number') ? safeParseNumber(rawValue) : modifiers.includes('trim') ? rawValue.trim() : rawValue;
-      }
-    }.bind(this);
-  }
-
-  function safeParseNumber(rawValue) {
-    var number = rawValue ? parseFloat(rawValue) : null;
-    return isNumeric(number) ? number : rawValue;
-  }
-
-  // `Reflect.set` method
-  // https://tc39.es/ecma262/#sec-reflect.set
-  function set(target, propertyKey, V /* , receiver */) {
-    var receiver = arguments.length < 4 ? target : arguments[3];
-    var ownDescriptor = objectGetOwnPropertyDescriptor.f(anObject(target), propertyKey);
-    var existingDescriptor, prototype;
-    if (!ownDescriptor) {
-      if (isObject(prototype = objectGetPrototypeOf(target))) {
-        return set(prototype, propertyKey, V, receiver);
-      }
-      ownDescriptor = createPropertyDescriptor(0);
-    }
-    if (has$1(ownDescriptor, 'value')) {
-      if (ownDescriptor.writable === false || !isObject(receiver)) return false;
-      if (existingDescriptor = objectGetOwnPropertyDescriptor.f(receiver, propertyKey)) {
-        if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;
-        existingDescriptor.value = V;
-        objectDefineProperty.f(receiver, propertyKey, existingDescriptor);
-      } else objectDefineProperty.f(receiver, propertyKey, createPropertyDescriptor(0, V));
-      return true;
-    }
-    return ownDescriptor.set === undefined ? false : (ownDescriptor.set.call(receiver, V), true);
-  }
-
-  // MS Edge 17-18 Reflect.set allows setting the property to object
-  // with non-writable property on the prototype
-  var MS_EDGE_BUG = fails(function () {
-    var Constructor = function () { /* empty */ };
-    var object = objectDefineProperty.f(new Constructor(), 'a', { configurable: true });
-    // eslint-disable-next-line no-undef
-    return Reflect.set(Constructor.prototype, 'a', 1, object) !== false;
-  });
-
-  _export({ target: 'Reflect', stat: true, forced: MS_EDGE_BUG }, {
-    set: set
-  });
-
-  function wrap(data, mutationCallback) {
-    /* IE11-ONLY:START */
-    return wrapForIe11(data, mutationCallback);
-  }
-  function unwrap(membrane, observable) {
-    var _this = this;
-
-    var unwrappedData = membrane.unwrapProxy(observable);
-    var copy = {};
-    Object.keys(unwrappedData).forEach(function (key) {
-      _newArrowCheck(this, _this);
-
-      if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return;
-      copy[key] = unwrappedData[key];
-    }.bind(this));
-    return copy;
-  }
-
-  function wrapForIe11(data, mutationCallback) {
-    var proxyHandler = {
-      set: function set(target, key, value) {
-        // Set the value converting it to a "Deep Proxy" when required
-        // Note that if a project is not a valid object, it won't be converted to a proxy
-        var setWasSuccessful = Reflect.set(target, key, deepProxy(value, proxyHandler));
-        mutationCallback(target, key);
-        return setWasSuccessful;
-      },
-      get: function get(target, key) {
-        // Provide a way to determine if this object is an Alpine proxy or not.
-        if (key === "$isAlpineProxy") return true; // Just return the flippin' value. Gawsh.
-
-        return target[key];
-      }
-    };
-    return {
-      data: deepProxy(data, proxyHandler),
-      membrane: {
-        unwrapProxy: function unwrapProxy(proxy) {
-          return proxy;
-        }
-      }
-    };
-  }
-
-  function deepProxy(target, proxyHandler) {
-    // If target is null, return it.
-    if (target === null) return target; // If target is not an object, return it.
-
-    if (_typeof(target) !== 'object') return target; // If target is a DOM node (like in the case of this.$el), return it.
-
-    if (target instanceof Node) return target; // If target is already an Alpine proxy, return it.
-
-    if (target['$isAlpineProxy']) return target; // Otherwise proxy the properties recursively.
-    // This enables reactivity on setting nested data.
-    // Note that if a project is not a valid object, it won't be converted to a proxy
-
-    for (var property in target) {
-      target[property] = deepProxy(target[property], proxyHandler);
-    }
-
-    return new Proxy(target, proxyHandler);
-  }
-
-  var Component = /*#__PURE__*/function () {
-    function Component(el) {
-      var _this = this;
-
-      var componentForClone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-
-      _classCallCheck(this, Component);
-
-      this.$el = el;
-      var dataAttr = this.$el.getAttribute('x-data');
-      var dataExpression = dataAttr === '' ? '{}' : dataAttr;
-      var dataExtras = {
-        $el: this.$el
-      };
-      var canonicalComponentElementReference = componentForClone ? componentForClone.$el : this.$el;
-      Object.entries(Alpine.magicProperties).forEach(function (_ref) {
-        _newArrowCheck(this, _this);
-
-        var _ref2 = _slicedToArray(_ref, 2),
-            name = _ref2[0],
-            callback = _ref2[1];
-
-        Object.defineProperty(dataExtras, "$".concat(name), {
-          get: function get() {
-            return callback(canonicalComponentElementReference);
-          }
-        });
-      }.bind(this));
-      this.unobservedData = componentForClone ? componentForClone.getUnobservedData() : saferEval(el, dataExpression, dataExtras);
-      /* IE11-ONLY:START */
-      // For IE11, add our magic properties to the original data for access.
-      // The Proxy polyfill does not allow properties to be added after creation.
-
-      this.unobservedData.$el = null;
-      this.unobservedData.$refs = null;
-      this.unobservedData.$nextTick = null;
-      this.unobservedData.$watch = null; // The IE build uses a proxy polyfill which doesn't allow properties
-      // to be defined after the proxy object is created so,
-      // for IE only, we need to define our helpers earlier.
-
-      Object.entries(Alpine.magicProperties).forEach(function (_ref3) {
-        _newArrowCheck(this, _this);
-
-        var _ref4 = _slicedToArray(_ref3, 2),
-            name = _ref4[0],
-            callback = _ref4[1];
-
-        Object.defineProperty(this.unobservedData, "$".concat(name), {
-          get: function get() {
-            return callback(canonicalComponentElementReference, this.$el);
-          }
-        });
-      }.bind(this));
-      /* IE11-ONLY:END */
-      // Construct a Proxy-based observable. This will be used to handle reactivity.
-
-      var _this$wrapDataInObser = this.wrapDataInObservable(this.unobservedData),
-          membrane = _this$wrapDataInObser.membrane,
-          data = _this$wrapDataInObser.data;
-
-      this.$data = data;
-      this.membrane = membrane; // After making user-supplied data methods reactive, we can now add
-      // our magic properties to the original data for access.
-
-      this.unobservedData.$el = this.$el;
-      this.unobservedData.$refs = this.getRefsProxy();
-      this.nextTickStack = [];
-
-      this.unobservedData.$nextTick = function (callback) {
-        _newArrowCheck(this, _this);
-
-        this.nextTickStack.push(callback);
-      }.bind(this);
-
-      this.watchers = {};
-
-      this.unobservedData.$watch = function (property, callback) {
-        _newArrowCheck(this, _this);
-
-        if (!this.watchers[property]) this.watchers[property] = [];
-        this.watchers[property].push(callback);
-      }.bind(this);
-
-      this.showDirectiveStack = [];
-      this.showDirectiveLastElement;
-      componentForClone || Alpine.onBeforeComponentInitializeds.forEach(function (callback) {
-        _newArrowCheck(this, _this);
-
-        return callback(this);
-      }.bind(this));
-      var initExpression = this.$el.getAttribute('x-init');
-      var initReturnedCallback; // If x-init is present AND we aren't cloning (skip x-init on clone)
-
-      if (initExpression && !componentForClone) {
-        // We want to allow data manipulation, but not trigger DOM updates just yet.
-        // We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
-        this.pauseReactivity = true;
-        initReturnedCallback = this.evaluateReturnExpression(this.$el, initExpression);
-        this.pauseReactivity = false;
-      } // Register all our listeners and set all our attribute bindings.
-      // If we're cloning a component, the third parameter ensures no duplicate
-      // event listeners are registered (the mutation observer will take care of them)
-
-
-      this.initializeElements(this.$el, function () {
-        _newArrowCheck(this, _this);
-      }.bind(this), componentForClone); // Use mutation observer to detect new elements being added within this component at run-time.
-      // Alpine's just so darn flexible amirite?
-
-      this.listenForNewElementsToInitialize();
-
-      if (typeof initReturnedCallback === 'function') {
-        // Run the callback returned from the "x-init" hook to allow the user to do stuff after
-        // Alpine's got it's grubby little paws all over everything.
-        initReturnedCallback.call(this.$data);
-      }
-
-      componentForClone || setTimeout(function () {
-        var _this2 = this;
-
-        _newArrowCheck(this, _this);
-
-        Alpine.onComponentInitializeds.forEach(function (callback) {
-          _newArrowCheck(this, _this2);
-
-          return callback(this);
-        }.bind(this));
-      }.bind(this), 0);
-    }
-
-    _createClass(Component, [{
-      key: "getUnobservedData",
-      value: function getUnobservedData() {
-        return unwrap(this.membrane, this.$data);
-      }
-    }, {
-      key: "wrapDataInObservable",
-      value: function wrapDataInObservable(data) {
-        var _this3 = this;
-
-        var self = this;
-        var updateDom = debounce(function () {
-          self.updateElements(self.$el);
-        }, 0);
-        return wrap(data, function (target, key) {
-          var _this4 = this;
-
-          _newArrowCheck(this, _this3);
-
-          if (self.watchers[key]) {
-            // If there's a watcher for this specific key, run it.
-            self.watchers[key].forEach(function (callback) {
-              _newArrowCheck(this, _this4);
-
-              return callback(target[key]);
-            }.bind(this));
-          } else if (Array.isArray(target)) {
-            // Arrays are special cases, if any of the items change, we consider the array as mutated.
-            Object.keys(self.watchers).forEach(function (fullDotNotationKey) {
-              var _this5 = this;
-
-              _newArrowCheck(this, _this4);
-
-              var dotNotationParts = fullDotNotationKey.split('.'); // Ignore length mutations since they would result in duplicate calls.
-              // For example, when calling push, we would get a mutation for the item's key
-              // and a second mutation for the length property.
-
-              if (key === 'length') return;
-              dotNotationParts.reduce(function (comparisonData, part) {
-                var _this6 = this;
-
-                _newArrowCheck(this, _this5);
-
-                if (Object.is(target, comparisonData[part])) {
-                  self.watchers[fullDotNotationKey].forEach(function (callback) {
-                    _newArrowCheck(this, _this6);
-
-                    return callback(target);
-                  }.bind(this));
-                }
-
-                return comparisonData[part];
-              }.bind(this), self.unobservedData);
-            }.bind(this));
-          } else {
-            // Let's walk through the watchers with "dot-notation" (foo.bar) and see
-            // if this mutation fits any of them.
-            Object.keys(self.watchers).filter(function (i) {
-              _newArrowCheck(this, _this4);
-
-              return i.includes('.');
-            }.bind(this)).forEach(function (fullDotNotationKey) {
-              var _this7 = this;
-
-              _newArrowCheck(this, _this4);
-
-              var dotNotationParts = fullDotNotationKey.split('.'); // If this dot-notation watcher's last "part" doesn't match the current
-              // key, then skip it early for performance reasons.
-
-              if (key !== dotNotationParts[dotNotationParts.length - 1]) return; // Now, walk through the dot-notation "parts" recursively to find
-              // a match, and call the watcher if one's found.
-
-              dotNotationParts.reduce(function (comparisonData, part) {
-                var _this8 = this;
-
-                _newArrowCheck(this, _this7);
-
-                if (Object.is(target, comparisonData)) {
-                  // Run the watchers.
-                  self.watchers[fullDotNotationKey].forEach(function (callback) {
-                    _newArrowCheck(this, _this8);
-
-                    return callback(target[key]);
-                  }.bind(this));
-                }
-
-                return comparisonData[part];
-              }.bind(this), self.unobservedData);
-            }.bind(this));
-          } // Don't react to data changes for cases like the `x-created` hook.
-
-
-          if (self.pauseReactivity) return;
-          updateDom();
-        }.bind(this));
-      }
-    }, {
-      key: "walkAndSkipNestedComponents",
-      value: function walkAndSkipNestedComponents(el, callback) {
-        var _this9 = this;
-
-        var initializeComponentCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
-          _newArrowCheck(this, _this9);
-        }.bind(this);
-        walk(el, function (el) {
-          _newArrowCheck(this, _this9);
-
-          // We've hit a component.
-          if (el.hasAttribute('x-data')) {
-            // If it's not the current one.
-            if (!el.isSameNode(this.$el)) {
-              // Initialize it if it's not.
-              if (!el.__x) initializeComponentCallback(el); // Now we'll let that sub-component deal with itself.
-
-              return false;
-            }
-          }
-
-          return callback(el);
-        }.bind(this));
-      }
-    }, {
-      key: "initializeElements",
-      value: function initializeElements(rootEl) {
-        var _this10 = this;
-
-        var extraVars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
-          _newArrowCheck(this, _this10);
-        }.bind(this);
-        var componentForClone = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
-        this.walkAndSkipNestedComponents(rootEl, function (el) {
-          _newArrowCheck(this, _this10);
-
-          // Don't touch spawns from for loop
-          if (el.__x_for_key !== undefined) return false; // Don't touch spawns from if directives
-
-          if (el.__x_inserted_me !== undefined) return false;
-          this.initializeElement(el, extraVars, componentForClone ? false : true);
-        }.bind(this), function (el) {
-          _newArrowCheck(this, _this10);
-
-          if (!componentForClone) el.__x = new Component(el);
-        }.bind(this));
-        this.executeAndClearRemainingShowDirectiveStack();
-        this.executeAndClearNextTickStack(rootEl);
-      }
-    }, {
-      key: "initializeElement",
-      value: function initializeElement(el, extraVars) {
-        var shouldRegisterListeners = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
-
-        // To support class attribute merging, we have to know what the element's
-        // original class attribute looked like for reference.
-        if (el.hasAttribute('class') && getXAttrs(el, this).length > 0) {
-          el.__x_original_classes = convertClassStringToArray(el.getAttribute('class'));
-        }
-
-        shouldRegisterListeners && this.registerListeners(el, extraVars);
-        this.resolveBoundAttributes(el, true, extraVars);
-      }
-    }, {
-      key: "updateElements",
-      value: function updateElements(rootEl) {
-        var _this11 = this;
-
-        var extraVars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
-          _newArrowCheck(this, _this11);
-        }.bind(this);
-        this.walkAndSkipNestedComponents(rootEl, function (el) {
-          _newArrowCheck(this, _this11);
-
-          // Don't touch spawns from for loop (and check if the root is actually a for loop in a parent, don't skip it.)
-          if (el.__x_for_key !== undefined && !el.isSameNode(this.$el)) return false;
-          this.updateElement(el, extraVars);
-        }.bind(this), function (el) {
-          _newArrowCheck(this, _this11);
-
-          el.__x = new Component(el);
-        }.bind(this));
-        this.executeAndClearRemainingShowDirectiveStack();
-        this.executeAndClearNextTickStack(rootEl);
-      }
-    }, {
-      key: "executeAndClearNextTickStack",
-      value: function executeAndClearNextTickStack(el) {
-        var _this12 = this;
-
-        // Skip spawns from alpine directives
-        if (el === this.$el && this.nextTickStack.length > 0) {
-          // We run the tick stack after the next frame to allow any
-          // running transitions to pass the initial show stage.
-          requestAnimationFrame(function () {
-            _newArrowCheck(this, _this12);
-
-            while (this.nextTickStack.length > 0) {
-              this.nextTickStack.shift()();
-            }
-          }.bind(this));
-        }
-      }
-    }, {
-      key: "executeAndClearRemainingShowDirectiveStack",
-      value: function executeAndClearRemainingShowDirectiveStack() {
-        var _this13 = this;
-
-        // The goal here is to start all the x-show transitions
-        // and build a nested promise chain so that elements
-        // only hide when the children are finished hiding.
-        this.showDirectiveStack.reverse().map(function (handler) {
-          var _this14 = this;
-
-          _newArrowCheck(this, _this13);
-
-          return new Promise(function (resolve, reject) {
-            _newArrowCheck(this, _this14);
-
-            handler(resolve, reject);
-          }.bind(this));
-        }.bind(this)).reduce(function (promiseChain, promise) {
-          var _this15 = this;
-
-          _newArrowCheck(this, _this13);
-
-          return promiseChain.then(function () {
-            var _this16 = this;
-
-            _newArrowCheck(this, _this15);
-
-            return promise.then(function (finishElement) {
-              _newArrowCheck(this, _this16);
-
-              finishElement();
-            }.bind(this));
-          }.bind(this));
-        }.bind(this), Promise.resolve(function () {
-          _newArrowCheck(this, _this13);
-        }.bind(this)))["catch"](function (e) {
-          _newArrowCheck(this, _this13);
-
-          if (e !== TRANSITION_CANCELLED) throw e;
-        }.bind(this)); // We've processed the handler stack. let's clear it.
-
-        this.showDirectiveStack = [];
-        this.showDirectiveLastElement = undefined;
-      }
-    }, {
-      key: "updateElement",
-      value: function updateElement(el, extraVars) {
-        this.resolveBoundAttributes(el, false, extraVars);
-      }
-    }, {
-      key: "registerListeners",
-      value: function registerListeners(el, extraVars) {
-        var _this17 = this;
-
-        getXAttrs(el, this).forEach(function (_ref5) {
-          _newArrowCheck(this, _this17);
-
-          var type = _ref5.type,
-              value = _ref5.value,
-              modifiers = _ref5.modifiers,
-              expression = _ref5.expression;
-
-          switch (type) {
-            case 'on':
-              registerListener(this, el, value, modifiers, expression, extraVars);
-              break;
-
-            case 'model':
-              registerModelListener(this, el, modifiers, expression, extraVars);
-              break;
-          }
-        }.bind(this));
-      }
-    }, {
-      key: "resolveBoundAttributes",
-      value: function resolveBoundAttributes(el) {
-        var _this18 = this;
-
-        var initialUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-        var extraVars = arguments.length > 2 ? arguments[2] : undefined;
-        var attrs = getXAttrs(el, this);
-        attrs.forEach(function (_ref6) {
-          var _this19 = this;
-
-          _newArrowCheck(this, _this18);
-
-          var type = _ref6.type,
-              value = _ref6.value,
-              modifiers = _ref6.modifiers,
-              expression = _ref6.expression;
-
-          switch (type) {
-            case 'model':
-              handleAttributeBindingDirective(this, el, 'value', expression, extraVars, type, modifiers);
-              break;
-
-            case 'bind':
-              // The :key binding on an x-for is special, ignore it.
-              if (el.tagName.toLowerCase() === 'template' && value === 'key') return;
-              handleAttributeBindingDirective(this, el, value, expression, extraVars, type, modifiers);
-              break;
-
-            case 'text':
-              var output = this.evaluateReturnExpression(el, expression, extraVars);
-              handleTextDirective(el, output, expression);
-              break;
-
-            case 'html':
-              handleHtmlDirective(this, el, expression, extraVars);
-              break;
-
-            case 'show':
-              var output = this.evaluateReturnExpression(el, expression, extraVars);
-              handleShowDirective(this, el, output, modifiers, initialUpdate);
-              break;
-
-            case 'if':
-              // If this element also has x-for on it, don't process x-if.
-              // We will let the "x-for" directive handle the "if"ing.
-              if (attrs.some(function (i) {
-                _newArrowCheck(this, _this19);
-
-                return i.type === 'for';
-              }.bind(this))) return;
-              var output = this.evaluateReturnExpression(el, expression, extraVars);
-              handleIfDirective(this, el, output, initialUpdate, extraVars);
-              break;
-
-            case 'for':
-              handleForDirective(this, el, expression, initialUpdate, extraVars);
-              break;
-
-            case 'cloak':
-              el.removeAttribute('x-cloak');
-              break;
-          }
-        }.bind(this));
-      }
-    }, {
-      key: "evaluateReturnExpression",
-      value: function evaluateReturnExpression(el, expression) {
-        var _this20 = this;
-
-        var extraVars = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
-          _newArrowCheck(this, _this20);
-        }.bind(this);
-        return saferEval(el, expression, this.$data, _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-          $dispatch: this.getDispatchFunction(el)
-        }));
-      }
-    }, {
-      key: "evaluateCommandExpression",
-      value: function evaluateCommandExpression(el, expression) {
-        var _this21 = this;
-
-        var extraVars = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
-          _newArrowCheck(this, _this21);
-        }.bind(this);
-        return saferEvalNoReturn(el, expression, this.$data, _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-          $dispatch: this.getDispatchFunction(el)
-        }));
-      }
-    }, {
-      key: "getDispatchFunction",
-      value: function getDispatchFunction(el) {
-        return function (event) {
-          var detail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-          el.dispatchEvent(new CustomEvent(event, {
-            detail: detail,
-            bubbles: true
-          }));
-        };
-      }
-    }, {
-      key: "listenForNewElementsToInitialize",
-      value: function listenForNewElementsToInitialize() {
-        var _this22 = this;
-
-        var targetNode = this.$el;
-        var observerOptions = {
-          childList: true,
-          attributes: true,
-          subtree: true
-        };
-        var observer = new MutationObserver(function (mutations) {
-          var _this23 = this;
-
-          _newArrowCheck(this, _this22);
-
-          for (var i = 0; i < mutations.length; i++) {
-            // Filter out mutations triggered from child components.
-            var closestParentComponent = mutations[i].target.closest('[x-data]');
-            if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) continue;
-
-            if (mutations[i].type === 'attributes' && mutations[i].attributeName === 'x-data') {
-              (function () {
-                var _this24 = this;
-
-                var xAttr = mutations[i].target.getAttribute('x-data') || '{}';
-                var rawData = saferEval(_this23.$el, xAttr, {
-                  $el: _this23.$el
-                });
-                Object.keys(rawData).forEach(function (key) {
-                  _newArrowCheck(this, _this24);
-
-                  if (_this23.$data[key] !== rawData[key]) {
-                    _this23.$data[key] = rawData[key];
-                  }
-                }.bind(this));
-              })();
-            }
-
-            if (mutations[i].addedNodes.length > 0) {
-              mutations[i].addedNodes.forEach(function (node) {
-                _newArrowCheck(this, _this23);
-
-                if (node.nodeType !== 1 || node.__x_inserted_me) return;
-
-                if (node.matches('[x-data]') && !node.__x) {
-                  node.__x = new Component(node);
-                  return;
-                }
-
-                node.__x_node_add_count = (node.__x_node_add_count || 0) + 1;
-                this.initializeElements(node);
-              }.bind(this));
-            }
-          }
-        }.bind(this));
-        observer.observe(targetNode, observerOptions);
-      }
-    }, {
-      key: "getRefsProxy",
-      value: function getRefsProxy() {
-        var _this25 = this;
-
-        var self = this;
-        var refObj = {};
-        /* IE11-ONLY:START */
-        // Add any properties up-front that might be necessary for the Proxy polyfill.
-
-        refObj.$isRefsProxy = false;
-        refObj.$isAlpineProxy = false; // If we are in IE, since the polyfill needs all properties to be defined before building the proxy,
-        // we just loop on the element, look for any x-ref and create a tmp property on a fake object.
-
-        this.walkAndSkipNestedComponents(self.$el, function (el) {
-          _newArrowCheck(this, _this25);
-
-          if (el.hasAttribute('x-ref')) {
-            refObj[el.getAttribute('x-ref')] = true;
-          }
-        }.bind(this));
-        /* IE11-ONLY:END */
-        // One of the goals of this is to not hold elements in memory, but rather re-evaluate
-        // the DOM when the system needs something from it. This way, the framework is flexible and
-        // friendly to outside DOM changes from libraries like Vue/Livewire.
-        // For this reason, I'm using an "on-demand" proxy to fake a "$refs" object.
-
-        return new Proxy(refObj, {
-          get: function get(object, property) {
-            var _this26 = this;
-
-            if (property === '$isAlpineProxy') return true;
-            var ref; // We can't just query the DOM because it's hard to filter out refs in
-            // nested components.
-
-            self.walkAndSkipNestedComponents(self.$el, function (el) {
-              _newArrowCheck(this, _this26);
-
-              if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
-                ref = el;
-              }
-            }.bind(this));
-            return ref;
-          }
-        });
-      }
-    }]);
-
-    return Component;
-  }();
-
-  var Alpine = {
-    version: "2.8.2",
-    pauseMutationObserver: false,
-    magicProperties: {},
-    onComponentInitializeds: [],
-    onBeforeComponentInitializeds: [],
-    ignoreFocusedForValueBinding: false,
-    start: function () {
-      var _start = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
-        var _this = this;
-
-        return regeneratorRuntime.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                if (isTesting()) {
-                  _context.next = 3;
-                  break;
-                }
-
-                _context.next = 3;
-                return domReady();
-
-              case 3:
-                this.discoverComponents(function (el) {
-                  _newArrowCheck(this, _this);
-
-                  this.initializeComponent(el);
-                }.bind(this)); // It's easier and more performant to just support Turbolinks than listen
-                // to MutationObserver mutations at the document level.
-
-                document.addEventListener("turbolinks:load", function () {
-                  var _this2 = this;
-
-                  _newArrowCheck(this, _this);
-
-                  this.discoverUninitializedComponents(function (el) {
-                    _newArrowCheck(this, _this2);
-
-                    this.initializeComponent(el);
-                  }.bind(this));
-                }.bind(this));
-                this.listenForNewUninitializedComponentsAtRunTime();
-
-              case 6:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
-
-      function start() {
-        return _start.apply(this, arguments);
-      }
-
-      return start;
-    }(),
-    discoverComponents: function discoverComponents(callback) {
-      var _this3 = this;
-
-      var rootEls = document.querySelectorAll('[x-data]');
-      rootEls.forEach(function (rootEl) {
-        _newArrowCheck(this, _this3);
-
-        callback(rootEl);
-      }.bind(this));
-    },
-    discoverUninitializedComponents: function discoverUninitializedComponents(callback) {
-      var _this4 = this;
-
-      var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-      var rootEls = (el || document).querySelectorAll('[x-data]');
-      Array.from(rootEls).filter(function (el) {
-        _newArrowCheck(this, _this4);
-
-        return el.__x === undefined;
-      }.bind(this)).forEach(function (rootEl) {
-        _newArrowCheck(this, _this4);
-
-        callback(rootEl);
-      }.bind(this));
-    },
-    listenForNewUninitializedComponentsAtRunTime: function listenForNewUninitializedComponentsAtRunTime() {
-      var _this5 = this;
-
-      var targetNode = document.querySelector('body');
-      var observerOptions = {
-        childList: true,
-        attributes: true,
-        subtree: true
-      };
-      var observer = new MutationObserver(function (mutations) {
-        var _this6 = this;
-
-        _newArrowCheck(this, _this5);
-
-        if (this.pauseMutationObserver) return;
-
-        for (var i = 0; i < mutations.length; i++) {
-          if (mutations[i].addedNodes.length > 0) {
-            mutations[i].addedNodes.forEach(function (node) {
-              var _this7 = this;
-
-              _newArrowCheck(this, _this6);
-
-              // Discard non-element nodes (like line-breaks)
-              if (node.nodeType !== 1) return; // Discard any changes happening within an existing component.
-              // They will take care of themselves.
-
-              if (node.parentElement && node.parentElement.closest('[x-data]')) return;
-              this.discoverUninitializedComponents(function (el) {
-                _newArrowCheck(this, _this7);
-
-                this.initializeComponent(el);
-              }.bind(this), node.parentElement);
-            }.bind(this));
-          }
-        }
-      }.bind(this));
-      observer.observe(targetNode, observerOptions);
-    },
-    initializeComponent: function initializeComponent(el) {
-      var _this8 = this;
-
-      if (!el.__x) {
-        // Wrap in a try/catch so that we don't prevent other components
-        // from initializing when one component contains an error.
-        try {
-          el.__x = new Component(el);
-        } catch (error) {
-          setTimeout(function () {
-            _newArrowCheck(this, _this8);
-
-            throw error;
-          }.bind(this), 0);
-        }
-      }
-    },
-    clone: function clone(component, newEl) {
-      if (!newEl.__x) {
-        newEl.__x = new Component(newEl, component);
-      }
-    },
-    addMagicProperty: function addMagicProperty(name, callback) {
-      this.magicProperties[name] = callback;
-    },
-    onComponentInitialized: function onComponentInitialized(callback) {
-      this.onComponentInitializeds.push(callback);
-    },
-    onBeforeComponentInitialized: function onBeforeComponentInitialized(callback) {
-      this.onBeforeComponentInitializeds.push(callback);
-    }
-  };
-
-  if (!isTesting()) {
-    window.Alpine = Alpine;
-
-    if (window.deferLoadingAlpine) {
-      window.deferLoadingAlpine(function () {
-        window.Alpine.start();
-      });
-    } else {
-      window.Alpine.start();
-    }
-  }
-
-})));

+ 0 - 1956
dist/alpine.js

@@ -1,1956 +0,0 @@
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-  typeof define === 'function' && define.amd ? define(factory) :
-  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alpine = factory());
-}(this, (function () { 'use strict';
-
-  function _defineProperty(obj, key, value) {
-    if (key in obj) {
-      Object.defineProperty(obj, key, {
-        value: value,
-        enumerable: true,
-        configurable: true,
-        writable: true
-      });
-    } else {
-      obj[key] = value;
-    }
-
-    return obj;
-  }
-
-  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 _objectSpread2(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) {
-          _defineProperty(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;
-  }
-
-  // Thanks @stimulus:
-  // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts
-  function domReady() {
-    return new Promise(resolve => {
-      if (document.readyState == "loading") {
-        document.addEventListener("DOMContentLoaded", resolve);
-      } else {
-        resolve();
-      }
-    });
-  }
-  function arrayUnique(array) {
-    return Array.from(new Set(array));
-  }
-  function isTesting() {
-    return navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom");
-  }
-  function checkedAttrLooseCompare(valueA, valueB) {
-    return valueA == valueB;
-  }
-  function warnIfMalformedTemplate(el, directive) {
-    if (el.tagName.toLowerCase() !== 'template') {
-      console.warn(`Alpine: [${directive}] directive should only be added to <template> tags. See https://github.com/alpinejs/alpine#${directive}`);
-    } else if (el.content.childElementCount !== 1) {
-      console.warn(`Alpine: <template> tag with [${directive}] encountered with an unexpected number of root elements. Make sure <template> has a single root element. `);
-    }
-  }
-  function kebabCase(subject) {
-    return subject.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[_\s]/, '-').toLowerCase();
-  }
-  function camelCase(subject) {
-    return subject.toLowerCase().replace(/-(\w)/g, (match, char) => char.toUpperCase());
-  }
-  function walk(el, callback) {
-    if (callback(el) === false) return;
-    let node = el.firstElementChild;
-
-    while (node) {
-      walk(node, callback);
-      node = node.nextElementSibling;
-    }
-  }
-  function debounce(func, wait) {
-    var timeout;
-    return function () {
-      var context = this,
-          args = arguments;
-
-      var later = function later() {
-        timeout = null;
-        func.apply(context, args);
-      };
-
-      clearTimeout(timeout);
-      timeout = setTimeout(later, wait);
-    };
-  }
-
-  const handleError = (el, expression, error) => {
-    console.warn(`Alpine Error: "${error}"\n\nExpression: "${expression}"\nElement:`, el);
-
-    if (!isTesting()) {
-      Object.assign(error, {
-        el,
-        expression
-      });
-      throw error;
-    }
-  };
-
-  function tryCatch(cb, {
-    el,
-    expression
-  }) {
-    try {
-      const value = cb();
-      return value instanceof Promise ? value.catch(e => handleError(el, expression, e)) : value;
-    } catch (e) {
-      handleError(el, expression, e);
-    }
-  }
-
-  function saferEval(el, expression, dataContext, additionalHelperVariables = {}) {
-    return tryCatch(() => {
-      if (typeof expression === 'function') {
-        return expression.call(dataContext);
-      }
-
-      return new Function(['$data', ...Object.keys(additionalHelperVariables)], `var __alpine_result; with($data) { __alpine_result = ${expression} }; return __alpine_result`)(dataContext, ...Object.values(additionalHelperVariables));
-    }, {
-      el,
-      expression
-    });
-  }
-  function saferEvalNoReturn(el, expression, dataContext, additionalHelperVariables = {}) {
-    return tryCatch(() => {
-      if (typeof expression === 'function') {
-        return Promise.resolve(expression.call(dataContext, additionalHelperVariables['$event']));
-      }
-
-      let AsyncFunction = Function;
-      /* MODERN-ONLY:START */
-
-      AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
-      /* MODERN-ONLY:END */
-      // For the cases when users pass only a function reference to the caller: `x-on:click="foo"`
-      // Where "foo" is a function. Also, we'll pass the function the event instance when we call it.
-
-      if (Object.keys(dataContext).includes(expression)) {
-        let methodReference = new Function(['dataContext', ...Object.keys(additionalHelperVariables)], `with(dataContext) { return ${expression} }`)(dataContext, ...Object.values(additionalHelperVariables));
-
-        if (typeof methodReference === 'function') {
-          return Promise.resolve(methodReference.call(dataContext, additionalHelperVariables['$event']));
-        } else {
-          return Promise.resolve();
-        }
-      }
-
-      return Promise.resolve(new AsyncFunction(['dataContext', ...Object.keys(additionalHelperVariables)], `with(dataContext) { ${expression} }`)(dataContext, ...Object.values(additionalHelperVariables)));
-    }, {
-      el,
-      expression
-    });
-  }
-  const xAttrRE = /^x-(on|bind|data|text|html|model|if|for|show|cloak|transition|ref|spread)\b/;
-  function isXAttr(attr) {
-    const name = replaceAtAndColonWithStandardSyntax(attr.name);
-    return xAttrRE.test(name);
-  }
-  function getXAttrs(el, component, type) {
-    let directives = Array.from(el.attributes).filter(isXAttr).map(parseHtmlAttribute); // Get an object of directives from x-spread.
-
-    let spreadDirective = directives.filter(directive => directive.type === 'spread')[0];
-
-    if (spreadDirective) {
-      let spreadObject = saferEval(el, spreadDirective.expression, component.$data); // Add x-spread directives to the pile of existing directives.
-
-      directives = directives.concat(Object.entries(spreadObject).map(([name, value]) => parseHtmlAttribute({
-        name,
-        value
-      })));
-    }
-
-    if (type) return directives.filter(i => i.type === type);
-    return sortDirectives(directives);
-  }
-
-  function sortDirectives(directives) {
-    let directiveOrder = ['bind', 'model', 'show', 'catch-all'];
-    return directives.sort((a, b) => {
-      let typeA = directiveOrder.indexOf(a.type) === -1 ? 'catch-all' : a.type;
-      let typeB = directiveOrder.indexOf(b.type) === -1 ? 'catch-all' : b.type;
-      return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB);
-    });
-  }
-
-  function parseHtmlAttribute({
-    name,
-    value
-  }) {
-    const normalizedName = replaceAtAndColonWithStandardSyntax(name);
-    const typeMatch = normalizedName.match(xAttrRE);
-    const valueMatch = normalizedName.match(/:([a-zA-Z0-9\-:]+)/);
-    const modifiers = normalizedName.match(/\.[^.\]]+(?=[^\]]*$)/g) || [];
-    return {
-      type: typeMatch ? typeMatch[1] : null,
-      value: valueMatch ? valueMatch[1] : null,
-      modifiers: modifiers.map(i => i.replace('.', '')),
-      expression: value
-    };
-  }
-  function isBooleanAttr(attrName) {
-    // As per HTML spec table https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute
-    // Array roughly ordered by estimated usage
-    const booleanAttributes = ['disabled', 'checked', 'required', 'readonly', 'hidden', 'open', 'selected', 'autofocus', 'itemscope', 'multiple', 'novalidate', 'allowfullscreen', 'allowpaymentrequest', 'formnovalidate', 'autoplay', 'controls', 'loop', 'muted', 'playsinline', 'default', 'ismap', 'reversed', 'async', 'defer', 'nomodule'];
-    return booleanAttributes.includes(attrName);
-  }
-  function replaceAtAndColonWithStandardSyntax(name) {
-    if (name.startsWith('@')) {
-      return name.replace('@', 'x-on:');
-    } else if (name.startsWith(':')) {
-      return name.replace(':', 'x-bind:');
-    }
-
-    return name;
-  }
-  function convertClassStringToArray(classList, filterFn = Boolean) {
-    return classList.split(' ').filter(filterFn);
-  }
-  const TRANSITION_TYPE_IN = 'in';
-  const TRANSITION_TYPE_OUT = 'out';
-  const TRANSITION_CANCELLED = 'cancelled';
-  function transitionIn(el, show, reject, component, forceSkip = false) {
-    // We don't want to transition on the initial page load.
-    if (forceSkip) return show();
-
-    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_IN) {
-      // there is already a similar transition going on, this was probably triggered by
-      // a change in a different property, let's just leave the previous one doing its job
-      return;
-    }
-
-    const attrs = getXAttrs(el, component, 'transition');
-    const showAttr = getXAttrs(el, component, 'show')[0]; // If this is triggered by a x-show.transition.
-
-    if (showAttr && showAttr.modifiers.includes('transition')) {
-      let modifiers = showAttr.modifiers; // If x-show.transition.out, we'll skip the "in" transition.
-
-      if (modifiers.includes('out') && !modifiers.includes('in')) return show();
-      const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out'); // If x-show.transition.in...out... only use "in" related modifiers for this transition.
-
-      modifiers = settingBothSidesOfTransition ? modifiers.filter((i, index) => index < modifiers.indexOf('out')) : modifiers;
-      transitionHelperIn(el, modifiers, show, reject); // Otherwise, we can assume x-transition:enter.
-    } else if (attrs.some(attr => ['enter', 'enter-start', 'enter-end'].includes(attr.value))) {
-      transitionClassesIn(el, component, attrs, show, reject);
-    } else {
-      // If neither, just show that damn thing.
-      show();
-    }
-  }
-  function transitionOut(el, hide, reject, component, forceSkip = false) {
-    // We don't want to transition on the initial page load.
-    if (forceSkip) return hide();
-
-    if (el.__x_transition && el.__x_transition.type === TRANSITION_TYPE_OUT) {
-      // there is already a similar transition going on, this was probably triggered by
-      // a change in a different property, let's just leave the previous one doing its job
-      return;
-    }
-
-    const attrs = getXAttrs(el, component, 'transition');
-    const showAttr = getXAttrs(el, component, 'show')[0];
-
-    if (showAttr && showAttr.modifiers.includes('transition')) {
-      let modifiers = showAttr.modifiers;
-      if (modifiers.includes('in') && !modifiers.includes('out')) return hide();
-      const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out');
-      modifiers = settingBothSidesOfTransition ? modifiers.filter((i, index) => index > modifiers.indexOf('out')) : modifiers;
-      transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hide, reject);
-    } else if (attrs.some(attr => ['leave', 'leave-start', 'leave-end'].includes(attr.value))) {
-      transitionClassesOut(el, component, attrs, hide, reject);
-    } else {
-      hide();
-    }
-  }
-  function transitionHelperIn(el, modifiers, showCallback, reject) {
-    // Default values inspired by: https://material.io/design/motion/speed.html#duration
-    const styleValues = {
-      duration: modifierValue(modifiers, 'duration', 150),
-      origin: modifierValue(modifiers, 'origin', 'center'),
-      first: {
-        opacity: 0,
-        scale: modifierValue(modifiers, 'scale', 95)
-      },
-      second: {
-        opacity: 1,
-        scale: 100
-      }
-    };
-    transitionHelper(el, modifiers, showCallback, () => {}, reject, styleValues, TRANSITION_TYPE_IN);
-  }
-  function transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hideCallback, reject) {
-    // Make the "out" transition .5x slower than the "in". (Visually better)
-    // HOWEVER, if they explicitly set a duration for the "out" transition,
-    // use that.
-    const duration = settingBothSidesOfTransition ? modifierValue(modifiers, 'duration', 150) : modifierValue(modifiers, 'duration', 150) / 2;
-    const styleValues = {
-      duration: duration,
-      origin: modifierValue(modifiers, 'origin', 'center'),
-      first: {
-        opacity: 1,
-        scale: 100
-      },
-      second: {
-        opacity: 0,
-        scale: modifierValue(modifiers, 'scale', 95)
-      }
-    };
-    transitionHelper(el, modifiers, () => {}, hideCallback, reject, styleValues, TRANSITION_TYPE_OUT);
-  }
-
-  function modifierValue(modifiers, key, fallback) {
-    // If the modifier isn't present, use the default.
-    if (modifiers.indexOf(key) === -1) return fallback; // If it IS present, grab the value after it: x-show.transition.duration.500ms
-
-    const rawValue = modifiers[modifiers.indexOf(key) + 1];
-    if (!rawValue) return fallback;
-
-    if (key === 'scale') {
-      // Check if the very next value is NOT a number and return the fallback.
-      // If x-show.transition.scale, we'll use the default scale value.
-      // That is how a user opts out of the opacity transition.
-      if (!isNumeric(rawValue)) return fallback;
-    }
-
-    if (key === 'duration') {
-      // Support x-show.transition.duration.500ms && duration.500
-      let match = rawValue.match(/([0-9]+)ms/);
-      if (match) return match[1];
-    }
-
-    if (key === 'origin') {
-      // Support chaining origin directions: x-show.transition.top.right
-      if (['top', 'right', 'left', 'center', 'bottom'].includes(modifiers[modifiers.indexOf(key) + 2])) {
-        return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(' ');
-      }
-    }
-
-    return rawValue;
-  }
-
-  function transitionHelper(el, modifiers, hook1, hook2, reject, styleValues, type) {
-    // clear the previous transition if exists to avoid caching the wrong styles
-    if (el.__x_transition) {
-      el.__x_transition.cancel && el.__x_transition.cancel();
-    } // If the user set these style values, we'll put them back when we're done with them.
-
-
-    const opacityCache = el.style.opacity;
-    const transformCache = el.style.transform;
-    const transformOriginCache = el.style.transformOrigin; // If no modifiers are present: x-show.transition, we'll default to both opacity and scale.
-
-    const noModifiers = !modifiers.includes('opacity') && !modifiers.includes('scale');
-    const transitionOpacity = noModifiers || modifiers.includes('opacity');
-    const transitionScale = noModifiers || modifiers.includes('scale'); // These are the explicit stages of a transition (same stages for in and for out).
-    // This way you can get a birds eye view of the hooks, and the differences
-    // between them.
-
-    const stages = {
-      start() {
-        if (transitionOpacity) el.style.opacity = styleValues.first.opacity;
-        if (transitionScale) el.style.transform = `scale(${styleValues.first.scale / 100})`;
-      },
-
-      during() {
-        if (transitionScale) el.style.transformOrigin = styleValues.origin;
-        el.style.transitionProperty = [transitionOpacity ? `opacity` : ``, transitionScale ? `transform` : ``].join(' ').trim();
-        el.style.transitionDuration = `${styleValues.duration / 1000}s`;
-        el.style.transitionTimingFunction = `cubic-bezier(0.4, 0.0, 0.2, 1)`;
-      },
-
-      show() {
-        hook1();
-      },
-
-      end() {
-        if (transitionOpacity) el.style.opacity = styleValues.second.opacity;
-        if (transitionScale) el.style.transform = `scale(${styleValues.second.scale / 100})`;
-      },
-
-      hide() {
-        hook2();
-      },
-
-      cleanup() {
-        if (transitionOpacity) el.style.opacity = opacityCache;
-        if (transitionScale) el.style.transform = transformCache;
-        if (transitionScale) el.style.transformOrigin = transformOriginCache;
-        el.style.transitionProperty = null;
-        el.style.transitionDuration = null;
-        el.style.transitionTimingFunction = null;
-      }
-
-    };
-    transition(el, stages, type, reject);
-  }
-
-  const ensureStringExpression = (expression, el, component) => {
-    return typeof expression === 'function' ? component.evaluateReturnExpression(el, expression) : expression;
-  };
-
-  function transitionClassesIn(el, component, directives, showCallback, reject) {
-    const enter = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'enter') || {
-      expression: ''
-    }).expression, el, component));
-    const enterStart = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'enter-start') || {
-      expression: ''
-    }).expression, el, component));
-    const enterEnd = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'enter-end') || {
-      expression: ''
-    }).expression, el, component));
-    transitionClasses(el, enter, enterStart, enterEnd, showCallback, () => {}, TRANSITION_TYPE_IN, reject);
-  }
-  function transitionClassesOut(el, component, directives, hideCallback, reject) {
-    const leave = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'leave') || {
-      expression: ''
-    }).expression, el, component));
-    const leaveStart = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'leave-start') || {
-      expression: ''
-    }).expression, el, component));
-    const leaveEnd = convertClassStringToArray(ensureStringExpression((directives.find(i => i.value === 'leave-end') || {
-      expression: ''
-    }).expression, el, component));
-    transitionClasses(el, leave, leaveStart, leaveEnd, () => {}, hideCallback, TRANSITION_TYPE_OUT, reject);
-  }
-  function transitionClasses(el, classesDuring, classesStart, classesEnd, hook1, hook2, type, reject) {
-    // clear the previous transition if exists to avoid caching the wrong classes
-    if (el.__x_transition) {
-      el.__x_transition.cancel && el.__x_transition.cancel();
-    }
-
-    const originalClasses = el.__x_original_classes || [];
-    const stages = {
-      start() {
-        el.classList.add(...classesStart);
-      },
-
-      during() {
-        el.classList.add(...classesDuring);
-      },
-
-      show() {
-        hook1();
-      },
-
-      end() {
-        // Don't remove classes that were in the original class attribute.
-        el.classList.remove(...classesStart.filter(i => !originalClasses.includes(i)));
-        el.classList.add(...classesEnd);
-      },
-
-      hide() {
-        hook2();
-      },
-
-      cleanup() {
-        el.classList.remove(...classesDuring.filter(i => !originalClasses.includes(i)));
-        el.classList.remove(...classesEnd.filter(i => !originalClasses.includes(i)));
-      }
-
-    };
-    transition(el, stages, type, reject);
-  }
-  function transition(el, stages, type, reject) {
-    const finish = once(() => {
-      stages.hide(); // Adding an "isConnected" check, in case the callback
-      // removed the element from the DOM.
-
-      if (el.isConnected) {
-        stages.cleanup();
-      }
-
-      delete el.__x_transition;
-    });
-    el.__x_transition = {
-      // Set transition type so we can avoid clearing transition if the direction is the same
-      type: type,
-      // create a callback for the last stages of the transition so we can call it
-      // from different point and early terminate it. Once will ensure that function
-      // is only called one time.
-      cancel: once(() => {
-        reject(TRANSITION_CANCELLED);
-        finish();
-      }),
-      finish,
-      // This store the next animation frame so we can cancel it
-      nextFrame: null
-    };
-    stages.start();
-    stages.during();
-    el.__x_transition.nextFrame = requestAnimationFrame(() => {
-      // Note: Safari's transitionDuration property will list out comma separated transition durations
-      // for every single transition property. Let's grab the first one and call it a day.
-      let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, '').replace('s', '')) * 1000;
-
-      if (duration === 0) {
-        duration = Number(getComputedStyle(el).animationDuration.replace('s', '')) * 1000;
-      }
-
-      stages.show();
-      el.__x_transition.nextFrame = requestAnimationFrame(() => {
-        stages.end();
-        setTimeout(el.__x_transition.finish, duration);
-      });
-    });
-  }
-  function isNumeric(subject) {
-    return !Array.isArray(subject) && !isNaN(subject);
-  } // Thanks @vuejs
-  // https://github.com/vuejs/vue/blob/4de4649d9637262a9b007720b59f80ac72a5620c/src/shared/util.js
-
-  function once(callback) {
-    let called = false;
-    return function () {
-      if (!called) {
-        called = true;
-        callback.apply(this, arguments);
-      }
-    };
-  }
-
-  function handleForDirective(component, templateEl, expression, initialUpdate, extraVars) {
-    warnIfMalformedTemplate(templateEl, 'x-for');
-    let iteratorNames = typeof expression === 'function' ? parseForExpression(component.evaluateReturnExpression(templateEl, expression)) : parseForExpression(expression);
-    let items = evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, templateEl, iteratorNames, extraVars); // As we walk the array, we'll also walk the DOM (updating/creating as we go).
-
-    let currentEl = templateEl;
-    items.forEach((item, index) => {
-      let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
-      let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
-      let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
-
-      if (!nextEl) {
-        nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl); // And transition it in if it's not the first page load.
-
-        transitionIn(nextEl, () => {}, () => {}, component, initialUpdate);
-        nextEl.__x_for = iterationScopeVariables;
-        component.initializeElements(nextEl, () => nextEl.__x_for); // Otherwise update the element we found.
-      } else {
-        // Temporarily remove the key indicator to allow the normal "updateElements" to work.
-        delete nextEl.__x_for_key;
-        nextEl.__x_for = iterationScopeVariables;
-        component.updateElements(nextEl, () => nextEl.__x_for);
-      }
-
-      currentEl = nextEl;
-      currentEl.__x_for_key = currentKey;
-    });
-    removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component);
-  } // This was taken from VueJS 2.* core. Thanks Vue!
-
-  function parseForExpression(expression) {
-    let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
-    let stripParensRE = /^\(|\)$/g;
-    let forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
-    let inMatch = String(expression).match(forAliasRE);
-    if (!inMatch) return;
-    let res = {};
-    res.items = inMatch[2].trim();
-    let item = inMatch[1].trim().replace(stripParensRE, '');
-    let iteratorMatch = item.match(forIteratorRE);
-
-    if (iteratorMatch) {
-      res.item = item.replace(forIteratorRE, '').trim();
-      res.index = iteratorMatch[1].trim();
-
-      if (iteratorMatch[2]) {
-        res.collection = iteratorMatch[2].trim();
-      }
-    } else {
-      res.item = item;
-    }
-
-    return res;
-  }
-
-  function getIterationScopeVariables(iteratorNames, item, index, items, extraVars) {
-    // We must create a new object, so each iteration has a new scope
-    let scopeVariables = extraVars ? _objectSpread2({}, extraVars) : {};
-    scopeVariables[iteratorNames.item] = item;
-    if (iteratorNames.index) scopeVariables[iteratorNames.index] = index;
-    if (iteratorNames.collection) scopeVariables[iteratorNames.collection] = items;
-    return scopeVariables;
-  }
-
-  function generateKeyForIteration(component, el, index, iterationScopeVariables) {
-    let bindKeyAttribute = getXAttrs(el, component, 'bind').filter(attr => attr.value === 'key')[0]; // If the dev hasn't specified a key, just return the index of the iteration.
-
-    if (!bindKeyAttribute) return index;
-    return component.evaluateReturnExpression(el, bindKeyAttribute.expression, () => iterationScopeVariables);
-  }
-
-  function evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, el, iteratorNames, extraVars) {
-    let ifAttribute = getXAttrs(el, component, 'if')[0];
-
-    if (ifAttribute && !component.evaluateReturnExpression(el, ifAttribute.expression)) {
-      return [];
-    }
-
-    let items = component.evaluateReturnExpression(el, iteratorNames.items, extraVars); // This adds support for the `i in n` syntax.
-
-    if (isNumeric(items) && items >= 0) {
-      items = Array.from(Array(items).keys(), i => i + 1);
-    }
-
-    return items;
-  }
-
-  function addElementInLoopAfterCurrentEl(templateEl, currentEl) {
-    let clone = document.importNode(templateEl.content, true);
-    currentEl.parentElement.insertBefore(clone, currentEl.nextElementSibling);
-    return currentEl.nextElementSibling;
-  }
-
-  function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
-    if (!nextEl) return; // If we are already past the x-for generated elements, we don't need to look ahead.
-
-    if (nextEl.__x_for_key === undefined) return; // If the the key's DO match, no need to look ahead.
-
-    if (nextEl.__x_for_key === currentKey) return nextEl; // If they don't, we'll look ahead for a match.
-    // If we find it, we'll move it to the current position in the loop.
-
-    let tmpNextEl = nextEl;
-
-    while (tmpNextEl) {
-      if (tmpNextEl.__x_for_key === currentKey) {
-        return tmpNextEl.parentElement.insertBefore(tmpNextEl, nextEl);
-      }
-
-      tmpNextEl = tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined ? tmpNextEl.nextElementSibling : false;
-    }
-  }
-
-  function removeAnyLeftOverElementsFromPreviousUpdate(currentEl, component) {
-    var nextElementFromOldLoop = currentEl.nextElementSibling && currentEl.nextElementSibling.__x_for_key !== undefined ? currentEl.nextElementSibling : false;
-
-    while (nextElementFromOldLoop) {
-      let nextElementFromOldLoopImmutable = nextElementFromOldLoop;
-      let nextSibling = nextElementFromOldLoop.nextElementSibling;
-      transitionOut(nextElementFromOldLoop, () => {
-        nextElementFromOldLoopImmutable.remove();
-      }, () => {}, component);
-      nextElementFromOldLoop = nextSibling && nextSibling.__x_for_key !== undefined ? nextSibling : false;
-    }
-  }
-
-  function handleAttributeBindingDirective(component, el, attrName, expression, extraVars, attrType, modifiers) {
-    var value = component.evaluateReturnExpression(el, expression, extraVars);
-
-    if (attrName === 'value') {
-      if (Alpine.ignoreFocusedForValueBinding && document.activeElement.isSameNode(el)) return; // If nested model key is undefined, set the default value to empty string.
-
-      if (value === undefined && String(expression).match(/\./)) {
-        value = '';
-      }
-
-      if (el.type === 'radio') {
-        // Set radio value from x-bind:value, if no "value" attribute exists.
-        // If there are any initial state values, radio will have a correct
-        // "checked" value since x-bind:value is processed before x-model.
-        if (el.attributes.value === undefined && attrType === 'bind') {
-          el.value = value;
-        } else if (attrType !== 'bind') {
-          el.checked = checkedAttrLooseCompare(el.value, value);
-        }
-      } else if (el.type === 'checkbox') {
-        // If we are explicitly binding a string to the :value, set the string,
-        // If the value is a boolean, leave it alone, it will be set to "on"
-        // automatically.
-        if (typeof value !== 'boolean' && ![null, undefined].includes(value) && attrType === 'bind') {
-          el.value = String(value);
-        } else if (attrType !== 'bind') {
-          if (Array.isArray(value)) {
-            // I'm purposely not using Array.includes here because it's
-            // strict, and because of Numeric/String mis-casting, I
-            // want the "includes" to be "fuzzy".
-            el.checked = value.some(val => checkedAttrLooseCompare(val, el.value));
-          } else {
-            el.checked = !!value;
-          }
-        }
-      } else if (el.tagName === 'SELECT') {
-        updateSelect(el, value);
-      } else {
-        if (el.value === value) return;
-        el.value = value;
-      }
-    } else if (attrName === 'class') {
-      if (Array.isArray(value)) {
-        const originalClasses = el.__x_original_classes || [];
-        el.setAttribute('class', arrayUnique(originalClasses.concat(value)).join(' '));
-      } else if (typeof value === 'object') {
-        // Sorting the keys / class names by their boolean value will ensure that
-        // anything that evaluates to `false` and needs to remove classes is run first.
-        const keysSortedByBooleanValue = Object.keys(value).sort((a, b) => value[a] - value[b]);
-        keysSortedByBooleanValue.forEach(classNames => {
-          if (value[classNames]) {
-            convertClassStringToArray(classNames).forEach(className => el.classList.add(className));
-          } else {
-            convertClassStringToArray(classNames).forEach(className => el.classList.remove(className));
-          }
-        });
-      } else {
-        const originalClasses = el.__x_original_classes || [];
-        const newClasses = value ? convertClassStringToArray(value) : [];
-        el.setAttribute('class', arrayUnique(originalClasses.concat(newClasses)).join(' '));
-      }
-    } else {
-      attrName = modifiers.includes('camel') ? camelCase(attrName) : attrName; // If an attribute's bound value is null, undefined or false, remove the attribute
-
-      if ([null, undefined, false].includes(value)) {
-        el.removeAttribute(attrName);
-      } else {
-        isBooleanAttr(attrName) ? setIfChanged(el, attrName, attrName) : setIfChanged(el, attrName, value);
-      }
-    }
-  }
-
-  function setIfChanged(el, attrName, value) {
-    if (el.getAttribute(attrName) != value) {
-      el.setAttribute(attrName, value);
-    }
-  }
-
-  function updateSelect(el, value) {
-    const arrayWrappedValue = [].concat(value).map(value => {
-      return value + '';
-    });
-    Array.from(el.options).forEach(option => {
-      option.selected = arrayWrappedValue.includes(option.value);
-    });
-  }
-
-  function handleTextDirective(el, output, expression) {
-    // If nested model key is undefined, set the default value to empty string.
-    if (output === undefined && String(expression).match(/\./)) {
-      output = '';
-    }
-
-    el.textContent = output;
-  }
-
-  function handleHtmlDirective(component, el, expression, extraVars) {
-    el.innerHTML = component.evaluateReturnExpression(el, expression, extraVars);
-  }
-
-  function handleShowDirective(component, el, value, modifiers, initialUpdate = false) {
-    const hide = () => {
-      el.style.display = 'none';
-      el.__x_is_shown = false;
-    };
-
-    const show = () => {
-      if (el.style.length === 1 && el.style.display === 'none') {
-        el.removeAttribute('style');
-      } else {
-        el.style.removeProperty('display');
-      }
-
-      el.__x_is_shown = true;
-    };
-
-    if (initialUpdate === true) {
-      if (value) {
-        show();
-      } else {
-        hide();
-      }
-
-      return;
-    }
-
-    const handle = (resolve, reject) => {
-      if (value) {
-        if (el.style.display === 'none' || el.__x_transition) {
-          transitionIn(el, () => {
-            show();
-          }, reject, component);
-        }
-
-        resolve(() => {});
-      } else {
-        if (el.style.display !== 'none') {
-          transitionOut(el, () => {
-            resolve(() => {
-              hide();
-            });
-          }, reject, component);
-        } else {
-          resolve(() => {});
-        }
-      }
-    }; // The working of x-show is a bit complex because we need to
-    // wait for any child transitions to finish before hiding
-    // some element. Also, this has to be done recursively.
-    // If x-show.immediate, foregoe the waiting.
-
-
-    if (modifiers.includes('immediate')) {
-      handle(finish => finish(), () => {});
-      return;
-    } // x-show is encountered during a DOM tree walk. If an element
-    // we encounter is NOT a child of another x-show element we
-    // can execute the previous x-show stack (if one exists).
-
-
-    if (component.showDirectiveLastElement && !component.showDirectiveLastElement.contains(el)) {
-      component.executeAndClearRemainingShowDirectiveStack();
-    }
-
-    component.showDirectiveStack.push(handle);
-    component.showDirectiveLastElement = el;
-  }
-
-  function handleIfDirective(component, el, expressionResult, initialUpdate, extraVars) {
-    warnIfMalformedTemplate(el, 'x-if');
-    const elementHasAlreadyBeenAdded = el.nextElementSibling && el.nextElementSibling.__x_inserted_me === true;
-
-    if (expressionResult && (!elementHasAlreadyBeenAdded || el.__x_transition)) {
-      const clone = document.importNode(el.content, true);
-      el.parentElement.insertBefore(clone, el.nextElementSibling);
-      transitionIn(el.nextElementSibling, () => {}, () => {}, component, initialUpdate);
-      component.initializeElements(el.nextElementSibling, extraVars);
-      el.nextElementSibling.__x_inserted_me = true;
-    } else if (!expressionResult && elementHasAlreadyBeenAdded) {
-      transitionOut(el.nextElementSibling, () => {
-        el.nextElementSibling.remove();
-      }, () => {}, component, initialUpdate);
-    }
-  }
-
-  function registerListener(component, el, event, modifiers, expression, extraVars = {}) {
-    const options = {
-      passive: modifiers.includes('passive')
-    };
-
-    if (modifiers.includes('camel')) {
-      event = camelCase(event);
-    }
-
-    const node_add_count = el.__x_node_add_count;
-    let handler, listenerTarget;
-
-    if (modifiers.includes('away')) {
-      listenerTarget = document;
-
-      handler = e => {
-        // Don't do anything if the click came from the element or within it.
-        if (el.contains(e.target)) return; // Don't do anything if this element isn't currently visible.
-
-        if (el.offsetWidth < 1 && el.offsetHeight < 1) return; // Now that we are sure the element is visible, AND the click
-        // is from outside it, let's run the expression.
-
-        runListenerHandler(component, expression, e, extraVars);
-
-        if (modifiers.includes('once')) {
-          document.removeEventListener(event, handler, options);
-        }
-      };
-    } else {
-      listenerTarget = modifiers.includes('window') ? window : modifiers.includes('document') ? document : el;
-
-      handler = e => {
-        // Remove this global event handler if the element that declared it
-        // has been removed. It's now stale.
-        if (listenerTarget === window || listenerTarget === document) {
-          if (!document.body.contains(el)) {
-            listenerTarget.removeEventListener(event, handler, options);
-            return;
-          }
-        }
-
-        if (el.__x_node_add_count !== node_add_count) {
-          listenerTarget.removeEventListener(event, handler, options);
-          return;
-        }
-
-        if (isKeyEvent(event)) {
-          if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {
-            return;
-          }
-        }
-
-        if (modifiers.includes('prevent')) e.preventDefault();
-        if (modifiers.includes('stop')) e.stopPropagation(); // If the .self modifier isn't present, or if it is present and
-        // the target element matches the element we are registering the
-        // event on, run the handler
-
-        if (!modifiers.includes('self') || e.target === el) {
-          const returnValue = runListenerHandler(component, expression, e, extraVars);
-          returnValue.then(value => {
-            if (value === false) {
-              e.preventDefault();
-            } else {
-              if (modifiers.includes('once')) {
-                listenerTarget.removeEventListener(event, handler, options);
-              }
-            }
-          });
-        }
-      };
-    }
-
-    if (modifiers.includes('debounce')) {
-      let nextModifier = modifiers[modifiers.indexOf('debounce') + 1] || 'invalid-wait';
-      let wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250;
-      handler = debounce(handler, wait);
-    }
-
-    listenerTarget.addEventListener(event, handler, options);
-  }
-
-  function runListenerHandler(component, expression, e, extraVars) {
-    return component.evaluateCommandExpression(e.target, expression, () => {
-      return _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        '$event': e
-      });
-    });
-  }
-
-  function isKeyEvent(event) {
-    return ['keydown', 'keyup'].includes(event);
-  }
-
-  function isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {
-    let keyModifiers = modifiers.filter(i => {
-      return !['window', 'document', 'prevent', 'stop'].includes(i);
-    });
-
-    if (keyModifiers.includes('debounce')) {
-      let debounceIndex = keyModifiers.indexOf('debounce');
-      keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || 'invalid-wait').split('ms')[0]) ? 2 : 1);
-    } // If no modifier is specified, we'll call it a press.
-
-
-    if (keyModifiers.length === 0) return false; // If one is passed, AND it matches the key pressed, we'll call it a press.
-
-    if (keyModifiers.length === 1 && keyModifiers[0] === keyToModifier(e.key)) return false; // The user is listening for key combinations.
-
-    const systemKeyModifiers = ['ctrl', 'shift', 'alt', 'meta', 'cmd', 'super'];
-    const selectedSystemKeyModifiers = systemKeyModifiers.filter(modifier => keyModifiers.includes(modifier));
-    keyModifiers = keyModifiers.filter(i => !selectedSystemKeyModifiers.includes(i));
-
-    if (selectedSystemKeyModifiers.length > 0) {
-      const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter(modifier => {
-        // Alias "cmd" and "super" to "meta"
-        if (modifier === 'cmd' || modifier === 'super') modifier = 'meta';
-        return e[`${modifier}Key`];
-      }); // If all the modifiers selected are pressed, ...
-
-      if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
-        // AND the remaining key is pressed as well. It's a press.
-        if (keyModifiers[0] === keyToModifier(e.key)) return false;
-      }
-    } // We'll call it NOT a valid keypress.
-
-
-    return true;
-  }
-
-  function keyToModifier(key) {
-    switch (key) {
-      case '/':
-        return 'slash';
-
-      case ' ':
-      case 'Spacebar':
-        return 'space';
-
-      default:
-        return key && kebabCase(key);
-    }
-  }
-
-  function registerModelListener(component, el, modifiers, expression, extraVars) {
-    // If the element we are binding to is a select, a radio, or checkbox
-    // we'll listen for the change event instead of the "input" event.
-    var event = el.tagName.toLowerCase() === 'select' || ['checkbox', 'radio'].includes(el.type) || modifiers.includes('lazy') ? 'change' : 'input';
-    const listenerExpression = `${expression} = rightSideOfExpression($event, ${expression})`;
-    registerListener(component, el, event, modifiers, listenerExpression, () => {
-      return _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        rightSideOfExpression: generateModelAssignmentFunction(el, modifiers, expression)
-      });
-    });
-  }
-
-  function generateModelAssignmentFunction(el, modifiers, expression) {
-    if (el.type === 'radio') {
-      // Radio buttons only work properly when they share a name attribute.
-      // People might assume we take care of that for them, because
-      // they already set a shared "x-model" attribute.
-      if (!el.hasAttribute('name')) el.setAttribute('name', expression);
-    }
-
-    return (event, currentValue) => {
-      // Check for event.detail due to an issue where IE11 handles other events as a CustomEvent.
-      if (event instanceof CustomEvent && event.detail) {
-        return event.detail;
-      } else if (el.type === 'checkbox') {
-        // If the data we are binding to is an array, toggle its value inside the array.
-        if (Array.isArray(currentValue)) {
-          const newValue = modifiers.includes('number') ? safeParseNumber(event.target.value) : event.target.value;
-          return event.target.checked ? currentValue.concat([newValue]) : currentValue.filter(el => !checkedAttrLooseCompare(el, newValue));
-        } else {
-          return event.target.checked;
-        }
-      } else if (el.tagName.toLowerCase() === 'select' && el.multiple) {
-        return modifiers.includes('number') ? Array.from(event.target.selectedOptions).map(option => {
-          const rawValue = option.value || option.text;
-          return safeParseNumber(rawValue);
-        }) : Array.from(event.target.selectedOptions).map(option => {
-          return option.value || option.text;
-        });
-      } else {
-        const rawValue = event.target.value;
-        return modifiers.includes('number') ? safeParseNumber(rawValue) : modifiers.includes('trim') ? rawValue.trim() : rawValue;
-      }
-    };
-  }
-
-  function safeParseNumber(rawValue) {
-    const number = rawValue ? parseFloat(rawValue) : null;
-    return isNumeric(number) ? number : rawValue;
-  }
-
-  /**
-   * Copyright (C) 2017 salesforce.com, inc.
-   */
-  const { isArray } = Array;
-  const { getPrototypeOf, create: ObjectCreate, defineProperty: ObjectDefineProperty, defineProperties: ObjectDefineProperties, isExtensible, getOwnPropertyDescriptor, getOwnPropertyNames, getOwnPropertySymbols, preventExtensions, hasOwnProperty, } = Object;
-  const { push: ArrayPush, concat: ArrayConcat, map: ArrayMap, } = Array.prototype;
-  function isUndefined(obj) {
-      return obj === undefined;
-  }
-  function isFunction(obj) {
-      return typeof obj === 'function';
-  }
-  function isObject(obj) {
-      return typeof obj === 'object';
-  }
-  const proxyToValueMap = new WeakMap();
-  function registerProxy(proxy, value) {
-      proxyToValueMap.set(proxy, value);
-  }
-  const unwrap$1 = (replicaOrAny) => proxyToValueMap.get(replicaOrAny) || replicaOrAny;
-
-  function wrapValue(membrane, value) {
-      return membrane.valueIsObservable(value) ? membrane.getProxy(value) : value;
-  }
-  /**
-   * Unwrap property descriptors will set value on original descriptor
-   * We only need to unwrap if value is specified
-   * @param descriptor external descrpitor provided to define new property on original value
-   */
-  function unwrapDescriptor(descriptor) {
-      if (hasOwnProperty.call(descriptor, 'value')) {
-          descriptor.value = unwrap$1(descriptor.value);
-      }
-      return descriptor;
-  }
-  function lockShadowTarget(membrane, shadowTarget, originalTarget) {
-      const targetKeys = ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
-      targetKeys.forEach((key) => {
-          let descriptor = getOwnPropertyDescriptor(originalTarget, key);
-          // We do not need to wrap the descriptor if configurable
-          // Because we can deal with wrapping it when user goes through
-          // Get own property descriptor. There is also a chance that this descriptor
-          // could change sometime in the future, so we can defer wrapping
-          // until we need to
-          if (!descriptor.configurable) {
-              descriptor = wrapDescriptor(membrane, descriptor, wrapValue);
-          }
-          ObjectDefineProperty(shadowTarget, key, descriptor);
-      });
-      preventExtensions(shadowTarget);
-  }
-  class ReactiveProxyHandler {
-      constructor(membrane, value) {
-          this.originalTarget = value;
-          this.membrane = membrane;
-      }
-      get(shadowTarget, key) {
-          const { originalTarget, membrane } = this;
-          const value = originalTarget[key];
-          const { valueObserved } = membrane;
-          valueObserved(originalTarget, key);
-          return membrane.getProxy(value);
-      }
-      set(shadowTarget, key, value) {
-          const { originalTarget, membrane: { valueMutated } } = this;
-          const oldValue = originalTarget[key];
-          if (oldValue !== value) {
-              originalTarget[key] = value;
-              valueMutated(originalTarget, key);
-          }
-          else if (key === 'length' && isArray(originalTarget)) {
-              // fix for issue #236: push will add the new index, and by the time length
-              // is updated, the internal length is already equal to the new length value
-              // therefore, the oldValue is equal to the value. This is the forking logic
-              // to support this use case.
-              valueMutated(originalTarget, key);
-          }
-          return true;
-      }
-      deleteProperty(shadowTarget, key) {
-          const { originalTarget, membrane: { valueMutated } } = this;
-          delete originalTarget[key];
-          valueMutated(originalTarget, key);
-          return true;
-      }
-      apply(shadowTarget, thisArg, argArray) {
-          /* No op */
-      }
-      construct(target, argArray, newTarget) {
-          /* No op */
-      }
-      has(shadowTarget, key) {
-          const { originalTarget, membrane: { valueObserved } } = this;
-          valueObserved(originalTarget, key);
-          return key in originalTarget;
-      }
-      ownKeys(shadowTarget) {
-          const { originalTarget } = this;
-          return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
-      }
-      isExtensible(shadowTarget) {
-          const shadowIsExtensible = isExtensible(shadowTarget);
-          if (!shadowIsExtensible) {
-              return shadowIsExtensible;
-          }
-          const { originalTarget, membrane } = this;
-          const targetIsExtensible = isExtensible(originalTarget);
-          if (!targetIsExtensible) {
-              lockShadowTarget(membrane, shadowTarget, originalTarget);
-          }
-          return targetIsExtensible;
-      }
-      setPrototypeOf(shadowTarget, prototype) {
-      }
-      getPrototypeOf(shadowTarget) {
-          const { originalTarget } = this;
-          return getPrototypeOf(originalTarget);
-      }
-      getOwnPropertyDescriptor(shadowTarget, key) {
-          const { originalTarget, membrane } = this;
-          const { valueObserved } = this.membrane;
-          // keys looked up via hasOwnProperty need to be reactive
-          valueObserved(originalTarget, key);
-          let desc = getOwnPropertyDescriptor(originalTarget, key);
-          if (isUndefined(desc)) {
-              return desc;
-          }
-          const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key);
-          if (!isUndefined(shadowDescriptor)) {
-              return shadowDescriptor;
-          }
-          // Note: by accessing the descriptor, the key is marked as observed
-          // but access to the value, setter or getter (if available) cannot observe
-          // mutations, just like regular methods, in which case we just do nothing.
-          desc = wrapDescriptor(membrane, desc, wrapValue);
-          if (!desc.configurable) {
-              // If descriptor from original target is not configurable,
-              // We must copy the wrapped descriptor over to the shadow target.
-              // Otherwise, proxy will throw an invariant error.
-              // This is our last chance to lock the value.
-              // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
-              ObjectDefineProperty(shadowTarget, key, desc);
-          }
-          return desc;
-      }
-      preventExtensions(shadowTarget) {
-          const { originalTarget, membrane } = this;
-          lockShadowTarget(membrane, shadowTarget, originalTarget);
-          preventExtensions(originalTarget);
-          return true;
-      }
-      defineProperty(shadowTarget, key, descriptor) {
-          const { originalTarget, membrane } = this;
-          const { valueMutated } = membrane;
-          const { configurable } = descriptor;
-          // We have to check for value in descriptor
-          // because Object.freeze(proxy) calls this method
-          // with only { configurable: false, writeable: false }
-          // Additionally, method will only be called with writeable:false
-          // if the descriptor has a value, as opposed to getter/setter
-          // So we can just check if writable is present and then see if
-          // value is present. This eliminates getter and setter descriptors
-          if (hasOwnProperty.call(descriptor, 'writable') && !hasOwnProperty.call(descriptor, 'value')) {
-              const originalDescriptor = getOwnPropertyDescriptor(originalTarget, key);
-              descriptor.value = originalDescriptor.value;
-          }
-          ObjectDefineProperty(originalTarget, key, unwrapDescriptor(descriptor));
-          if (configurable === false) {
-              ObjectDefineProperty(shadowTarget, key, wrapDescriptor(membrane, descriptor, wrapValue));
-          }
-          valueMutated(originalTarget, key);
-          return true;
-      }
-  }
-
-  function wrapReadOnlyValue(membrane, value) {
-      return membrane.valueIsObservable(value) ? membrane.getReadOnlyProxy(value) : value;
-  }
-  class ReadOnlyHandler {
-      constructor(membrane, value) {
-          this.originalTarget = value;
-          this.membrane = membrane;
-      }
-      get(shadowTarget, key) {
-          const { membrane, originalTarget } = this;
-          const value = originalTarget[key];
-          const { valueObserved } = membrane;
-          valueObserved(originalTarget, key);
-          return membrane.getReadOnlyProxy(value);
-      }
-      set(shadowTarget, key, value) {
-          return false;
-      }
-      deleteProperty(shadowTarget, key) {
-          return false;
-      }
-      apply(shadowTarget, thisArg, argArray) {
-          /* No op */
-      }
-      construct(target, argArray, newTarget) {
-          /* No op */
-      }
-      has(shadowTarget, key) {
-          const { originalTarget, membrane: { valueObserved } } = this;
-          valueObserved(originalTarget, key);
-          return key in originalTarget;
-      }
-      ownKeys(shadowTarget) {
-          const { originalTarget } = this;
-          return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
-      }
-      setPrototypeOf(shadowTarget, prototype) {
-      }
-      getOwnPropertyDescriptor(shadowTarget, key) {
-          const { originalTarget, membrane } = this;
-          const { valueObserved } = membrane;
-          // keys looked up via hasOwnProperty need to be reactive
-          valueObserved(originalTarget, key);
-          let desc = getOwnPropertyDescriptor(originalTarget, key);
-          if (isUndefined(desc)) {
-              return desc;
-          }
-          const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key);
-          if (!isUndefined(shadowDescriptor)) {
-              return shadowDescriptor;
-          }
-          // Note: by accessing the descriptor, the key is marked as observed
-          // but access to the value or getter (if available) cannot be observed,
-          // just like regular methods, in which case we just do nothing.
-          desc = wrapDescriptor(membrane, desc, wrapReadOnlyValue);
-          if (hasOwnProperty.call(desc, 'set')) {
-              desc.set = undefined; // readOnly membrane does not allow setters
-          }
-          if (!desc.configurable) {
-              // If descriptor from original target is not configurable,
-              // We must copy the wrapped descriptor over to the shadow target.
-              // Otherwise, proxy will throw an invariant error.
-              // This is our last chance to lock the value.
-              // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
-              ObjectDefineProperty(shadowTarget, key, desc);
-          }
-          return desc;
-      }
-      preventExtensions(shadowTarget) {
-          return false;
-      }
-      defineProperty(shadowTarget, key, descriptor) {
-          return false;
-      }
-  }
-  function createShadowTarget(value) {
-      let shadowTarget = undefined;
-      if (isArray(value)) {
-          shadowTarget = [];
-      }
-      else if (isObject(value)) {
-          shadowTarget = {};
-      }
-      return shadowTarget;
-  }
-  const ObjectDotPrototype = Object.prototype;
-  function defaultValueIsObservable(value) {
-      // intentionally checking for null
-      if (value === null) {
-          return false;
-      }
-      // treat all non-object types, including undefined, as non-observable values
-      if (typeof value !== 'object') {
-          return false;
-      }
-      if (isArray(value)) {
-          return true;
-      }
-      const proto = getPrototypeOf(value);
-      return (proto === ObjectDotPrototype || proto === null || getPrototypeOf(proto) === null);
-  }
-  const defaultValueObserved = (obj, key) => {
-      /* do nothing */
-  };
-  const defaultValueMutated = (obj, key) => {
-      /* do nothing */
-  };
-  const defaultValueDistortion = (value) => value;
-  function wrapDescriptor(membrane, descriptor, getValue) {
-      const { set, get } = descriptor;
-      if (hasOwnProperty.call(descriptor, 'value')) {
-          descriptor.value = getValue(membrane, descriptor.value);
-      }
-      else {
-          if (!isUndefined(get)) {
-              descriptor.get = function () {
-                  // invoking the original getter with the original target
-                  return getValue(membrane, get.call(unwrap$1(this)));
-              };
-          }
-          if (!isUndefined(set)) {
-              descriptor.set = function (value) {
-                  // At this point we don't have a clear indication of whether
-                  // or not a valid mutation will occur, we don't have the key,
-                  // and we are not sure why and how they are invoking this setter.
-                  // Nevertheless we preserve the original semantics by invoking the
-                  // original setter with the original target and the unwrapped value
-                  set.call(unwrap$1(this), membrane.unwrapProxy(value));
-              };
-          }
-      }
-      return descriptor;
-  }
-  class ReactiveMembrane {
-      constructor(options) {
-          this.valueDistortion = defaultValueDistortion;
-          this.valueMutated = defaultValueMutated;
-          this.valueObserved = defaultValueObserved;
-          this.valueIsObservable = defaultValueIsObservable;
-          this.objectGraph = new WeakMap();
-          if (!isUndefined(options)) {
-              const { valueDistortion, valueMutated, valueObserved, valueIsObservable } = options;
-              this.valueDistortion = isFunction(valueDistortion) ? valueDistortion : defaultValueDistortion;
-              this.valueMutated = isFunction(valueMutated) ? valueMutated : defaultValueMutated;
-              this.valueObserved = isFunction(valueObserved) ? valueObserved : defaultValueObserved;
-              this.valueIsObservable = isFunction(valueIsObservable) ? valueIsObservable : defaultValueIsObservable;
-          }
-      }
-      getProxy(value) {
-          const unwrappedValue = unwrap$1(value);
-          const distorted = this.valueDistortion(unwrappedValue);
-          if (this.valueIsObservable(distorted)) {
-              const o = this.getReactiveState(unwrappedValue, distorted);
-              // when trying to extract the writable version of a readonly
-              // we return the readonly.
-              return o.readOnly === value ? value : o.reactive;
-          }
-          return distorted;
-      }
-      getReadOnlyProxy(value) {
-          value = unwrap$1(value);
-          const distorted = this.valueDistortion(value);
-          if (this.valueIsObservable(distorted)) {
-              return this.getReactiveState(value, distorted).readOnly;
-          }
-          return distorted;
-      }
-      unwrapProxy(p) {
-          return unwrap$1(p);
-      }
-      getReactiveState(value, distortedValue) {
-          const { objectGraph, } = this;
-          let reactiveState = objectGraph.get(distortedValue);
-          if (reactiveState) {
-              return reactiveState;
-          }
-          const membrane = this;
-          reactiveState = {
-              get reactive() {
-                  const reactiveHandler = new ReactiveProxyHandler(membrane, distortedValue);
-                  // caching the reactive proxy after the first time it is accessed
-                  const proxy = new Proxy(createShadowTarget(distortedValue), reactiveHandler);
-                  registerProxy(proxy, value);
-                  ObjectDefineProperty(this, 'reactive', { value: proxy });
-                  return proxy;
-              },
-              get readOnly() {
-                  const readOnlyHandler = new ReadOnlyHandler(membrane, distortedValue);
-                  // caching the readOnly proxy after the first time it is accessed
-                  const proxy = new Proxy(createShadowTarget(distortedValue), readOnlyHandler);
-                  registerProxy(proxy, value);
-                  ObjectDefineProperty(this, 'readOnly', { value: proxy });
-                  return proxy;
-              }
-          };
-          objectGraph.set(distortedValue, reactiveState);
-          return reactiveState;
-      }
-  }
-  /** version: 0.26.0 */
-
-  function wrap(data, mutationCallback) {
-
-    let membrane = new ReactiveMembrane({
-      valueMutated(target, key) {
-        mutationCallback(target, key);
-      }
-
-    });
-    return {
-      data: membrane.getProxy(data),
-      membrane: membrane
-    };
-  }
-  function unwrap(membrane, observable) {
-    let unwrappedData = membrane.unwrapProxy(observable);
-    let copy = {};
-    Object.keys(unwrappedData).forEach(key => {
-      if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return;
-      copy[key] = unwrappedData[key];
-    });
-    return copy;
-  }
-
-  class Component {
-    constructor(el, componentForClone = null) {
-      this.$el = el;
-      const dataAttr = this.$el.getAttribute('x-data');
-      const dataExpression = dataAttr === '' ? '{}' : dataAttr;
-      let dataExtras = {
-        $el: this.$el
-      };
-      let canonicalComponentElementReference = componentForClone ? componentForClone.$el : this.$el;
-      Object.entries(Alpine.magicProperties).forEach(([name, callback]) => {
-        Object.defineProperty(dataExtras, `$${name}`, {
-          get: function get() {
-            return callback(canonicalComponentElementReference);
-          }
-        });
-      });
-      this.unobservedData = componentForClone ? componentForClone.getUnobservedData() : saferEval(el, dataExpression, dataExtras);
-      // Construct a Proxy-based observable. This will be used to handle reactivity.
-
-      let {
-        membrane,
-        data
-      } = this.wrapDataInObservable(this.unobservedData);
-      this.$data = data;
-      this.membrane = membrane; // After making user-supplied data methods reactive, we can now add
-      // our magic properties to the original data for access.
-
-      this.unobservedData.$el = this.$el;
-      this.unobservedData.$refs = this.getRefsProxy();
-      this.nextTickStack = [];
-
-      this.unobservedData.$nextTick = callback => {
-        this.nextTickStack.push(callback);
-      };
-
-      this.watchers = {};
-
-      this.unobservedData.$watch = (property, callback) => {
-        if (!this.watchers[property]) this.watchers[property] = [];
-        this.watchers[property].push(callback);
-      };
-      /* MODERN-ONLY:START */
-      // We remove this piece of code from the legacy build.
-      // In IE11, we have already defined our helpers at this point.
-      // Register custom magic properties.
-
-
-      Object.entries(Alpine.magicProperties).forEach(([name, callback]) => {
-        Object.defineProperty(this.unobservedData, `$${name}`, {
-          get: function get() {
-            return callback(canonicalComponentElementReference, this.$el);
-          }
-        });
-      });
-      /* MODERN-ONLY:END */
-
-      this.showDirectiveStack = [];
-      this.showDirectiveLastElement;
-      componentForClone || Alpine.onBeforeComponentInitializeds.forEach(callback => callback(this));
-      const initExpression = this.$el.getAttribute('x-init');
-      var initReturnedCallback; // If x-init is present AND we aren't cloning (skip x-init on clone)
-
-      if (initExpression && !componentForClone) {
-        // We want to allow data manipulation, but not trigger DOM updates just yet.
-        // We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
-        this.pauseReactivity = true;
-        initReturnedCallback = this.evaluateReturnExpression(this.$el, initExpression);
-        this.pauseReactivity = false;
-      } // Register all our listeners and set all our attribute bindings.
-      // If we're cloning a component, the third parameter ensures no duplicate
-      // event listeners are registered (the mutation observer will take care of them)
-
-
-      this.initializeElements(this.$el, () => {}, componentForClone); // Use mutation observer to detect new elements being added within this component at run-time.
-      // Alpine's just so darn flexible amirite?
-
-      this.listenForNewElementsToInitialize();
-
-      if (typeof initReturnedCallback === 'function') {
-        // Run the callback returned from the "x-init" hook to allow the user to do stuff after
-        // Alpine's got it's grubby little paws all over everything.
-        initReturnedCallback.call(this.$data);
-      }
-
-      componentForClone || setTimeout(() => {
-        Alpine.onComponentInitializeds.forEach(callback => callback(this));
-      }, 0);
-    }
-
-    getUnobservedData() {
-      return unwrap(this.membrane, this.$data);
-    }
-
-    wrapDataInObservable(data) {
-      var self = this;
-      let updateDom = debounce(function () {
-        self.updateElements(self.$el);
-      }, 0);
-      return wrap(data, (target, key) => {
-        if (self.watchers[key]) {
-          // If there's a watcher for this specific key, run it.
-          self.watchers[key].forEach(callback => callback(target[key]));
-        } else if (Array.isArray(target)) {
-          // Arrays are special cases, if any of the items change, we consider the array as mutated.
-          Object.keys(self.watchers).forEach(fullDotNotationKey => {
-            let dotNotationParts = fullDotNotationKey.split('.'); // Ignore length mutations since they would result in duplicate calls.
-            // For example, when calling push, we would get a mutation for the item's key
-            // and a second mutation for the length property.
-
-            if (key === 'length') return;
-            dotNotationParts.reduce((comparisonData, part) => {
-              if (Object.is(target, comparisonData[part])) {
-                self.watchers[fullDotNotationKey].forEach(callback => callback(target));
-              }
-
-              return comparisonData[part];
-            }, self.unobservedData);
-          });
-        } else {
-          // Let's walk through the watchers with "dot-notation" (foo.bar) and see
-          // if this mutation fits any of them.
-          Object.keys(self.watchers).filter(i => i.includes('.')).forEach(fullDotNotationKey => {
-            let dotNotationParts = fullDotNotationKey.split('.'); // If this dot-notation watcher's last "part" doesn't match the current
-            // key, then skip it early for performance reasons.
-
-            if (key !== dotNotationParts[dotNotationParts.length - 1]) return; // Now, walk through the dot-notation "parts" recursively to find
-            // a match, and call the watcher if one's found.
-
-            dotNotationParts.reduce((comparisonData, part) => {
-              if (Object.is(target, comparisonData)) {
-                // Run the watchers.
-                self.watchers[fullDotNotationKey].forEach(callback => callback(target[key]));
-              }
-
-              return comparisonData[part];
-            }, self.unobservedData);
-          });
-        } // Don't react to data changes for cases like the `x-created` hook.
-
-
-        if (self.pauseReactivity) return;
-        updateDom();
-      });
-    }
-
-    walkAndSkipNestedComponents(el, callback, initializeComponentCallback = () => {}) {
-      walk(el, el => {
-        // We've hit a component.
-        if (el.hasAttribute('x-data')) {
-          // If it's not the current one.
-          if (!el.isSameNode(this.$el)) {
-            // Initialize it if it's not.
-            if (!el.__x) initializeComponentCallback(el); // Now we'll let that sub-component deal with itself.
-
-            return false;
-          }
-        }
-
-        return callback(el);
-      });
-    }
-
-    initializeElements(rootEl, extraVars = () => {}, componentForClone = false) {
-      this.walkAndSkipNestedComponents(rootEl, el => {
-        // Don't touch spawns from for loop
-        if (el.__x_for_key !== undefined) return false; // Don't touch spawns from if directives
-
-        if (el.__x_inserted_me !== undefined) return false;
-        this.initializeElement(el, extraVars, componentForClone ? false : true);
-      }, el => {
-        if (!componentForClone) el.__x = new Component(el);
-      });
-      this.executeAndClearRemainingShowDirectiveStack();
-      this.executeAndClearNextTickStack(rootEl);
-    }
-
-    initializeElement(el, extraVars, shouldRegisterListeners = true) {
-      // To support class attribute merging, we have to know what the element's
-      // original class attribute looked like for reference.
-      if (el.hasAttribute('class') && getXAttrs(el, this).length > 0) {
-        el.__x_original_classes = convertClassStringToArray(el.getAttribute('class'));
-      }
-
-      shouldRegisterListeners && this.registerListeners(el, extraVars);
-      this.resolveBoundAttributes(el, true, extraVars);
-    }
-
-    updateElements(rootEl, extraVars = () => {}) {
-      this.walkAndSkipNestedComponents(rootEl, el => {
-        // Don't touch spawns from for loop (and check if the root is actually a for loop in a parent, don't skip it.)
-        if (el.__x_for_key !== undefined && !el.isSameNode(this.$el)) return false;
-        this.updateElement(el, extraVars);
-      }, el => {
-        el.__x = new Component(el);
-      });
-      this.executeAndClearRemainingShowDirectiveStack();
-      this.executeAndClearNextTickStack(rootEl);
-    }
-
-    executeAndClearNextTickStack(el) {
-      // Skip spawns from alpine directives
-      if (el === this.$el && this.nextTickStack.length > 0) {
-        // We run the tick stack after the next frame to allow any
-        // running transitions to pass the initial show stage.
-        requestAnimationFrame(() => {
-          while (this.nextTickStack.length > 0) {
-            this.nextTickStack.shift()();
-          }
-        });
-      }
-    }
-
-    executeAndClearRemainingShowDirectiveStack() {
-      // The goal here is to start all the x-show transitions
-      // and build a nested promise chain so that elements
-      // only hide when the children are finished hiding.
-      this.showDirectiveStack.reverse().map(handler => {
-        return new Promise((resolve, reject) => {
-          handler(resolve, reject);
-        });
-      }).reduce((promiseChain, promise) => {
-        return promiseChain.then(() => {
-          return promise.then(finishElement => {
-            finishElement();
-          });
-        });
-      }, Promise.resolve(() => {})).catch(e => {
-        if (e !== TRANSITION_CANCELLED) throw e;
-      }); // We've processed the handler stack. let's clear it.
-
-      this.showDirectiveStack = [];
-      this.showDirectiveLastElement = undefined;
-    }
-
-    updateElement(el, extraVars) {
-      this.resolveBoundAttributes(el, false, extraVars);
-    }
-
-    registerListeners(el, extraVars) {
-      getXAttrs(el, this).forEach(({
-        type,
-        value,
-        modifiers,
-        expression
-      }) => {
-        switch (type) {
-          case 'on':
-            registerListener(this, el, value, modifiers, expression, extraVars);
-            break;
-
-          case 'model':
-            registerModelListener(this, el, modifiers, expression, extraVars);
-            break;
-        }
-      });
-    }
-
-    resolveBoundAttributes(el, initialUpdate = false, extraVars) {
-      let attrs = getXAttrs(el, this);
-      attrs.forEach(({
-        type,
-        value,
-        modifiers,
-        expression
-      }) => {
-        switch (type) {
-          case 'model':
-            handleAttributeBindingDirective(this, el, 'value', expression, extraVars, type, modifiers);
-            break;
-
-          case 'bind':
-            // The :key binding on an x-for is special, ignore it.
-            if (el.tagName.toLowerCase() === 'template' && value === 'key') return;
-            handleAttributeBindingDirective(this, el, value, expression, extraVars, type, modifiers);
-            break;
-
-          case 'text':
-            var output = this.evaluateReturnExpression(el, expression, extraVars);
-            handleTextDirective(el, output, expression);
-            break;
-
-          case 'html':
-            handleHtmlDirective(this, el, expression, extraVars);
-            break;
-
-          case 'show':
-            var output = this.evaluateReturnExpression(el, expression, extraVars);
-            handleShowDirective(this, el, output, modifiers, initialUpdate);
-            break;
-
-          case 'if':
-            // If this element also has x-for on it, don't process x-if.
-            // We will let the "x-for" directive handle the "if"ing.
-            if (attrs.some(i => i.type === 'for')) return;
-            var output = this.evaluateReturnExpression(el, expression, extraVars);
-            handleIfDirective(this, el, output, initialUpdate, extraVars);
-            break;
-
-          case 'for':
-            handleForDirective(this, el, expression, initialUpdate, extraVars);
-            break;
-
-          case 'cloak':
-            el.removeAttribute('x-cloak');
-            break;
-        }
-      });
-    }
-
-    evaluateReturnExpression(el, expression, extraVars = () => {}) {
-      return saferEval(el, expression, this.$data, _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        $dispatch: this.getDispatchFunction(el)
-      }));
-    }
-
-    evaluateCommandExpression(el, expression, extraVars = () => {}) {
-      return saferEvalNoReturn(el, expression, this.$data, _objectSpread2(_objectSpread2({}, extraVars()), {}, {
-        $dispatch: this.getDispatchFunction(el)
-      }));
-    }
-
-    getDispatchFunction(el) {
-      return (event, detail = {}) => {
-        el.dispatchEvent(new CustomEvent(event, {
-          detail,
-          bubbles: true
-        }));
-      };
-    }
-
-    listenForNewElementsToInitialize() {
-      const targetNode = this.$el;
-      const observerOptions = {
-        childList: true,
-        attributes: true,
-        subtree: true
-      };
-      const observer = new MutationObserver(mutations => {
-        for (let i = 0; i < mutations.length; i++) {
-          // Filter out mutations triggered from child components.
-          const closestParentComponent = mutations[i].target.closest('[x-data]');
-          if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) continue;
-
-          if (mutations[i].type === 'attributes' && mutations[i].attributeName === 'x-data') {
-            const xAttr = mutations[i].target.getAttribute('x-data') || '{}';
-            const rawData = saferEval(this.$el, xAttr, {
-              $el: this.$el
-            });
-            Object.keys(rawData).forEach(key => {
-              if (this.$data[key] !== rawData[key]) {
-                this.$data[key] = rawData[key];
-              }
-            });
-          }
-
-          if (mutations[i].addedNodes.length > 0) {
-            mutations[i].addedNodes.forEach(node => {
-              if (node.nodeType !== 1 || node.__x_inserted_me) return;
-
-              if (node.matches('[x-data]') && !node.__x) {
-                node.__x = new Component(node);
-                return;
-              }
-
-              node.__x_node_add_count = (node.__x_node_add_count || 0) + 1;
-              this.initializeElements(node);
-            });
-          }
-        }
-      });
-      observer.observe(targetNode, observerOptions);
-    }
-
-    getRefsProxy() {
-      var self = this;
-      var refObj = {};
-      // One of the goals of this is to not hold elements in memory, but rather re-evaluate
-      // the DOM when the system needs something from it. This way, the framework is flexible and
-      // friendly to outside DOM changes from libraries like Vue/Livewire.
-      // For this reason, I'm using an "on-demand" proxy to fake a "$refs" object.
-
-      return new Proxy(refObj, {
-        get(object, property) {
-          if (property === '$isAlpineProxy') return true;
-          var ref; // We can't just query the DOM because it's hard to filter out refs in
-          // nested components.
-
-          self.walkAndSkipNestedComponents(self.$el, el => {
-            if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
-              ref = el;
-            }
-          });
-          return ref;
-        }
-
-      });
-    }
-
-  }
-
-  const Alpine = {
-    version: "2.8.2",
-    pauseMutationObserver: false,
-    magicProperties: {},
-    onComponentInitializeds: [],
-    onBeforeComponentInitializeds: [],
-    ignoreFocusedForValueBinding: false,
-    start: async function start() {
-      if (!isTesting()) {
-        await domReady();
-      }
-
-      this.discoverComponents(el => {
-        this.initializeComponent(el);
-      }); // It's easier and more performant to just support Turbolinks than listen
-      // to MutationObserver mutations at the document level.
-
-      document.addEventListener("turbolinks:load", () => {
-        this.discoverUninitializedComponents(el => {
-          this.initializeComponent(el);
-        });
-      });
-      this.listenForNewUninitializedComponentsAtRunTime();
-    },
-    discoverComponents: function discoverComponents(callback) {
-      const rootEls = document.querySelectorAll('[x-data]');
-      rootEls.forEach(rootEl => {
-        callback(rootEl);
-      });
-    },
-    discoverUninitializedComponents: function discoverUninitializedComponents(callback, el = null) {
-      const rootEls = (el || document).querySelectorAll('[x-data]');
-      Array.from(rootEls).filter(el => el.__x === undefined).forEach(rootEl => {
-        callback(rootEl);
-      });
-    },
-    listenForNewUninitializedComponentsAtRunTime: function listenForNewUninitializedComponentsAtRunTime() {
-      const targetNode = document.querySelector('body');
-      const observerOptions = {
-        childList: true,
-        attributes: true,
-        subtree: true
-      };
-      const observer = new MutationObserver(mutations => {
-        if (this.pauseMutationObserver) return;
-
-        for (let i = 0; i < mutations.length; i++) {
-          if (mutations[i].addedNodes.length > 0) {
-            mutations[i].addedNodes.forEach(node => {
-              // Discard non-element nodes (like line-breaks)
-              if (node.nodeType !== 1) return; // Discard any changes happening within an existing component.
-              // They will take care of themselves.
-
-              if (node.parentElement && node.parentElement.closest('[x-data]')) return;
-              this.discoverUninitializedComponents(el => {
-                this.initializeComponent(el);
-              }, node.parentElement);
-            });
-          }
-        }
-      });
-      observer.observe(targetNode, observerOptions);
-    },
-    initializeComponent: function initializeComponent(el) {
-      if (!el.__x) {
-        // Wrap in a try/catch so that we don't prevent other components
-        // from initializing when one component contains an error.
-        try {
-          el.__x = new Component(el);
-        } catch (error) {
-          setTimeout(() => {
-            throw error;
-          }, 0);
-        }
-      }
-    },
-    clone: function clone(component, newEl) {
-      if (!newEl.__x) {
-        newEl.__x = new Component(newEl, component);
-      }
-    },
-    addMagicProperty: function addMagicProperty(name, callback) {
-      this.magicProperties[name] = callback;
-    },
-    onComponentInitialized: function onComponentInitialized(callback) {
-      this.onComponentInitializeds.push(callback);
-    },
-    onBeforeComponentInitialized: function onBeforeComponentInitialized(callback) {
-      this.onBeforeComponentInitializeds.push(callback);
-    }
-  };
-
-  if (!isTesting()) {
-    window.Alpine = Alpine;
-
-    if (window.deferLoadingAlpine) {
-      window.deferLoadingAlpine(function () {
-        window.Alpine.start();
-      });
-    } else {
-      window.Alpine.start();
-    }
-  }
-
-  return Alpine;
-
-})));

+ 0 - 116
examples/card-game.html

@@ -1,116 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>Document</title>
-    <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
-    <script src="/dist/alpine.js" defer></script>
-    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
-</head>
-
-<body>
-    <!-- Memory Game -->
-    <div x-data="game()" class="px-10 flex items-center justify-center min-h-screen">
-        <h1 class="fixed top-0 right-0 p-10 font-bold text-3xl">
-            <span x-text="points"></span>
-            <span class="text-xs">pts</span>
-        </h1>
-
-        <div class="flex-1 grid grid-cols-4 gap-10">
-            <template x-for="(card, index) in cards" :key="index">
-                <div>
-                    <button x-show="! card.cleared"
-                            :style="'background: ' + (card.flipped ? card.color : '#999')"
-                            :disabled="flippedCards.length >= 2"
-                            class="w-full h-32"
-                            @click="flipCard(card)"
-                    >
-                    </button>
-                </div>
-            </template>
-        </div>
-    </div>
-
-    <!-- Flash Message -->
-    <div x-data="{ show: false, message: '' }"
-         x-show.transition.opacity="show"
-         x-text="message"
-         @flash.window="
-            message = $event.detail.message;
-            show = true;
-            setTimeout(() => show = false, 1000)
-        "
-         class="fixed bottom-0 right-0 bg-green-500 text-white p-2 mb-4 mr-4 rounded"
-    >
-    </div>
-
-    <script>
-        function pause(milliseconds = 1000) {
-            return new Promise(resolve => setTimeout(resolve, milliseconds));
-        }
-
-        function flash(message) {
-            window.dispatchEvent(new CustomEvent('flash', {
-                detail: { message }
-            }));
-        }
-
-        function game() {
-            return {
-                cards: [
-                    { color: 'green', flipped: false, cleared: false },
-                    { color: 'red', flipped: false, cleared: false },
-                    { color: 'blue', flipped: false, cleared: false },
-                    { color: 'yellow', flipped: false, cleared: false },
-                    { color: 'green', flipped: false, cleared: false },
-                    { color: 'red', flipped: false, cleared: false },
-                    { color: 'blue', flipped: false, cleared: false },
-                    { color: 'yellow', flipped: false, cleared: false },
-                ].sort(() => Math.random() - .5),
-
-                get flippedCards() {
-                    return this.cards.filter(card => card.flipped);
-                },
-
-                get clearedCards() {
-                    return this.cards.filter(card => card.cleared);
-                },
-
-                get remainingCards() {
-                    return this.cards.filter(card => ! card.cleared);
-                },
-
-                get points() {
-                    return this.clearedCards.length;
-                },
-
-                async flipCard(card) {
-                    card.flipped = ! card.flipped;
-
-                    if (this.flippedCards.length !== 2) return;
-
-                    if (this.hasMatch()) {
-                        flash('You found a match!');
-
-                        await pause();
-
-                        this.flippedCards.forEach(card => card.cleared = true);
-
-                        if (! this.remainingCards.length) {
-                            alert('You Won!');
-                        }
-                    } else {
-                        await pause();
-                    }
-
-                    this.flippedCards.forEach(card => card.flipped = false);
-                },
-
-                hasMatch() {
-                    return this.flippedCards[0]['color'] === this.flippedCards[1]['color'];
-                }
-            };
-        }
-    </script>
-</body>
-</html>

+ 0 - 507
examples/index.html

@@ -1,507 +0,0 @@
-<html>
-    <head>
-        <meta charset="utf-8"/>
-        <style>
-            .hidden { display: none; }
-            [x-cloak] { display: none; }
-            .opacity-0 { opacity: 0; }
-            .opacity-100 { opacity: 1; }
-            .transition-slow { transition-duration: 300ms; }
-            .transition-medium { transition-duration: 200ms; }
-            .transition-faster { transition-duration: 100ms; }
-            .scale-90 { transform: scale(0.9); }
-            .scale-100 { transform: scale(1); }
-            .ease-in { transition-timing-function: cubic-bezier(0.4, 0, 1, 1); }
-            .ease-out { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); }
-
-            /** Thanks Animate.css */
-            .animation {animation-duration: 1000ms; --animate-duration: 1000ms; }
-            @keyframes jackInTheBox {
-                from { opacity: 0; transform: scale(0.1) rotate(30deg); transform-origin: center bottom; }
-                50% { transform: rotate(-10deg); }
-                70% { transform: rotate(3deg); }
-                to { opacity: 1; transform: scale(1); }
-            }
-            @keyframes hinge {
-                0% {animation-timing-function: ease-in-out;}
-                20%, 60% { transform: rotate3d(0, 0, 1, 80deg); animation-timing-function: ease-in-out; }
-                40%, 80% { transform: rotate3d(0, 0, 1, 60deg); animation-timing-function: ease-in-out; opacity: 1; }
-                to { transform: translate3d(0, 700px, 0); opacity: 0; }
-            }
-            .jackInTheBox {animation-name: jackInTheBox;}
-            .hinge {
-                animation-duration: calc(var(--animate-duration) * 2);
-                animation-name: hinge;
-                transform-origin: top left;
-            }
-        </style>
-
-        <script src="/dist/alpine.js" defer></script>
-        <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
-    </head>
-    <body>
-        <table>
-            <thead>
-                <tr>
-                    <th>Feature</th>
-                    <th>Demo</th>
-                </tr>
-            </thead>
-            <tbody>
-                <tr>
-                    <td>Broken Components</td>
-                    <td>
-                        <div x-data="some.bad.expression()">I'm a broken component</div>
-                        <button x-data x-on:click="something()">I break on click</button>
-                        <div x-data x-spread="not.good">Broken x-spread</div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Simple x-if</td>
-                    <td>
-                        <div x-data="{ show: false }">
-                            <template x-if="show">
-                                <span>hey</span>
-                            </template>
-
-                            <button @click="show = ! show">Show</button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Dropdown</td>
-                    <td>
-                        <div x-data="{ open: false }">
-                            <button x-on:click="open= true">Open Dropdown</button>
-                            <ul
-                                x-bind:class="{ 'hidden': ! open }"
-                                x-on:click.away="open= false"
-                                x-cloak>
-                                Dropdown Body
-                            </ul>6
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Tabs</td>
-                    <td>
-                        <div x-data="{ currentTab: 'tab1' }">
-                            <button x-bind:class="{ 'active': currentTab ===
-                                'tab1' }" x-on:click="currentTab= 'tab1'">Foo</button>
-                            <button x-bind:class="{ 'active': currentTab ===
-                                'tab2' }" x-on:click="currentTab= 'tab2'">Bar</button>
-                            <div x-bind:class="{ 'hidden': currentTab !== 'tab1'
-                                }">Tab Foo</div>
-                            <div class="hidden" x-bind:class="{ 'hidden':
-                                currentTab !== 'tab2' }">Tab Bar</div>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Data Binding</td>
-                    <td>
-                        <div x-data="{ text: 'foo', checkbox: ['foo'], radio:
-                            'foo', select: 'foo', 'multiselect': ['foo'] }">
-                            Text:
-                            <span x-text="JSON.stringify(text)"></span>
-                            <input type="text" x-model="text">
-                            Checkbox:
-                            <span x-text="JSON.stringify(checkbox)"></span>
-                            <input type="checkbox" x-model="checkbox"
-                                value="foo">
-                                <input type="checkbox" x-model="checkbox"
-                                :value="0">
-                            <input type="checkbox" x-model="checkbox"
-                                value="bar">
-                            Radio:
-                            <span x-text="JSON.stringify(radio)"></span>
-                            <input type="radio" x-model="radio" value="foo">
-                            <input type="radio" x-model="radio" value="bar">
-                            Select:
-                            <span x-text="JSON.stringify(select)"></span>
-                            <select x-model="select">
-                                <option>foo</option>
-                                <option>bar</option>
-                            </select>
-                            Multiple Select:
-                            <span x-text="JSON.stringify(multiselect)"></span>
-                            <select x-model="multiselect" multiple>
-                                <option>foo</option>
-                                <option>bar</option>
-                            </select>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Cast to number</td>
-                    <td>
-                        <div x-data="{ number: 1 }">
-                            <div x-text="JSON.stringify($data.number)"></div>
-                            <input type="text" x-model.number="number">
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Nested Binding</td>
-                    <td>
-                        <div x-data="{ foo: { bar: 'baz' } }">
-                            <div x-text="foo.bar"></div>
-                            <input type="text" x-model="foo.bar">
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>On Click</td>
-                    <td>
-                        <div x-data="{ show: false }">
-                            <div x-show="show">Hi There!</div>
-
-                            <button x-on:click="show= ! show">Show/Hide</button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Refs</td>
-                    <td>
-                        <div x-data="{ someText: 'bar' }">
-                            <div x-ref="remove-target">Remove Me</div>
-
-                            <button
-                                x-on:click="$refs['remove-target'].remove()">Remove</button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-on:click.stop</td>
-                    <td>
-                        <div x-data="{ someText: 'bar' }">
-                            <span x-text="someText"></span>
-
-                            <div x-on:click="someText= 'baz'">
-                                <button x-on:click.stop>Shouldn't change to baz</button>
-                            </div>
-
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-on:click (with return false)</td>
-                    <td>
-                        <div x-data>
-                            <label for="checkbox-frozen">I should be frozen on un-checked</label>
-                            <input id="checkbox-frozen" type="checkbox" @click="return false"></input>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-on:click.prevent</td>
-                    <td>
-                        <div x-data="{}">
-                            <a href="https://google.com" x-on:click.prevent>Shouldn't
-                                go to Google</a>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-on:click.once</td>
-                    <td>
-                        <div x-data="{ count: 0 }">
-                            <button x-on:click.once="count++">I've been clicked:
-                                <span x-text="count"></span></button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Append DOM</td>
-                    <td>
-                        <div id="goHere">Click me.</div>
-                        <script>
-                            const thing = document.querySelector('#goHere')
-                            const handler = (e) => {
-                                thing.removeEventListener('click', handler)
-
-                                const div = document.createElement('div')
-                                div.setAttribute('x-data', '{hey: "there"}')
-                                div.innerHTML = '<input type="text" x-model="hey"><h1 x-text="hey"></h1>'
-                                e.target.appendChild(div)
-                            }
-
-                            var listener = thing.addEventListener('click', handler)
-                        </script>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Append Nested DOM</td>
-                    <td>
-                        <div id="goHere2">Click me.</div>
-                        <script>
-                            const thing2 = document.querySelector('#goHere2')
-                            const handler2 = (e) => {
-                                thing2.removeEventListener('click', handler2)
-
-                                e.target.innerHTML = `
-                                    <article>
-                                        <div x-data="{hey: 'there'}">
-                                            <input type="text" x-model="hey"><h1 x-text="hey"></h1>
-                                        </div>
-                                    </article>
-                                `
-                            }
-
-                            var listener = thing2.addEventListener('click', handler2)
-                        </script>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-for</td>
-                    <td>
-                        <div x-data="{ items: ['foo', 'bar'], foo: 'bar' }">
-                            <input type="checkbox" x-model="items" value="foo">
-                            <input type="checkbox" x-model="items" value="bar">
-                            <input type="checkbox" x-model="items" value="baz">
-
-                            <button @click="items = ['bar', 'bob']">hey</button>
-
-                            <template x-for="item in items" :key="item">
-                                <div x-text="item" x-transition:enter-start="opacity-0 scale-90"
-                                    x-transition:enter="ease-out transition-medium"
-                                    x-transition:enter-end="opacity-100 scale-100"
-                                    x-transition:leave-start="opacity-100 scale-100"
-                                    x-transition:leave="ease-in transition-faster"
-                                    x-transition:leave-end="opacity-0 scale-90"
-                                ></div>
-                            </template>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Nested x-for</td>
-                    <td>
-                        <div x-data="{ foos: [{bars: [{bobs: ['one', 'two']}, {bobs: ['three', 'four']}]}, {bars: [{bobs: ['five', 'six']}, {bobs: ['seven', 'eight']}]}] }">
-                            <template x-for="foo in foos">
-                                <div>
-                                    <template x-for="bar in foo.bars">
-                                        <div>
-                                            <template x-for="bob in bar.bobs">
-                                                <span x-text="bob"></span>
-                                            </template>
-                                        </div>
-                                    </template>
-                                </div>
-                            </template>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-for over a range using <code>i in 10</code> syntax</td>
-                    <td>
-                        <div x-data>
-                            <template x-for="i in 10" :key="i">
-                                <span x-text="i"></span>
-                            </template>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-for over a range using <code>i in 10</code> syntax and data property</td>
-                    <td>
-                        <div x-data="{ count: 10 }">
-                            <template x-for="i in count" :key="i">
-                                <span x-text="i"></span>
-                            </template>
-                            <button type="button" @click="count++">Increment count</button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Transitions</td>
-                    <td>
-                        <div x-data="{ open: false }">
-                            <button x-on:click="open= ! open">
-                                Open Modal
-                            </button>
-
-                            <div x-show="open"
-                                x-transition:enter="transition-medium"
-                                x-transition:leave="transition-medium">
-                                <div x-show="open"
-                                    x-transition:enter="transition-medium"
-                                    x-transition:enter-start="opacity-0"
-                                    x-transition:leave-end="opacity-0"
-                                    x-transition:leave="transition-medium"></div>
-                                <div x-show="open"
-                                    x-transition:enter-start="opacity-0 scale-90"
-                                    x-transition:enter="ease-out transition-medium"
-                                    x-transition:enter-end="opacity-100 scale-100"
-                                    x-transition:leave-start="opacity-100 scale-100"
-                                    x-transition:leave="ease-in transition-faster"
-                                    x-transition:leave-end="opacity-0 scale-90">
-                                    <div>
-                                        hey
-                                    </div>
-                                    <div>
-                                        <button x-on:click="open= false" type="button">
-                                            Cancel
-                                        </button>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>CSS animations</td>
-                    <td>
-                        <div x-data="{ open: false }">
-                            <button x-on:click="open= ! open">
-                                Open Modal
-                            </button>
-
-                            <div x-show="open"
-                                x-transition:enter="animation jackInTheBox"
-                                x-transition:leave="animation hinge">
-                                    <div>
-                                        hey
-                                    </div>
-                                    <div>
-                                        <button x-on:click="open= false" type="button">
-                                            Cancel
-                                        </button>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Transitions (with x-if)</td>
-                    <td>
-                        <div x-data="{ open: false }">
-                            <button x-on:click="open= ! open">
-                                Open Modal
-                            </button>
-
-                            <template x-if="open">
-                                    <div x-transition:enter-start="opacity-0 scale-90"
-                                    x-transition:enter="ease-out transition-medium"
-                                    x-transition:enter-end="opacity-100 scale-100"
-                                    x-transition:leave-start="opacity-100 scale-100"
-                                    x-transition:leave="ease-in transition-faster"
-                                    x-transition:leave-end="opacity-0 scale-90">
-                                        hey
-                                    </div>
-                            </template>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Nested Transitions (with x-show)</td>
-                    <td>
-                        <div x-data="{ open: false }">
-                            <button x-on:click="open= ! open">
-                                Open Modal
-                            </button>
-
-                            <div x-show="open">
-                                I shouldn't leave until the transition finishes.
-                                <div x-show="open"
-                                    x-transition:leave-start="opacity-100 scale-100"
-                                    x-transition:leave="ease-in transition-slow"
-                                    x-transition:leave-end="opacity-0 scale-90">
-                                        I'm transitioning
-                                </div>
-                            </div>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Init function callback access refs and mutate data</td>
-                    <td>
-                        <div x-data="initialData()" x-init="init()">
-                            <div :style="'width: '+width+'px; background: purple;'">hey</div>
-
-                            <button x-ref="inc">increase</button>
-                        </div>
-
-                        <script>
-                            function initialData() {
-                                return {
-                                    width: 20,
-                                    init() {
-                                        this.$refs.inc.addEventListener('click', () => {
-                                            this.width = this.width + 20
-                                        })
-                                    }
-                                }
-                            }
-                        </script>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Dispatch</td>
-                    <td>
-                        <div x-data="{ foo: 'bar' }" x-on:custom-event="foo = $event.detail.newValue">
-                            <span x-text="foo"></span>
-
-                            <button x-on:click="$dispatch('custom-event', {newValue: 'baz'})">Turn 'bar' to 'baz'</button>
-                        </div>
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>x-bind spread</td>
-                    <td>
-                        <div x-data="modal()">
-                            I should be "hey": <span x-spread="bound"></span>
-                        </div>
-
-                        <script>
-                            function modal() {
-                               return {
-                                   foo: { bar: 'hey' },
-                                   bound: {
-                                       ['x-text']() { return this.foo.bar }
-                                   },
-                               }
-                            }
-                        </script>
-
-                    </td>
-                </tr>
-
-                <tr>
-                    <td>Cloak</td>
-                    <td>
-                        <div x-data="{}" x-cloak>
-                            I'm cloaked
-                        </div>
-                    </td>
-                </tr>
-            </tbody>
-        </table>
-    </body>
-</html>

+ 0 - 97
examples/tags.html

@@ -1,97 +0,0 @@
-<html>
-    <head>
-        <meta charset="utf-8"/>
-        <style>
-        .tags-input {
-        display: flex;
-        flex-wrap: wrap;
-        background-color: #fff;
-        border-width: 1px;
-        border-radius: .25rem;
-        padding-left: .5rem;
-        padding-right: 1rem;
-        padding-top: .5rem;
-        padding-bottom: .25rem;
-        }
-
-        .tags-input-tag {
-        display: inline-flex;
-        line-height: 1;
-        align-items: center;
-        font-size: .875rem;
-        background-color: #bcdefa;
-        color: #1c3d5a;
-        border-radius: .25rem;
-        user-select: none;
-        padding: .25rem;
-        margin-right: .5rem;
-        margin-bottom: .25rem;
-        }
-
-        .tags-input-tag:last-of-type {
-        margin-right: 0;
-        }
-
-        .tags-input-remove {
-        color: #2779bd;
-        font-size: 1.125rem;
-        line-height: 1;
-        }
-
-        .tags-input-remove:first-child {
-        margin-right: .25rem;
-        }
-
-        .tags-input-remove:last-child {
-        margin-left: .25rem;
-        }
-
-        .tags-input-remove:focus {
-        outline: 0;
-        }
-
-        .tags-input-text {
-        flex: 1;
-        outline: 0;
-        padding-top: .25rem;
-        padding-bottom: .25rem;
-        margin-left: .5rem;
-        margin-bottom: .25rem;
-        min-width: 10rem;
-        }
-
-        .py-16 {
-        padding-top: 4rem;
-        padding-bottom: 4rem;
-    }
-    </style>
-        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/0.5.1/tailwind.css">
-        <script src="/dist/alpine.js" defer></script>
-    </head>
-    <body>
-<div x-data="{tags: ['hey'], newTag: '' }" class="bg-grey-lighter px-8 py-16 min-h-screen">
-    <template x-for="tag in tags">
-        <input type="hidden" name="tags[]" :value="tag">
-    </template>
-
-    <div class="max-w-sm w-full mx-auto">
-        <div class="tags-input">
-            <template x-for="tag in tags" :key="tag">
-                <span class="tags-input-tag">
-                    <span x-text="tag"></span>
-                    <button type="button" class="tags-input-remove" @click="tags = tags.filter(i => i !== tag)">
-                        &times;
-                    </button>
-                </span>
-            </template>
-
-            <input class="tags-input-text" placeholder="Add tag..."
-                @keydown.enter.prevent="if (newTag.trim() !== '') tags.push(newTag.trim()); newTag = ''"
-                @keydown.backspace="if (newTag.trim() === '') tags.pop()"
-                x-model="newTag"
-            >
-        </div>
-    </div>
-</div>
-    </body>
-</html>

+ 10 - 0
index.html

@@ -0,0 +1,10 @@
+<html>
+    <script src="/packages/intersect/dist/cdn.js" defer></script>
+    <script src="/packages/morph/dist/cdn.js" defer></script>
+    <script src="/packages/history/dist/cdn.js"></script>
+    <script src="/packages/persist/dist/cdn.js"></script>
+    <script src="/packages/trap/dist/cdn.js"></script>
+    <script src="/packages/alpinejs/dist/cdn.js" defer></script>
+
+    <!-- Play around. -->
+</html>

+ 0 - 10
inject-version-readme.js

@@ -1,10 +0,0 @@
-// Replace pinned version in README to latest (per package.json version field)
-const fs = require('fs');
-const pkg = require('./package.json');
-
-const readmeTranslations = fs.readdirSync('.').filter((name) => name.includes('README'))
-readmeTranslations.forEach((readmeName) => {
-    const original = fs.readFileSync(readmeName, 'utf8')
-    const updated = original.replace(/[0-9]+\.[0-9]+\.[0-9]+/gi, pkg.version)
-    fs.writeFileSync(readmeName, updated, 'utf8')
-})

+ 4 - 185
jest.config.js

@@ -1,186 +1,5 @@
-// For a detailed explanation regarding each configuration property, visit:
-// https://jestjs.io/docs/en/configuration.html
+let config = {
+    rootDir: './tests/jest',
+}
 
-module.exports = {
-    // All imported modules in your tests should be mocked automatically
-    // automock: false,
-
-    // Stop running tests after `n` failures
-    // bail: 0,
-
-    // Respect "browser" field in package.json when resolving modules
-    // browser: false,
-
-    // The directory where Jest should store its cached dependency information
-    // cacheDirectory: "/private/var/folders/p8/t_s1ktjx6qqczfcrb5jpn30c0000gn/T/jest_dx",
-
-    // Automatically clear mock calls and instances between every test
-    clearMocks: true,
-
-    // Indicates whether the coverage information should be collected while executing the test
-    // collectCoverage: false,
-
-    // An array of glob patterns indicating a set of files for which coverage information should be collected
-    // collectCoverageFrom: null,
-
-    // The directory where Jest should output its coverage files
-    // coverageDirectory: null,
-
-    // An array of regexp pattern strings used to skip coverage collection
-    // coveragePathIgnorePatterns: [
-    //   "/node_modules/"
-    // ],
-
-    // A list of reporter names that Jest uses when writing coverage reports
-    // coverageReporters: [
-    //   "json",
-    //   "text",
-    //   "lcov",
-    //   "clover"
-    // ],
-
-    // An object that configures minimum threshold enforcement for coverage results
-    // coverageThreshold: null,
-
-    // A path to a custom dependency extractor
-    // dependencyExtractor: null,
-
-    // Make calling deprecated APIs throw helpful error messages
-    // errorOnDeprecated: false,
-
-    // Force coverage collection from ignored files usin a array of glob patterns
-    // forceCoverageMatch: [],
-
-    // A path to a module which exports an async function that is triggered once before all test suites
-    // globalSetup: null,
-
-    // A path to a module which exports an async function that is triggered once after all test suites
-    // globalTeardown: null,
-
-    // A set of global variables that need to be available in all test environments
-    // globals: {},
-
-    // An array of directory names to be searched recursively up from the requiring module's location
-    moduleDirectories: [
-      "node_modules",
-      "src/js"
-    ],
-
-    // An array of file extensions your modules use
-    // moduleFileExtensions: [
-    //   "js",
-    //   "json",
-    //   "jsx",
-    //   "ts",
-    //   "tsx",
-    //   "node"
-    // ],
-
-    // A map from regular expressions to module names that allow to stub out resources with a single module
-    // moduleNameMapper: {},
-
-    // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
-    // modulePathIgnorePatterns: [],
-
-    // Activates notifications for test results
-    notify: true,
-
-    // An enum that specifies notification mode. Requires { notify: true }
-    // notifyMode: "failure-change",
-
-    // A preset that is used as a base for Jest's configuration
-    // preset: null,
-
-    // Run tests from one or more projects
-    // projects: null,
-
-    // Use this configuration option to add custom reporters to Jest
-    // reporters: undefined,
-
-    // Automatically reset mock state between every test
-    // resetMocks: false,
-
-    // Reset the module registry before running each individual test
-    // resetModules: false,
-
-    // A path to a custom resolver
-    // resolver: null,
-
-    // Automatically restore mock state between every test
-    // restoreMocks: false,
-
-    // The root directory that Jest should scan for tests and modules within
-    // rootDir: null,
-
-    // A list of paths to directories that Jest should use to search for files in
-    // roots: [
-    //   "<rootDir>"
-    // ],
-
-    // Allows you to use a custom runner instead of Jest's default test runner
-    // runner: "jest-runner",
-
-    // The paths to modules that run some code to configure or set up the testing environment before each test
-    // setupFiles: [],
-
-    // A list of paths to modules that run some code to configure or set up the testing framework before each test
-    // setupFilesAfterEnv: [],
-
-    // A list of paths to snapshot serializer modules Jest should use for snapshot testing
-    // snapshotSerializers: [],
-
-    // The test environment that will be used for testing
-    // testEnvironment: "jest-environment-jsdom",
-
-    // Options that will be passed to the testEnvironment
-    // testEnvironmentOptions: {},
-
-    // Adds a location field to test results
-    // testLocationInResults: false,
-
-    // The glob patterns Jest uses to detect test files
-    // testMatch: [
-    //   "**/__tests__/**/*.[jt]s?(x)",
-    //   "**/?(*.)+(spec|test).[tj]s?(x)"
-    // ],
-
-    // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
-    // testPathIgnorePatterns: [
-    //   "/node_modules/"
-    // ],
-
-    // The regexp pattern or array of patterns that Jest uses to detect test files
-    // testRegex: [],
-
-    // This option allows the use of a custom results processor
-    // testResultsProcessor: null,
-
-    // This option allows use of a custom test runner
-    // testRunner: "jasmine2",
-
-    // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
-    // testURL: "http://localhost",
-
-    // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
-    // timers: "real",
-
-    // A map from regular expressions to paths to transformers
-    // transform: null,
-
-    // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
-    // transformIgnorePatterns: [
-    //   "/node_modules/"
-    // ],
-
-    // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
-    // unmockedModulePathPatterns: undefined,
-
-    // Indicates whether each individual test should be reported during the run
-    // verbose: null,
-
-    // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
-    // watchPathIgnorePatterns: [],
-
-    // Whether to use watchman for file crawling
-    // watchman: true,
-  };
+module.exports = config

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4380 - 4746
package-lock.json


+ 17 - 42
package.json

@@ -1,46 +1,21 @@
 {
-    "main": "dist/alpine.js",
-    "name": "alpinejs",
-    "version": "2.8.2",
-    "repository": {
-        "type": "git",
-        "url": "git://github.com/alpinejs/alpine.git"
-    },
-    "scripts": {
-        "watch": "rollup -c -w",
-        "build": "concurrently \"rollup -c\" \"npx rollup -c rollup-ie11.config.js\" \"node inject-version-readme\"",
-        "test": "npx jest",
-        "test:debug": "node --inspect node_modules/.bin/jest --runInBand"
-    },
-    "author": "Caleb Porzio",
-    "license": "MIT",
+    "private": true,
+    "workspaces": [
+        "packages/*"
+    ],
     "devDependencies": {
-        "@babel/core": "^7.12.10",
-        "@babel/preset-env": "^7.12.11",
-        "@rollup/plugin-commonjs": "^11.1.0",
-        "@rollup/plugin-multi-entry": "^3.0.1",
-        "@rollup/plugin-replace": "^2.3.4",
-        "@testing-library/dom": "^6.16.0",
-        "@testing-library/jest-dom": "^4.2.4",
-        "@webcomponents/template": "^1.4.4",
-        "babel-jest": "^25.5.1",
-        "classlist-polyfill": "^1.2.0",
-        "concurrently": "^5.3.0",
-        "core-js": "^3.8.3",
-        "element-closest": "^3.0.2",
-        "element-remove": "^1.0.4",
-        "events-polyfill": "^2.1.2",
-        "jest": "^25.5.4",
-        "jsdom-simulant": "^1.1.2",
-        "observable-membrane": "^0.26.1",
-        "proxy-polyfill": "^0.3.2",
-        "rollup": "^2.45.2",
-        "rollup-plugin-babel": "^4.4.0",
-        "rollup-plugin-filesize": "^9.1.1",
-        "rollup-plugin-node-resolve": "^5.2.0",
-        "rollup-plugin-strip-code": "^0.2.7",
-        "rollup-plugin-terser": "^7.0.2",
-        "shim-selected-options": "^1.0.1"
+        "brotli-size": "^4.0.0",
+        "cypress": "^5.5.0",
+        "cypress-plugin-tab": "^1.0.5",
+        "dot-json": "^1.2.2",
+        "esbuild": "^0.8.39",
+        "jest": "^26.6.3"
     },
-    "dependencies": {}
+    "scripts": {
+        "build": "node ./scripts/build.js",
+        "watch": "node ./scripts/build.js --watch",
+        "test": "jest test && cypress run",
+        "cypress": "cypress open",
+        "jest": "jest test"
+    }
 }

+ 7 - 0
packages/alpinejs/builds/cdn.js

@@ -0,0 +1,7 @@
+import Alpine from './../src/index'
+
+window.Alpine = Alpine
+
+queueMicrotask(() => {
+    Alpine.start()
+})

+ 3 - 0
packages/alpinejs/builds/module.js

@@ -0,0 +1,3 @@
+import Alpine from './../src/index'
+
+export default Alpine

+ 12 - 0
packages/alpinejs/package.json

@@ -0,0 +1,12 @@
+{
+    "name": "alpinejs",
+    "version": "3.0.0-alpha.0",
+    "description": "The rugged, minimal JavaScript framework",
+    "author": "Caleb Porzio",
+    "license": "MIT",
+    "main": "dist/module.cjs.js",
+    "module": "dist/module.esm.js",
+    "dependencies": {
+        "@vue/reactivity": "^3.0.2"
+    }
+}

+ 40 - 0
packages/alpinejs/src/alpine.js

@@ -0,0 +1,40 @@
+import { setReactivityEngine, reactive, effect, release, raw } from './reactivity'
+import { mapAttributes, directive, setPrefix as prefix } from './directives'
+import { setEvaluator, evaluate, evaluateLater } from './evaluator'
+import { start, addRootSelector, closestRoot } from './lifecycle'
+import { interceptor } from './interceptor'
+import { mutateDom } from './mutation'
+import { nextTick } from './nextTick'
+import { plugin } from './plugin'
+import { magic } from './magics'
+import { store } from './store'
+import { clone } from './clone'
+import { data } from './datas'
+
+let Alpine = {
+    get reactive() { return reactive },
+    get release() { return release },
+    get effect() { return effect },
+    get raw() { return raw },
+    version: ALPINE_VERSION,
+    setReactivityEngine,
+    addRootSelector,
+    mapAttributes,
+    evaluateLater,
+    setEvaluator,
+    closestRoot,
+    interceptor,
+    mutateDom,
+    directive,
+    evaluate,
+    nextTick,
+    prefix,
+    plugin,
+    magic,
+    store,
+    start,
+    clone,
+    data,
+}
+
+export default Alpine

+ 63 - 0
packages/alpinejs/src/clone.js

@@ -0,0 +1,63 @@
+import { effect, release, overrideEffect } from "./reactivity"
+import { initTree, isRoot } from "./lifecycle"
+import { walk } from "./utils/walk"
+
+let isCloning = false
+
+export function skipDuringClone(callback) {
+    return (...args) => isCloning || callback(...args)
+}
+
+export function onlyDuringClone(callback) {
+    return (...args) => isCloning && callback(...args)
+}
+
+export function skipWalkingSubClone(callback) {
+    return (...args) => isCloning || callback(...args)
+}
+
+export function interuptCrawl(callback) {
+    return (...args) => isCloning || callback(...args)
+}
+
+export function clone(oldEl, newEl) {
+    newEl._x_dataStack = oldEl._x_dataStack
+
+    isCloning = true
+
+    dontRegisterReactiveSideEffects(() => {
+        cloneTree(newEl)
+    })
+
+    isCloning = false
+}
+
+export function cloneTree(el) {
+    let hasRunThroughFirstEl = false
+
+    let shallowWalker = (el, callback) => {
+        walk(el, (el, skip) => {
+            if (hasRunThroughFirstEl && isRoot(el)) return skip()
+
+            hasRunThroughFirstEl = true
+
+            callback(el, skip)
+        })
+    }
+
+    initTree(el, shallowWalker)
+}
+
+function dontRegisterReactiveSideEffects(callback) {
+    let cache = effect
+
+    overrideEffect((callback, el) => {
+        let storedEffect = cache(callback)
+
+        release(storedEffect)
+    })
+
+    callback()
+
+    overrideEffect(cache)
+}

+ 10 - 0
packages/alpinejs/src/datas.js

@@ -0,0 +1,10 @@
+
+let datas = {}
+
+export function data(name, callback) {
+    datas[name] = callback
+}
+
+export function getNamedDataProvider(name) {
+    return datas[name]
+}

+ 164 - 0
packages/alpinejs/src/directives.js

@@ -0,0 +1,164 @@
+import { onAttributeRemoved, onElRemoved } from './mutation'
+import { evaluate, evaluateLater } from './evaluator'
+import { elementBoundEffect } from './reactivity'
+import Alpine from './alpine'
+
+let prefixAsString = 'x-'
+
+export function prefix(subject = '') {
+    return prefixAsString + subject
+}
+
+export function setPrefix(newPrefix) {
+    prefixAsString = newPrefix
+}
+
+let directiveHandlers = {}
+
+export function directive(name, callback) {
+    directiveHandlers[name] = callback
+}
+
+export function directives(el, attributes, originalAttributeOverride) {
+    let transformedAttributeMap = {}
+
+    let directives = Array.from(attributes)
+        .map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName))
+        .filter(outNonAlpineAttributes)
+        .map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride))
+        .sort(byPriority)
+
+    return directives.map(directive => {
+        return getDirectiveHandler(el, directive)
+    })
+}
+
+let isDeferringHandlers = false
+let directiveHandlerStack = []
+
+export function deferHandlingDirectives(callback) {
+    isDeferringHandlers = true
+
+    let flushHandlers = () => {
+        while (directiveHandlerStack.length) directiveHandlerStack.shift()()
+    }
+
+    let stopDeferring = () => { isDeferringHandlers = false; flushHandlers() }
+
+    callback(flushHandlers)
+
+    stopDeferring()
+}
+
+export function getDirectiveHandler(el, directive) {
+    let noop = () => {}
+
+    let handler = directiveHandlers[directive.type] || noop
+
+    let cleanups = []
+
+    let cleanup = callback => cleanups.push(callback)
+
+    let [effect, cleanupEffect] = elementBoundEffect(el)
+
+    cleanups.push(cleanupEffect)
+
+    let utilities = {
+        Alpine,
+        effect,
+        cleanup,
+        evaluateLater: evaluateLater.bind(evaluateLater, el),
+        evaluate: evaluate.bind(evaluate, el),
+    }
+
+    let doCleanup = () => cleanups.forEach(i => i())
+
+    onAttributeRemoved(el, directive.original, doCleanup)
+
+    let fullHandler = () => {
+        if (el._x_ignore || el._x_ignore_self) return
+
+        handler.inline && handler.inline(el, directive, utilities)
+
+        handler = handler.bind(handler, el, directive, utilities)
+
+        isDeferringHandlers ? directiveHandlerStack.push(handler) : handler()
+    }
+
+    fullHandler.runCleanups = doCleanup
+
+    return fullHandler
+}
+
+export let startingWith = (subject, replacement) => ({ name, value }) => {
+    if (name.startsWith(subject)) name = name.replace(subject, replacement)
+
+    return { name, value }
+}
+
+export let into = i => i
+
+function toTransformedAttributes(callback) {
+    return ({ name, value }) => {
+        let { name: newName, value: newValue } = attributeTransformers.reduce((carry, transform) => {
+            return transform(carry)
+        }, { name, value })
+
+        if (newName !== name) callback(newName, name)
+
+        return { name: newName, value: newValue }
+    }
+}
+
+let attributeTransformers = []
+
+export function mapAttributes(callback) {
+    attributeTransformers.push(callback)
+}
+
+function outNonAlpineAttributes({ name }) {
+    return alpineAttributeRegex().test(name)
+}
+
+let alpineAttributeRegex = () => (new RegExp(`^${prefixAsString}([^:^.]+)\\b`))
+
+function toParsedDirectives(transformedAttributeMap, originalAttributeOverride) {
+    return ({ name, value }) => {
+        let typeMatch = name.match(alpineAttributeRegex())
+        let valueMatch = name.match(/:([a-zA-Z0-9\-:]+)/)
+        let modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []
+        let original = originalAttributeOverride || transformedAttributeMap[name] || name
+
+        return {
+            type: typeMatch ? typeMatch[1] : null,
+            value: valueMatch ? valueMatch[1] : null,
+            modifiers: modifiers.map(i => i.replace('.', '')),
+            expression: value,
+            original,
+        }
+    }
+}
+
+const DEFAULT = 'DEFAULT'
+
+let directiveOrder = [
+    'ignore',
+    'ref',
+    'data',
+    'bind',
+    'init',
+    'for',
+    'model',
+    'transition',
+    'show',
+    'if',
+    DEFAULT,
+    'element',
+]
+
+function byPriority(a, b) {
+    let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type
+    let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type
+
+    return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB)
+}

+ 14 - 0
packages/alpinejs/src/directives/index.js

@@ -0,0 +1,14 @@
+import './x-transition'
+import './x-ignore'
+import './x-effect'
+import './x-model'
+import './x-cloak'
+import './x-init'
+import './x-text'
+import './x-bind'
+import './x-data'
+import './x-show'
+import './x-for'
+import './x-ref'
+import './x-if'
+import './x-on'

+ 43 - 0
packages/alpinejs/src/directives/x-bind.js

@@ -0,0 +1,43 @@
+import { directive, directives, into, mapAttributes, prefix, startingWith } from '../directives'
+import { evaluateLater } from '../evaluator'
+import { mutateDom } from '../mutation'
+import bind from '../utils/bind'
+
+mapAttributes(startingWith(':', into(prefix('bind:'))))
+
+directive('bind', (el, { value, modifiers, expression, original }, { effect }) => {
+    if (! value) return applyBindingsObject(el, expression, original, effect)
+
+    if (value === 'key') return storeKeyForXFor(el, expression)
+
+    let evaluate = evaluateLater(el, expression)
+
+    effect(() => evaluate(result => {
+        mutateDom(() => bind(el, value, result, modifiers))
+    }))
+})
+
+function applyBindingsObject(el, expression, original, effect) {
+    let getBindings = evaluateLater(el, expression)
+
+    let cleanupRunners = []
+
+    effect(() => {
+        while (cleanupRunners.length) cleanupRunners.pop()()
+
+        getBindings(bindings => {
+            let attributes = Object.entries(bindings).map(([name, value]) => ({ name, value }))
+
+            directives(el, attributes, original).map(handle => {
+                cleanupRunners.push(handle.runCleanups)
+
+                handle()
+            })
+        })
+
+    })
+}
+
+function storeKeyForXFor(el, expression) {
+    el._x_key_expression = expression
+}

+ 5 - 0
packages/alpinejs/src/directives/x-cloak.js

@@ -0,0 +1,5 @@
+import { directive, prefix } from '../directives'
+import { mutateDom } from '../mutation'
+import { nextTick } from '../nextTick'
+
+directive('cloak', el => nextTick(() => mutateDom(() => el.removeAttribute(prefix('cloak')))))

+ 43 - 0
packages/alpinejs/src/directives/x-data.js

@@ -0,0 +1,43 @@
+import { directive, prefix } from '../directives'
+import { initInterceptors } from '../interceptor'
+import { getNamedDataProvider } from '../datas'
+import { addRootSelector } from '../lifecycle'
+import { skipDuringClone } from '../clone'
+import { addScopeToNode } from '../scope'
+import { injectMagics } from '../magics'
+import { reactive } from '../reactivity'
+import { evaluate } from '../evaluator'
+
+addRootSelector(() => `[${prefix('data')}]`)
+
+directive('data', skipDuringClone((el, { expression }, { cleanup }) => {
+    expression = expression === '' ? '{}' : expression
+
+    let dataProvider = getNamedDataProvider(expression)
+
+    let data = {}
+
+    if (dataProvider) {
+        let magics = injectMagics({}, el)
+
+        data = dataProvider.bind(magics)()
+    } else {
+        data = evaluate(el, expression)
+    }
+
+    initInterceptors(data)
+
+    injectMagics(data, el)
+
+    let reactiveData = reactive(data)
+
+    let undo = addScopeToNode(el, reactiveData)
+
+    if (reactiveData['init']) reactiveData['init']()
+
+    cleanup(() => {
+        undo()
+
+        reactiveData['destroy'] && reactiveData['destroy']()
+    })
+}))

+ 4 - 0
packages/alpinejs/src/directives/x-effect.js

@@ -0,0 +1,4 @@
+import { directive } from '../directives'
+import { evaluateLater } from '../evaluator'
+
+directive('effect', (el, { expression }, { effect }) => effect(evaluateLater(el, expression)))

+ 249 - 0
packages/alpinejs/src/directives/x-for.js

@@ -0,0 +1,249 @@
+import { addScopeToNode, refreshScope } from '../scope'
+import { evaluateLater } from '../evaluator'
+import { directive } from '../directives'
+import { reactive } from '../reactivity'
+import { initTree } from '../lifecycle'
+import { mutateDom } from '../mutation'
+import { flushJobs } from '../scheduler'
+
+directive('for', (el, { expression }, { effect, cleanup }) => {
+    let iteratorNames = parseForExpression(expression)
+
+    let evaluateItems = evaluateLater(el, iteratorNames.items)
+    let evaluateKey = evaluateLater(el,
+        // the x-bind:key expression is stored for our use instead of evaluated.
+        el._x_key_expression || 'index'
+    )
+
+    el._x_prev_keys = []
+    el._x_lookup = {}
+
+    effect(() => loop(el, iteratorNames, evaluateItems, evaluateKey))
+
+    cleanup(() => {
+        Object.values(el._x_lookup).forEach(el => el.remove())
+
+        delete el._x_prev_keys
+        delete el._x_lookup
+    })
+})
+
+let shouldFastRender = true
+
+function loop(el, iteratorNames, evaluateItems, evaluateKey) {
+    let isObject = i => typeof i === 'object' && ! Array.isArray(i)
+    let templateEl = el
+
+    evaluateItems(items => {
+        // Prepare yourself. There's a lot going on here. Take heart,
+        // every bit of complexity in this function was added for
+        // the purpose of making Alpine fast with large datas.
+
+        // Support number literals. Ex: x-for="i in 100"
+        if (isNumeric(items) && items >= 0) {
+            items = Array.from(Array(items).keys(), i => i + 1)
+        }
+
+        let lookup = el._x_lookup
+        let prevKeys = el._x_prev_keys
+        let scopes = []
+        let keys = []
+
+        // In order to preserve DOM elements (move instead of replace)
+        // we need to generate all the keys for every iteration up
+        // front. These will be our source of truth for diffing.
+        if (isObject(items)) {
+            items = Object.entries(items).map(([key, value]) => {
+                let scope = getIterationScopeVariables(iteratorNames, value, key, items)
+
+                evaluateKey(value => keys.push(value), { scope: { index: key, ...scope} })
+
+                scopes.push(scope)
+            })
+        } else {
+            for (let i = 0; i < items.length; i++) {
+                let scope = getIterationScopeVariables(iteratorNames, items[i], i, items)
+
+                evaluateKey(value => keys.push(value), { scope: { index: i, ...scope} })
+
+                scopes.push(scope)
+            }
+        }
+
+        // Rather than making DOM manipulations inside one large loop, we'll
+        // instead track which mutations need to be made in the following
+        // arrays. After we're finished, we can batch them at the end.
+        let adds = []
+        let moves = []
+        let removes = []
+        let sames = []
+
+        // First, we track elements that will need to be removed.
+        for (let i = 0; i < prevKeys.length; i++) {
+            let key = prevKeys[i]
+
+            if (keys.indexOf(key) === -1) removes.push(key)
+        }
+
+        // Notice we're mutating prevKeys as we go. This makes it
+        // so that we can efficiently make incremental comparisons.
+        prevKeys = prevKeys.filter(key => ! removes.includes(key))
+
+        let lastKey = 'template'
+
+        // This is the important part of the diffing algo. Identifying
+        // which keys (future DOM elements) are new, which ones have
+        // or haven't moved (noting where they moved to / from).
+        for (let i = 0; i < keys.length; i++) {
+            let key = keys[i]
+
+            let prevIndex = prevKeys.indexOf(key)
+
+            if (prevIndex === -1) {
+                // New key found.
+                prevKeys.splice(i, 0, key)
+
+                adds.push([lastKey, i])
+            } else if (prevIndex !== i) {
+                // A key has moved.
+                let keyInSpot = prevKeys.splice(i, 1)[0]
+                let keyForSpot = prevKeys.splice(prevIndex - 1, 1)[0]
+
+                prevKeys.splice(i, 0, keyForSpot)
+                prevKeys.splice(prevIndex, 0, keyInSpot)
+
+                moves.push([keyInSpot, keyForSpot])
+            } else {
+                // This key hasn't moved, but we'll still keep track
+                // so that we can refresh it later on.
+                sames.push(key)
+            }
+
+            lastKey = key
+        }
+
+        // Now that we've done the diffing work, we can apply the mutations
+        // in batches for both seperating types work and optimizing
+        // for browser performance.
+
+        // We'll remove all the nodes that need to be removed,
+        // letting the mutation observer pick them up and
+        // clean up any side effects they had.
+        for (let i = 0; i < removes.length; i++) {
+            let key = removes[i]
+
+            lookup[key].remove()
+
+            lookup[key] = null
+            delete lookup[key]
+        }
+
+        // Here we'll move elements around, skiping
+        // mutation observer triggers by using "mutateDom".
+        for (let i = 0; i < moves.length; i++) {
+            let [keyInSpot, keyForSpot] = moves[i]
+
+            let elInSpot = lookup[keyInSpot]
+            let elForSpot = lookup[keyForSpot]
+
+            let marker = document.createElement('div')
+
+            mutateDom(() => {
+                elForSpot.after(marker)
+                elInSpot.after(elForSpot)
+                marker.before(elInSpot)
+                marker.remove()
+            })
+
+            refreshScope(elForSpot, scopes[keys.indexOf(keyForSpot)])
+        }
+
+        // We can now create and add new elements. They will get picked up
+        // by the mutation observer and get initialized by Alpine.
+        for (let i = 0; i < adds.length; i++) {
+            let [lastKey, index] = adds[i]
+
+            let lastEl = (lastKey === 'template') ? templateEl : lookup[lastKey]
+
+            let scope = scopes[index]
+            let key = keys[index]
+
+            let clone = document.importNode(templateEl.content, true).firstElementChild
+
+            addScopeToNode(clone, reactive(scope), templateEl)
+
+            initTree(clone)
+
+            mutateDom(() => {
+                lastEl.after(clone)
+            })
+
+            lookup[key] = clone
+        }
+
+        // If an element hasn't changed, we still want to "refresh" the
+        // data it depends on in case the data has changed in an
+        // "unobservable" way.
+        for (let i = 0; i < sames.length; i++) {
+            refreshScope(lookup[sames[i]], scopes[keys.indexOf(sames[i])])
+        }
+
+        // Now we'll log the keys (and the order they're in) for comparing
+        // against next time.
+        templateEl._x_prev_keys = keys
+    })
+}
+
+// This was taken from VueJS 2.* core. Thanks Vue!
+function parseForExpression(expression) {
+    let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
+    let stripParensRE = /^\(|\)$/g
+    let forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
+    let inMatch = expression.match(forAliasRE)
+
+    if (! inMatch) return
+
+    let res = {}
+    res.items = inMatch[2].trim()
+    let item = inMatch[1].trim().replace(stripParensRE, '')
+    let iteratorMatch = item.match(forIteratorRE)
+
+    if (iteratorMatch) {
+        res.item = item.replace(forIteratorRE, '').trim()
+        res.index = iteratorMatch[1].trim()
+
+        if (iteratorMatch[2]) {
+            res.collection = iteratorMatch[2].trim()
+        }
+    } else {
+        res.item = item
+    }
+
+    return res
+}
+
+function getIterationScopeVariables(iteratorNames, item, index, items) {
+    // We must create a new object, so each iteration has a new scope
+    let scopeVariables = {}
+
+    // Support array destructuring ([foo, bar]).
+    if (/^\[.*\]$/.test(iteratorNames.item) && Array.isArray(item)) {
+        let names = iteratorNames.item.replace('[', '').replace(']', '').split(',').map(i => i.trim())
+
+        names.forEach((name, i) => {
+            scopeVariables[name] = item[i]
+        })
+    } else {
+        scopeVariables[iteratorNames.item] = item
+    }
+
+    if (iteratorNames.index) scopeVariables[iteratorNames.index] = index
+
+    if (iteratorNames.collection) scopeVariables[iteratorNames.collection] = items
+
+    return scopeVariables
+}
+
+function isNumeric(subject){
+    return ! Array.isArray(subject) && ! isNaN(subject)
+}

+ 30 - 0
packages/alpinejs/src/directives/x-if.js

@@ -0,0 +1,30 @@
+import { evaluateLater } from '../evaluator'
+import { setStyles } from '../utils/styles'
+import { directive } from '../directives'
+import { once } from '../utils/once'
+
+directive('if', (el, { modifiers, expression }, { effect, cleanup }) => {
+    let evaluate = evaluateLater(el, expression)
+
+    let show = () => {
+        if (el._x_currentIfEl) return el._x_currentIfEl
+
+        let clone = el.content.cloneNode(true).firstElementChild
+
+        el.after(clone)
+
+        el._x_currentIfEl = clone
+
+        el._x_undoIf = () => { clone.remove(); delete el._x_currentIfEl }
+
+        return clone
+    }
+
+    let hide = () => el._x_undoIf?.() || delete el._x_undoIf
+
+    effect(() => evaluate(value => {
+        value ? show() : hide()
+    }))
+
+    cleanup(() => el._x_undoIf && el._x_undoIf())
+})

+ 17 - 0
packages/alpinejs/src/directives/x-ignore.js

@@ -0,0 +1,17 @@
+import { directive } from "../directives"
+
+let handler = () => {}
+
+handler.inline = (el, { modifiers }, { cleanup }) => {
+    modifiers.includes('self')
+        ? el._x_ignore_self = true
+        : el._x_ignore = true
+
+    cleanup(() => {
+        modifiers.includes('self')
+            ? delete el._x_ignore_self
+            : delete el._x_ignore
+    })
+}
+
+directive('ignore', handler)

+ 8 - 0
packages/alpinejs/src/directives/x-init.js

@@ -0,0 +1,8 @@
+import { directive, prefix } from "../directives";
+import { addRootSelector } from "../lifecycle";
+import { skipDuringClone } from "../clone";
+import { evaluate } from "../evaluator";
+
+addRootSelector(() => `[${prefix('init')}]`)
+
+directive('init', skipDuringClone((el, { expression }) => evaluate(el, expression, {}, false)))

+ 105 - 0
packages/alpinejs/src/directives/x-model.js

@@ -0,0 +1,105 @@
+import { evaluateLater } from '../evaluator'
+import { directive } from '../directives'
+import { mutateDom } from '../mutation'
+import bind from '../utils/bind'
+import on from '../utils/on'
+
+directive('model', (el, { modifiers, expression }, { effect, cleanup }) => {
+    let evaluate = evaluateLater(el, expression)
+    let assignmentExpression = `${expression} = rightSideOfExpression($event, ${expression})`
+    let evaluateAssignment = evaluateLater(el, assignmentExpression)
+
+    // If the element we are binding to is a select, a radio, or checkbox
+    // we'll listen for the change event instead of the "input" event.
+    var event = (el.tagName.toLowerCase() === 'select')
+        || ['checkbox', 'radio'].includes(el.type)
+        || modifiers.includes('lazy')
+            ? 'change' : 'input'
+
+    let assigmentFunction = generateAssignmentFunction(el, modifiers, expression)
+
+    let removeListener = on(el, event, modifiers, (e) => {
+        evaluateAssignment(() => {}, { scope: {
+            '$event': e,
+            rightSideOfExpression: assigmentFunction
+        }})
+    })
+
+    cleanup(() => removeListener())
+
+    el._x_forceModelUpdate = () => {
+        evaluate(value => {
+            // If nested model key is undefined, set the default value to empty string.
+            if (value === undefined && expression.match(/\./)) value = ''
+
+            // @todo: This is nasty
+            window.fromModel = true
+            mutateDom(() => bind(el, 'value', value))
+            delete window.fromModel
+        })
+    }
+
+    effect(() => {
+        // Don't modify the value of the input if it's focused.
+        if (modifiers.includes('unintrusive') && document.activeElement.isSameNode(el)) return
+
+        el._x_forceModelUpdate()
+    })
+})
+
+function generateAssignmentFunction(el, modifiers, expression) {
+    if (el.type === 'radio') {
+        // Radio buttons only work properly when they share a name attribute.
+        // People might assume we take care of that for them, because
+        // they already set a shared "x-model" attribute.
+        mutateDom(() => {
+            if (! el.hasAttribute('name')) el.setAttribute('name', expression)
+        })
+    }
+
+    return (event, currentValue) => {
+        return mutateDom(() => {
+            // Check for event.detail due to an issue where IE11 handles other events as a CustomEvent.
+            if (event instanceof CustomEvent && event.detail !== undefined) {
+                return event.detail
+            } else if (el.type === 'checkbox') {
+                // If the data we are binding to is an array, toggle its value inside the array.
+                if (Array.isArray(currentValue)) {
+                    let newValue = modifiers.includes('number') ? safeParseNumber(event.target.value) : event.target.value
+
+                    return event.target.checked ? currentValue.concat([newValue]) : currentValue.filter(el => ! checkedAttrLooseCompare(el, newValue))
+                } else {
+                    return event.target.checked
+                }
+            } else if (el.tagName.toLowerCase() === 'select' && el.multiple) {
+                return modifiers.includes('number')
+                    ? Array.from(event.target.selectedOptions).map(option => {
+                        let rawValue = option.value || option.text
+                        return safeParseNumber(rawValue)
+                    })
+                    : Array.from(event.target.selectedOptions).map(option => {
+                        return option.value || option.text
+                    })
+            } else {
+                let rawValue = event.target.value
+                return modifiers.includes('number')
+                    ? safeParseNumber(rawValue)
+                    : (modifiers.includes('trim') ? rawValue.trim() : rawValue)
+            }
+        })
+    }
+}
+
+function safeParseNumber(rawValue) {
+    let number = rawValue ? parseFloat(rawValue) : null
+
+    return isNumeric(number) ? number : rawValue
+}
+
+function checkedAttrLooseCompare(valueA, valueB) {
+    return valueA == valueB
+}
+
+function isNumeric(subject){
+    return ! Array.isArray(subject) && ! isNaN(subject)
+}

+ 16 - 0
packages/alpinejs/src/directives/x-on.js

@@ -0,0 +1,16 @@
+import { directive, into, mapAttributes, prefix, startingWith } from '../directives'
+import { evaluateLater } from '../evaluator'
+import { skipDuringClone } from '../clone'
+import on from '../utils/on'
+
+mapAttributes(startingWith('@', into(prefix('on:'))))
+
+directive('on', skipDuringClone((el, { value, modifiers, expression }, { cleanup }) => {
+    let evaluate = expression ? evaluateLater(el, expression) : () => {}
+
+    let removeListener = on(el, value, modifiers, e => {
+        evaluate(() => {}, { scope: { '$event': e }, params: [e] })
+    })
+
+    cleanup(() => removeListener())
+}))

+ 16 - 0
packages/alpinejs/src/directives/x-ref.js

@@ -0,0 +1,16 @@
+import { closestRoot } from '../lifecycle'
+import { directive } from '../directives'
+
+function handler () {}
+
+handler.inline = (el, { expression }, { cleanup }) => {
+    let root = closestRoot(el)
+
+    if (! root._x_refs) root._x_refs = {}
+
+    root._x_refs[expression] = el
+
+    cleanup(() => delete root._x_refs[expression])
+}
+
+directive('ref', handler)

+ 46 - 0
packages/alpinejs/src/directives/x-show.js

@@ -0,0 +1,46 @@
+import { evaluateLater } from '../evaluator'
+import { directive } from '../directives'
+import { mutateDom } from '../mutation'
+import { once } from '../utils/once'
+
+directive('show', (el, { modifiers, expression }, { effect }) => {
+    let evaluate = evaluateLater(el, expression)
+
+    let hide = () => mutateDom(() => {
+        el.style.display = 'none'
+
+        el._x_is_shown = false
+    })
+
+    let show = () => mutateDom(() => {
+        if (el.style.length === 1 && el.style.display === 'none') {
+            el.removeAttribute('style')
+        } else {
+            el.style.removeProperty('display')
+        }
+
+        el._x_is_shown = true
+    })
+
+    // We are wrapping this function in a setTimeout here to prevent
+    // a race condition from happening where elements that have a
+    // @click.away always view themselves as shown on the page.
+    let clickAwayCompatibleShow = () => setTimeout(show)
+
+    let toggle = once(
+        value => value ? show() : hide(),
+        value => {
+            if (typeof el._x_toggleAndCascadeWithTransitions === 'function') {
+                el._x_toggleAndCascadeWithTransitions(el, value, show, hide)
+            } else {
+                value ? clickAwayCompatibleShow() : hide()
+            }
+        }
+    )
+
+    effect(() => evaluate(value => {
+        if (modifiers.includes('immediate')) value ? clickAwayCompatibleShow() : hide()
+
+        toggle(value)
+    }))
+})

+ 15 - 0
packages/alpinejs/src/directives/x-text.js

@@ -0,0 +1,15 @@
+import { evaluateLater } from '../evaluator'
+import { directive } from '../directives'
+import { mutateDom } from '../mutation'
+
+directive('text', (el, { expression }, { effect, cleanup }) => {
+    let evaluate = evaluateLater(el, expression)
+
+    effect(() => {
+        evaluate(value => {
+            mutateDom(() => {
+                el.textContent = value
+            })
+        })
+    })
+})

+ 311 - 0
packages/alpinejs/src/directives/x-transition.js

@@ -0,0 +1,311 @@
+import { releaseNextTicks, holdNextTicks } from '../nextTick'
+import { setClasses } from '../utils/classes'
+import { setStyles } from '../utils/styles'
+import { directive } from '../directives'
+import { mutateDom } from '../mutation'
+import { once } from '../utils/once'
+
+directive('transition', (el, { value, modifiers, expression }) => {
+    if (! expression) {
+        registerTransitionsFromHelper(el, modifiers, value)
+    } else {
+        registerTransitionsFromClassString(el, expression, value)
+    }
+})
+
+function registerTransitionsFromClassString(el, classString, stage) {
+    registerTransitionObject(el, setClasses, '')
+
+    let directiveStorageMap = {
+        'enter': (classes) => { el._x_transition.enter.during = classes },
+        'enter-start': (classes) => { el._x_transition.enter.start = classes },
+        'enter-end': (classes) => { el._x_transition.enter.end = classes },
+        'leave': (classes) => { el._x_transition.leave.during = classes },
+        'leave-start': (classes) => { el._x_transition.leave.start = classes },
+        'leave-end': (classes) => { el._x_transition.leave.end = classes },
+    }
+
+    directiveStorageMap[stage](classString)
+}
+
+function registerTransitionsFromHelper(el, modifiers, stage) {
+    registerTransitionObject(el, setStyles)
+
+    let doesntSpecify = (! modifiers.includes('in') && ! modifiers.includes('out')) && ! stage
+    let transitioningIn = doesntSpecify || modifiers.includes('in') || ['enter'].includes(stage)
+    let transitioningOut = doesntSpecify || modifiers.includes('out') || ['leave'].includes(stage)
+
+    if (modifiers.includes('in') && ! doesntSpecify) {
+        modifiers = modifiers.filter((i, index) => index < modifiers.indexOf('out'))
+    }
+
+    if (modifiers.includes('out') && ! doesntSpecify) {
+        modifiers = modifiers.filter((i, index) => index > modifiers.indexOf('out'))
+    }
+
+    let wantsAll = ! modifiers.includes('opacity') && ! modifiers.includes('scale')
+    let wantsOpacity = wantsAll || modifiers.includes('opacity')
+    let wantsScale = wantsAll || modifiers.includes('scale')
+    let opacityValue = wantsOpacity ? 0 : 1
+    let scaleValue = wantsScale ? modifierValue(modifiers, 'scale', 95) / 100 : 1
+    let delay = modifierValue(modifiers, 'delay', 0)
+    let origin = modifierValue(modifiers, 'origin', 'center')
+    let property = 'opacity, transform'
+    let durationIn = modifierValue(modifiers, 'duration', 150) / 1000
+    let durationOut = modifierValue(modifiers, 'duration', 75) / 1000
+    let easing = `cubic-bezier(0.4, 0.0, 0.2, 1)`
+
+    if (transitioningIn) {
+        el._x_transition.enter.during = {
+            transformOrigin: origin,
+            transitionDelay: delay,
+            transitionProperty: property,
+            transitionDuration: `${durationIn}s`,
+            transitionTimingFunction: easing,
+        }
+
+        el._x_transition.enter.start = {
+            opacity: opacityValue,
+            transform: `scale(${scaleValue})`,
+        }
+
+        el._x_transition.enter.end = {
+            opacity: 1,
+            transform: `scale(1)`,
+        }
+    }
+
+    if (transitioningOut) {
+        el._x_transition.leave.during = {
+            transformOrigin: origin,
+            transitionDelay: delay,
+            transitionProperty: property,
+            transitionDuration: `${durationOut}s`,
+            transitionTimingFunction: easing,
+        }
+
+        el._x_transition.leave.start = {
+            opacity: 1,
+            transform: `scale(1)`,
+        }
+
+        el._x_transition.leave.end = {
+            opacity: opacityValue,
+            transform: `scale(${scaleValue})`,
+        }
+    }
+}
+
+function registerTransitionObject(el, setFunction, defaultValue = {}) {
+    if (! el._x_transition) el._x_transition = {
+        enter: { during: defaultValue, start: defaultValue, end: defaultValue },
+
+        leave: { during: defaultValue, start: defaultValue, end: defaultValue },
+
+        in(before = () => {}, after = () => {}) {
+            return transition(el, setFunction, {
+                during: this.enter.during,
+                start: this.enter.start,
+                end: this.enter.end,
+                entering: true,
+            }, before, after)
+        },
+
+        out(before = () => {}, after = () => {}) {
+            return transition(el, setFunction, {
+                during: this.leave.during,
+                start: this.leave.start,
+                end: this.leave.end,
+                entering: false,
+            }, before, after)
+        },
+    }
+}
+
+window.Element.prototype._x_toggleAndCascadeWithTransitions = function (el, value, show, hide) {
+    let clickAwayCompatibleShow = () => requestAnimationFrame(show)
+
+    if (value) {
+        el._x_transition
+            ? el._x_transition.in(show)
+            : clickAwayCompatibleShow()
+
+        return
+    }
+
+    el._x_hide_promise = el._x_transition
+        ? new Promise((resolve, reject) => {
+            el._x_transition.out(() => {}, () => resolve(hide))
+
+            el._x_transitioning.beforeCancel(() => reject({ isFromCancelledTransition: true }))
+        })
+        : Promise.resolve(hide)
+
+    queueMicrotask(() => {
+        let closest = closestHide(el)
+
+        if (closest) {
+            if (! closest._x_hide_children) closest._x_hide_children = []
+
+            closest._x_hide_children.push(el)
+        } else {
+            queueMicrotask(() => {
+                let hideAfterChildren = el => {
+                    let carry = Promise.all([
+                        el._x_hide_promise,
+                        ...(el._x_hide_children || []).map(hideAfterChildren)
+                    ]).then(([i]) => i())
+
+                    delete el._x_hide_promise
+                    delete el._x_hide_children
+
+                    return carry
+                }
+
+                hideAfterChildren(el).catch((e) => {
+                    if (! e.isFromCancelledTransition) throw e
+                })
+            })
+        }
+    })
+}
+
+function closestHide(el) {
+    let parent = el.parentNode
+
+    if (! parent) return
+
+    return parent._x_hide_promise ? parent : closestHide(parent)
+}
+
+export function transition(el, setFunction, { during, start, end, entering } = {}, before = () => {}, after = () => {}) {
+    if (el._x_transitioning) el._x_transitioning.cancel()
+
+    let undoStart, undoDuring, undoEnd
+
+    performTransition(el, {
+        start() {
+            undoStart = setFunction(el, start)
+        },
+        during() {
+            undoDuring = setFunction(el, during)
+        },
+        before,
+        end() {
+            undoStart()
+
+            undoEnd = setFunction(el, end)
+        },
+        after,
+        cleanup() {
+            undoDuring()
+            undoEnd()
+        },
+    }, entering)
+}
+
+export function performTransition(el, stages, entering) {
+    // All transitions need to be truly "cancellable". Meaning we need to
+    // account for interuptions at ALL stages of the transitions and
+    // immediately run the rest of the transition.
+    let interrupted, reachedBefore, reachedEnd
+
+    let finish = once(() => {
+        mutateDom(() => {
+            interrupted = true
+
+            if (! reachedBefore) stages.before()
+
+            if (! reachedEnd) {
+                stages.end()
+
+                releaseNextTicks()
+            }
+
+            stages.after()
+
+            // Adding an "isConnected" check, in case the callback removed the element from the DOM.
+            if (el.isConnected) stages.cleanup()
+
+            delete el._x_transitioning
+        })
+    })
+
+    el._x_transitioning = {
+        beforeCancels: [],
+        beforeCancel(callback) { this.beforeCancels.push(callback) },
+        cancel: once(function () { while (this.beforeCancels.length) { this.beforeCancels.shift()() }; finish(); }),
+        finish,
+        entering
+    }
+
+    mutateDom(() => {
+        stages.start()
+        stages.during()
+    })
+
+    holdNextTicks()
+
+    requestAnimationFrame(() => {
+        if (interrupted) return
+
+        // Note: Safari's transitionDuration property will list out comma separated transition durations
+        // for every single transition property. Let's grab the first one and call it a day.
+        let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, '').replace('s', '')) * 1000
+        let delay = Number(getComputedStyle(el).transitionDelay.replace(/,.*/, '').replace('s', '')) * 1000
+
+        if (duration === 0) duration = Number(getComputedStyle(el).animationDuration.replace('s', '')) * 1000
+
+        mutateDom(() => {
+            stages.before()
+        })
+
+        reachedBefore = true
+
+        requestAnimationFrame(() => {
+            if (interrupted) return
+
+            mutateDom(() => {
+                stages.end()
+            })
+
+            releaseNextTicks()
+
+            setTimeout(el._x_transitioning.finish, duration + delay)
+
+            reachedEnd = true
+        })
+    })
+}
+
+function modifierValue(modifiers, key, fallback) {
+    // If the modifier isn't present, use the default.
+    if (modifiers.indexOf(key) === -1) return fallback
+
+    // If it IS present, grab the value after it: x-show.transition.duration.500ms
+    const rawValue = modifiers[modifiers.indexOf(key) + 1]
+
+    if (! rawValue) return fallback
+
+    if (key === 'scale') {
+        // Check if the very next value is NOT a number and return the fallback.
+        // If x-show.transition.scale, we'll use the default scale value.
+        // That is how a user opts out of the opacity transition.
+        if (isNaN(rawValue)) return fallback
+    }
+
+    if (key === 'duration') {
+        // Support x-show.transition.duration.500ms && duration.500
+        let match = rawValue.match(/([0-9]+)ms/)
+        if (match) return match[1]
+    }
+
+    if (key === 'origin') {
+        // Support chaining origin directions: x-show.transition.top.right
+        if (['top', 'right', 'left', 'center', 'bottom'].includes(modifiers[modifiers.indexOf(key) + 2])) {
+            return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(' ')
+        }
+    }
+
+    return rawValue
+}

+ 121 - 0
packages/alpinejs/src/evaluator.js

@@ -0,0 +1,121 @@
+import { closestDataStack, mergeProxies } from './scope'
+import { injectMagics } from './magics'
+
+export function evaluate(el, expression, extras = {}) {
+    let result
+
+    evaluateLater(el, expression)(value => result = value, extras)
+
+    return result
+}
+
+export function evaluateLater(...args) {
+    return theEvaluatorFunction(...args)
+}
+
+let theEvaluatorFunction = normalEvaluator
+
+export function setEvaluator(newEvaluator) {
+    theEvaluatorFunction = newEvaluator
+}
+
+export function normalEvaluator(el, expression) {
+    let overriddenMagics = {}
+
+    injectMagics(overriddenMagics, el)
+
+    let dataStack = [overriddenMagics, ...closestDataStack(el)]
+
+    if (typeof expression === 'function') {
+        return generateEvaluatorFromFunction(dataStack, expression)
+    }
+
+    let evaluator = generateEvaluatorFromString(dataStack, expression)
+
+    return tryCatch.bind(null, el, expression, evaluator)
+}
+
+export function generateEvaluatorFromFunction(dataStack, func) {
+    return (receiver = () => {}, { scope = {}, params = [] } = {}) => {
+        let result = func.apply(mergeProxies([scope, ...dataStack]), params)
+
+        runIfTypeOfFunction(receiver, result)
+    }
+}
+
+let evaluatorMemo = {}
+
+function generateFunctionFromString(expression) {
+    if (evaluatorMemo[expression]) {
+        return evaluatorMemo[expression]
+    }
+
+    let AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
+
+    // Some expressions that are useful in Alpine are not valid as the right side of an expression.
+    // Here we'll detect if the expression isn't valid for an assignement and wrap it in a self-
+    // calling function so that we don't throw an error AND a "return" statement can b e used.
+    let rightSideSafeExpression = 0
+        // Support expressions starting with "if" statements like: "if (...) doSomething()"
+        || /^[\n\s]*if.*\(.*\)/.test(expression)
+        // Support expressions starting with "let/const" like: "let foo = 'bar'"
+        || /^(let|const)/.test(expression)
+            ? `(() => { ${expression} })()`
+            : expression
+
+    let func = new AsyncFunction(['__self', 'scope'], `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;`)
+
+    evaluatorMemo[expression] = func
+
+    return func
+}
+
+function generateEvaluatorFromString(dataStack, expression) {
+    let func = generateFunctionFromString(expression)
+
+    return (receiver = () => {}, { scope = {}, params = [] } = {}) => {
+        func.result = undefined
+        func.finished = false
+
+        // Run the function.
+
+        let completeScope = mergeProxies([ scope, ...dataStack ])
+
+        let promise = func(func, completeScope)
+
+        // Check if the function ran synchronously,
+        if (func.finished) {
+            // Return the immediate result.
+            runIfTypeOfFunction(receiver, func.result, completeScope, params)
+        } else {
+            // If not, return the result when the promise resolves.
+            promise.then(result => {
+                runIfTypeOfFunction(receiver, result, completeScope, params)
+            })
+        }
+    }
+}
+
+export function runIfTypeOfFunction(receiver, value, scope, params) {
+    if (typeof value === 'function') {
+        let result = value.apply(scope, params)
+
+        if (result instanceof Promise) {
+            result.then(i => runIfTypeOfFunction(receiver, i, scope, params))
+        } else {
+            receiver(result)
+        }
+    } else {
+        receiver(value)
+    }
+}
+
+export function tryCatch(el, expression, callback, ...args) {
+    try {
+        return callback(...args)
+    } catch (e) {
+        console.warn(`Alpine Expression Error: ${e.message}\n\nExpression: "${expression}"\n\n`, el)
+
+        throw e
+    }
+}

+ 74 - 0
packages/alpinejs/src/index.js

@@ -0,0 +1,74 @@
+/**
+ *           _
+ *     /\   | |     (_)            (_)
+ *    /  \  | |_ __  _ _ __   ___   _ ___
+ *   / /\ \ | | '_ \| | '_ \ / _ \ | / __|
+ *  / ____ \| | |_) | | | | |  __/_| \__ \
+ * /_/    \_\_| .__/|_|_| |_|\___(_) |___/
+ *            | |                 _/ |
+ *            |_|                |__/
+ *
+ * Let's build Alpine together. It's easier than you think.
+ * For starters, we'll import Alpine's core. This is the
+ * object that will expose all of Alpine's public API.
+ */
+import Alpine from './alpine'
+
+/**
+ * _______________________________________________________
+ * The Evaluator
+ * -------------------------------------------------------
+ *
+ * Now we're ready to bootstrap Alpine's evaluation system.
+ * It's the function that converts raw JavaScript string
+ * expressions like @click="toggle()", into actual JS.
+ */
+import { normalEvaluator } from './evaluator'
+
+Alpine.setEvaluator(normalEvaluator)
+
+/**
+ * _______________________________________________________
+ * The Reactivity Engine
+ * -------------------------------------------------------
+ *
+ * This is the reactivity core of Alpine. It's the part of
+ * Alpine that triggers an element with x-text="message"
+ * to update its inner text when "message" is changed.
+ */
+import { reactive, effect, stop, toRaw } from '@vue/reactivity'
+
+Alpine.setReactivityEngine({ reactive, effect, release: stop, raw: toRaw })
+
+/**
+ * _______________________________________________________
+ * The Magics
+ * -------------------------------------------------------
+ *
+ * Yeah, we're calling them magics here like they're nouns.
+ * These are the properties that are magically available
+ * to all the Alpine expressions, within your web app.
+ */
+import './magics/index'
+
+/**
+ * _______________________________________________________
+ * The Directives
+ * -------------------------------------------------------
+ *
+ * Now that the core is all set up, we can register Alpine
+ * directives like x-text or x-on that form the basis of
+ * how Alpine adds behavior to an app's static markup.
+ */
+import './directives/index'
+
+/**
+ * _______________________________________________________
+ * The Alpine Global
+ * -------------------------------------------------------
+ *
+ * Now that we have set everything up internally, anything
+ * Alpine-related that will need to be accessed on-going
+ * will be made available through the "Alpine" global.
+ */
+export default Alpine

+ 77 - 0
packages/alpinejs/src/interceptor.js

@@ -0,0 +1,77 @@
+export function initInterceptors(data) {
+    let isObject = val => typeof val === 'object' && !Array.isArray(val) && val !== null
+
+    let recurse = (obj, basePath = '') => {
+        Object.entries(obj).forEach(([key, value]) => {
+            let path = basePath === '' ? key : `${basePath}.${key}`
+
+            if (typeof value === 'function' && value.interceptor) {
+                let result = value(key, path)
+
+                Object.defineProperty(obj, key, result[0])
+            }
+
+            if (isObject(value)) {
+                recurse(value, path)
+            }
+        })
+    }
+
+    return recurse(data)
+}
+
+export function interceptor(callback, mutateFunc = () => {}) {
+    return initialValue => {
+        function func(key, path) {
+            let parentFunc = func.parent
+                ? func.parent
+                : (key, path) => ([{}, { initer() {}, setter() {} }])
+
+            let [parentNoop, { initer: parentIniter, setter: parentSetter, initialValue: parentInitialValue }] = parentFunc(key, path)
+
+            let store = parentInitialValue === undefined ? initialValue : parentInitialValue
+
+            let { init: initer, set: setter } = callback(key, path)
+
+            let inited = false
+
+            let setValue = i => store = i
+            let reactiveSetValue = function (i) { this[key] = i }
+
+            let setup = (context) => {
+                if (inited) return
+
+                parentIniter.bind(context)(store, setValue, reactiveSetValue.bind(context))
+                initer.bind(context)(store, setValue, reactiveSetValue.bind(context))
+
+                inited = true
+            }
+
+            return [{
+                get() {
+                    setup(this)
+
+                    return store
+                },
+                set(value) {
+                    setup(this)
+
+                    parentSetter.bind(this)(value, setValue, reactiveSetValue.bind(this))
+                    setter.bind(this)(value, setValue, reactiveSetValue.bind(this))
+                },
+                enumerable: true,
+                configurable: true,
+            }, { initer, setter, initialValue }]
+        }
+
+        func.interceptor = true
+
+        mutateFunc(func)
+
+        if (typeof initialValue === 'function' && initialValue.interceptor) {
+            func.parent = initialValue
+        }
+
+        return func
+    }
+}

+ 79 - 0
packages/alpinejs/src/lifecycle.js

@@ -0,0 +1,79 @@
+import { startObservingMutations, onAttributesAdded, onElAdded, onElRemoved } from "./mutation"
+import { deferHandlingDirectives, directives } from "./directives"
+import { dispatch } from './utils/dispatch'
+import { nextTick } from "./nextTick"
+import { walk } from "./utils/walk"
+import { warn } from './utils/warn'
+
+export function start() {
+    if (! document.body) warn('Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine\'s `<script>` tag?')
+
+    dispatch(document, 'alpine:initializing')
+
+    startObservingMutations()
+
+    onElAdded(el => initTree(el, walk))
+    onElRemoved(el => nextTick(() => destroyTree(el)))
+
+    onAttributesAdded((el, attrs) => {
+        directives(el, attrs).forEach(handle => handle())
+    })
+
+    let outNestedComponents = el => ! closestRoot(el.parentNode || closestRoot(el))
+
+    Array.from(document.querySelectorAll(rootSelectors()))
+        .filter(outNestedComponents)
+        .forEach(el => {
+            initTree(el)
+        })
+
+    dispatch(document, 'alpine:initialized')
+}
+
+let rootSelectorCallbacks = []
+
+export function rootSelectors() {
+    return rootSelectorCallbacks.map(fn => fn())
+}
+
+export function addRootSelector(selectorCallback) { rootSelectorCallbacks.push(selectorCallback) }
+
+export function closestRoot(el) {
+    if (rootSelectors().some(selector => el.matches(selector))) return el
+
+    if (! el.parentElement) return
+
+    return closestRoot(el.parentElement)
+}
+
+export function isRoot(el) {
+    return rootSelectors().some(selector => el.matches(selector))
+}
+
+export function initTree(el, walker = walk) {
+    deferHandlingDirectives(() => {
+        walker(el, (el, skip) => {
+            directives(el, el.attributes).forEach(handle => handle())
+
+            el._x_ignore && skip()
+        })
+    })
+}
+
+let onDestroys = new WeakMap
+
+export function onDestroy(el, callback) {
+    if (! onDestroys.get(el)) onDestroys.set(el, [])
+
+    onDestroys.get(el).push(callback)
+}
+
+function destroyTree(root) {
+    walk(root, el => {
+        let callbacks = onDestroys.get(el)
+
+        callbacks && callbacks.forEach(callback => callback())
+
+        onDestroys.delete(el)
+    })
+}

+ 20 - 0
packages/alpinejs/src/magics.js

@@ -0,0 +1,20 @@
+import Alpine from './alpine'
+import { interceptor } from './interceptor'
+
+let magics = {}
+
+export function magic(name, callback) {
+    magics[name] = callback
+}
+
+export function injectMagics(obj, el) {
+    Object.entries(magics).forEach(([name, callback]) => {
+        Object.defineProperty(obj, `$${name}`, {
+            get() { return callback(el, { Alpine, interceptor }) },
+
+            enumerable: true,
+        })
+    })
+
+    return obj
+}

+ 4 - 0
packages/alpinejs/src/magics/$dispatch.js

@@ -0,0 +1,4 @@
+import { dispatch } from '../utils/dispatch'
+import { magic } from '../magics'
+
+magic('dispatch', el => dispatch.bind(dispatch, el))

+ 3 - 0
packages/alpinejs/src/magics/$el.js

@@ -0,0 +1,3 @@
+import { magic } from "../magics";
+
+magic('el', el => el)

+ 4 - 0
packages/alpinejs/src/magics/$nextTick.js

@@ -0,0 +1,4 @@
+import { nextTick } from '../nextTick'
+import { magic } from '../magics'
+
+magic('nextTick', () => nextTick)

+ 4 - 0
packages/alpinejs/src/magics/$refs.js

@@ -0,0 +1,4 @@
+import { closestRoot } from '../lifecycle'
+import { magic } from '../magics'
+
+magic('refs', el => closestRoot(el)._x_refs || {})

+ 4 - 0
packages/alpinejs/src/magics/$store.js

@@ -0,0 +1,4 @@
+import { getStores } from '../store'
+import { magic } from '../magics'
+
+magic('store', getStores)

+ 23 - 0
packages/alpinejs/src/magics/$watch.js

@@ -0,0 +1,23 @@
+import { evaluateLater } from '../evaluator'
+import { effect } from '../reactivity'
+import { magic } from '../magics'
+
+magic('watch', el => (key, callback) => {
+    let evaluate = evaluateLater(el, key)
+
+    let firstTime = true
+
+    let oldValue
+
+    effect(() => evaluate(value => {
+        // This is a hack to force deep reactivity for things like "items.push()".
+        let div = document.createElement('div')
+        div.dataset.throwAway = value
+
+        if (! firstTime) callback(value, oldValue)
+
+        oldValue = value
+
+        firstTime = false
+    }))
+})

+ 6 - 0
packages/alpinejs/src/magics/index.js

@@ -0,0 +1,6 @@
+import './$nextTick'
+import './$dispatch'
+import './$watch'
+import './$store'
+import './$refs'
+import './$el'

+ 177 - 0
packages/alpinejs/src/mutation.js

@@ -0,0 +1,177 @@
+let onAttributeRemoveds = new WeakMap
+let onAttributeAddeds = []
+let onElRemovedByEl = new WeakMap
+let onElRemoveds = []
+let onElAddeds = []
+
+export function onElAdded(callback) {
+    onElAddeds.push(callback)
+}
+
+export function onElRemoved(el, callback) {
+    if (typeof el === 'function' && callback === undefined) {
+        onElRemoveds.push(el)
+    } else {
+        if (! onElRemovedByEl.has(el)) onElRemovedByEl.set(el, [])
+
+        onElRemovedByEl.get(el).push(callback)
+    }
+}
+
+export function onAttributesAdded(callback) {
+    onAttributeAddeds.push(callback)
+}
+
+export function onAttributeRemoved(el, name, callback) {
+    if (! onAttributeRemoveds.has(el)) onAttributeRemoveds.set(el, {})
+    if (! onAttributeRemoveds.get(el)[name]) onAttributeRemoveds.get(el)[name] = []
+
+    onAttributeRemoveds.get(el)[name].push(callback)
+}
+
+let observer = new MutationObserver(onMutate)
+
+let currentlyObserving = false
+
+export function startObservingMutations() {
+    observer.observe(document, { subtree: true, childList: true, attributes: true, attributeOldValue: true })
+
+    currentlyObserving = true
+}
+
+export function stopObservingMutations() {
+    observer.disconnect()
+
+    currentlyObserving = false
+}
+
+let recordQueue = []
+let willProcessRecordQueue = false
+
+export function flushObserver() {
+    recordQueue = recordQueue.concat(observer.takeRecords())
+
+    if (recordQueue.length && ! willProcessRecordQueue) {
+        willProcessRecordQueue = true
+
+        queueMicrotask(() => {
+            processRecordQueue()
+
+            willProcessRecordQueue = false
+        })
+    }
+}
+
+function processRecordQueue() {
+     onMutate(recordQueue)
+
+     recordQueue.length = 0
+}
+
+export function mutateDom(callback) {
+    if (! currentlyObserving) return callback()
+
+    flushObserver()
+
+    stopObservingMutations()
+
+    let result = callback()
+
+    startObservingMutations()
+
+    return result
+}
+
+function onMutate(mutations) {
+    let addedNodes = []
+    let removedNodes = []
+    let addedAttributes = new Map
+    let removedAttributes = new Map
+
+    for (let i = 0; i < mutations.length; i++) {
+        if (mutations[i].target._x_ignoreMutationObserver) continue
+
+        if (mutations[i].type === 'childList') {
+            mutations[i].addedNodes.forEach(node => node.nodeType === 1 && addedNodes.push(node))
+            mutations[i].removedNodes.forEach(node => node.nodeType === 1 && removedNodes.push(node))
+        }
+
+        if (mutations[i].type === 'attributes') {
+            let el = mutations[i].target
+            let name = mutations[i].attributeName
+            let oldValue = mutations[i].oldValue
+
+            let add = () => {
+                if (! addedAttributes.has(el)) addedAttributes.set(el, [])
+
+                addedAttributes.get(el).push({ name,  value: el.getAttribute(name) })
+            }
+
+            let remove = () => {
+                if (! removedAttributes.has(el)) removedAttributes.set(el, [])
+
+                removedAttributes.get(el).push(name)
+            }
+
+            // New attribute.
+            if (el.hasAttribute(name) && oldValue === null) {
+                add()
+            // Changed atttribute.
+            } else if (el.hasAttribute(name)) {
+                remove()
+                add()
+            // Removed atttribute.
+            } else {
+                remove()
+            }
+        }
+    }
+
+    removedAttributes.forEach((attrs, el) => {
+        if (onAttributeRemoveds.get(el)) {
+            attrs.forEach(name => {
+                if (onAttributeRemoveds.get(el)[name]) {
+                    onAttributeRemoveds.get(el)[name].forEach(i => i())
+                }
+            })
+        }
+    })
+
+    addedAttributes.forEach((attrs, el) => {
+        onAttributeAddeds.forEach(i => i(el, attrs))
+    })
+
+    for (let node of addedNodes) {
+       // If an element gets moved on a page, it's registered
+        // as both an "add" and "remove", so we wan't to skip those.
+        if (removedNodes.includes(node)) continue
+
+        onElAddeds.forEach(i => i(node))
+    }
+
+    for (let node of removedNodes) {
+        // If an element gets moved on a page, it's registered
+        // as both an "add" and "remove", so we want to skip those.
+        if (addedNodes.includes(node)) continue
+
+
+        if (onAttributeRemoveds.has(node)) {
+            Object.entries(onAttributeRemoveds.get(node)).forEach(([key, value]) => {
+                value.forEach(i => i())
+            })
+            onAttributeRemoveds.delete(node)
+        }
+
+        if (onElRemovedByEl.has(node)) {
+            onElRemovedByEl.get(node).forEach(i => i())
+            onElRemovedByEl.delete(node)
+        }
+
+        onElRemoveds.forEach(i => i(node))
+    }
+
+    addedNodes = null
+    removedNodes = null
+    addedAttributes = null
+    removedAttributes = null
+}

+ 24 - 0
packages/alpinejs/src/nextTick.js

@@ -0,0 +1,24 @@
+
+let tickStack = []
+
+let isHolding = false
+
+export function nextTick(callback) {
+    tickStack.push(callback)
+
+    queueMicrotask(() => {
+        isHolding || setTimeout(() => {
+            releaseNextTicks()
+        })
+    })
+}
+
+export function releaseNextTicks() {
+    isHolding = false
+
+    while (tickStack.length) tickStack.shift()()
+}
+
+export function holdNextTicks() {
+    isHolding = true
+}

+ 5 - 0
packages/alpinejs/src/plugin.js

@@ -0,0 +1,5 @@
+import Alpine from './alpine'
+
+export function plugin(callback) {
+    callback(Alpine)
+}

+ 44 - 0
packages/alpinejs/src/reactivity.js

@@ -0,0 +1,44 @@
+
+import { scheduler } from './scheduler'
+
+let reactive, effect, release, raw
+
+export function setReactivityEngine(engine) {
+    reactive = engine.reactive
+    release = engine.release
+    effect = (callback) => engine.effect(callback, { scheduler })
+    raw = engine.raw
+}
+
+export function overrideEffect(override) { effect = override }
+
+export function elementBoundEffect(el) {
+    let cleanup = () => {}
+
+    let wrappedEffect = (callback) => {
+        let effectReference = effect(callback)
+
+        if (! el._x_effects) {
+            el._x_effects = new Set
+
+            el._x_runEffects = () => { el._x_effects.forEach(i => i()) }
+        }
+
+        el._x_effects.add(effectReference)
+
+        cleanup = () => {
+            el._x_effects.delete(effectReference)
+
+            release(effectReference)
+        }
+    }
+
+    return [wrappedEffect, () => { cleanup() }]
+}
+
+export {
+    release,
+    reactive,
+    effect,
+    raw,
+}

+ 33 - 0
packages/alpinejs/src/scheduler.js

@@ -0,0 +1,33 @@
+
+let flushPending = false
+let flushing = false
+let queue = []
+
+export function scheduler (callback) { queueJob(callback) }
+
+function queueJob(job) {
+    if (! queue.includes(job)) queue.push(job)
+
+    queueFlush()
+}
+
+function queueFlush() {
+    if (! flushing && ! flushPending) {
+        flushPending = true
+
+        queueMicrotask(flushJobs)
+    }
+}
+
+export function flushJobs() {
+    flushPending = false
+    flushing = true
+
+    for (let i = 0; i < queue.length; i++) {
+        queue[i]()
+    }
+
+    queue.length = 0
+
+    flushing = false
+}

+ 70 - 0
packages/alpinejs/src/scope.js

@@ -0,0 +1,70 @@
+
+export function scope(node) {
+    return mergeProxies(closestDataStack(node))
+}
+
+export function addScopeToNode(node, data, referenceNode) {
+    node._x_dataStack = [data, ...closestDataStack(referenceNode || node)]
+
+    return () => {
+        node._x_dataStack = node._x_dataStack.filter(i => i !== data)
+    }
+}
+
+export function hasScope(node) {
+    return !! node._x_dataStack
+}
+
+export function refreshScope(element, scope) {
+    let existingScope = element._x_dataStack[0]
+
+    Object.entries(scope).forEach(([key, value]) => {
+        existingScope[key] = value
+    })
+}
+
+export function closestDataStack(node) {
+    if (node._x_dataStack) return node._x_dataStack
+
+    if (node instanceof ShadowRoot) {
+        return closestDataStack(node.host)
+    }
+
+    if (! node.parentNode) {
+        return []
+    }
+
+    return closestDataStack(node.parentNode)
+}
+
+export function closestDataProxy(el) {
+    return mergeProxies(closestDataStack(el))
+}
+
+export function mergeProxies(objects) {
+    return new Proxy({}, {
+        ownKeys: () => {
+            return Array.from(new Set(objects.flatMap(i => Object.keys(i))))
+        },
+
+        has: (target, name) => {
+            return objects.some(obj => obj.hasOwnProperty(name))
+        },
+
+        get: (target, name) => {
+            return (objects.find(obj => obj.hasOwnProperty(name)) || {})[name]
+        },
+
+        set: (target, name, value) => {
+            let closestObjectWithKey = objects.find(obj => obj.hasOwnProperty(name))
+
+            if (closestObjectWithKey) {
+                closestObjectWithKey[name] = value
+            } else {
+                objects[objects.length - 1][name] = value
+            }
+
+            return true
+        },
+    })
+}

+ 20 - 0
packages/alpinejs/src/store.js

@@ -0,0 +1,20 @@
+import { reactive } from "./reactivity"
+
+let stores = {}
+let isReactive = false
+
+export function store(name, value) {
+    if (! isReactive) { stores = reactive(stores); isReactive = true; }
+
+    if (value === undefined) {
+        return stores[name]
+    }
+
+    if (typeof value === 'object' && value !== null && value.hasOwnProperty('init') && typeof value.init === 'function') {
+        value.init()
+    }
+
+    stores[name] = value
+}
+
+export function getStores() { return stores }

+ 129 - 0
packages/alpinejs/src/utils/bind.js

@@ -0,0 +1,129 @@
+import { reactive } from '../reactivity'
+import { setClasses } from './classes'
+import { setStyles } from './styles'
+
+export default function bind(el, name, value, modifiers = []) {
+    // Register bound data as pure observable data for other APIs to use.
+    if (! el._x_bindings) el._x_bindings = reactive({})
+
+    el._x_bindings[name] = value
+
+    name = modifiers.includes('camel') ? camelCase(name) : name
+
+    switch (name) {
+        case 'value':
+            bindInputValue(el, value)
+            break;
+
+        case 'style':
+            bindStyles(el, value)
+            break;
+
+        case 'class':
+            bindClasses(el, value)
+            break;
+
+        default:
+            bindAttribute(el, name, value)
+            break;
+    }
+}
+
+function bindInputValue(el, value) {
+    if (el.type === 'radio') {
+        // Set radio value from x-bind:value, if no "value" attribute exists.
+        // If there are any initial state values, radio will have a correct
+        // "checked" value since x-bind:value is processed before x-model.
+        if (el.attributes.value === undefined) {
+            el.value = value
+        }
+
+        // @todo: yuck
+        if (window.fromModel) {
+            el.checked = checkedAttrLooseCompare(el.value, value)
+        }
+    } else if (el.type === 'checkbox') {
+        // If we are explicitly binding a string to the :value, set the string,
+        // If the value is a boolean/array/number/null/undefined, leave it alone, it will be set to "on"
+        // automatically.
+        if (Number.isInteger(value)) {
+            el.value = value
+        } else if (! Number.isInteger(value) && ! Array.isArray(value) && typeof value !== 'boolean' && ! [null, undefined].includes(value)) {
+            el.value = String(value)
+        } else {
+            if (Array.isArray(value)) {
+                el.checked = value.some(val => checkedAttrLooseCompare(val, el.value))
+            } else {
+                el.checked = !!value
+            }
+        }
+    } else if (el.tagName === 'SELECT') {
+        updateSelect(el, value)
+    } else {
+        if (el.value === value) return
+
+        el.value = value
+    }
+}
+
+function bindClasses(el, value) {
+    if (el._x_undoAddedClasses) el._x_undoAddedClasses()
+
+    el._x_undoAddedClasses = setClasses(el, value)
+}
+
+function bindStyles(el, value) {
+    if (el._x_undoAddedStyles) el._x_undoAddedStyles()
+
+    el._x_undoAddedStyles = setStyles(el, value)
+}
+
+function bindAttribute(el, name, value) {
+    if ([null, undefined, false].includes(value) && attributeShouldntBePreservedIfFalsy(name)) {
+        el.removeAttribute(name)
+    } else {
+        if (isBooleanAttr(name)) value = name
+
+        setIfChanged(el, name, value)
+    }
+}
+
+function setIfChanged(el, attrName, value) {
+    if (el.getAttribute(attrName) != value) {
+        el.setAttribute(attrName, value)
+    }
+}
+
+function updateSelect(el, value) {
+    const arrayWrappedValue = [].concat(value).map(value => { return value + '' })
+
+    Array.from(el.options).forEach(option => {
+        option.selected = arrayWrappedValue.includes(option.value)
+    })
+}
+
+function camelCase(subject) {
+    return subject.toLowerCase().replace(/-(\w)/g, (match, char) => char.toUpperCase())
+}
+
+function checkedAttrLooseCompare(valueA, valueB) {
+    return valueA == valueB
+}
+
+function isBooleanAttr(attrName) {
+    // As per HTML spec table https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute
+    // Array roughly ordered by estimated usage
+    const booleanAttributes = [
+        'disabled','checked','required','readonly','hidden','open', 'selected',
+        'autofocus', 'itemscope', 'multiple', 'novalidate','allowfullscreen',
+        'allowpaymentrequest', 'formnovalidate', 'autoplay', 'controls', 'loop',
+        'muted', 'playsinline', 'default', 'ismap', 'reversed', 'async', 'defer',
+        'nomodule'
+    ]
+
+    return booleanAttributes.includes(attrName)
+}
+
+function attributeShouldntBePreservedIfFalsy(name) {
+    return ! ['aria-pressed', 'aria-checked'].includes(name)
+}

+ 56 - 0
packages/alpinejs/src/utils/classes.js

@@ -0,0 +1,56 @@
+
+export function setClasses(el, value) {
+    if (Array.isArray(value)) {
+        return setClassesFromString(el, value.join(' '))
+    } else if (typeof value === 'object' && value !== null) {
+        return setClassesFromObject(el, value)
+    }
+
+    return setClassesFromString(el, value)
+}
+
+function setClassesFromString(el, classString) {
+    let split = classString => classString.split(' ').filter(Boolean)
+
+    let missingClasses = classString => classString.split(' ').filter(i => ! el.classList.contains(i)).filter(Boolean)
+
+    let addClassesAndReturnUndo = classes => {
+        el.classList.add(...classes)
+
+        return () => { el.classList.remove(...classes) }
+    }
+
+    // This is to allow short-circuit expressions like: :class="show || 'hidden'" && "show && 'block'"
+    classString = (classString === true) ? classString = '' : (classString || '')
+
+    return addClassesAndReturnUndo(missingClasses(classString))
+}
+
+function setClassesFromObject(el, classObject) {
+    let split = classString => classString.split(' ').filter(Boolean)
+
+    let forAdd = Object.entries(classObject).flatMap(([classString, bool]) => bool ? split(classString) : false).filter(Boolean)
+    let forRemove = Object.entries(classObject).flatMap(([classString, bool]) => ! bool ? split(classString) : false).filter(Boolean)
+
+    let added = []
+    let removed = []
+
+    forAdd.forEach(i => {
+        if (! el.classList.contains(i)) {
+            el.classList.add(i)
+            added.push(i)
+        }
+    })
+
+    forRemove.forEach(i => {
+        if (el.classList.contains(i)) {
+            el.classList.remove(i)
+            removed.push(i)
+        }
+    })
+
+    return () => {
+        added.forEach(i => el.classList.remove(i))
+        removed.forEach(i => el.classList.add(i))
+    }
+}

+ 12 - 0
packages/alpinejs/src/utils/dispatch.js

@@ -0,0 +1,12 @@
+
+export function dispatch(el, name, detail = {}) {
+    el.dispatchEvent(
+        new CustomEvent(name, {
+            detail,
+            bubbles: true,
+            // Allows events to pass the shadow DOM barrier.
+            composed: true,
+            cancelable: true,
+        })
+    )
+}

+ 174 - 0
packages/alpinejs/src/utils/on.js

@@ -0,0 +1,174 @@
+
+export default function on (el, event, modifiers, callback) {
+    let listenerTarget = el
+
+    let handler = e => callback(e)
+
+    let options = {}
+
+    // This little helper allows us to add functionality to the listener's
+    // handler more flexibly in a "middleware" style.
+    let wrapHandler = (callback, wrapper) => (e) => wrapper(callback, e)
+
+    if (modifiers.includes('camel')) event = camelCase(event)
+    if (modifiers.includes('passive')) options.passive = true
+    if (modifiers.includes('window')) listenerTarget = window
+    if (modifiers.includes('document')) listenerTarget = document
+    if (modifiers.includes('prevent')) handler = wrapHandler(handler, (next, e) => { e.preventDefault(); next(e) })
+    if (modifiers.includes('stop')) handler = wrapHandler(handler, (next, e) => { e.stopPropagation(); next(e) })
+    if (modifiers.includes('self')) handler = wrapHandler(handler, (next, e) => { e.target === el && next(e) })
+
+    if (modifiers.includes('away') || modifiers.includes('outside')) {
+        listenerTarget = document
+
+        handler = wrapHandler(handler, (next, e) => {
+            if (el.contains(e.target)) return
+
+            if (el.offsetWidth < 1 && el.offsetHeight < 1) return
+
+            next(e)
+        })
+    }
+
+    // Handle :keydown and :keyup listeners.
+    handler = wrapHandler(handler, (next, e) => {
+        if (isKeyEvent(event)) {
+            if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {
+                return
+            }
+        }
+
+        next(e)
+    })
+
+    if (modifiers.includes('debounce')) {
+        let nextModifier = modifiers[modifiers.indexOf('debounce')+1] || 'invalid-wait'
+        let wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250
+
+        handler = debounce(handler, wait, this)
+    }
+
+    if (modifiers.includes('throttle')) {
+        let nextModifier = modifiers[modifiers.indexOf('throttle')+1] || 'invalid-wait'
+        let wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250
+
+        handler = throttle(handler, wait, this)
+    }
+
+    if (modifiers.includes('once')) {
+        handler = wrapHandler(handler, (next, e) => {
+            next(e)
+
+            listenerTarget.removeEventListener(event, handler, options)
+        })
+    }
+
+    listenerTarget.addEventListener(event, handler, options)
+
+    return () => {
+        listenerTarget.removeEventListener(event, handler, options)
+    }
+}
+
+function camelCase(subject) {
+    return subject.toLowerCase().replace(/-(\w)/g, (match, char) => char.toUpperCase())
+}
+
+function debounce(func, wait) {
+    var timeout
+
+    return function() {
+        var context = this, args = arguments
+
+        var later = function () {
+            timeout = null
+
+            func.apply(context, args)
+        }
+
+        clearTimeout(timeout)
+
+        timeout = setTimeout(later, wait)
+    }
+}
+
+function throttle(func, limit) {
+    let inThrottle
+
+    return function() {
+        let context = this, args = arguments
+
+        if (! inThrottle) {
+            func.apply(context, args)
+
+            inThrottle = true
+
+            setTimeout(() => inThrottle = false, limit)
+        }
+    }
+}
+
+function isNumeric(subject){
+    return ! Array.isArray(subject) && ! isNaN(subject)
+}
+
+function kebabCase(subject) {
+    return subject.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[_\s]/, '-').toLowerCase()
+}
+
+function isKeyEvent(event) {
+    return ['keydown', 'keyup'].includes(event)
+}
+
+function isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {
+    let keyModifiers = modifiers.filter(i => {
+        return ! ['window', 'document', 'prevent', 'stop', 'once'].includes(i)
+    })
+
+    if (keyModifiers.includes('debounce')) {
+        let debounceIndex = keyModifiers.indexOf('debounce')
+        keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex+1] || 'invalid-wait').split('ms')[0]) ? 2 : 1)
+    }
+
+    // If no modifier is specified, we'll call it a press.
+    if (keyModifiers.length === 0) return false
+
+    // If one is passed, AND it matches the key pressed, we'll call it a press.
+    if (keyModifiers.length === 1 && keyModifiers[0] === keyToModifier(e.key)) return false
+
+    // The user is listening for key combinations.
+    const systemKeyModifiers = ['ctrl', 'shift', 'alt', 'meta', 'cmd', 'super']
+    const selectedSystemKeyModifiers = systemKeyModifiers.filter(modifier => keyModifiers.includes(modifier))
+
+    keyModifiers = keyModifiers.filter(i => ! selectedSystemKeyModifiers.includes(i))
+
+    if (selectedSystemKeyModifiers.length > 0) {
+        const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter(modifier => {
+            // Alias "cmd" and "super" to "meta"
+            if (modifier === 'cmd' || modifier === 'super') modifier = 'meta'
+
+            return e[`${modifier}Key`]
+        })
+
+        // If all the modifiers selected are pressed, ...
+        if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
+            // AND the remaining key is pressed as well. It's a press.
+            if (keyModifiers[0] === keyToModifier(e.key)) return false
+        }
+    }
+
+    // We'll call it NOT a valid keypress.
+    return true
+}
+
+function keyToModifier(key) {
+    switch (key) {
+        case '/':
+            return 'slash'
+        case ' ':
+        case 'Spacebar':
+            return 'space'
+        default:
+            return key && kebabCase(key)
+    }
+}

+ 14 - 0
packages/alpinejs/src/utils/once.js

@@ -0,0 +1,14 @@
+
+export function once(callback, fallback = () => {}) {
+    let called = false
+
+    return function () {
+        if (! called) {
+            called = true
+
+            callback.apply(this, arguments)
+        } else {
+            fallback.apply(this, arguments)
+        }
+    }
+}

+ 38 - 0
packages/alpinejs/src/utils/styles.js

@@ -0,0 +1,38 @@
+
+export function setStyles(el, value) {
+    if (typeof value === 'object' && value !== null) {
+        return setStylesFromObject(el, value)
+    }
+
+    return setStylesFromString(el, value)
+}
+
+function setStylesFromObject(el, value) {
+    let previousStyles = {}
+
+    Object.entries(value).forEach(([key, value]) => {
+        previousStyles[key] = el.style[key]
+
+        el.style[key] = value
+    })
+
+    setTimeout(() => {
+        if (el.style.length === 0) {
+            el.removeAttribute('style')
+        }
+    })
+
+    return () => {
+        setStyles(el, previousStyles)
+    }
+}
+
+function setStylesFromString(el, value) {
+    let cache = el.getAttribute('style', value)
+
+    el.setAttribute('style', value)
+
+    return () => {
+        el.setAttribute('style', cache)
+    }
+}

+ 38 - 0
packages/alpinejs/src/utils/walk.js

@@ -0,0 +1,38 @@
+export function walk(el, callback) {
+    if (el instanceof ShadowRoot) {
+        Array.from(el.children).forEach(el => walk(el, callback))
+
+        return
+    }
+
+    let skip = false
+
+    callback(el, () => skip = true)
+
+    if (skip) return
+
+    let node = el.firstElementChild
+
+    while (node) {
+        walk(node, callback, false)
+
+        node = node.nextElementSibling
+    }
+}
+// export function walk(el, callback) {
+//     if (el instanceof ShadowRoot || el instanceof DocumentFragment) {
+//         Array.from(el.children).forEach(el => walk(el, callback))
+
+//         return
+//     }
+
+//     callback(el, () => {
+//         let node = el.firstElementChild
+
+//         while (node) {
+//             walk(node, callback)
+
+//             node = node.nextElementSibling
+//         }
+//     })
+// }

+ 4 - 0
packages/alpinejs/src/utils/warn.js

@@ -0,0 +1,4 @@
+
+export function warn(message, ...args) {
+    console.warn(`Alpine Warning: ${message}`, ...args)
+}

+ 7 - 0
packages/csp/builds/cdn.js

@@ -0,0 +1,7 @@
+import Alpine from './../src/index'
+
+window.Alpine = Alpine
+
+queueMicrotask(() => {
+    Alpine.start()
+})

+ 3 - 0
packages/csp/builds/module.js

@@ -0,0 +1,3 @@
+import Alpine from './../src/index'
+
+export default Alpine

+ 12 - 0
packages/csp/package.json

@@ -0,0 +1,12 @@
+{
+    "name": "@alpinejs/csp",
+    "version": "3.0.0-alpha.0",
+    "description": "A CSP compatible build of Alpine",
+    "author": "Caleb Porzio",
+    "license": "MIT",
+    "main": "dist/module.cjs.js",
+    "module": "dist/module.esm.js",
+    "dependencies": {
+        "@vue/reactivity": "^3.0.2"
+    }
+}

+ 37 - 0
packages/csp/src/index.js

@@ -0,0 +1,37 @@
+import Alpine from 'alpinejs/src/alpine'
+
+Alpine.setEvaluator(cspCompliantEvaluator)
+
+import { reactive, effect, stop, toRaw } from '@vue/reactivity'
+Alpine.setReactivityEngine({ reactive, effect, release: stop, raw: toRaw })
+
+import 'alpinejs/src/magics/index'
+import 'alpinejs/src/directives/index'
+
+import { closestDataStack, mergeProxies } from 'alpinejs/src/scope'
+import { injectMagics } from 'alpinejs/src/magics'
+import { generateEvaluatorFromFunction, runIfTypeOfFunction, tryCatch } from 'alpinejs/src/evaluator'
+
+function cspCompliantEvaluator(el, expression) {
+    let overriddenMagics = {}
+
+    injectMagics(overriddenMagics, el)
+
+    let dataStack = [overriddenMagics, ...closestDataStack(el)]
+
+    if (typeof expression === 'function') {
+        return generateEvaluatorFromFunction(dataStack, expression)
+    }
+
+    let evaluator = (receiver = () => {}, { scope = {}, params = [] } = {}) => {
+        let completeScope = mergeProxies([scope, ...dataStack])
+
+        if (completeScope[expression] !== undefined) {
+            runIfTypeOfFunction(receiver, completeScope[expression], completeScope, params)
+        }
+   }
+
+    return tryCatch.bind(null, el, expression, evaluator)
+}
+
+export default Alpine

+ 7 - 0
packages/docs/package.json

@@ -0,0 +1,7 @@
+{
+    "name": "@alpinejs/docs",
+    "version": "3.0.0-alpha.0",
+    "description": "The documentation for Alpine",
+    "author": "Caleb Porzio",
+    "license": "MIT"
+}

+ 5 - 0
packages/docs/src/en/advanced.md

@@ -0,0 +1,5 @@
+---
+order: 8
+title: Advanced
+type: sub-directory
+---

+ 40 - 0
packages/docs/src/en/advanced/async.md

@@ -0,0 +1,40 @@
+---
+order: 4
+title: Async
+---
+
+# Async
+
+Alpine is built to support asynchronous functions in most places it supports standard ones.
+
+For example, let's say you have a simple function called `getLabel()` that you use as the input to an `x-text` directive:
+
+```js
+function getLabel() {
+    return 'Hello World!'
+}
+```
+```html
+<span x-text="getLabel()"></span>
+```
+
+Because `getLabel` is synchronous, everything works as expected.
+
+Now let's pretend that `getLabel` makes a network request to retrieve the label and can't return one instantaniously (asynchronous). By making `getLabel` an async function, you can call it from Alpine using JavaScript's `await` syntax.
+
+```js
+async function getLabel() {
+    let response = await fetch('/api/label')
+
+    return await response.text()
+}
+```
+```html
+<span x-text="await getLabel()"></span>
+```
+
+Additionally, if you prefer calling methods in Alpine without the trailing parenthesis, you can leave them out and Alpine will detect that the provided function is async and handle it accordingly. For example:
+
+```html
+<span x-text="getLabel"></span>
+```

+ 72 - 0
packages/docs/src/en/advanced/csp.md

@@ -0,0 +1,72 @@
+---
+order: 5
+title: CSP
+---
+
+# CSP (Content-Security Policy)
+
+In for Alpine to be able to execute plain strings from HTML attributes as JavaScript expressions, for example `x-on:click="console.log()"`, it needs to rely on utilities that violate the "unsafe-eval" content security policy.
+
+> Under the hood, Alpine doesn't actually use eval() itself because it's slow and problematic. Instead it uses Function declarations, which are much better, but still violate "unsafe-eval".
+
+In order to accomodate environments where this CSP is necessary, Alpine offers an alternate build that doesn't violate "unsafe-eval", but has a more restrictive syntax.
+
+<a name="installation"></a>
+## Installation
+
+Like all Alpine extensions, you can use this include this either via `<script>` tag or module import:
+
+<a name="script-tag"></a>
+### Script tag
+
+```html
+<html>
+    <script src="alpinejs/alpinejs-csp/cdn.js" defer></script>
+</html>
+```
+
+<a name="module-import"></a>
+### Module import
+
+```js
+import Alpine from '@alpinejs/csp'
+
+window.Alpine = Alpine
+window.Alpine.start()
+```
+
+<a name="restrictions"></a>
+## Restrictions
+
+Because Alpine can no longer interpret strings as plain JavaScript, it has to parse and construct JavaScript functions from them manually.
+
+Because of this limitation, you must `Alpine.data` to register your `x-data` objects, and must reference properties and methods from it by key only.
+
+For example, an inline component like this will not work.
+
+```html
+<!-- Bad -->
+<div x-data="{ count: 1 }">
+    <button @click="count++">Increment</button>
+
+    <span x-text="count"></span>
+</div>
+```
+
+However, breaking out the expressions into external APIs, the following is valid with the CSP build:
+
+```html
+<!-- Good -->
+<div x-data="counter">
+    <button @click="increment">Increment</button>
+
+    <span x-text="count"></span>
+</div>
+```
+```js
+Alpine.data('counter', () => ({
+    count: 1,
+
+    increment() { this.count++ }
+}))
+```

+ 360 - 0
packages/docs/src/en/advanced/extending.md

@@ -0,0 +1,360 @@
+---
+order: 2
+title: Extending
+---
+
+# Extending
+
+Alpine has a very open codebase that allows for extension in a number of ways. In fact, every available directive and magic in Alpine itself uses these exact APIs. In theory you could rebuild all of Alpine's functionality using them yourself.
+
+<a name="lifecycle-concerns"></a>
+## Lifecycle concerns
+Before we dive into each individual API, let's first talk about where in your codebase you should consume these APIs.
+
+Because these APIs have an impact on how Alpine intiailizes the page, they must be registered AFTER Alpine is downloaded and available on the page, but BEFORE it has initialized the page itself.
+
+There are two different techniques depending on if you are importing Alpine into a bundle, or including it directly via a `<script>` tag. Let's look at them both:
+
+<a name="via-script-tag"></a>
+### Via a script tag
+
+If you are including Alpine via a script tag, you will need to register any custom extension code inside an `alpine:initializing` event listener.
+
+Here's an example:
+
+```html
+<html>
+    <script src="/js/alpine.js" defer></script>
+
+    <div x-data x-foo></div>
+
+    <script>
+        document.addEventListener('alpine:initializing', () => {
+            Alpine.directive('foo', ...)
+        })
+    </script>
+</html>
+```
+
+If you want to extract your extension code into an external file, you will need to make sure that file's `<script>` tag is located BEFORE Alpine's like so:
+
+```html
+<html>
+    <script src="/js/foo.js" defer></script>
+    <script src="/js/alpine.js" defer></script>
+
+    <div x-data x-foo></div>
+</html>
+```
+
+<a name="via-npm"></a>
+### Via an NPM module
+
+If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the `Alpine` global object, and when you initialize Alpine by calling `Alpine.start()`. For example:
+
+```js
+import Alpine from 'alpinejs'
+
+Alpine.directive('foo', ...)
+
+window.Alpine = Alpine
+window.Alpine.start()
+```
+
+Now that we know where to use these extension APIs, let's look more closely at how to use each one:
+
+<a name="custom-directives"></a>
+## Custom directives
+
+Alpine allows you to register your own custom directives using the `Alpine.directive()` API.
+
+<a name="method-signature"></a>
+### Method Signature
+
+```js
+Alpine.directive('[name]', (el, { value, modifiers, expression }, { Alpine, effect, cleanup }) => {})
+```
+
+&nbsp; | &nbsp;
+---|---
+name | The name of the directive. The name "foo" for example would be consumed as `x-foo`
+el | The DOM element the directive is added to
+value | If provided, the part of the directive after a colon. Ex: `'bar'` in `x-foo:bar`
+modifiers | An array of dot-separated trailing additions to the directive. Ex: `['baz', 'lob']` from `x-foo.baz.lob`
+expression | The attribute value portion of the directive. Ex: `law` from `x-foo="law"`
+Alpine | The Alpine global object
+effect | A function to create reactive effects that will auto-cleanup after this directive is removed from the DOM
+cleanup | A function you can pass bespoke callbacks to that will run when this directive is removed from the DOM
+
+<a name="simple-example"></a>
+### Simple Example
+
+Here's an example of a simple directive we're going to create called: `x-uppercase`:
+
+```js
+Alpine.directive('uppercase', el => {
+    el.textContent = el.textContent.toUpperCase()
+})
+```
+```html
+<div x-data>
+    <span x-uppercase>Hello World!</span>
+</div>
+```
+
+<a name="evaluating-expressions"></a>
+### Evaluating expressions
+
+When registering a custom directive, you may want to evaluate a user-supplied JavaScript expression:
+
+For example, let's say you wanted to create a custom directive as a shortcut to `console.log()`. Something like:
+
+```html
+<div x-data="{ message: 'Hello World!' }">
+    <div x-log="message"></div>
+</div>
+```
+
+You need to retrieve the actual value of `message` by evaluating it as a JavaScript expression with the `x-data` scope.
+
+Fortunately, Alpine exposes its system for evaluating JavaScript expressions with an `evaluate()` API. Here's an example:
+
+```js
+Alpine.directive('log', (el, { expression }, { evaluate }) => {
+    // expression === 'message'
+
+    console.log(
+        evaluate(el, expression)
+    )
+})
+```
+
+Now, when Alpine initializes the `<div x-log...>`, it will retrieve the expression passed into the directive ("message" in this case), and evaluate it in the context of the current element's Alpine component scope.
+
+<a name="introducing-reactivity"></a>
+### Introducing reactivity
+
+Building on the `x-log` example from before, let's say we wanted `x-log` to log the value of `message` and also log it if the value changes.
+
+Given the following template:
+
+```html
+<div x-data="{ message: 'Hello World!' }">
+    <div x-log="message"></div>
+
+    <button @click="message = 'yolo'">Change</button>
+</div>
+```
+
+We want "Hello World!" to be logged initially, then we want "yolo" to be logged after pressing the `<button>`.
+
+We can adjust the implementation of `x-log` and introduce two new APIs to achieve this: `evaluateLater()` and `effect()`:
+
+```js
+Alpine.directive('log', (el, { expression }, { evaluateLater, effect }) => {
+    let getThingToLog = evaluateLater(expression)
+
+    effect(() => {
+        getThingToLog(thingToLog => {
+            console.log(thingToLog)
+        })
+    })
+})
+```
+
+Let's walk through the above code, line by line.
+
+```js
+let getThingToLog = evaluateLater(expression)
+```
+
+Here, instead of immediately evaluating `message` and retreiving the result, we will convert the string expression ("message") into an actual JavaScript function that we can run at any time. If you're going to evaluate a JavaScript expression more than once, it is highly recommended to first generate a JavaScript function and use that rather than calling `evaluate()` directly. The reason being that the process to interpret a plain string as a JavaScript function is expensive and should be avoided when unnecessary.
+
+```js
+effect(() => {
+    ...
+})
+```
+
+By passing in a callback to `effect()`, we are telling Alpine to run the callback immediately, then track any dependancies it uses (`x-data` properties like `message` in our case). Now as soon as one of the dependancies changes, this callback will be re-run. This gives us our "reactivity".
+
+You may recognize this functionality from `x-effect`. It is the same mechanism under the hood.
+
+You may also notice that `Alpine.effect()` exists and wonder why we're not using it here. The reason is that the `effect` function provided via the method parameter has special functionality that cleans itself up when the directive is removed from the page for any reason.
+
+For example, if for some reason the element with `x-log` on it got removed from the page, by using `effect()` instead of `Alpine.effect()` when the `message` property is changed, the value will no longer be logged to the console.
+
+[→ Read more about reactivity in Alpine](/advanced/reactivity)
+
+```js
+getThingToLog(thingToLog => {
+    console.log(thingToLog)
+})
+```
+
+Now we will call `getThingToLog`, which if you recall is the actual JavaScript function version of the string expression: "message"
+
+You might expect `getThingToCall()` to return the result right away, but instead Alpine requires you to pass in a callback to receive the result.
+
+The reason for this is to support async expressions like `await getMessage()`. By passing in a "receiver" callback instead of getting the result immediately, you are allowing your directive to work with async expressions as well.
+
+[→ Read more about async in Alpine](/advanced/async)
+
+<a name="cleaning-up"></a>
+### Cleaning Up
+
+Let's say you needed to register an event listener from a custom directive. After that directive is removed from the page for any reason, you would want to remove the event listener as well.
+
+Alpine makes this simple by providing you with a `cleanup` function when registering custom directives.
+
+Here's an example:
+
+```js
+Alpine.directive('...', (el, {}, { cleanup }) => {
+    let handler = () => {}
+
+    window.addEventListener('click', handler)
+
+    cleanup(() => {
+        window.removeEventListener('click', handler)
+    })
+
+})
+```
+
+Now if the directive is removed from this element or the element is removed itself, the event listener will be removed as well.
+
+<a name="custom-magics"></a>
+## Custom magics
+
+Alpine allows you to register custom "magics" (properties or methods) using `Alpine.magic()`. Any magic you register will be available to all your application's Alpine code with the `$` prefix.
+
+<a name="method-signature"></a>
+### Method Signature
+
+```js
+Alpine.magic('[name]', (el, { Alpine }) => {})
+```
+
+&nbsp; | &nbsp;
+---|---
+name | The name of the magic. The name "foo" for example would be consumed as `$foo`
+el | The DOM element the magic was triggered from
+Alpine | The Alpine global object
+
+<a name="magic-properties"></a>
+### Magic Properties
+
+Here's a basic example of a "$now" magic helper to easily get the current time from anywhere in Alpine:
+
+```js
+Alpine.magic('now', () => {
+    return (new Date).toLocaleTimeString()
+})
+```
+```html
+<span x-text="$now"></span>
+```
+
+Now the `<span>` tag will contain the current time, resembling something like "12:00:00 PM".
+
+As you can see `$now` behaves like a static property, but under the hood is actually a getter that evaluates every time the property is accessed.
+
+Because of this, you can impliment magic "functions" by returning a function from the getter.
+
+<a name="magic-functions"></a>
+### Magic Functions
+
+For example, if we wanted to create a `$clipboard()` magic function that accepts a string to copy to clipboard, we could impliement it like so:
+
+```js
+Alpine.magic('clipboard', () => {
+    return subject => navigator.clipboard.writeText(subject)
+})
+```
+```html
+<button @click="$clipboard('hello world')">Copy "Hello World"</button>
+```
+
+Now that accessing `$clipboard` returns a function itself, we can immediately call it and pass it an argument like we see in the template with `$clipboard('hello world')`.
+
+You can use the more brief syntax (a double arrow function) for returning a function from a function if you'd prefer:
+
+```js
+Alpine.magic('clipboard', () => subject => {
+    navigator.clipboard.writeText(subject)
+})
+```
+
+<a name="writing-and-sharing-plugins"></a>
+## Writing and sharing plugins
+
+By now you should see how friendly and simple it is to register your own custom directives and magics in your application, but what about sharing that functionality with others via an NPM package or something?
+
+You can get started quickly with Alpine's official "plugin-blueprint" package. It's as simple as cloning the repository and running `npm install && npm run build` to get a plugin authored.
+
+Otherwise, let's create a pretend Alpine plugin by hand called `Foo` that includes both a directive (`x-foo`) and a magic (`$foo`).
+
+We'll start with what producing this plugin for consumption as a simple `<script>` tag alongside Alpine, then we'll level it up to a module for importing into a bundle:
+
+<a name="script-include"></a>
+### Script include
+
+Let's start in reverse by looking at how our plugin will be included into a project:
+
+```html
+<html>
+    <script src="/js/foo.js" defer></script>
+    <script src="/js/alpine.js" defer></script>
+
+    <div x-data x-init="$foo()">
+        <span x-foo="'hello world'">
+    </div>
+</html>
+```
+
+Notice how our script is included BEFORE Alpine itself. This is important, otherwise, Alpine would have already been initialized by the time our plugin got loaded.
+
+Now let's look inside of `/js/foo.js`'s contents:
+
+```js
+document.addEventListener('alpine:initializing', () => {
+    window.Alpine.directive('foo', ...)
+
+    window.Alpine.magic('foo', ...)
+})
+```
+
+That's it! Authoring a plugin for inclusion via a script tag is extremely simple with Alpine.
+
+<a name="bundle-module"></a>
+### Bundle module
+
+Now let's say you wanted to author a plugin that someone could install via NPM and include into their bundle.
+
+Like the last example, we'll walk through this in reverse, starting with what it will look like to consume this plugin:
+
+```js
+import Alpine from 'alpinejs'
+
+import foo from 'foo'
+Alpine.plugin(foo)
+
+window.Alpine = Alpine
+window.Alpine.start()
+```
+
+You'll notice a new API here: `Alpine.plugin()`. This is a convenience method Alpine exposes to prevent consumers of your plugin from having to register multiple different directives and magics themselves.
+
+Now let's look at the source of the plugin and what gets exported from `foo`:
+
+```js
+export default function (Alpine) {
+    Alpine.directive('foo', ...)
+    Alpine.magic('foo', ...)
+}
+```
+
+You'll see that `Alpine.plugin` is incredibly simple. It accepts a callback and immediately invokes it while providing the `Alpine` global as a parameter for use inside of it.
+
+Then you can go about extending Alpine as you please.

+ 101 - 0
packages/docs/src/en/advanced/reactivity.md

@@ -0,0 +1,101 @@
+---
+order: 1
+title: Reactivity
+---
+
+# Reactivity
+
+Alpine is "reactive" in the sense that when you change a peice of data, everything that depends on that data "reacts" automatically to that change.
+
+Every bit of reactivity that takes place in Alpine, happens because of two very important reactive functions in Alpine's core: `Alpine.reactive()`, and `Alpine.effect()`.
+
+> Alpine uses VueJS's reactivity engine under the hood to provide these functions.
+> [→ Read more about @vue/reactivity](https://github.com/vuejs/vue-next/tree/master/packages/reactivity)
+
+Understanding these two functions will give you super powers as an Alpine developer, but also just as a web developer in general.
+
+<a name="alpine-reactive"></a>
+## Alpine.reactive()
+
+Let's first look at `Alpine.reactive()`. This function accepts a JavaScript object as its parameter and returns a "reactive" version of that object. For example:
+
+```js
+let data = { count: 1 }
+
+let reactiveData = Alpine.reactive(data)
+```
+
+Under the hood, when `Alpine.reactive` receives `data`, it wraps it inside a custom JavaScript proxy.
+
+A proxy is a special kind of object in JavaScript that can intercept "get" and "set" calls to a JavaScript objct.
+
+[→ Read more about JavaScript proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
+
+At face value, `reactiveData` should behave exactly like `data`. For example:
+
+```js
+console.log(data.count) // 1
+console.log(reactiveData.count) // 1
+
+reactiveData.count = 2
+
+console.log(data.count) // 2
+console.log(reactiveData.count) // 2
+```
+
+What you see here is that because `reactiveData` is a thin wrapper around `data`, any attempts to get or set a property will behave exactly as if you had interacted with `data` directly.
+
+The main difference here is that any time you modify or retreive (get or set) a value from `reactiveData`, Alpine is aware of it and can execute any other logic that depends on this data.
+
+`Alpine.reactive` is only the first half of the story. `Alpine.effect` is the other half, let's dig in.
+
+<a name="alpine-effect"></a><a name="alpine-effect"></a>
+## Alpine.effect()
+
+`Alpine.effect` accepts a single callback function. As soon as `Alpine.effect` is called, it will run the provided function, but actively look for any interactions with reactive data. If it detects an interaction (a get or set from the aforementioned reactive proxy) it will keep track of it and make sure to re-run the callback if any of reactive data changes in the future. For example:
+
+```js
+let data = Alpine.reactive({ count: 1 })
+
+Alpine.effect(() => {
+    console.log(data.count)
+})
+```
+
+When this code is firt run, "1" will be logged to the console. Any time `data.count` changes, it's value will be logged to the console again.
+
+This is the mechanism that unlocks all of the reactivity at the core of Alpine.
+
+To connect the dots further, let's look at a simple "counter" component example without using Alpine syntax at all, only using `Alpine.reactive` and `Alpine.effect`:
+
+```html
+<button>Increment</button>
+
+Count: <span></span>
+```
+```js
+let button = document.querySelector('button')
+let span = document.querySelector('span')
+
+let data = Alpine.reactive({ count: 1 })
+
+Alpine.effect(() => {
+    span.textContent = data.count
+})
+
+button.addEventListener('click', () => {
+    data.count = data.count + 1
+})
+```
+
+<!-- START_VERBATIM -->
+<div x-data="{ count: 1 }" class="demo">
+    <button @click="count++">Increment</button>
+
+    <div>Count: <span x-text="count"></span></div>
+</div>
+<!-- END_VERBATIM -->
+
+As you can see, you can make any data reactive, and you can also wrap any functionality in `Alpine.effect`.
+
+This combination unlocks an incredibly powerful programming paradaigm for web development. Run wild and free.

+ 326 - 0
packages/docs/src/en/alpine-101.md

@@ -0,0 +1,326 @@
+---
+order: 1
+title: Alpine 101
+---
+
+# Alpine 101
+
+Create a blank HTML file somewhere on you computer with a name like: `i-love-alpine.html`
+
+Using a text editor, fill the file with these contents:
+
+```html
+<html>
+<head>
+    <script defer src="https://something.com/alpine.js"></script>
+</head>
+<body>
+    <h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1>
+</body>
+</html>
+```
+
+Open your file in a web browser, if you see `I ❤️ Alpine`, you're ready to rumble!
+
+Now that you're all set up to play around, let's look at three practical examples as a foundation for teaching you the basics of Alpine. By the end of this excercise, you should be more than equipped to start building stuff on your own. Let's goooooo.
+
+<!-- START_VERBATIM -->
+<ul class="flex flex-col space-y-2 list-inside !list-decimal">
+    <li><a href="#building-a-counter">Building a counter</a></li>
+    <li><a href="#building-a-dropdown">Building a dropdown</a></li>
+    <li><a href="#building-a-search-input">Building a search Input</a></li>
+</ul>
+<!-- END_VERBATIM -->
+
+<a name="building-a-counter"></a>
+## Building a counter
+
+Let's start with a simple "counter" component to demonstrate the basics of state and event listening in Alpine, two core features.
+
+Insert the following into the `<body>` tag:
+
+```html
+<div x-data="{ count: 0 }">
+    <button x-on:click="count++">Increment</button>
+
+    <span x-text="count"></span>
+</div>
+```
+
+<!-- START_VERBATIM -->
+<div class="demo">
+    <div x-data="{ count: 0 }">
+        <button x-on:click="count++">Increment</button>
+        <span x-text="count"></span>
+    </div>
+</div>
+<!-- END_VERBATIM -->
+
+Now, you can see with 3 bits of Alpine sprinkled into this HTML, we've created an interactive "counter" component.
+
+Let's walk through what's happening briefly:
+
+<a name="declaring-data"></a>
+### Declaring data
+
+```html
+<div x-data="{ count: 0 }">
+```
+
+Everything in Alpine starts with an `x-data` directive. Inside of `x-data`, in plain JavaScript, you declare an object of data that Alpine will track.
+
+Every property inside this object will be made available to other directives inside this HTML element. In addition, when one of these properties changes, everything that relies on it will change as well.
+
+[→ Read more about `x-data`](/directives/data)
+
+Let's look at `x-on` and see how it can access and modify the `count` property from above:
+
+<a name="listening-for-events"></a>
+### Listening for events
+
+```html
+<button x-on:click="count++">Increment</button>
+```
+
+`x-on` is a directive you can use to listen for any event on an element. We're listening for a `click` event in this case, so ours looks like `x-on:click`.
+
+You can listen for other events as you'd imagine. For example, listening for a `mouseenter` event would look like this: `x-on:mouseenter`.
+
+When a `click` event happens, Alpine will call the associated JavaScript expression, `count++` in our case. As you can see, we have direct access to data declared in the `x-data` expression.
+
+> You will often see `@` instead of `x-on`. This is a shorter, friendlier syntax that many prefer. From now on, this documentation will likely use `@` instead of `x-on`.
+
+[→ Read more about `x-on`](/directives/on)
+
+<a name="reacting-to-changes"></a>
+### Reacting to changes
+
+```html
+<h1 x-text="count"></h1>
+```
+
+`x-text` is an Alpine directive you can use to set the text content of an element to the result of a JavaScript expression.
+
+In this case, we're telling Alpine to always make sure that the contents of this `h1` tag reflect the value of the `count` property.
+
+In case it's not clear, `x-text`, like most directives accepts a plain JavaScript expression as an argument. So for example, you could instead set its contents to: `x-text="count * 2"` and the text content of the `h1` will now always be 2 times the value of `count`.
+
+[→ Read more about `x-text`](/directives/text)
+
+<a name="building-a-dropdown"></a>
+## Building a dropdown
+
+Now that we've seen some basic functionality, let's keep going and look at an important directive in Alpine: `x-show`, by building a contrived "dropdown" component.
+
+Insert the following code into the `<body>` tag:
+
+```html
+<div x-data="{ open: false }">
+    <button @click="open = ! open">Toggle</button>
+
+    <div x-show="open" @click.outside="open = false">Contents...</div>
+</div>
+```
+
+<!-- START_VERBATIM -->
+<div class="demo">
+    <div x-data="{ open: false }">
+        <button @click="open = ! open">Toggle</button>
+        <div x-show="open" @click.outside="open = false">Contents...</div>
+    </div>
+</div>
+<!-- END_VERBATIM -->
+
+If you load this component, you should see that the "Contents..." are hidden by default. You can toggle showing them on the page by clicking the "Toggle" button.
+
+The `x-data` and `x-on` directives should be familiar to you from the previous example, so we'll skip those explanations.
+
+<a name="toggling-elements"></a>
+### Toggling elements
+
+```html
+<div x-show="open" ...>Contents...</div>
+```
+
+`x-show` is an extremely powerful directive in Alpine that can be used to show and hide a block of HTML on a page based on the result of a JavaScript expression, in our case: `open`.
+
+[→ Read more about `x-show`](/directives/show)
+
+<a name="listening-for-a-click-outside"></a>
+### Listening for a click outside
+
+```html
+<div ... @click.outside="open = false">Contents...</div>
+```
+
+You'll notice something new in this example: `.outside`. Many directives in Alpine accept "modifiers" that are chained onto the end of the directive and are seperated by periods.
+
+In this case, `.outside` tells Alpine to instead of listening for a click INSIDE the `<div>`, to listen for the click only if it happens OUTSIDE the `<div>`.
+
+This is a convenience helper built into Alpine because this is a common need and implementing it by hand is annoying and complex.
+
+[→ Read more about `x-on` modifiers](/directives/on#modifiers)
+
+<a name="building-a-search-input"></a>
+## Building a search input
+
+Let's now build a more complex component and introduce a handful of other directives and patterns.
+
+Insert the following code into the `<body>` tag:
+
+```html
+<div
+    x-data="{
+        search: '',
+
+        items: ['foo', 'bar', 'baz'],
+
+        get filteredItems() {
+            return this.items.filter(
+                i => i.startsWith(this.search)
+            )
+        }
+    }"
+>
+    <input x-model="search" placeholder="Search...">
+
+    <ul>
+        <template x-for="item in filteredItems" :key="item">
+            <li x-text="item"></li>
+        </template>
+    </ul>
+</div>
+```
+
+<!-- START_VERBATIM -->
+<div class="demo">
+    <div
+        x-data="{
+            search: '',
+
+            items: ['foo', 'bar', 'baz'],
+
+            get filteredItems() {
+                return this.items.filter(
+                    i => i.startsWith(this.search)
+                )
+            }
+        }"
+    >
+        <input x-model="search" placeholder="Search...">
+
+        <ul class="pl-6 pt-2">
+            <template x-for="item in filteredItems" :key="item">
+                <li x-text="item"></li>
+            </template>
+        </ul>
+    </div>
+</div>
+<!-- END_VERBATIM -->
+
+By default, all of the "items" (foo, bar, and baz) will be shown on the page, but you can filter them by typing into the text input. As you type, the list of items will change to reflect what you're searching for.
+
+Now there's quite a bit happening here, so let's go through this snippet piece by piece.
+
+<a name="multi-line-formatting"></a>
+### Multi line formatting
+
+The first thing I'd like to point out is that `x-data` now has a lot more going on in it than before. To make it easier to write and read, we've split it up into multiple lines in our HTML. This is completely optional and we'll talk more in a bit about how to avoid this problem alltogether, but for now, we'll keep all of this JavaScript directly in the HTML.
+
+<a name="binding-to-inputs"></a>
+### Binding to inputs
+
+```html
+<input x-model="search" placeholder="Search...">
+```
+
+You'll notice a new directive we haven't seen yet: `x-model`.
+
+`x-model` is used to "bind" the value of an input element with a data property: "search" from `x-data="{ search: '', ... }"` in our case.
+
+This means that anytime the value of the input changes, the value of "search" will change to reflect that.
+
+`x-model` is capable of much more than this simple example.
+
+[→ Read more about `x-model`](/directives/model)
+
+<a name="computed-properties-using-getters"></a>
+### Computed properties using getters
+
+The next bit I'd like to draw your attention to is the `items` and `filteredItems` properties from the `x-data` directive.
+
+```js
+{
+    ...
+    items: ['foo', 'bar', 'baz'],
+
+    get filteredItems() {
+        return this.items.filter(
+            i => i.startsWith(this.search)
+        )
+    }
+}
+```
+
+The `items` property should be self-explanitory. Here we are setting the value of `items` to a JavaScript array of 3 different items (foo, bar, and baz).
+
+The interesting part of this snippet is the `filteredItems` property.
+
+Denoted by the `get` prefix for this property, `filteredItems` is a "getter" property in this object. This means we can access `filteredItems` as if it was a normal property in our data object, but when we do, JavaScript will evaluate the provided function under the hood and return the result.
+
+It's completely acceptable to forgo the `get` and just make this a method that you can call from the template, but some prefer the nicer syntax of the getter.
+
+[→ Read more about JavaScript getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
+
+Now let's look inside the `filteredItems` getter and make sure we understand what's going on there:
+
+```js
+return this.items.filter(
+    i => i.startsWith(this.search)
+)
+```
+
+This is all plain JavaScript. We are first getting the array of items (foo, bar, and baz) and filtering them using the provided callback: `i => i.startsWith(this.search)`.
+
+By passing in this callback to `filter`, we are telling JavaScript to only return the items that start with the string: `this.search`, which like we saw with `x-model` will always reflect the value of the input.
+
+You may notice that up until now, we haven't had to use `this.` to reference properties. However, because we are working directly inside the `x-data` object, we must reference any properties using `this.[property]` instead of simply `[property]`.
+
+Because Alpine is a "reactive" framework. Any time the value of `this.search` changes, parts of the template that use `filteredItems` will automatically be updated.
+
+<a name="looping-elements"></a>
+### Looping elements
+
+Now that we understand the data part of our component, let's understand what's happening in the template that allows us to loop through `filteredItems` on the page.
+
+```html
+<ul>
+    <template x-for="item in filteredItems">
+        <li x-text="item"></li>
+    </template>
+</ul>
+```
+
+The first thing to notice here is the `x-for` directive. `x-for` expressions take the following form: `[item] in [items]` where [items] is any array of data, and [item] is the name of the variable that will be assigned to an iteration inside the loop.
+
+Also notice that `x-for` is declared on a `<template>` element and not directly on the `<li>`. This is a requirement of using `x-for`. It allows Alpine to leverage the existing behavior of `<template>` tags in the browser to its advantage.
+
+Now any element inside the `<template>` tag will be repeated for every item inside `filteredItems` and all expressions evaluated inside the loop will have direct access to the iteration variable (`item` in this case).
+
+[→ Read more about `x-for`](/directives/for)
+
+<a name="recap"></a>
+## Recap
+
+If you've made it this far, you've been exposed to the following directives in Alpine:
+
+* x-data
+* x-on
+* x-text
+* x-show
+* x-model
+* x-for
+
+That's a great start, however, there are many more directives to sink your teeth into. The best way to absorb Alpine is to read through this documentation. No need to comb over every word, but if you at least glance through every page you will be MUCH more effective when using Alpine.
+
+Happy Coding!

+ 7 - 0
packages/docs/src/en/directives.md

@@ -0,0 +1,7 @@
+---
+order: 4
+title: Directives
+prefix: x-
+font-type: mono
+type: sub-directory
+---

+ 189 - 0
packages/docs/src/en/directives/bind.md

@@ -0,0 +1,189 @@
+---
+order: 4
+title: bind
+---
+
+# `x-bind`
+
+`x-bind` allows you to set HTML attributes on elements based on the result of JavaScript expressions.
+
+For example, here's a component where we will use `x-bind` to set the placeholder value of an input.
+
+```html
+<div x-data="{ placeholder: 'Type here...' }">
+  <input type="text" x-bind:placeholder="placeholder">
+</div>
+```
+
+<a name="shorthand-syntax"></a>
+## Shorthand syntax
+
+If `x-bind:` is too verbose for your liking, you can use the shorthand: `:`. For example, here is the same input element as above, but refactored to use the shorthand syntax.
+
+```html
+<input type="text" :placeholder="placeholder">
+```
+
+<a name="binding-classes"></a>
+## Binding classes
+
+`x-bind` is most often useful for setting specific classes on an element based on your Alpine state.
+
+Here's a simple example of a simple dropdown toggle, but instead of using `x-show`, we'll use a "hidden" class to toggle an element.
+
+```html
+<div x-data="{ open: false }">
+  <button x-on:click="open = ! open">Toggle Dropdown</button>
+
+  <div :class="open ? '' : 'hidden'">
+    Dropdown Contents...
+  </div>
+</div>
+```
+
+Now, when `open` is `false`, the "hidden" class will be added to the dropdown.
+
+<a name="shorthand-conditionals"></a>
+### Shorthand conditionals
+
+In cases like these, if you prefer a less verbose syntax you can use JavaScript's short-circuit evaluation instead of standard conditionals:
+
+```html
+<div :class="show ? '' : 'hidden'">
+<!-- Is equivelant to: -->
+<div :class="show || 'hidden'">
+```
+
+The inverse is also available to you. Suppose instead of `open`, we use a variable with the opposite value: `closed`.
+
+```html
+<div :class="closed ? 'hidden' : ''">
+<!-- Is equivelant to: -->
+<div :class="closed && 'hidden'">
+```
+
+<a name="class-object-syntax"></a>
+### Class object syntax
+
+Alpine offers an additional syntax for toggling classes if you prefer. By passing a JavaScript object where the classes are the keys and booleans are the values, Alpine will know which classes to apply and which to remove. For example:
+
+```html
+<div :class="{ 'hidden': ! show }">
+```
+
+This technique offers a unique advantage to other methods. When using object-syntax, Alpine will NOT preserve original classes applied to an element's `class` attribute.
+
+For example, if you wanted to apply the "hidden" class to an element before Alpine loads, AND use Alpine to toggle its existance you can only achieve that behavior using object-syntax:
+
+```html
+<div class="hidden" :class="{ 'hidden': ! show }">
+```
+
+In case that confused you, let's dig deeper into how Alpine handles `x-bind:class` differently than other attributes.
+
+<a name="special-behavior"></a>
+### Special behavior
+
+`x-bind:class` behaves differently than other attributes under the hood.
+
+Consider the following case.
+
+```html
+<div class="opacity-50" :class="hide && 'hidden'">
+```
+
+If "class" were any other attribute, the `:class` binding would overwrite any existing class attribute, causing `opacity-50` to be overwritten by either `hidden` or `''`.
+
+However, Alpine treats `class` bindings differently. It's smart enough to preserve existing classes on an element.
+
+For example, if `hide` is true, the above example will result in the following DOM element:
+
+```html
+<div class="opacity-50 hidden">
+```
+
+If `hide` is false, the DOM element will look like:
+
+```html
+<div class="opacity-50">
+```
+
+This behavior should be invisible and intuitive to most users, but it is worth mentioning explicitly for the inquiring developer or any special cases that might crop up.
+
+<a name="binding-styles"></a>
+## Binding styles
+
+Similar to the special syntax for binding classes with JavaScript objects, Alpine also offers an object-based syntax for binding `style` attributes.
+
+Just like the class objects, this syntax is entirely optional. Only use it if it affords you some advantage.
+
+```html
+<div :style="{ color: 'red', display: 'flex' }">
+
+<!-- Will render: -->
+<div style="color: red; display: flex;" ...>
+```
+
+One advantage of this approach is being able to mix it in with existing styles on an element:
+
+```html
+<div style="padding: 1rem;" :style="{ color: 'red', display: 'flex' }">
+
+<!-- Will render: -->
+<div style="padding: 1rem; color: red; display: flex;" ...>
+```
+
+And like most expressions in Alpine, you can always use the result of a JavaScript expression as the reference:
+
+```html
+<div x-data="{ styles: { color: 'red', display: 'flex' }}">
+    <div :style="styles">
+</div>
+
+<!-- Will render: -->
+<div ...>
+    <div style="color: red; display: flex;" ...>
+</div>
+```
+
+<a name="bind-directives"></a>
+## Binding Alpine Directives Directly
+
+`x-bind` allows you to bind an object of different properties to an element.
+
+The object keys are the directives (can be any directive including modifiers), and the values are callbacks to be evaluated by Alpine.
+
+```html
+<div x-data="dropdown()">
+    <button x-bind="trigger">Open Dropdown</button>
+
+    <span x-bind="dialogue">Dropdown Contents</span>
+</div>
+
+<script>
+    document.addEventListener('alpine:initializing', () => {
+        Alpine.data('dropdown', () => ({
+            open: false,
+
+            trigger: {
+                ['@click']() {
+                    this.open = true
+                },
+            },
+
+            dialogue: {
+                ['x-show']() {
+                    return this.open
+                },
+                ['@click.outside']() {
+                    this.open = false
+                },
+            },
+        }))
+    })
+</script>
+```
+
+There are a couple of caveats to this usage of `x-bind`:
+
+> When the directive being "bound" or "applied" is `x-for`, you should return a normal expression string from the callback. For example: `['x-for']() { return 'item in items' }`

+ 38 - 0
packages/docs/src/en/directives/cloak.md

@@ -0,0 +1,38 @@
+---
+order: 12
+title: cloak
+---
+
+# `x-cloak`
+
+Sometimes, when you're using AlpineJS for a part of your template, there is a "blip" where you might see your uninitialized template after the page loads, but before Alpine loads.
+
+`x-cloak` addresses this scenerio by hiding the element it's attached to until Alpine is fully loaded on the page.
+
+For `x-cloak` to work however, you must add the following CSS to the page.
+
+```css
+[x-cloak] { display: none !important; }
+```
+
+Now, the following example will hide the `<span>` tag until Alpine has set its text content to the `message` property.
+
+```html
+<span x-cloak x-text="message"></span>
+```
+
+When Alpine loads on the page, it removes all `x-cloak` property from the element, which also removes the `display: none;` applied by CSS, therefore showing the element.
+
+If you'd like to achieve this same behavior, but avoid having to include a global style, you can use the following cool, but admittadly odd trick:
+
+```html
+<template x-if="true">
+    <span x-text="message"></span>
+</template>
+```
+
+This will achieve the same goal as `x-cloak` by just leveraging the way `x-if` works.
+
+Because `<template>` elements are "hidden" in browsers by default, you won't see the `<span>` until Alpine has had a chance to render the `x-if="true"` and show it.
+
+Again, this solution is not for everyone, but it's worth mentioning for special cases.

+ 170 - 0
packages/docs/src/en/directives/data.md

@@ -0,0 +1,170 @@
+---
+order: 1
+title: data
+---
+
+# `x-data`
+
+Everything in Alpine starts with the `x-data` directive.
+
+`x-data` defines a chunk of HTML as an Alpine component and provides the reactive data for that component to reference.
+
+Here's an example of a contrived dropdown component:
+
+```html
+<div x-data="{ open: false }">
+    <button @click="open = ! open">Toggle Content</button>
+
+    <div x-show="open">
+        Content...
+    </div>
+</div>
+```
+
+Don't worry about the other directives in this example (`@click` and `x-show`), we'll get to those in a bit. For now, let's focus on `x-data`.
+
+<a name="scope"></a>
+## Scope
+
+Properties defined in an `x-data` directive are available to all element children. Even ones inside other, nested `x-data` components.
+
+For example:
+
+```html
+<div x-data="{ foo: 'bar' }">
+    <span x-text="foo"><!-- Will output: "bar" --></span>
+
+    <div x-data="{ bar: 'baz' }">
+        <span x-text="foo"><!-- Will output: "bar" --></span>
+
+        <div x-data="{ foo: 'bob' }">
+            <span x-text="foo"><!-- Will output: "bob" --></span>
+        </div>
+    </div>
+</div>
+```
+
+<a name="methods"></a>
+## Methods
+
+Because `x-data` is evaluated as a normal JavaScript object, in addition to state, you can store methods and even getters.
+
+For example, let's extract the "Toggle Content" behavior into a method on  `x-data`.
+
+```html
+<div x-data="{ open: false, toggle() { this.open = ! this.open } }">
+    <button @click="toggle()">Toggle Content</button>
+
+    <div x-show="open">
+        Content...
+    </div>
+</div>
+```
+
+Notice the added `toggle() { this.open = ! this.open }` method on `x-data`. This method can now be called from anywhere inside the component.
+
+You'll also notice the usage of `this.` to access state on the object itself. This is because Alpine evaluates this data object like any standard JavaScript object with a `this` context.
+
+If you prefer, you can leave the calling parenthesis off of the `toggle` method completely. For example:
+
+```html
+<!-- Before -->
+<button @click="toggle()">...</button>
+
+<!-- After -->
+<button @click="toggle">...</button>
+```
+
+<a name="getters"></a>
+## Getters
+
+JavaScript [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) are handy when the sole purpose of a method is to return data based on other state.
+
+Think of them like "computed properties" (although, they are not cached like Vue's computed properties).
+
+Let's refactor our component to use a getter called `isOpen` instead of accessing `open` directly.
+
+```html
+<div x-data="{
+  open: false,
+  get isOpen() { return this.open },
+  toggle() { this.open = ! this.open },
+}">
+    <button @click="toggle()">Toggle Content</button>
+
+    <div x-show="isOpen">
+        Content...
+    </div>
+</div>
+```
+
+Notice the "Content" now depends on the `isOpen` getter instead of the `open` property directly.
+
+In this case there is no tangible benefit. But in some cases, getters are helpful for providing a more expressive syntax in your components.
+
+<a name="data-less-components"></a>
+## Data-less components
+
+Occasionally, you want to create an Alpine component, but you don't need any data.
+
+In these cases, you can always pass in an empty object.
+
+```html
+<div x-data="{}"...
+```
+
+However, if you wish, you can also eliminate the attribute value entirely if it looks better to you.
+
+```html
+<div x-data...
+```
+
+<a name="single-element-components"></a>
+## Single-element components
+
+Sometimes you may only have a single element inside your Alpine component, like the following:
+
+```html
+<div x-data="{ open: true }">
+    <button @click="open = false" x-show="open">Hide Me</button>
+</div>
+```
+
+In these cases, you can declare `x-data` directly on that single element:
+
+```html
+<button x-data="{ open: true }" @click="open = false" x-show="show">
+    Hide Me
+</button>
+```
+
+<a name="re-usable-data"></a>
+## Re-usable Data
+
+If you find yourself duplicating the contents of `x-data`, or you find the inline syntax verbose, you can extract the `x-data` object out to a dedicated component using `Alpine.data`.
+
+Here's a quick example:
+
+```html
+<div x-data="dropdown">
+    <button @click="toggle">Toggle Content</button>
+
+    <div x-show="open">
+        Content...
+    </div>
+</div>
+
+<script>
+    document.addEventListener('alpine:intializing', () => {
+        Alpine.data('dropdown', () => ({
+            open: false,
+
+            toggle() {
+                this.open = ! this.open
+            },
+        }))
+    })
+</script>
+```
+
+[→ Read more about `Alpine.data(...)`](/globals/alpine-data)

+ 20 - 0
packages/docs/src/en/directives/effect.md

@@ -0,0 +1,20 @@
+---
+order: 11
+title: effect
+---
+
+# `x-effect`
+
+`x-effect` is a useful directive for re-evaluating an expression when one of its dependancies change. You can think of it as a watcher where you don't have to specify what property to watch, it will watch all properties used within it.
+
+If this definition is confusing for you, that's ok. It's better explained through an example:
+
+```html
+<div x-data="{ label: 'Hello' }" x-effect="console.log(label)">
+    <button @click="label += ' World!'">Change Message</button>
+</div>
+```
+
+When this component is loaded, the `x-effect` expression will be run and "Hello" will be logged into the console.
+
+Because Alpine knows about any property references contained within `x-effect`, when the button is clicked and `label` is changed", the effect will be retriggered and "Hello World!" will be logged to the console.

+ 87 - 0
packages/docs/src/en/directives/for.md

@@ -0,0 +1,87 @@
+---
+order: 8
+title: for
+---
+
+# `x-for`
+
+Alpine's `x-for` directive allows you to create DOM elements by iterating through a list. Here's a simple example of using it to create a list of colors based on an array.
+
+```html
+<ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
+    <template x-for="color in colors">
+        <li x-text="color"></li>
+    </template>
+</ul>
+```
+
+<!-- START_VERBATIM -->
+<div class="demo">
+    <ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
+        <template x-for="color in colors">
+            <li x-text="color"></li>
+        </template>
+    </ul>
+</div>
+<!-- END_VERBATIM -->
+
+There are two rules worth noting about `x-for`:
+
+* `x-for` MUST be declared on a `<template>` element
+* That `<template>` element MUST have only one root element
+
+<a name="keys"></a>
+## Keys
+
+It is important to specificy keys for each `x-for` iteration if you are going to be re-ordering items. Without dynamic keys, Alpine may have a hard time keeping track of what re-orders and will cause odd side-effects.
+
+```html
+<ul x-data="{ colors: [
+    { id: 1, label: 'Red' },
+    { id: 2, label: 'Orange' },
+    { id: 3, label: 'Yellow' },
+]}">
+    <template x-for="color in colors" :key="color.id">
+        <li x-text="color.label"></li>
+    </template>
+</ul>
+```
+
+Now if the colors are added, removed, re-ordered, or their "id"s change, Alpine will preserve or destroy the iterated `<li>`elements accordingly.
+
+<a name="accessing-indexes"></a>
+## Accessing indexes
+
+If you need to access the index of each item in the iteration, you can do so using the `([item], [index]) in [items]` syntax like so:
+
+```html
+<ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
+    <template x-for="(color, index) in colors">
+        <li>
+            <span x-text="index + ': '"></span>
+            <span x-text="color"></span>
+        </li>
+    </template>
+</ul>
+```
+
+You can also access the index inside a dynamic `:key` expression.
+
+```html
+<template x-for="(color, index) in colors" :key="index">
+```
+
+<a name="iterating-over-a-range"></a>
+## Iterating over a range
+
+If you need to simply loop `n` number of times, rather than iterate through an array, Alpine offers a short syntax.
+
+```html
+<ul>
+    <template x-for="i in 10">
+        <li x-text="i"></li>
+    </template>
+</ul>
+```
+
+`i` in this case can be named anything you like.

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác