diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..7d4aaa6
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: aryehraber
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43f7d78
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+.DS_Store
+.env
+node_modules/
+package.json
+mix-manifest.json
+webpack.config.js
+webpack.mix.js
+gulpfile.js
+yarn.lock
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..f993f1c
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Aryeh Raber
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..102523a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,125 @@
+# Splash (Statamic 3)
+
+**Browse Unsplash images right from the CP.**
+
+## Installation
+
+Install the addon via composer:
+
+```
+composer require aryehraber/statamic-splash
+```
+
+Publish the fieldtype assets & config file:
+
+```
+php artisan vendor:publish --provider="AryehRaber\Splash\SplashServiceProvider"
+```
+
+Once installed, you will need to add an Unsplash API `Access Key` to `config/splash.php`.
+
+You can register for a free account via the [Unsplash Developers page](https://unsplash.com/developers). Next, simply create a "New Application" and use the Demo `Access Key`, which allows 50 requests/hour, or go through the approval process to increase to 5000 requests/hour (this is still free but takes a little more effort). Note: "requests" only refers to search queries in the CP, once an image has been selected you will be referencing the CDN link which doesn't go through the API.
+
+## Usage
+
+Simply add a field inside your blueprint and use `type: splash` to get started.
+
+**Blueprint**
+
+```yaml
+fields:
+ -
+ handle: hero_image
+ field:
+ type: splash
+```
+
+After selecting an image and saving your content, the full Unsplash response data will be accessible in templates using Antlers. The image itself *will not* be saved inside your Asset Container, instead you will be referencing images using Unsplash's CDN, also called Hotlinking (this is required by their [API Guidelines](https://help.unsplash.com/en/articles/2511271-guideline-hotlinking-images)).
+
+The benefit here is that it takes a significant load off your server, since images are often the heaviest assets on a page. Additionally, since Unsplash's CDN is spread worldwide, images will load super fast regardless of the visitor's location.
+
+## Tags
+
+### Raw
+
+`{{ splash:raw :image="field_name" }}`
+
+This tag outputs the CDN link to the image's `raw` URL. Due to the high-quality nature of Unsplash photos, images are often 10-20MB, which is overkill for _most_ websites; you can therefore use a few Glide-like parameters to request exactly what you need (more info below).
+
+**Example**
+
+```html
+{{ splash:raw :image="hero_image" width="2000" quality="80" }}
+```
+
+---
+
+### Image
+
+`{{ splash:image :image="field_name" }}` or `{{ splash:field_name }}`
+
+This tag also outputs the CDN link to the image's `raw` URL, but includes a few sensible defaults to reduce the image filesize a whole lot.
+
+Any of these params can be overriden by using the parameters listed below, the defaults used are:
+
+```php
+'q' => '80',
+'w' => '1500',
+'fit' => 'crop',
+'crop' => 'faces,edges',
+'auto' => 'format',
+```
+
+**Example**
+
+```html
+{{ splash:image :image="hero_image" width="1000" }}
+```
+Or using the shorthand:
+```html
+{{ splash:hero_image width="1000" }}
+```
+
+---
+
+### Attribution
+
+`{{ splash:attribution :image="field_name" }}`
+
+This tag outputs the Unsplash attribution text from their [API Guidelines](https://help.unsplash.com/en/articles/2511315-guideline-attribution), including links to the photographer's profile and Unsplash website.
+
+**Example**
+
+```html
+{{ splash:attribution :image="hero_image" }}
+```
+
+**Output**
+
+```html
+Photo by Annie Spratt on Unsplash
+```
+
+Since the photo's meta data is stored inside your content, you can also loop over the photographer's data using Antlers:
+
+```html
+{{ hero_image:user }}
+
+{{ /hero_image:user }}
+```
+
+### Parameters
+
+Splash offers a number of Glide-like parameters to transform images to your needs. You can pass any [Unsplash parameter](https://unsplash.com/documentation#supported-parameters) into the `raw` and `image` tags to get started. Just like when using Glide within Statamic, you can also use the easier-to-read alias parameters below:
+
+| Param | Description |
+|-------|-------------|
+| `width` | Sets the width (in pixels). |
+| `height` | Sets the height (in pixels). |
+| `square` | Shortcut to set width and height to the same value. |
+| `quality` | Sets the compression quality (value between 0 and 100). |
+| `format` | Encodes the image to a specific format (recommended to use `auto="format"` instead to auto-pick based on visitor's browser). |
+| `dpr` | Adjusts the device pixel ratio of the image. |
+| `fit` | Changes the fit of the image within the specified dimensions ([see all available values on Imgix](https://docs.imgix.com/apis/url/size/fit)). |
+| `crop` | Applies cropping to the image ([see all available values on Imgix](https://docs.imgix.com/apis/url/size/crop)). |
+| `auto` | Automates a baseline level of optimization for the image ([see all available values on Imgix](https://docs.imgix.com/apis/url/auto/auto)). |
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..029763e
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "aryehraber/statamic-splash",
+ "type": "statamic-addon",
+ "description": "Browse Unsplash images right from the CP.",
+ "keywords": [
+ "statamic",
+ "unsplash",
+ "splash"
+ ],
+ "homepage": "https://github.com/aryehraber/statamic-splash",
+ "license": "MIT",
+ "require": {
+ "statamic/cms": "3.0.*@beta"
+ },
+ "autoload": {
+ "psr-4": {
+ "AryehRaber\\Splash\\": "src"
+ }
+ },
+ "authors": [
+ {
+ "name": "Aryeh Raber",
+ "email": "aryeh.raber@gmail.com",
+ "homepage": "https://aryeh.dev",
+ "role": "Developer"
+ }
+ ],
+ "extra": {
+ "statamic": {
+ "name": "Splash",
+ "description": "Browse Unsplash images right from the CP.",
+ "version": "1.0.0"
+ },
+ "laravel": {
+ "providers": [
+ "AryehRaber\\Splash\\SplashServiceProvider"
+ ]
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
+}
diff --git a/config/splash.php b/config/splash.php
new file mode 100644
index 0000000..a83df9f
--- /dev/null
+++ b/config/splash.php
@@ -0,0 +1,6 @@
+ env('UNSPLASH_KEY', ''),
+ 'default_thumb_size' => 'small',
+];
diff --git a/resources/dist/js/splash-fieldtype.js b/resources/dist/js/splash-fieldtype.js
new file mode 100644
index 0000000..c4603c2
--- /dev/null
+++ b/resources/dist/js/splash-fieldtype.js
@@ -0,0 +1 @@
+!function(t){var e={};function n(s){if(e[s])return e[s].exports;var i=e[s]={i:s,l:!1,exports:{}};return t[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,s){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(n.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(s,i,function(e){return t[e]}.bind(null,i));return s},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=1)}([function(t,e,n){var s=n(3);"string"==typeof s&&(s=[[t.i,s,""]]);var i={hmr:!0,transform:void 0,insertInto:void 0};n(5)(s,i);s.locals&&(t.exports=s.locals)},function(t,e,n){t.exports=n(7)},function(t,e,n){"use strict";var s=n(0);n.n(s).a},function(t,e,n){(t.exports=n(4)(!1)).push([t.i,"\n.-z-1 { z-index: -1 !important;\n}\n.lazyloaded { transition: all 0.3s ease;\n}\n",""])},function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n=function(t,e){var n=t[1]||"",s=t[3];if(!s)return n;if(e&&"function"==typeof btoa){var i=(a=s,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),r=s.sources.map((function(t){return"/*# sourceURL="+s.sourceRoot+t+" */"}));return[n].concat(r).concat([i]).join("\n")}var a;return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n})).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var s={},i=0;i=0&&f.splice(e,1)}function g(t){var e=document.createElement("style");if(void 0===t.attrs.type&&(t.attrs.type="text/css"),void 0===t.attrs.nonce){var s=function(){0;return n.nc}();s&&(t.attrs.nonce=s)}return b(e,t.attrs),m(t,e),e}function b(t,e){Object.keys(e).forEach((function(n){t.setAttribute(n,e[n])}))}function w(t,e){var n,s,i,r;if(e.transform&&t.css){if(!(r="function"==typeof e.transform?e.transform(t.css):e.transform.default(t.css)))return function(){};t.css=r}if(e.singleton){var a=u++;n=c||(c=g(e)),s=_.bind(null,n,a,!1),i=_.bind(null,n,a,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(t){var e=document.createElement("link");return void 0===t.attrs.type&&(t.attrs.type="text/css"),t.attrs.rel="stylesheet",b(e,t.attrs),m(t,e),e}(e),s=S.bind(null,n,e),i=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=g(e),s=C.bind(null,n),i=function(){v(n)});return s(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;s(t=e)}else i()}}t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=a()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=p(t,e);return h(n,e),function(t){for(var s=[],i=0;i0&&void 0!==arguments[0]&&arguments[0];if(!this.loading){this.loading=!0,this.error=null,e&&this.searchPage++;var n="https://api.unsplash.com",s=this.searchQuery?"/search/photos":"/photos",i={client_id:this.meta.access_key,query:this.searchQuery,page:this.searchPage,per_page:30};this.$axios.get("".concat(n).concat(s),{params:i}).then((function(n){var s=n.data,i=s.results||s;t.images=e?t.images.concat(i):i,t.hasNextPage=s.total_pages?s.total_pages>t.searchPage:null,t.loading=!1})).catch((function(e){if(e.response){var n=e.response,s=n.data,i=n.status;t.error={data:s,status:i}}}))}},loadMore:function(){this.search(!0)},openBrowser:function(){this.showBrowser=!0,this.search()},closeBrowser:function(){this.showBrowser=!1,this.images=[],this.searchQuery="",this.searchPage=1,this.hasNextPage=null,this.selectedImage=null},openImage:function(t){this.selectedImage=t},closeImage:function(){this.selectedImage=null},select:function(){this.$emit("input",this.selectedImage),this.closeBrowser()},removeImage:function(){this.selectedImage=null,this.$emit("input",null)},setDefaultThumbSize:function(){void 0!==this.config.thumb_size?this.selectedThumbSize=this.config.thumb_size:void 0!==this.meta.default_thumb_size&&(this.selectedThumbSize=this.meta.default_thumb_size)},initInfiniteScroll:function(){var t=this,e=this.$refs.imageContainer;e&&e.addEventListener("scroll",_.throttle((function(){if(!t.loading){t.$refs.loadMoreButton&&e.scrollTop+e.clientHeight>=e.scrollHeight-300&&t.loadMore()}}),250))}},watch:{showBrowser:function(t){t&&setTimeout(this.initInfiniteScroll,100)},searchQuery:function(){this.images=[],this.searchPage=1,this.hasNextPage=null,this.selectedImage=null,this.search()}},created:function(){this.setDefaultThumbSize()}},l=(n(2),s(o,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.meta.access_key?n("div",[n("input-field",{attrs:{value:t.value},on:{open:t.openBrowser,remove:t.removeImage}}),t._v(" "),t.showBrowser?n("stack",{attrs:{name:"unsplash-browser"},on:{closed:t.closeBrowser}},[n("div",{staticClass:"flex flex-col h-full bg-white"},[n("div",{staticClass:"relative flex flex-col h-full"},[t.selectedImage?n("image-viewer",{attrs:{image:t.selectedImage,"thumb-width":t.thumbWidth,"thumb-sizes":t.thumbSizes},on:{close:t.closeImage}}):t._e(),t._v(" "),n("div",{staticClass:"flex items-center justify-between w-full p-2 bg-white"},[n("data-list-search",{attrs:{placeholder:"Search Unsplash..."},model:{value:t.searchQuery,callback:function(e){t.searchQuery=e},expression:"searchQuery"}}),t._v(" "),n("div",{staticClass:"hidden md:flex ml-1"},[n("button",{staticClass:"btn btn-icon icon",class:"large"===t.selectedThumbSize?"icon-resize-100":"icon-resize-full-screen",on:{click:function(e){t.selectedThumbSize="large"===t.selectedThumbSize?"small":"large"}}})])],1),t._v(" "),n("div",{ref:"imageContainer",staticClass:"relative flex-1 w-full h-full",class:{"overflow-y-scroll":!t.selectedImage}},[n("div",{staticClass:"absolute pin p-2"},[n("div",{staticClass:"flex flex-wrap -mx-1"},t._l(t.filteredImages,(function(e){return n("thumb",{key:e.id,attrs:{image:e,width:t.thumbWidth,sizes:t.thumbSizes},on:{open:function(n){return t.openImage(e)}}})})),1),t._v(" "),t.canLoadMore?n("div",{staticClass:"z-20 p-2 pb-4 text-center"},[n("button",{ref:"loadMoreButton",staticClass:"btn",attrs:{disabled:t.loading},domProps:{textContent:t._s(t.loading?"Loading...":"Load More")},on:{click:t.loadMore}})]):t._e(),t._v(" "),t.error?n("div",{staticClass:"pb-5 font-medium text-center text-red",domProps:{textContent:t._s("Unsplash Error: "+t.error.data+" ("+t.error.status+")")}}):t._e()])])],1),t._v(" "),n("div",{staticClass:"flex items-center justify-end z-20 p-2 bg-grey-20 border-t"},[n("button",{staticClass:"btn",on:{click:t.closeBrowser}},[t._v("\n Cancel\n ")]),t._v(" "),n("button",{staticClass:"btn-primary ml-1",attrs:{disabled:!t.selectedImage},on:{click:t.select}},[t._v("\n Select\n ")])])])]):t._e()],1):n("div",{staticClass:"text-sm"},[n("code",[t._v("Missing Unsplash API Access Key")])])}),[],!1,null,null,null).exports);Statamic.$components.register("splash-fieldtype",l)}]);
\ No newline at end of file
diff --git a/resources/js/Splash.vue b/resources/js/Splash.vue
new file mode 100644
index 0000000..f9aa4c2
--- /dev/null
+++ b/resources/js/Splash.vue
@@ -0,0 +1,295 @@
+
+