From 79367642b1b7bede0add08c982a29aea44382f98 Mon Sep 17 00:00:00 2001
From: snipe <snipe@snipe.net>
Date: Sat, 29 Sep 2018 21:33:52 -0700
Subject: [PATCH] [WIP] Added #5957 - Flysystem support (#6262)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Added AWS url to example env

* Upgrader - added check for new storage path and attempt to move

* Ignore symlink

* Updated paths for models

* Moved copy methods

* Added AWS_URL support

For some reasin, Flysystem was generating the wrong AWS url (with a region included)

* Switch to Flysystem for image uploads

* Nicer display of image preview

* Updated image preview on edit blades to use Flysystem

* Twiddled some more paths

* Working filesystems config

* Updated Asset Models and Departments to use Flysystem

* Janky workaround for differing S3/local urls/paths

* Try to smartly use S3 as public disk if S3 is configured

* Use public disk Storage options for public files

* Additional transformer edits for Flysystem

* Removed debugging

* Added missing use Storage directive

* Updated seeders to use Flysystem

* Default logo

* Set a default width

We can potentially override this in settings later

* Use Flysystem for logo upload

* Update downloadFile to use Flysystem

* Updated AssetFilesController to use Flysystem

* Updated acceptance signatures to use Flysystem

* Updated signature view to use Flysystem

This isn’t working 100% yet

* Use Flysystem facade for displaying asset image

* Set assets path

Should clean all these up when we’re done here

* Added Rackspace support for Flysystem

* Added Flysystem migrator console command

* Added use Storage directive for categories

* Added user avatars to Flysystem

* Added profile avatar to Flysystem

* Added the option to delete local files with the migrator

* Added a check to prevent people from trying to move from local to local

* Fixed the selectlists for Flysystem

* Fixed the getImageUrl method to reflect Flysystem

* Fixed AWS copy process

* Fixed models path

* More selectlist updates for Flysystem

* Updated example .envs with updated env variable names

* *sigh*

* Updated non-asset getImageUrl() methods to use Flysystem

* Removed S3 hardcoding

* Use Flysystem in email headers

* Fixed typo

* Removed camera support from asset file upload

We’ll find a way to add this in later (and add that support to all of the other image uploads as well)

* Fixed path for categories

* WIP - Switched to standard handleImages for asset upload.

This is currently broken as I refact the handleImages method. Because the assets store/create methods use their own Form Request, the handleImages method doesn’t exist in that Form Request so it wil error now.

* Fixed css URL error

* Updated Debugbar to latest version (#6265)

v3.2 adds support for Laravel 5.7

* Fixed: Missing CSS file in basic.blade.php (#6264)

* Fixed missing CSS file in basic.blade.php

* Added

* Changed stylesheet import for authorize.blade.php

* Updated composer lock

* Added AWS_BUCKET_ROOT as env variable

* Use nicer image preview for logo upload

* Removed AssetRequest form request

* Removed asset form request, moved custom field validation into model

* Added additional help text for logo upload

* Increased the size of the image resize - should make this a setting tho

* Few more formatting tweaks to logo section of branding blade preview

* Use Flysystem for asset/license file uploads

* Use Flysystem for removing images from models that have been deleted

* Enable backups to use Flysystem

This only handles part of the problem. This just makes it so we can ship files to S3 if we want, but does not account for how we backup files that are hosted on S3

* Use Flysystem to download license files

* Updated audits to use Flysystem
---
 .env.example                                  |   8 +-
 .env.testing                                  |   8 +-
 .env.testing-ci                               |   8 +-
 app/Console/Commands/MoveUploadsToNewDisk.php | 183 ++++++++
 app/Console/Kernel.php                        |   1 +
 .../Accessories/AccessoriesController.php     |  10 +
 .../Account/AcceptanceController.php          |  15 +-
 .../Controllers/Api/AssetModelsController.php |   5 +-
 app/Http/Controllers/Api/AssetsController.php |   5 +-
 .../Controllers/Api/CategoriesController.php  |   3 +-
 .../Controllers/Api/CompaniesController.php   |   2 +-
 .../Api/CustomFieldsetsController.php         |   1 -
 .../Controllers/Api/DepartmentsController.php |   3 +-
 app/Http/Controllers/Api/ImportController.php |   3 +-
 .../Controllers/Api/LocationsController.php   |   3 +-
 .../Api/ManufacturersController.php           |   3 +-
 .../Controllers/Api/SuppliersController.php   |   3 +-
 app/Http/Controllers/Api/UsersController.php  |   9 +
 .../Controllers/AssetModelsController.php     |   6 +-
 .../Assets/AssetFilesController.php           |  26 +-
 .../Controllers/Assets/AssetsController.php   | 118 ++---
 app/Http/Controllers/CategoriesController.php |   3 +-
 app/Http/Controllers/CompaniesController.php  |  10 +
 .../Components/ComponentsController.php       |  11 +
 .../Controllers/DepartmentsController.php     |   9 +
 .../Licenses/LicenseFilesController.php       |  45 +-
 app/Http/Controllers/LocationsController.php  |  12 +-
 .../Controllers/ManufacturersController.php   |   7 +-
 app/Http/Controllers/ProfileController.php    |  39 +-
 app/Http/Controllers/SettingsController.php   |  84 ++--
 app/Http/Controllers/SuppliersController.php  |   1 +
 app/Http/Requests/AssetRequest.php            |  68 ---
 app/Http/Requests/ImageUploadRequest.php      |  36 +-
 .../Transformers/AccessoriesTransformer.php   |   4 +-
 .../Transformers/ActionlogsTransformer.php    |   2 +-
 .../Transformers/AssetModelsTransformer.php   |   3 +-
 .../Transformers/CategoriesTransformer.php    |   3 +-
 .../Transformers/CompaniesTransformer.php     |   3 +-
 .../Transformers/ComponentsTransformer.php    |   3 +-
 .../Transformers/ConsumablesTransformer.php   |   3 +-
 .../Transformers/DepartmentsTranformer.php    |   3 +-
 .../Transformers/LocationsTransformer.php     |   3 +-
 .../Transformers/ManufacturersTransformer.php |   3 +-
 .../Transformers/SuppliersTransformer.php     |   3 +-
 app/Models/Accessory.php                      |   3 +-
 app/Models/Asset.php                          |  32 +-
 app/Models/AssetModel.php                     |   3 +-
 app/Models/Consumable.php                     |   3 +-
 app/Presenters/UserPresenter.php              |   3 +-
 app/Providers/SettingsServiceProvider.php     |  41 +-
 composer.json                                 |   1 +
 composer.lock                                 | 406 ++++++++++++++----
 config/backup.php                             |   7 +-
 config/filesystems.php                        |  83 ++--
 database/seeds/AssetModelSeeder.php           |  26 +-
 database/seeds/AssetSeeder.php                |  15 +-
 database/seeds/CompanySeeder.php              |  27 +-
 database/seeds/LocationSeeder.php             |  27 +-
 database/seeds/ManufacturerSeeder.php         |  26 +-
 public/img/demo/logo.png                      | Bin 0 -> 22482 bytes
 resources/lang/en/general.php                 |   1 +
 resources/views/accessories/edit.blade.php    |   2 +-
 resources/views/account/profile.blade.php     |   2 +-
 resources/views/categories/edit.blade.php     |   2 +-
 resources/views/companies/edit.blade.php      |   2 +-
 resources/views/components/edit.blade.php     |   2 +-
 resources/views/consumables/edit.blade.php    |   2 +-
 resources/views/departments/edit.blade.php    |   2 +-
 resources/views/hardware/edit.blade.php       | 131 +-----
 resources/views/hardware/view.blade.php       |   4 +-
 resources/views/layouts/basic.blade.php       |   2 +-
 resources/views/layouts/default.blade.php     |   4 +-
 resources/views/locations/edit.blade.php      |   4 +-
 resources/views/manufacturers/edit.blade.php  |   2 +-
 resources/views/models/edit.blade.php         |   2 +-
 .../forms/edit/image-upload.blade.php         |   4 +-
 resources/views/settings/backups.blade.php    |   2 +-
 resources/views/settings/branding.blade.php   |  32 +-
 resources/views/users/view.blade.php          |   6 +-
 .../views/vendor/mail/html/header.blade.php   |   4 +-
 upgrade.php                                   |  59 ++-
 81 files changed, 1093 insertions(+), 662 deletions(-)
 create mode 100644 app/Console/Commands/MoveUploadsToNewDisk.php
 delete mode 100644 app/Http/Requests/AssetRequest.php
 create mode 100644 public/img/demo/logo.png

diff --git a/.env.example b/.env.example
index f6ad25fc1..dee4985cc 100644
--- a/.env.example
+++ b/.env.example
@@ -85,10 +85,12 @@ REDIS_PORT-null
 # --------------------------------------------
 # OPTIONAL: AWS S3 SETTINGS
 # --------------------------------------------
-AWS_SECRET=null
-AWS_KEY=null
-AWS_REGION=null
+AWS_SECRET_ACCESS_KEY=null
+AWS_ACCESS_KEY_ID=null
+AWS_DEFAULT_REGION=null
 AWS_BUCKET=null
+AWS_BUCKET_ROOT=null
+AWS_URL=null
 
 # --------------------------------------------
 # OPTIONAL: LOGIN THROTTLING
diff --git a/.env.testing b/.env.testing
index f84dd82e9..980f24f09 100644
--- a/.env.testing
+++ b/.env.testing
@@ -40,10 +40,12 @@ IMAGE_LIB=gd
 # --------------------------------------------
 # OPTIONAL: AWS S3 SETTINGS
 # --------------------------------------------
-AWS_SECRET=null
-AWS_KEY=null
-AWS_REGION=null
+AWS_SECRET_ACCESS_KEY=null
+AWS_ACCESS_KEY_ID=null
+AWS_DEFAULT_REGION=null
 AWS_BUCKET=null
+AWS_BUCKET_ROOT=null
+AWS_URL=null
 
 
 # --------------------------------------------
diff --git a/.env.testing-ci b/.env.testing-ci
index b12a99d44..978c1895a 100644
--- a/.env.testing-ci
+++ b/.env.testing-ci
@@ -40,10 +40,12 @@ IMAGE_LIB=gd
 # --------------------------------------------
 # OPTIONAL: AWS S3 SETTINGS
 # --------------------------------------------
-AWS_SECRET=null
-AWS_KEY=null
-AWS_REGION=null
+AWS_SECRET_ACCESS_KEY=null
+AWS_ACCESS_KEY_ID=null
+AWS_DEFAULT_REGION=null
 AWS_BUCKET=null
+AWS_BUCKET_ROOT=null
+AWS_URL=null
 
 
 # --------------------------------------------
diff --git a/app/Console/Commands/MoveUploadsToNewDisk.php b/app/Console/Commands/MoveUploadsToNewDisk.php
new file mode 100644
index 000000000..505e260ce
--- /dev/null
+++ b/app/Console/Commands/MoveUploadsToNewDisk.php
@@ -0,0 +1,183 @@
+<?php
+
+namespace App\Console\Commands;
+
+
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Storage;
+
+class MoveUploadsToNewDisk extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'snipeit:move-uploads {delete_local?}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'This will move your uploaded files to whatever your current disk is.';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        if (config('filesystems.default')=='local') {
+            $this->error('Your current disk is set to local so we cannot proceed.');
+            $this->warn("Please configure your .env settings for S3 or Rackspace, \nand change your FILESYSTEM_DISK value to 's3' or 'rackspace'.");
+            return false;
+        }
+        $delete_local = $this->argument('delete_local');
+
+        $public_uploads['accessories'] = glob('storage/app/public/accessories'."/*.*");
+        $public_uploads['assets'] = glob('storage/app/public/assets'."/*.*");
+        $public_uploads['avatars'] = glob('storage/app/public/avatars'."/*.*");
+        $public_uploads['barcodes'] = glob('storage/app/public/barcodes'."/*.*");
+        $public_uploads['categories'] = glob('storage/app/public/categories'."/*.*");
+        $public_uploads['companies'] = glob('storage/app/public/companies'."/*.*");
+        $public_uploads['components'] = glob('storage/app/public/components'."/*.*");
+        $public_uploads['consumables'] = glob('storage/app/public/consumables'."/*.*");
+        $public_uploads['departments'] = glob('storage/app/public/departments'."/*.*");
+        $public_uploads['locations'] = glob('storage/app/public/locations'."/*.*");
+        $public_uploads['manufacturers'] = glob('storage/app/public/manufacturers'."/*.*");
+        $public_uploads['suppliers'] = glob('storage/app/public/suppliers'."/*.*");
+        $public_uploads['assetmodels'] = glob('storage/app/public/models'."/*.*");
+
+
+        // iterate files
+        foreach($public_uploads as $public_type => $public_upload)
+        {
+            $type_count = 0;
+            $this->info("\nThere are ".count($public_upload).' PUBLIC '.$public_type.' files.');
+
+            for ($i = 0; $i < count($public_upload); $i++) {
+                $type_count++;
+                $filename = basename($public_upload[$i]);
+
+                try  {
+                    Storage::disk('public')->put($public_type.'/'.$filename, file_get_contents($public_upload[$i]));
+                    $new_url = Storage::disk('public')->url($public_type.'/'.$filename, $filename);
+                    $this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
+                } catch (\Exception $e) {
+                    \Log::debug($e);
+                    $this->error($e);
+                }
+
+            }
+
+        }
+
+        $logos = glob('public/uploads'."/logo*.*");
+        $this->info("\nThere are ".count($logos).' files that might be logos.');
+        $type_count=0;
+
+        for ($l = 0; $l < count($logos); $l++) {
+            $type_count++;
+            $filename = basename($logos[$l]);
+            $new_url = Storage::disk('public')->url($logos[$l], file_get_contents($public_upload[$i]));
+            $this->info($type_count.'. LOGO: '.$filename.' was copied to '.$new_url);
+        }
+
+        $private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
+        $private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
+        $private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
+        $private_uploads['assetmodels'] = glob('storage/private_uploads/assetmodels'."/*.*");
+        $private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
+        $private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
+        $private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
+
+
+        foreach($private_uploads as $private_type => $private_upload)
+        {
+            $this->info("\nThere are ".count($private_upload).' PRIVATE '.$private_type.' files.');
+            // $this->info(print_r($private_upload, true));
+
+            $type_count = 0;
+            for ($x = 0; $x < count($private_upload); $x++) {
+                $type_count++;
+                $filename = basename($private_upload[$x]);
+
+                try  {
+                    Storage::disk('private_uploads')->put($private_type.'/'.$filename, file_get_contents($public_upload[$i]));
+                    $new_url = Storage::url($private_type.'/'.$filename, $filename);
+                    $this->info($type_count.'. PRIVATE: '.$filename.' was copied to '.$new_url);
+
+                } catch (\Exception $e) {
+                    \Log::debug($e);
+                    $this->error($e);
+                }
+
+            }
+
+        }
+
+
+        if ($delete_local=='true') {
+            $public_delete_count = 0;
+            $private_delete_count = 0;
+
+            $this->info("\n\n");
+            $this->error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
+            $this->warn("\nTHIS WILL DELETE ALL OF YOUR LOCAL UPLOADED FILES. \n\nThis cannot be undone, so you should take a backup of your system before you proceed.\n");
+            $this->error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
+
+            if ($this->confirm("Do you wish to continue?")) {
+
+                foreach($public_uploads as $public_type => $public_upload) {
+
+                    for ($i = 0; $i < count($public_upload); $i++) {
+                        $filename = $public_upload[$i];
+                        try {
+                            unlink($filename);
+                            $public_delete_count++;
+                        } catch (\Exception $e) {
+                            \Log::debug($e);
+                            $this->error($e);
+                        }
+
+                    }
+                }
+
+                foreach($private_uploads as $private_type => $private_upload)
+                {
+
+                    for ($i = 0; $i < count($private_upload); $i++) {
+                        $filename = $private_upload[$i];
+                        try {
+                            unlink($filename);
+                            $private_delete_count++;
+                        } catch (\Exception $e) {
+                            \Log::debug($e);
+                            $this->error($e);
+                        }
+
+                    }
+                }
+
+                $this->info($public_delete_count." PUBLIC local files and ".$private_delete_count." PRIVATE local files were delete from your filesystem.");
+            }
+        }
+
+
+
+
+    }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 750369df5..ad2d6dcfd 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -32,6 +32,7 @@ class Kernel extends ConsoleKernel
         Commands\SyncAssetCounters::class,
         Commands\RestoreDeletedUsers::class,
         Commands\SendCurrentInventoryToUsers::class,
+        Commands\MoveUploadsToNewDisk::class,
     ];
 
     /**
diff --git a/app/Http/Controllers/Accessories/AccessoriesController.php b/app/Http/Controllers/Accessories/AccessoriesController.php
index 53cceb46a..057029706 100755
--- a/app/Http/Controllers/Accessories/AccessoriesController.php
+++ b/app/Http/Controllers/Accessories/AccessoriesController.php
@@ -9,6 +9,7 @@ use App\Models\Company;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Http\Request;
 use Redirect;
+use Illuminate\Support\Facades\Storage;
 
 /** This controller handles all actions related to Accessories for
  * the Snipe-IT Asset Management application.
@@ -170,6 +171,15 @@ class AccessoriesController extends Controller
         if ($accessory->hasUsers() > 0) {
              return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
         }
+
+        if ($accessory->image) {
+            try  {
+                Storage::disk('public')->delete('accessories'.'/'.$accessory->image);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
+        }
+
         $accessory->delete();
         return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.delete.success'));
     }
diff --git a/app/Http/Controllers/Account/AcceptanceController.php b/app/Http/Controllers/Account/AcceptanceController.php
index 198e11e99..23cd29d2d 100644
--- a/app/Http/Controllers/Account/AcceptanceController.php
+++ b/app/Http/Controllers/Account/AcceptanceController.php
@@ -15,6 +15,7 @@ use App\Models\License;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Str;
+use Illuminate\Support\Facades\Storage;
 
 class AcceptanceController extends Controller {
 	
@@ -40,7 +41,7 @@ class AcceptanceController extends Controller {
         $acceptance = CheckoutAcceptance::find($id);
 
         if (is_null($acceptance)) {
-            return redirect()->reoute('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
+            return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
         }
 
         if (! $acceptance->isPending()) {
@@ -70,7 +71,7 @@ class AcceptanceController extends Controller {
         $acceptance = CheckoutAcceptance::find($id);
 
         if (is_null($acceptance)) {
-            return redirect()->reoute('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
+            return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
         }
 
         if (! $acceptance->isPending()) {
@@ -92,13 +93,17 @@ class AcceptanceController extends Controller {
         /**
          * Get the signature and save it
          */
+
+        if (!Storage::exists('private_uploads/signatures'))  Storage::makeDirectory('private_uploads/signatures', 775);
+
+
+
         if ($request->filled('signature_output')) {
-            $path = config('app.private_uploads').'/signatures';
             $sig_filename = "siglog-" .Str::uuid() . '-'.date('Y-m-d-his').".png";
             $data_uri = e($request->input('signature_output'));
             $encoded_image = explode(",", $data_uri);
             $decoded_image = base64_decode($encoded_image[1]);
-            file_put_contents($path."/".$sig_filename, $decoded_image);
+            Storage::put('private_uploads/signatures/'.$sig_filename, (string)$decoded_image);
         }
 
 
@@ -122,4 +127,4 @@ class AcceptanceController extends Controller {
 
         return redirect()->to('account/accept')->with('success', $return_msg);
     }	
-}
\ No newline at end of file
+}
diff --git a/app/Http/Controllers/Api/AssetModelsController.php b/app/Http/Controllers/Api/AssetModelsController.php
index c0011b61a..289348f17 100644
--- a/app/Http/Controllers/Api/AssetModelsController.php
+++ b/app/Http/Controllers/Api/AssetModelsController.php
@@ -9,6 +9,7 @@ use Illuminate\Http\Request;
 use App\Http\Transformers\AssetModelsTransformer;
 use App\Http\Transformers\AssetsTransformer;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 
 /**
@@ -177,7 +178,7 @@ class AssetModelsController extends Controller
 
         if ($assetmodel->image) {
             try  {
-                unlink(public_path().'/uploads/models/'.$assetmodel->image);
+                Storage::disk('public')->delete('assetmodels/'.$assetmodel->image);
             } catch (\Exception $e) {
                 \Log::error($e);
             }
@@ -234,7 +235,7 @@ class AssetModelsController extends Controller
                 $assetmodel->use_text .=  ' (#'.e($assetmodel->model_number).')';
             }
 
-            $assetmodel->use_image = ($settings->modellistCheckedValue('image') && ($assetmodel->image)) ? url('/').'/uploads/models/'.$assetmodel->image : null;
+            $assetmodel->use_image = ($settings->modellistCheckedValue('image') && ($assetmodel->image)) ? Storage::disk('public')->url('assetmodels/'.e($assetmodel->image)) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($assetmodels);
diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php
index dbed7be79..0b65508c5 100644
--- a/app/Http/Controllers/Api/AssetsController.php
+++ b/app/Http/Controllers/Api/AssetsController.php
@@ -3,7 +3,6 @@ namespace App\Http\Controllers\Api;
 
 use App\Helpers\Helper;
 use App\Http\Controllers\Controller;
-use App\Http\Requests\AssetRequest;
 use App\Http\Requests\AssetCheckoutRequest;
 use App\Http\Transformers\AssetsTransformer;
 use App\Models\Asset;
@@ -400,7 +399,7 @@ class AssetsController extends Controller
      * @since [v4.0]
      * @return JsonResponse
      */
-    public function store(AssetRequest $request)
+    public function store(Request $request)
     {
 
         $this->authorize('create', Asset::class);
@@ -431,7 +430,7 @@ class AssetsController extends Controller
         // Update custom fields in the database.
         // Validation for these fields is handled through the AssetRequest form request
         $model = AssetModel::find($request->get('model_id'));
-        if ($model->fieldset) {
+        if (($model) && ($model->fieldset)) {
             foreach ($model->fieldset->fields as $field) {
                 $asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug(), null));
             }
diff --git a/app/Http/Controllers/Api/CategoriesController.php b/app/Http/Controllers/Api/CategoriesController.php
index 3a208c64a..1cee93110 100644
--- a/app/Http/Controllers/Api/CategoriesController.php
+++ b/app/Http/Controllers/Api/CategoriesController.php
@@ -8,6 +8,7 @@ use App\Helpers\Helper;
 use App\Models\Category;
 use App\Http\Transformers\CategoriesTransformer;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 class CategoriesController extends Controller
 {
@@ -158,7 +159,7 @@ class CategoriesController extends Controller
         // This lets us have more flexibility in special cases like assets, where
         // they may not have a ->name value but we want to display something anyway
         foreach ($categories as $category) {
-            $category->use_image = ($category->image) ? url('/').'/uploads/categories/'.$category->image : null;
+            $category->use_image = ($category->image) ? Storage::disk('public')->url('categories/'.$category->image, $category->image) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($categories);
diff --git a/app/Http/Controllers/Api/CompaniesController.php b/app/Http/Controllers/Api/CompaniesController.php
index d2dc5990c..6b1c63f54 100644
--- a/app/Http/Controllers/Api/CompaniesController.php
+++ b/app/Http/Controllers/Api/CompaniesController.php
@@ -178,7 +178,7 @@ class CompaniesController extends Controller
         // This lets us have more flexibility in special cases like assets, where
         // they may not have a ->name value but we want to display something anyway
         foreach ($companies as $company) {
-            $company->use_image = ($company->image) ? url('/').'/uploads/companies/'.$company->image : null;
+            $company->use_image = ($company->image) ? Storage::disk('public')->url('companies/'.$company->image, $company->image) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($companies);
diff --git a/app/Http/Controllers/Api/CustomFieldsetsController.php b/app/Http/Controllers/Api/CustomFieldsetsController.php
index f5cfafdf9..5ed916152 100644
--- a/app/Http/Controllers/Api/CustomFieldsetsController.php
+++ b/app/Http/Controllers/Api/CustomFieldsetsController.php
@@ -16,7 +16,6 @@ use App\Http\Controllers\Controller;
 use App\Helpers\Helper;
 use App\Http\Transformers\CustomFieldsTransformer;
 use App\Http\Transformers\CustomFieldsetsTransformer;
-use App\Http\Requests\AssetRequest;
 
 /**
  * This controller handles all actions related to Custom Asset Fieldsets for
diff --git a/app/Http/Controllers/Api/DepartmentsController.php b/app/Http/Controllers/Api/DepartmentsController.php
index 50a03baff..1d0e11dcf 100644
--- a/app/Http/Controllers/Api/DepartmentsController.php
+++ b/app/Http/Controllers/Api/DepartmentsController.php
@@ -9,6 +9,7 @@ use App\Http\Transformers\DepartmentsTransformer;
 use App\Helpers\Helper;
 use Auth;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 class DepartmentsController extends Controller
 {
@@ -152,7 +153,7 @@ class DepartmentsController extends Controller
         // This lets us have more flexibility in special cases like assets, where
         // they may not have a ->name value but we want to display something anyway
         foreach ($departments as $department) {
-            $department->use_image = ($department->image) ? url('/').'/uploads/departments/'.$department->image : null;
+            $department->use_image = ($department->image) ? Storage::disk('public')->url('departments/'.$department->image, $department->image) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($departments);
diff --git a/app/Http/Controllers/Api/ImportController.php b/app/Http/Controllers/Api/ImportController.php
index e18acf3a7..797df4d9e 100644
--- a/app/Http/Controllers/Api/ImportController.php
+++ b/app/Http/Controllers/Api/ImportController.php
@@ -15,6 +15,7 @@ use League\Csv\Reader;
 use Symfony\Component\HttpFoundation\File\Exception\FileException;
 use Artisan;
 use App\Models\Asset;
+use Illuminate\Support\Facades\Storage;
 
 class ImportController extends Controller
 {
@@ -167,7 +168,7 @@ class ImportController extends Controller
         if ($import = Import::find($import_id)) {
             try {
                 // Try to delete the file
-                unlink(config('app.private_uploads').'/imports/'.$import->file_path);
+                Storage::delete('imports/'.$import->file_path);
                 $import->delete();
                 return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.import.file_delete_success')));
 
diff --git a/app/Http/Controllers/Api/LocationsController.php b/app/Http/Controllers/Api/LocationsController.php
index 452b5b73b..eaabc0ac3 100644
--- a/app/Http/Controllers/Api/LocationsController.php
+++ b/app/Http/Controllers/Api/LocationsController.php
@@ -8,6 +8,7 @@ use App\Helpers\Helper;
 use App\Models\Location;
 use App\Http\Transformers\LocationsTransformer;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 class LocationsController extends Controller
 {
@@ -203,7 +204,7 @@ class LocationsController extends Controller
         // they may not have a ->name value but we want to display something anyway
         foreach ($locations as $location) {
             $location->use_text = $location->name;
-            $location->use_image = ($location->image) ? url('/').'/uploads/locations/'.$location->image : null;
+            $location->use_image = ($location->image) ? Storage::disk('public')->url('locations/'.$location->image, $location->image): null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($locations);
diff --git a/app/Http/Controllers/Api/ManufacturersController.php b/app/Http/Controllers/Api/ManufacturersController.php
index a943cc21d..2d30b3d5f 100644
--- a/app/Http/Controllers/Api/ManufacturersController.php
+++ b/app/Http/Controllers/Api/ManufacturersController.php
@@ -9,6 +9,7 @@ use App\Models\Manufacturer;
 use App\Http\Transformers\DatatablesTransformer;
 use App\Http\Transformers\ManufacturersTransformer;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 class ManufacturersController extends Controller
 {
@@ -166,7 +167,7 @@ class ManufacturersController extends Controller
         // they may not have a ->name value but we want to display something anyway
         foreach ($manufacturers as $manufacturer) {
             $manufacturer->use_text = $manufacturer->name;
-            $manufacturer->use_image = ($manufacturer->image) ? url('/').'/uploads/manufacturers/'.$manufacturer->image : null;
+            $manufacturer->use_image = ($manufacturer->image) ? Storage::disk('public')->url('manufacturers/'.$manufacturer->image, $manufacturer->image) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($manufacturers);
diff --git a/app/Http/Controllers/Api/SuppliersController.php b/app/Http/Controllers/Api/SuppliersController.php
index b79fda773..d15492b1b 100644
--- a/app/Http/Controllers/Api/SuppliersController.php
+++ b/app/Http/Controllers/Api/SuppliersController.php
@@ -8,6 +8,7 @@ use App\Helpers\Helper;
 use App\Models\Supplier;
 use App\Http\Transformers\SuppliersTransformer;
 use App\Http\Transformers\SelectlistTransformer;
+use Illuminate\Support\Facades\Storage;
 
 
 class SuppliersController extends Controller
@@ -164,7 +165,7 @@ class SuppliersController extends Controller
         // they may not have a ->name value but we want to display something anyway
         foreach ($suppliers as $supplier) {
             $supplier->use_text = $supplier->name;
-            $supplier->use_image = ($supplier->image) ? url('/').'/uploads/suppliers/'.$supplier->image : null;
+            $supplier->use_image = ($supplier->image) ? Storage::disk('public')->url('suppliers/'.$supplier->image, $supplier->image) : null;
         }
 
         return (new SelectlistTransformer)->transformSelectlist($suppliers);
diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php
index 7fca6bf3a..f787f4654 100644
--- a/app/Http/Controllers/Api/UsersController.php
+++ b/app/Http/Controllers/Api/UsersController.php
@@ -283,6 +283,15 @@ class UsersController extends Controller
             return response()->json(Helper::formatStandardApiResponse('error', null,  trans('admin/users/message.error.delete_has_assets')));
         }
 
+        // Remove the user's avatar if they have one
+        if (Storage::disk('public')->exists('avatars/'.$user->avatar)) {
+            try  {
+                Storage::disk('public')->delete('avatars/'.$user->avatar);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
+        }
+
         if ($user->delete()) {
             return response()->json(Helper::formatStandardApiResponse('success', null,  trans('admin/users/message.success.delete')));
         }
diff --git a/app/Http/Controllers/AssetModelsController.php b/app/Http/Controllers/AssetModelsController.php
index d97c36e13..790b8c987 100755
--- a/app/Http/Controllers/AssetModelsController.php
+++ b/app/Http/Controllers/AssetModelsController.php
@@ -82,7 +82,7 @@ class AssetModelsController extends Controller
             $model->fieldset_id = e($request->input('custom_fieldset'));
         }
 
-        $model = $request->handleImages($model, app('models_upload_path'));
+        $model = $request->handleImages($model);
 
             // Was it created?
         if ($model->save()) {
@@ -161,7 +161,7 @@ class AssetModelsController extends Controller
             }
         }
 
-        $model = $request->handleImages($model, app('models_upload_path'));
+        $model = $request->handleImages($model);
 
         if ($model->save()) {
             return redirect()->route("models.index")->with('success', trans('admin/models/message.update.success'));
@@ -194,7 +194,7 @@ class AssetModelsController extends Controller
 
         if ($model->image) {
             try  {
-                unlink(public_path().'/uploads/models/'.$model->image);
+                Storage::disk('public')->delete('models/'.$model->image);
             } catch (\Exception $e) {
                 \Log::error($e);
             }
diff --git a/app/Http/Controllers/Assets/AssetFilesController.php b/app/Http/Controllers/Assets/AssetFilesController.php
index 9f31b80dc..bc7f80813 100644
--- a/app/Http/Controllers/Assets/AssetFilesController.php
+++ b/app/Http/Controllers/Assets/AssetFilesController.php
@@ -31,13 +31,14 @@ class AssetFilesController extends Controller
         $this->authorize('update', $asset);
 
         if ($request->hasFile('file')) {
+
+            if (!Storage::exists('private_uploads/assets')) Storage::makeDirectory('private_uploads/assets', 775);
+
             foreach ($request->file('file') as $file) {
                 $extension = $file->getClientOriginalExtension();
-                $filename = 'hardware-'.$asset->id.'-'.str_random(8);
-                $filename .= '-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
-
-                $file->storeAs('storage/private_uploads/assets', $filename);
-                $asset->logUpload($filename, e($request->get('notes')));
+                $file_name = 'hardware-'.$asset->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
+                Storage::put('private_uploads/assets/'.$file_name, $file);
+                $asset->logUpload($file_name, e($request->get('notes')));
             }
             return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
         }
@@ -67,24 +68,25 @@ class AssetFilesController extends Controller
                     ->header('Content-Type', 'text/plain');
             }
 
-            $file = $log->get_src('assets');
+            $file = 'private_uploads/assets/'.$log->filename;
+            \Log::debug('Checking for '.$file);
 
             if ($log->action_type =='audit') {
-                $file = $log->get_src('audits');
+                $file = 'private_uploads/audits/'.$log->filename;
             }
 
-            if (!file_exists($file)) {
+            if (!Storage::exists($file)) {
                 return response('File '.$file.' not found on server', 404)
                     ->header('Content-Type', 'text/plain');
             }
 
             if ($download != 'true') {
-                  if ($contents = file_get_contents($file)) {
-                      return Response::make($contents)->header('Content-Type', mime_content_type($file));
+                  if ($contents = file_get_contents(Storage::url($file))) {
+                      return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
                   }
                 return JsonResponse::create(["error" => "Failed validation: "], 500);
             }
-            return Response::download($file);
+            return Storage::download($file);
         }
         // Prepare the error message
         $error = trans('admin/hardware/message.does_not_exist', ['id' => $fileId]);
@@ -114,7 +116,7 @@ class AssetFilesController extends Controller
             $this->authorize('update', $asset);
             $log = Actionlog::find($fileId);
             if (file_exists(base_path().'/'.$rel_path.'/'.$log->filename)) {
-                Storage::delete($rel_path.'/'.$log->filename);
+                Storage::disk('public')->delete($rel_path.'/'.$log->filename);
             }
             $log->delete();
             return redirect()->back()
diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php
index ce0fa1886..1baf6235a 100755
--- a/app/Http/Controllers/Assets/AssetsController.php
+++ b/app/Http/Controllers/Assets/AssetsController.php
@@ -3,7 +3,7 @@ namespace App\Http\Controllers\Assets;
 
 use App\Helpers\Helper;
 use App\Http\Controllers\Controller;
-use App\Http\Requests\AssetRequest;
+use App\Http\Requests\ImageUploadRequest;
 use App\Models\Actionlog;
 use App\Models\Asset;
 use App\Models\AssetModel;
@@ -33,6 +33,7 @@ use TCPDF;
 use Validator;
 use View;
 use App\Models\CheckoutRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This class controls all actions related to assets for
@@ -106,7 +107,7 @@ class AssetsController extends Controller
      * @since [v1.0]
      * @return Redirect
      */
-    public function store(AssetRequest $request)
+    public function store(ImageUploadRequest $request)
     {
         $this->authorize(Asset::class);
 
@@ -138,48 +139,14 @@ class AssetsController extends Controller
             $asset->location_id = $request->input('rtd_location_id', null);
         }
 
-        // Create the image (if one was chosen.)
-        if ($request->hasFile('image')) {
-            $image = $request->input('image');
-
-            // After modification, the image is prefixed by mime info like the following:
-            // data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
-            $header = explode(';', $image, 2)[0];
-            // Grab the image type from the header while we're at it.
-            $extension = substr($header, strpos($header, '/')+1);
-            // Start reading the image after the first comma, postceding the base64.
-            $image = substr($image, strpos($image, ',')+1);
-
-            $file_name = str_random(25).".".$extension;
-
-            $directory= public_path('uploads/assets/');
-            // Check if the uploads directory exists.  If not, try to create it.
-            if (!file_exists($directory)) {
-                mkdir($directory, 0755, true);
-            }
-            $path = public_path('uploads/assets/'.$file_name);
-            try {
-                Image::make($image)->resize(500, 500, function ($constraint) {
-                    $constraint->aspectRatio();
-                    $constraint->upsize();
-                })->save($path);
-                $asset->image = $file_name;
-            } catch (\Exception $e) {
-                \Input::flash();
-                $messageBag = new \Illuminate\Support\MessageBag();
-                $messageBag->add('image', $e->getMessage());
-                \Session()->flash('errors', \Session::get('errors', new \Illuminate\Support\ViewErrorBag)
-                    ->put('default', $messageBag));
-                return response()->json(['image' => $e->getMessage()], 422);
-            }
-        }
+        $asset = $request->handleImages($asset);
 
 
         // Update custom fields in the database.
         // Validation for these fields is handled through the AssetRequest form request
         $model = AssetModel::find($request->get('model_id'));
 
-        if ($model->fieldset) {
+        if (($model) && ($model->fieldset)) {
             foreach ($model->fieldset->fields as $field) {
                 if ($field->field_encrypted=='1') {
                     if (Gate::allows('admin')) {
@@ -210,12 +177,11 @@ class AssetsController extends Controller
                 $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')), $location);
             }
             // Redirect to the asset listing page
-            \Session::flash('success', trans('admin/hardware/message.create.success'));
-            return response()->json(['redirect_url' => route('hardware.index')]);
+            return redirect()->route('hardware.index')
+                ->with('success', trans('admin/hardware/message.create.success'));
         }
-        \Input::flash();
-        \Session::flash('errors', $asset->getErrors());
-        return response()->json(['errors' => $asset->getErrors()], 500);
+        return redirect()->back()->withInput()->withErrors($asset->getErrors());
+
     }
 
     /**
@@ -293,7 +259,7 @@ class AssetsController extends Controller
      * @return Redirect
      */
 
-    public function update(AssetRequest $request, $assetId = null)
+    public function update(ImageUploadRequest $request, $assetId = null)
     {
         // Check if the asset exists
         if (!$asset = Asset::find($assetId)) {
@@ -338,38 +304,7 @@ class AssetsController extends Controller
         $asset->notes        = $request->input('notes');
         $asset->physical     = '1';
 
-        // Update the image
-        if ($request->filled('image')) {
-            $image = $request->input('image');
-            // See postCreate for more explaination of the following.
-            $header = explode(';', $image, 2)[0];
-            $extension = substr($header, strpos($header, '/')+1);
-            $image = substr($image, strpos($image, ',')+1);
-
-            $directory= public_path('uploads/assets/');
-            // Check if the uploads directory exists.  If not, try to create it.
-            if (!file_exists($directory)) {
-                mkdir($directory, 0755, true);
-            }
-
-            $file_name = str_random(25).".".$extension;
-            $path = public_path('uploads/assets/'.$file_name);
-            try {
-                Image::make($image)->resize(500, 500, function ($constraint) {
-                    $constraint->aspectRatio();
-                    $constraint->upsize();
-                })->save($path);
-                $asset->image = $file_name;
-            } catch (\Exception $e) {
-                \Input::flash();
-                $messageBag = new \Illuminate\Support\MessageBag();
-                $messageBag->add('image', $e->getMessage());
-                \Session()->flash('errors', \Session::get('errors', new \Illuminate\Support\ViewErrorBag)
-                    ->put('default', $messageBag));
-                return response()->json(['image' => $e->getMessage()], 422);
-            }
-            $asset->image = $file_name;
-        }
+        $asset = $request->handleImages($asset);
 
         // Update custom fields in the database.
         // Validation for these fields is handlded through the AssetRequest form request
@@ -421,6 +356,14 @@ class AssetsController extends Controller
             ->where('id', $asset->id)
             ->update(array('assigned_to' => null));
 
+        if ($asset->image) {
+            try  {
+                Storage::disk('public')->delete('assets'.'/'.$asset->image);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
+        }
+
         $asset->delete();
 
         return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
@@ -740,7 +683,7 @@ class AssetsController extends Controller
     }
 
 
-    public function auditStore(AssetFileRequest $request, $id)
+    public function auditStore(Request $request, $id)
     {
         $this->authorize('audit', Asset::class);
 
@@ -773,22 +716,15 @@ class AssetsController extends Controller
 
         if ($asset->save()) {
 
+            $path = 'private_uploads/audits';
+            if (!Storage::exists($path)) Storage::makeDirectory($path, 775);
 
-            $filename = '';
-
-            if ($request->hasFile('image')) {
-                $file = $request->file('image');
-                try {
-                    $destinationPath = config('app.private_uploads').'/audits';
-                    $extension = $file->getClientOriginalExtension();
-                    $filename = 'audit-'.$asset->id.'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
-                    $file->move($destinationPath, $filename);
-                } catch (\Exception $e) {
-                    \Log::error($e);
-                }
-            }
+            $upload = $image = $request->file('image');
+            $ext = $image->getClientOriginalExtension();
+            $file_name = 'audit-'.str_random(18).'.'.$ext;
+            Storage::putFileAs($path, $upload, $file_name);
 
-            $asset->logAudit($request->input('note'), $request->input('location_id'), $filename);
+            $asset->logAudit($request->input('note'), $request->input('location_id'), $file_name);
             return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
         }
     }
diff --git a/app/Http/Controllers/CategoriesController.php b/app/Http/Controllers/CategoriesController.php
index 2de5fd9a5..bc643841e 100755
--- a/app/Http/Controllers/CategoriesController.php
+++ b/app/Http/Controllers/CategoriesController.php
@@ -17,6 +17,7 @@ use Str;
 use View;
 use Image;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This class controls all actions related to Categories for
@@ -182,7 +183,7 @@ class CategoriesController extends Controller
             return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
         }
 
-
+        Storage::disk('public')->delete('categories'.'/'.$category->image);
         $category->delete();
         // Redirect to the locations management page
         return redirect()->route('categories.index')->with('success', trans('admin/categories/message.delete.success'));
diff --git a/app/Http/Controllers/CompaniesController.php b/app/Http/Controllers/CompaniesController.php
index 2ca0d1549..1e6a8473d 100644
--- a/app/Http/Controllers/CompaniesController.php
+++ b/app/Http/Controllers/CompaniesController.php
@@ -5,6 +5,7 @@ use App\Models\Company;
 use Illuminate\Http\Request;
 use Image;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to Companies for
@@ -142,6 +143,15 @@ final class CompaniesController extends Controller
         }
 
         try {
+
+            if ($company->image) {
+                try  {
+                    Storage::disk('public')->delete('companies'.'/'.$company->image);
+                } catch (\Exception $e) {
+                    \Log::debug($e);
+                }
+            }
+
             $company->delete();
             return redirect()->route('companies.index')
                 ->with('success', trans('admin/companies/message.delete.success'));
diff --git a/app/Http/Controllers/Components/ComponentsController.php b/app/Http/Controllers/Components/ComponentsController.php
index 9e7d5d5a3..6839e1604 100644
--- a/app/Http/Controllers/Components/ComponentsController.php
+++ b/app/Http/Controllers/Components/ComponentsController.php
@@ -7,6 +7,7 @@ use App\Models\Company;
 use App\Models\Component;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Input;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This class controls all actions related to Components for
@@ -159,6 +160,16 @@ class ComponentsController extends Controller
         }
 
         $this->authorize('delete', $component);
+
+        // Remove the image if one exists
+        if (Storage::disk('public')->exists('components/'.$component->image)) {
+            try  {
+                Storage::disk('public')->delete('components/'.$component->image);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
+        }
+
         $component->delete();
         return redirect()->route('components.index')->with('success', trans('admin/components/message.delete.success'));
     }
diff --git a/app/Http/Controllers/DepartmentsController.php b/app/Http/Controllers/DepartmentsController.php
index 0922c4125..4afcd2a5a 100644
--- a/app/Http/Controllers/DepartmentsController.php
+++ b/app/Http/Controllers/DepartmentsController.php
@@ -7,6 +7,7 @@ use App\Models\Department;
 use Illuminate\Support\Facades\Auth;
 use Image;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 class DepartmentsController extends Controller
 {
@@ -124,7 +125,15 @@ class DepartmentsController extends Controller
             return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
         }
 
+        if ($department->image) {
+            try  {
+                Storage::disk('public')->delete('departments'.'/'.$department->image);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
+        }
         $department->delete();
+
         return redirect()->back()->with('success', trans('admin/departments/message.delete.success'));
 
     }
diff --git a/app/Http/Controllers/Licenses/LicenseFilesController.php b/app/Http/Controllers/Licenses/LicenseFilesController.php
index a25b15ada..4ff388335 100644
--- a/app/Http/Controllers/Licenses/LicenseFilesController.php
+++ b/app/Http/Controllers/Licenses/LicenseFilesController.php
@@ -35,16 +35,20 @@ class LicenseFilesController extends Controller
             $this->authorize('update', $license);
 
             if (Input::hasFile('file')) {
+
+                if (!Storage::exists('private_uploads/licenses')) Storage::makeDirectory('private_uploads/licenses', 775);
+
                 $upload_success = false;
                 foreach (Input::file('file') as $file) {
                     $extension = $file->getClientOriginalExtension();
-                    $filename = 'license-'.$license->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
+                    $file_name = 'license-'.$license->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
 
-                    $upload_success = $file->storeAs('storage/private_uploads/licenses', $filename);
+                    $upload_success = Storage::put('private_uploads/licenses/'.$file_name, $file);
 
                     //Log the upload to the log
-                    $license->logUpload($filename, e($request->input('notes')));
+                    $license->logUpload($file_name, e($request->input('notes')));
                 }
+
                 // This being called from a modal seems to confuse redirect()->back()
                 // It thinks we should go to the dashboard.  As this is only used
                 // from the modal at present, hardcode the redirect.  Longterm
@@ -76,15 +80,20 @@ class LicenseFilesController extends Controller
     {
         $license = License::find($licenseId);
 
-        $rel_path = 'storage/private_uploads/licenses';
-
         // the asset is valid
         if (isset($license->id)) {
             $this->authorize('update', $license);
             $log = Actionlog::find($fileId);
-            if (file_exists(base_path().'/'.$rel_path.'/'.$log->filename)) {
-                Storage::delete($rel_path.'/'.$log->filename);
+
+            // Remove the file if one exists
+            if (Storage::exists('licenses/'.$log->filename)) {
+                try  {
+                    Storage::delete('licenses/'.$log->filename);
+                } catch (\Exception $e) {
+                    \Log::debug($e);
+                }
             }
+
             $log->delete();
             return redirect()->back()
                 ->with('success', trans('admin/hardware/message.deletefile.success'));
@@ -114,34 +123,30 @@ class LicenseFilesController extends Controller
         // the license is valid
         if (isset($license->id)) {
             $this->authorize('view', $license);
-            $log = Actionlog::find($fileId);
-            $file = $log->get_src('licenses');
-
 
-            if ($file =='') {
-                return response('File not found on server', 404)
+            if (!$log = Actionlog::find($fileId)) {
+                return response('No matching record for that asset/file', 500)
                     ->header('Content-Type', 'text/plain');
             }
 
-            $mimetype = \File::mimeType($file);
+            $file = 'private_uploads/licenses/'.$log->filename;
+            \Log::debug('Checking for '.$file);
 
-
-            if (!file_exists($file)) {
+            if (!Storage::exists($file)) {
                 return response('File '.$file.' not found on server', 404)
                     ->header('Content-Type', 'text/plain');
             }
 
             if ($download != 'true') {
-                if ($contents = file_get_contents($file)) {
-                    return Response::make($contents)->header('Content-Type', $mimetype);
+                if ($contents = file_get_contents(Storage::url($file))) {
+                    return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
                 }
                 return JsonResponse::create(["error" => "Failed validation: "], 500);
             }
-            return Response::download($file);
+            return Storage::download($file);
         }
+        return redirect()->route('hardware.index')->with('error', trans('admin/licenses/message.does_not_exist', ['id' => $fileId]));
 
-
-        return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
     }
 
 
diff --git a/app/Http/Controllers/LocationsController.php b/app/Http/Controllers/LocationsController.php
index 87ff779eb..9314ede8b 100755
--- a/app/Http/Controllers/LocationsController.php
+++ b/app/Http/Controllers/LocationsController.php
@@ -6,6 +6,7 @@ use App\Models\Location;
 use Illuminate\Support\Facades\Auth;
 use Image;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to Locations for
@@ -89,7 +90,7 @@ class LocationsController extends Controller
         $location->manager_id       = $request->input('manager_id');
         $location->user_id          = Auth::id();
 
-        $location = $request->handleImages($location);
+        $location = $request->handleImages($location, 'public/uploads/locations');
 
         if ($location->save()) {
             return redirect()->route("locations.index")->with('success', trans('admin/locations/message.create.success'));
@@ -159,7 +160,7 @@ class LocationsController extends Controller
         $location->ldap_ou      = $request->input('ldap_ou');
         $location->manager_id   = $request->input('manager_id');
 
-        $location = $request->handleImages($location);
+        $location = $request->handleImages($location, 'public/uploads/locations');
 
 
         if ($location->save()) {
@@ -198,6 +199,13 @@ class LocationsController extends Controller
 
         }
 
+        if ($location->image) {
+            try  {
+                Storage::disk('public')->delete('locations/'.$location->image);
+            } catch (\Exception $e) {
+                \Log::error($e);
+            }
+        }
         $location->delete();
         return redirect()->to(route('locations.index'))->with('success', trans('admin/locations/message.delete.success'));
     }
diff --git a/app/Http/Controllers/ManufacturersController.php b/app/Http/Controllers/ManufacturersController.php
index 1bbd4466d..c99ac10d9 100755
--- a/app/Http/Controllers/ManufacturersController.php
+++ b/app/Http/Controllers/ManufacturersController.php
@@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Auth;
 use Redirect;
 use Illuminate\Http\Request;
 use Image;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to Manufacturers for
@@ -72,7 +73,7 @@ class ManufacturersController extends Controller
         $manufacturer->support_email    = $request->input('support_email');
 
 
-        $manufacturer = $request->handleImages($manufacturer);
+        $manufacturer = $request->handleImages($manufacturer,'manufacturers');
 
 
 
@@ -162,9 +163,9 @@ class ManufacturersController extends Controller
 
         if ($manufacturer->image) {
             try  {
-                unlink(public_path().'/uploads/manufacturers/'.$manufacturer->image);
+                Storage::disk('public')->delete('manufacturers/'.$manufacturer->image);
             } catch (\Exception $e) {
-
+                \Log::error($e);
             }
         }
 
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 492b65db0..5b0a06ede 100755
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -12,6 +12,7 @@ use Gate;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to User Profiles for
@@ -61,19 +62,39 @@ class ProfileController extends Controller
         if (Gate::allows('self.edit_location')  && (!config('app.lock_passwords'))) {
             $user->location_id    = $request->input('location_id');
         }
-        
-        if (Input::file('avatar')) {
-            $image = Input::file('avatar');
-            $file_name = str_slug($user->first_name."-".$user->last_name).".".$image->getClientOriginalExtension();
-            $path = public_path('uploads/avatars/'.$file_name);
-            Image::make($image->getRealPath())->resize(84, 84)->save($path);
-            $user->avatar = $file_name;
-        }
 
-        if (Input::get('avatar_delete') == 1 && Input::file('avatar') == "") {
+
+        if ($request->input('avatar_delete') == 1) {
             $user->avatar = null;
         }
 
+
+        if ($request->hasFile('avatar')) {
+            $path = 'avatars';
+
+            if(!Storage::disk('public')->exists($path)) Storage::disk('public')->makeDirectory($path, 775);
+
+            $upload = $image = $request->file('avatar');
+            $ext = $image->getClientOriginalExtension();
+            $file_name = 'avatar-'.str_random(18).'.'.$ext;
+
+            if ($image->getClientOriginalExtension()!='svg') {
+                $upload =  Image::make($image->getRealPath())->resize(84, 84);
+            }
+
+            // This requires a string instead of an object, so we use ($string)
+            Storage::disk('public')->put($path.'/'.$file_name, (string)$upload->encode());
+
+            // Remove Current image if exists
+            if (($user->avatar) && (Storage::disk('public')->exists($path.'/'.$user->avatar))) {
+                Storage::disk('public')->delete($path.'/'.$user->avatar);
+            }
+
+            $user->avatar = $file_name;
+        }
+
+
+
         if ($user->save()) {
             return redirect()->route('profile')->with('success', 'Account successfully updated');
         }
diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php
index 90391a23f..067bbd562 100755
--- a/app/Http/Controllers/SettingsController.php
+++ b/app/Http/Controllers/SettingsController.php
@@ -24,6 +24,7 @@ use App\Http\Requests\ImageUploadRequest;
 use App\Http\Requests\SettingsLdapRequest;
 use App\Helpers\Helper;
 use App\Notifications\FirstAdminNotification;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to Settings for
@@ -418,25 +419,32 @@ class SettingsController extends Controller
 
         // If the user wants to clear the logo, reset the brand type
         if ($request->input('clear_logo')=='1') {
+            Storage::disk('public')->delete($setting->logo);
             $setting->logo = null;
             $setting->brand = 1;
 
+
         // If they are uploading an image, validate it and upload it
         } elseif ($request->hasFile('image')) {
 
-            if (!config('app.lock_passwords')) {
-                $image = $request->file('image');
-                $file_name = "logo.".$image->getClientOriginalExtension();
-                $path = public_path('uploads');
-                if ($image->getClientOriginalExtension()!='svg') {
-                    Image::make($image->getRealPath())->resize(null, 150, function ($constraint) {
-                        $constraint->aspectRatio();
-                        $constraint->upsize();
-                    })->save($path.'/'.$file_name);
-                } else {
-                    $image->move($path, $file_name);
-                }
-                $setting->logo = $file_name;
+            $image = $request->file('image');
+            $ext = $image->getClientOriginalExtension();
+            $setting->logo = $file_name = 'logo.'.$ext;
+
+            if ($image->getClientOriginalExtension()!='svg') {
+                $upload = Image::make($image->getRealPath())->resize(null, 150, function ($constraint) {
+                    $constraint->aspectRatio();
+                    $constraint->upsize();
+                });
+            }
+
+
+            // This requires a string instead of an object, so we use ($string)
+            Storage::disk('public')->put($file_name, (string)$upload->encode());
+
+            // Remove Current image if exists
+            if (($setting->logo) && (file_exists($file_name))) {
+                Storage::disk('public')->delete($file_name);
             }
         }
 
@@ -911,29 +919,22 @@ class SettingsController extends Controller
     public function getBackups()
     {
 
-        $path = storage_path().'/app/'.config('backup.backup.name');
+        $path = 'backups';
+        $backup_files = Storage::files($path);
+        $files = [];
 
-        $files = array();
+        if (count($backup_files) > 0) {
 
-        if ($handle = opendir($path)) {
-
-            /* This is the correct way to loop over the directory. */
-            while (false !== ($entry = readdir($handle))) {
-                clearstatcache();
-                if (substr(strrchr($entry, '.'), 1)=='zip') {
-                    $files[] = array(
-                          'filename' => $entry,
-                          'filesize' => Setting::fileSizeConvert(filesize($path.'/'.$entry)),
-                          'modified' => filemtime($path.'/'.$entry)
-                      );
-                }
 
+            for ($f = 0; $f < count($backup_files); $f++) {
+                $files[] = array(
+                    'filename' => basename($backup_files[$f]),
+                    'filesize' => Setting::fileSizeConvert(Storage::size($backup_files[$f])),
+                    'modified' => Storage::lastModified($backup_files[$f])
+                );
             }
-            closedir($handle);
-            rsort($files);
         }
 
-
         return view('settings/backups', compact('path', 'files'));
     }
 
@@ -987,12 +988,10 @@ class SettingsController extends Controller
     public function downloadFile($filename = null)
     {
         if (!config('app.lock_passwords')) {
-            $path = storage_path().'/app/'.config('backup.backup.name');
-            $file = $path.'/'.$filename;
-            if (file_exists($file)) {
-                return Response::download($file);
-            } else {
 
+            if (Storage::exists($filename)) {
+                return Response::download(Storage::url('').e($filename));
+            } else {
                 // Redirect to the backup page
                 return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
             }
@@ -1013,14 +1012,17 @@ class SettingsController extends Controller
     */
     public function deleteFile($filename = null)
     {
-
         if (!config('app.lock_passwords')) {
+            $path = 'backups';
+
+            if (Storage::exists($path.'/'.$filename)) {
+                try  {
+                    Storage::delete($path.'/'.$filename);
+                    return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
+                } catch (\Exception $e) {
+                    \Log::debug($e);
+                }
 
-            $path = storage_path().'/app/'.config('backup.backup.name');
-            $file = $path.'/'.$filename;
-            if (file_exists($file)) {
-                unlink($file);
-                return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
             } else {
                 return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
             }
diff --git a/app/Http/Controllers/SuppliersController.php b/app/Http/Controllers/SuppliersController.php
index 5af0097ee..985c2d892 100755
--- a/app/Http/Controllers/SuppliersController.php
+++ b/app/Http/Controllers/SuppliersController.php
@@ -6,6 +6,7 @@ use App\Models\Supplier;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Http\Request;
 use App\Http\Requests\ImageUploadRequest;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * This controller handles all actions related to Suppliers for
diff --git a/app/Http/Requests/AssetRequest.php b/app/Http/Requests/AssetRequest.php
deleted file mode 100644
index 4004dcec3..000000000
--- a/app/Http/Requests/AssetRequest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-namespace App\Http\Requests;
-
-use App\Http\Requests\Request;
-use App\Models\AssetModel;
-use Session;
-
-class AssetRequest extends Request
-{
-    /**
-     * Determine if the user is authorized to make this request.
-     *
-     * @return bool
-     */
-    public function authorize()
-    {
-        return true;
-    }
-
-    /**
-     * Get the validation rules that apply to the request.
-     *
-     * @return array
-     */
-    public function rules()
-    {
-        $rules = [
-            'name'            => 'max:255|nullable',
-            'model_id'        => 'required|integer|exists:models,id',
-            'status_id'       => 'required|integer|exists:status_labels,id',
-            'company_id'      => 'integer|nullable',
-            'warranty_months' => 'numeric|nullable',
-            'physical'        => 'integer|nullable',
-            'checkout_date'   => 'date',
-            'checkin_date'    => 'date',
-            'supplier_id'     => 'integer|nullable',
-            'status'          => 'integer|nullable',
-            'purchase_cost'   => 'numeric|nullable',
-            "assigned_user"   => 'sometimes:required_without_all:assigned_asset,assigned_location',
-            "assigned_asset"   => 'sometimes:required_without_all:assigned_user,assigned_location',
-            "assigned_location"   => 'sometimes:required_without_all:assigned_user,assigned_asset',
-        ];
-
-        $settings = \App\Models\Setting::getSettings();
-
-        $rules['asset_tag'] = ($settings->auto_increment_assets == '1') ? 'max:255' : 'required';
-
-        if($this->request->get('model_id') != '') {
-            $model = AssetModel::find($this->request->get('model_id'));
-
-            if (($model) && ($model->fieldset)) {
-                $rules += $model->fieldset->validation_rules();
-            }
-        }
-
-        return $rules;
-
-    }
-
-    public function response(array $errors)
-    {
-        $this->session()->flash('errors', Session::get('errors', new \Illuminate\Support\ViewErrorBag)
-            ->put('default', new \Illuminate\Support\MessageBag($errors)));
-        \Input::flash();
-        return parent::response($errors);
-    }
-}
diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php
index a01df7b4f..19a545331 100644
--- a/app/Http/Requests/ImageUploadRequest.php
+++ b/app/Http/Requests/ImageUploadRequest.php
@@ -4,6 +4,8 @@ namespace App\Http\Requests;
 
 use App\Models\SnipeModel;
 use Intervention\Image\Facades\Image;
+use Storage;
+use Illuminate\Support\Facades\File;
 
 class ImageUploadRequest extends Request
 {
@@ -41,36 +43,44 @@ class ImageUploadRequest extends Request
      * @param String $path  location for uploaded images, defaults to uploads/plural of item type.
      * @return SnipeModel        Target asset is being checked out to.
      */
-    public function handleImages($item, $path = null)
+    public function handleImages($item, $w = 550, $path = null)
     {
 
+        $type = strtolower(class_basename(get_class($item)));
+
+        if(is_null($path)) {
+            $path =  str_plural($type);
+        }
+
+
         if ($this->hasFile('image')) {
             if (!config('app.lock_passwords')) {
-                if(is_null($path)) {
-                    $type = strtolower(class_basename(get_class($item)));
-                    $plural = str_plural($type);
-                    $path = public_path('/uploads/'.$plural);
-                }
-                $image = $this->file('image');
+
+                if(!Storage::disk('public')->exists($path)) Storage::disk('public')->makeDirectory($path, 775);
+
+                $upload = $image = $this->file('image');
                 $ext = $image->getClientOriginalExtension();
                 $file_name = $type.'-'.str_random(18).'.'.$ext;
+
                 if ($image->getClientOriginalExtension()!='svg') {
-                    Image::make($image->getRealPath())->resize(null, 250, function ($constraint) {
+                    $upload = Image::make($image->getRealPath())->resize(null, $w, function ($constraint) {
                         $constraint->aspectRatio();
                         $constraint->upsize();
-                    })->save($path.'/'.$file_name);
-                } else {
-                    $image->move($path, $file_name);
+                    });
                 }
 
-                // Remove Current image if exists.
+                // This requires a string instead of an object, so we use ($string)
+                Storage::disk('public')->put($path.'/'.$file_name, (string)$upload->encode());
+
+                // Remove Current image if exists
                 if (($item->image) && (file_exists($path.'/'.$item->image))) {
-                    unlink($path.'/'.$item->image);
+                    Storage::disk('public')->delete($path.'/'.$file_name);
                 }
 
                 $item->image = $file_name;
             }
         } elseif ($this->input('image_delete')=='1') {
+            Storage::disk('public')->delete($path.'/'.$item->image);
             $item->image = null;
         }
         return $item;
diff --git a/app/Http/Transformers/AccessoriesTransformer.php b/app/Http/Transformers/AccessoriesTransformer.php
index a4e935dab..1f828bd1e 100644
--- a/app/Http/Transformers/AccessoriesTransformer.php
+++ b/app/Http/Transformers/AccessoriesTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Accessory;
 use Gate;
 use Illuminate\Database\Eloquent\Collection;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class AccessoriesTransformer
 {
@@ -23,6 +24,7 @@ class AccessoriesTransformer
         $array = [
             'id' => $accessory->id,
             'name' => e($accessory->name),
+            'image' => ($accessory->image) ? Storage::disk('public')->url('accessories/'.e($accessory->image)) : null,
             'company' => ($accessory->company) ? ['id' => $accessory->company->id,'name'=> e($accessory->company->name)] : null,
             'manufacturer' => ($accessory->manufacturer) ? ['id' => $accessory->manufacturer->id,'name'=> e($accessory->manufacturer->name)] : null,
             'supplier' => ($accessory->supplier) ? ['id' => $accessory->supplier->id,'name'=> e($accessory->supplier->name)] : null,
@@ -36,7 +38,7 @@ class AccessoriesTransformer
             'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
             'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
             'remaining_qty' => $accessory->numRemaining(),
-            'image' => ($accessory->image) ? url('/').'/uploads/accessories/'.e($accessory->image) : null,
+
             'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
             'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
 
diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php
index 53ece0558..c5ea16f59 100644
--- a/app/Http/Transformers/ActionlogsTransformer.php
+++ b/app/Http/Transformers/ActionlogsTransformer.php
@@ -63,7 +63,7 @@ class ActionlogsTransformer
             ] : null,
 
             'note'          => ($actionlog->note) ? e($actionlog->note): null,
-            'signature_file'   => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
+            'signature_file'   => ($actionlog->signature_filename) ? route('log.signature.view', ['filename' => $actionlog->signature_filename ]) : null,
             'log_meta'          => ($actionlog->log_meta) ? json_decode($actionlog->log_meta): null,
 
 
diff --git a/app/Http/Transformers/AssetModelsTransformer.php b/app/Http/Transformers/AssetModelsTransformer.php
index 2bb0a9e1a..a344e76d0 100644
--- a/app/Http/Transformers/AssetModelsTransformer.php
+++ b/app/Http/Transformers/AssetModelsTransformer.php
@@ -5,6 +5,7 @@ use App\Models\AssetModel;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class AssetModelsTransformer
 {
@@ -28,7 +29,7 @@ class AssetModelsTransformer
                 'id' => (int) $assetmodel->manufacturer->id,
                 'name'=> e($assetmodel->manufacturer->name)
             ]  : null,
-            'image' => ($assetmodel->image!='') ? app('models_upload_url').e($assetmodel->image) : null,
+            'image' => ($assetmodel->image!='') ? Storage::disk('public')->url('assetmodels/'.e($assetmodel->image)) : null,
             'model_number' => e($assetmodel->model_number),
             'depreciation' => ($assetmodel->depreciation) ? [
                 'id' => (int) $assetmodel->depreciation->id,
diff --git a/app/Http/Transformers/CategoriesTransformer.php b/app/Http/Transformers/CategoriesTransformer.php
index 710bf84bc..b93790f77 100644
--- a/app/Http/Transformers/CategoriesTransformer.php
+++ b/app/Http/Transformers/CategoriesTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Category;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class CategoriesTransformer
 {
@@ -25,7 +26,7 @@ class CategoriesTransformer
             $array = [
                 'id' => (int) $category->id,
                 'name' => e($category->name),
-                'image' =>   ($category->image) ? app('categories_upload_url').e($category->image) : null,
+                'image' =>   ($category->image) ? Storage::disk('public')->url('categories/'.e($category->image)) : null,
                 'category_type' => e($category->category_type),
                 'eula' => ($category->getEula()) ? true : false,
                 'checkin_email' => ($category->checkin_email =='1') ? true : false,
diff --git a/app/Http/Transformers/CompaniesTransformer.php b/app/Http/Transformers/CompaniesTransformer.php
index 96951bdf8..7fac8ee6d 100644
--- a/app/Http/Transformers/CompaniesTransformer.php
+++ b/app/Http/Transformers/CompaniesTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Company;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class CompaniesTransformer
 {
@@ -25,7 +26,7 @@ class CompaniesTransformer
             $array = [
                 'id' => (int) $company->id,
                 'name' => e($company->name),
-                'image' =>   ($company->image) ? app('companies_upload_url').e($company->image) : null,
+                'image' =>   ($company->image) ? Storage::disk('public')->url('companies/'.e($company->image)) : null,
                 "created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
                 "updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
                 "assets_count" => (int) $company->assets_count,
diff --git a/app/Http/Transformers/ComponentsTransformer.php b/app/Http/Transformers/ComponentsTransformer.php
index cf51b55d7..6cd4b98c7 100644
--- a/app/Http/Transformers/ComponentsTransformer.php
+++ b/app/Http/Transformers/ComponentsTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Component;
 use Illuminate\Database\Eloquent\Collection;
 use App\Helpers\Helper;
 use Gate;
+use Illuminate\Support\Facades\Storage;
 
 class ComponentsTransformer
 {
@@ -22,7 +23,7 @@ class ComponentsTransformer
         $array = [
             'id' => (int) $component->id,
             'name' => e($component->name),
-            'image' =>   ($component->image) ? e(url('/').'/uploads/components/'.e($component->image)) : null,
+            'image' =>   ($component->image) ? Storage::disk('public')->url('components/'.e($component->image)) : null,
             'serial' => ($component->serial) ? e($component->serial) : null,
             'location' => ($component->location) ? [
                 'id' => (int) $component->location->id,
diff --git a/app/Http/Transformers/ConsumablesTransformer.php b/app/Http/Transformers/ConsumablesTransformer.php
index 3d68697a5..36ec8d9c2 100644
--- a/app/Http/Transformers/ConsumablesTransformer.php
+++ b/app/Http/Transformers/ConsumablesTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Consumable;
 use Illuminate\Database\Eloquent\Collection;
 use App\Helpers\Helper;
 use Gate;
+use Illuminate\Support\Facades\Storage;
 
 class ConsumablesTransformer
 {
@@ -23,7 +24,7 @@ class ConsumablesTransformer
         $array = [
             'id'            => (int) $consumable->id,
             'name'          => e($consumable->name),
-            'image' =>   ($consumable->image) ? e(url('/').'/uploads/consumables/'.e($consumable->image)) : null,
+            'image' =>   ($consumable->image) ? Storage::disk('public')->url('consumables/'.e($consumable->image)) : null,
             'category'      => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
             'company'   => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
             'item_no'       => e($consumable->item_no),
diff --git a/app/Http/Transformers/DepartmentsTranformer.php b/app/Http/Transformers/DepartmentsTranformer.php
index f81954f94..a24943b96 100644
--- a/app/Http/Transformers/DepartmentsTranformer.php
+++ b/app/Http/Transformers/DepartmentsTranformer.php
@@ -5,6 +5,7 @@ use App\Models\Department;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class DepartmentsTransformer
 {
@@ -25,7 +26,7 @@ class DepartmentsTransformer
             $array = [
                 'id' => (int) $department->id,
                 'name' => e($department->name),
-                'image' =>   ($department->image) ? app('departments_upload_url').e($department->image) : null,
+                'image' =>   ($department->image) ? Storage::disk('public')->url(app('departments_upload_url').e($department->image)) : null,
                 'company' => ($department->company) ? [
                     'id' => (int) $department->company->id,
                     'name'=> e($department->company->name)
diff --git a/app/Http/Transformers/LocationsTransformer.php b/app/Http/Transformers/LocationsTransformer.php
index 5d93db4de..ce018d4f6 100644
--- a/app/Http/Transformers/LocationsTransformer.php
+++ b/app/Http/Transformers/LocationsTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Location;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class LocationsTransformer
 {
@@ -33,7 +34,7 @@ class LocationsTransformer
             $array = [
                 'id' => (int) $location->id,
                 'name' => e($location->name),
-                'image' =>   ($location->image) ? app('locations_upload_url').e($location->image) : null,
+                'image' =>   ($location->image) ? Storage::disk('public')->url('locations/'.e($location->image)) : null,
                 'address' =>  ($location->address) ? e($location->address) : null,
                 'address2' =>  ($location->address2) ? e($location->address2) : null,
                 'city' =>  ($location->city) ? e($location->city) : null,
diff --git a/app/Http/Transformers/ManufacturersTransformer.php b/app/Http/Transformers/ManufacturersTransformer.php
index 3db65ee9f..5457d1c94 100644
--- a/app/Http/Transformers/ManufacturersTransformer.php
+++ b/app/Http/Transformers/ManufacturersTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Manufacturer;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class ManufacturersTransformer
 {
@@ -26,7 +27,7 @@ class ManufacturersTransformer
                 'id' => (int) $manufacturer->id,
                 'name' => e($manufacturer->name),
                 'url' => e($manufacturer->url),
-                'image' =>   ($manufacturer->image) ? app('manufacturers_upload_url').e($manufacturer->image) : null,
+                'image' =>   ($manufacturer->image) ? Storage::disk('public')->url('manufacturers/'.e($manufacturer->image)) : null,
                 'support_url' => e($manufacturer->support_url),
                 'support_phone' => e($manufacturer->support_phone),
                 'support_email' => e($manufacturer->support_email),
diff --git a/app/Http/Transformers/SuppliersTransformer.php b/app/Http/Transformers/SuppliersTransformer.php
index ea636e4a6..a3bb8c6f2 100644
--- a/app/Http/Transformers/SuppliersTransformer.php
+++ b/app/Http/Transformers/SuppliersTransformer.php
@@ -5,6 +5,7 @@ use App\Models\Supplier;
 use Illuminate\Database\Eloquent\Collection;
 use Gate;
 use App\Helpers\Helper;
+use Illuminate\Support\Facades\Storage;
 
 class SuppliersTransformer
 {
@@ -25,7 +26,7 @@ class SuppliersTransformer
             $array = [
                 'id' => (int) $supplier->id,
                 'name' => e($supplier->name),
-                'image' =>   ($supplier->image) ? app('suppliers_upload_url').e($supplier->image) : null,
+                'image' =>   ($supplier->image) ? Storage::disk('public')->url('suppliers/'.e($supplier->image)) : null,
                 'url' => e($supplier->url),
                 'address' => ($supplier->address) ? e($supplier->address) : null,
                 'address2' => ($supplier->address2) ? e($supplier->address2) : null,
diff --git a/app/Models/Accessory.php b/app/Models/Accessory.php
index 76b50704c..41dee8ef1 100755
--- a/app/Models/Accessory.php
+++ b/app/Models/Accessory.php
@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
 use Watson\Validating\ValidatingTrait;
 use App\Notifications\CheckinAccessoryNotification;
 use App\Notifications\CheckoutAccessoryNotification;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * Model for Accessories.
@@ -219,7 +220,7 @@ class Accessory extends SnipeModel
      */
     public function getImageUrl() {
         if ($this->image) {
-            return url('/').'/uploads/accessories/'.$this->image;
+            return Storage::disk('public')->url(app('accessories_upload_path').$this->image);
         }
         return false;
 
diff --git a/app/Models/Asset.php b/app/Models/Asset.php
index c2d48cee2..e0918d20a 100644
--- a/app/Models/Asset.php
+++ b/app/Models/Asset.php
@@ -21,6 +21,7 @@ use Watson\Validating\ValidatingTrait;
 use DB;
 use App\Notifications\CheckinAssetNotification;
 use App\Notifications\CheckoutAssetNotification;
+use Illuminate\Support\Facades\Storage;
 /**
  * Model for Assets.
  *
@@ -159,7 +160,32 @@ class Asset extends Depreciable
         'model'              => ['name', 'model_number'],
         'model.category'     => ['name'],
         'model.manufacturer' => ['name'],
-    ];     
+    ];
+
+
+    /**
+     * This handles the custom field validation for assets
+     *
+     * @var array
+     */
+    public function save($params = [])
+    {
+        $settings = \App\Models\Setting::getSettings();
+
+        // I don't remember why we have this here? Asset tag would always be required, even if auto increment is on...
+        $this->rules['asset_tag'] = ($settings->auto_increment_assets == '1') ? 'max:255' : 'required';
+
+        if($this->model_id != '') {
+            $model = AssetModel::find($this->model_id);
+
+            if (($model) && ($model->fieldset)) {
+                $this->rules += $model->fieldset->validation_rules();
+            }
+        }
+
+        return parent::save($params);
+    }
+
 
     public function getDisplayNameAttribute()
     {
@@ -486,9 +512,9 @@ class Asset extends Depreciable
     public function getImageUrl()
     {
         if ($this->image && !empty($this->image)) {
-            return url('/').'/uploads/assets/'.$this->image;
+            return Storage::disk('public')->url(app('assets_upload_path').e($this->image));
         } elseif ($this->model && !empty($this->model->image)) {
-            return url('/').'/uploads/models/'.$this->model->image;
+            return Storage::disk('public')->url(app('models_upload_path').e($this->model->image));
         }
         return false;
     }
diff --git a/app/Models/AssetModel.php b/app/Models/AssetModel.php
index a570cd8c7..1998b277d 100755
--- a/app/Models/AssetModel.php
+++ b/app/Models/AssetModel.php
@@ -8,6 +8,7 @@ use App\Presenters\Presentable;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Watson\Validating\ValidatingTrait;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * Model for Asset Models. Asset Models contain higher level
@@ -175,7 +176,7 @@ class AssetModel extends SnipeModel
      */
     public function getImageUrl() {
         if ($this->image) {
-            return url('/').'/uploads/models/'.$this->image;
+            return Storage::disk('public')->url(app('models_upload_path').$this->image);
         }
         return false;
     }
diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php
index 596106c26..853c52493 100644
--- a/app/Models/Consumable.php
+++ b/app/Models/Consumable.php
@@ -7,6 +7,7 @@ use App\Presenters\Presentable;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Watson\Validating\ValidatingTrait;
 use App\Notifications\CheckoutConsumableNotification;
+use Illuminate\Support\Facades\Storage;
 
 class Consumable extends SnipeModel
 {
@@ -203,7 +204,7 @@ class Consumable extends SnipeModel
      */
     public function getImageUrl() {
         if ($this->image) {
-            return url('/').'/uploads/consumables/'.$this->image;
+            return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
         }
         return false;
 
diff --git a/app/Presenters/UserPresenter.php b/app/Presenters/UserPresenter.php
index 0d4985226..cc6c16968 100644
--- a/app/Presenters/UserPresenter.php
+++ b/app/Presenters/UserPresenter.php
@@ -6,6 +6,7 @@ use App\Helpers\Helper;
 use App\Models\Setting;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Storage;
 
 /**
  * Class UserPresenter
@@ -320,7 +321,7 @@ class UserPresenter extends Presenter
     {
 
         if ($this->avatar) {
-            return config('app.url').'/uploads/avatars/'.$this->avatar;
+            return Storage::disk('public')->url('avatars/'.$this->avatar, $this->avatar);
         }
 
         if ((Setting::getSettings()->load_remote=='1') && ($this->email!='')) {
diff --git a/app/Providers/SettingsServiceProvider.php b/app/Providers/SettingsServiceProvider.php
index ed965bf9c..63ed2e68e 100644
--- a/app/Providers/SettingsServiceProvider.php
+++ b/app/Providers/SettingsServiceProvider.php
@@ -39,76 +39,85 @@ class SettingsServiceProvider extends ServiceProvider
          * Set some common variables so that they're globally available.
          * The paths should always be public (versus private uploads)
          */
+
+
+
         // Model paths and URLs
+
+        \App::singleton('assets_upload_path', function(){
+            return 'assets/';
+        });
+
+
         \App::singleton('models_upload_path', function(){
-            return public_path('/uploads/models/');
+            return 'assetmodels/';
         });
 
         \App::singleton('models_upload_url', function(){
-            return url('/').'/uploads/models/';
+            return 'assetmodels/';
         });
 
         // Categories
         \App::singleton('categories_upload_path', function(){
-            return public_path('/uploads/categories/');
+            return 'categories/';
         });
 
         \App::singleton('categories_upload_url', function(){
-            return url('/').'/uploads/categories/';
+            return 'categories/';
         });
 
         // Locations
         \App::singleton('locations_upload_path', function(){
-            return public_path('/uploads/locations/');
+            return 'locations/';
         });
 
         \App::singleton('locations_upload_url', function(){
-            return url('/').'/uploads/locations/';
+            return 'storage/public_uploads/locations/';
         });
 
         // Users
         \App::singleton('users_upload_path', function(){
-            return public_path('/uploads/users/');
+            return 'users/';
         });
 
         \App::singleton('users_upload_url', function(){
-            return url('/').'/uploads/users/';
+            return 'public_uploads/users/';
         });
 
         // Manufacturers
         \App::singleton('manufacturers_upload_path', function(){
-            return public_path('/uploads/manufacturers/');
+            return 'manufacturers/';
         });
 
         \App::singleton('manufacturers_upload_url', function(){
-            return url('/').'/uploads/manufacturers/';
+            return 'public_uploads/manufacturers/';
         });
 
         // Suppliers
         \App::singleton('suppliers_upload_path', function(){
-            return public_path('/uploads/suppliers/');
+            return 'suppliers/';
         });
 
         \App::singleton('suppliers_upload_url', function(){
-            return url('/').'/uploads/suppliers/';
+            return 'storage/public_uploads/suppliers/';
         });
 
         // Departments
         \App::singleton('departments_upload_path', function(){
-            return public_path('/uploads/departments/');
+            return 'departments/';
         });
 
         \App::singleton('departments_upload_url', function(){
-            return url('/').'/uploads/departments/';
+            return 'departments/';
         });
 
         // Company paths and URLs
         \App::singleton('companies_upload_path', function(){
-            return public_path('/uploads/companies/');
+            return 'companies/';
         });
 
         \App::singleton('companies_upload_url', function(){
-            return url('/').'/uploads/companies/';
+            return 'storage/public_uploads/companies/';
         });
 
 
diff --git a/composer.json b/composer.json
index 41e35cdf9..d92704077 100644
--- a/composer.json
+++ b/composer.json
@@ -24,6 +24,7 @@
     "league/csv": "^9.0",
     "league/flysystem-aws-s3-v3": "~1.0",
     "league/flysystem-cached-adapter": "~1.0",
+    "league/flysystem-rackspace": "^1.0",
     "league/flysystem-sftp": "~1.0",
     "maknz/slack": "^1.7",
     "neitanod/forceutf8": "^2.0",
diff --git a/composer.lock b/composer.lock
index 027871bbd..d18eed45c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "94a7bad067cd5d3ea24175dce2f318d6",
+    "content-hash": "1b2d866e20b5d160ea9d055221d1fec4",
     "packages": [
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.67.7",
+            "version": "3.67.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "002577f67703af64a1be35d65edd6a74842c1e65"
+                "reference": "0d05816beeaf187a3897c28aaa68d683974818d9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/002577f67703af64a1be35d65edd6a74842c1e65",
-                "reference": "002577f67703af64a1be35d65edd6a74842c1e65",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0d05816beeaf187a3897c28aaa68d683974818d9",
+                "reference": "0d05816beeaf187a3897c28aaa68d683974818d9",
                 "shasum": ""
             },
             "require": {
@@ -84,7 +84,7 @@
                 "s3",
                 "sdk"
             ],
-            "time": "2018-09-06T22:05:51+00:00"
+            "time": "2018-09-28T18:46:40+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1108,16 +1108,16 @@
         },
         {
             "name": "egulias/email-validator",
-            "version": "2.1.5",
+            "version": "2.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/egulias/EmailValidator.git",
-                "reference": "54859fabea8b3beecbb1a282888d5c990036b9e3"
+                "reference": "0578b32b30b22de3e8664f797cf846fc9246f786"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/54859fabea8b3beecbb1a282888d5c990036b9e3",
-                "reference": "54859fabea8b3beecbb1a282888d5c990036b9e3",
+                "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0578b32b30b22de3e8664f797cf846fc9246f786",
+                "reference": "0578b32b30b22de3e8664f797cf846fc9246f786",
                 "shasum": ""
             },
             "require": {
@@ -1161,7 +1161,7 @@
                 "validation",
                 "validator"
             ],
-            "time": "2018-08-16T20:49:45+00:00"
+            "time": "2018-09-25T20:47:26+00:00"
         },
         {
             "name": "erusev/parsedown",
@@ -1309,6 +1309,99 @@
             "homepage": "https://github.com/firebase/php-jwt",
             "time": "2017-06-27T22:17:23+00:00"
         },
+        {
+            "name": "guzzle/guzzle",
+            "version": "v3.8.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/guzzle.git",
+                "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
+                "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "php": ">=5.3.3",
+                "symfony/event-dispatcher": ">=2.1"
+            },
+            "replace": {
+                "guzzle/batch": "self.version",
+                "guzzle/cache": "self.version",
+                "guzzle/common": "self.version",
+                "guzzle/http": "self.version",
+                "guzzle/inflection": "self.version",
+                "guzzle/iterator": "self.version",
+                "guzzle/log": "self.version",
+                "guzzle/parser": "self.version",
+                "guzzle/plugin": "self.version",
+                "guzzle/plugin-async": "self.version",
+                "guzzle/plugin-backoff": "self.version",
+                "guzzle/plugin-cache": "self.version",
+                "guzzle/plugin-cookie": "self.version",
+                "guzzle/plugin-curlauth": "self.version",
+                "guzzle/plugin-error-response": "self.version",
+                "guzzle/plugin-history": "self.version",
+                "guzzle/plugin-log": "self.version",
+                "guzzle/plugin-md5": "self.version",
+                "guzzle/plugin-mock": "self.version",
+                "guzzle/plugin-oauth": "self.version",
+                "guzzle/service": "self.version",
+                "guzzle/stream": "self.version"
+            },
+            "require-dev": {
+                "doctrine/cache": "*",
+                "monolog/monolog": "1.*",
+                "phpunit/phpunit": "3.7.*",
+                "psr/log": "1.0.*",
+                "symfony/class-loader": "*",
+                "zendframework/zend-cache": "<2.3",
+                "zendframework/zend-log": "<2.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Guzzle": "src/",
+                    "Guzzle\\Tests": "tests/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Guzzle Community",
+                    "homepage": "https://github.com/guzzle/guzzle/contributors"
+                }
+            ],
+            "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
+            "homepage": "http://guzzlephp.org/",
+            "keywords": [
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "http client",
+                "rest",
+                "web service"
+            ],
+            "abandoned": "guzzlehttp/guzzle",
+            "time": "2014-01-28T22:29:15+00:00"
+        },
         {
             "name": "guzzlehttp/guzzle",
             "version": "6.3.3",
@@ -1562,32 +1655,32 @@
         },
         {
             "name": "jakub-onderka/php-console-color",
-            "version": "0.1",
+            "version": "v0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/JakubOnderka/PHP-Console-Color.git",
-                "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1"
+                "reference": "d5deaecff52a0d61ccb613bb3804088da0307191"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1",
-                "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1",
+                "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/d5deaecff52a0d61ccb613bb3804088da0307191",
+                "reference": "d5deaecff52a0d61ccb613bb3804088da0307191",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.2"
+                "php": ">=5.4.0"
             },
             "require-dev": {
                 "jakub-onderka/php-code-style": "1.0",
-                "jakub-onderka/php-parallel-lint": "0.*",
+                "jakub-onderka/php-parallel-lint": "1.0",
                 "jakub-onderka/php-var-dump-check": "0.*",
-                "phpunit/phpunit": "3.7.*",
+                "phpunit/phpunit": "~4.3",
                 "squizlabs/php_codesniffer": "1.*"
             },
             "type": "library",
             "autoload": {
-                "psr-0": {
-                    "JakubOnderka\\PhpConsoleColor": "src/"
+                "psr-4": {
+                    "JakubOnderka\\PhpConsoleColor\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1597,11 +1690,10 @@
             "authors": [
                 {
                     "name": "Jakub Onderka",
-                    "email": "jakub.onderka@gmail.com",
-                    "homepage": "http://www.acci.cz"
+                    "email": "jakub.onderka@gmail.com"
                 }
             ],
-            "time": "2014-04-08T15:00:19+00:00"
+            "time": "2018-09-29T17:23:10+00:00"
         },
         {
             "name": "jakub-onderka/php-console-highlighter",
@@ -1679,16 +1771,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v5.7.2",
+            "version": "v5.7.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "86e1f98a6d2aab018e0257a7cb2ef2110d64a873"
+                "reference": "93e761bb5367166ce98ba908d5eb0edd6be76792"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/86e1f98a6d2aab018e0257a7cb2ef2110d64a873",
-                "reference": "86e1f98a6d2aab018e0257a7cb2ef2110d64a873",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/93e761bb5367166ce98ba908d5eb0edd6be76792",
+                "reference": "93e761bb5367166ce98ba908d5eb0edd6be76792",
                 "shasum": ""
             },
             "require": {
@@ -1816,7 +1908,7 @@
                 "framework",
                 "laravel"
             ],
-            "time": "2018-09-06T14:01:05+00:00"
+            "time": "2018-09-25T14:29:00+00:00"
         },
         {
             "name": "laravel/passport",
@@ -2195,26 +2287,26 @@
         },
         {
             "name": "league/flysystem",
-            "version": "1.0.46",
+            "version": "1.0.47",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2"
+                "reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2",
-                "reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a11e4a75f256bdacf99d20780ce42d3b8272975c",
+                "reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c",
                 "shasum": ""
             },
             "require": {
+                "ext-fileinfo": "*",
                 "php": ">=5.5.9"
             },
             "conflict": {
                 "league/flysystem-sftp": "<1.0.6"
             },
             "require-dev": {
-                "ext-fileinfo": "*",
                 "phpspec/phpspec": "^3.4",
                 "phpunit/phpunit": "^5.7.10"
             },
@@ -2275,20 +2367,20 @@
                 "sftp",
                 "storage"
             ],
-            "time": "2018-08-22T07:45:22+00:00"
+            "time": "2018-09-14T15:30:29+00:00"
         },
         {
             "name": "league/flysystem-aws-s3-v3",
-            "version": "1.0.19",
+            "version": "1.0.20",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
-                "reference": "f135691ef6761542af301b7c9880f140fb12dc74"
+                "reference": "398c56027e49653712a8fba1eb12600d2a83f3b7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/f135691ef6761542af301b7c9880f140fb12dc74",
-                "reference": "f135691ef6761542af301b7c9880f140fb12dc74",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/398c56027e49653712a8fba1eb12600d2a83f3b7",
+                "reference": "398c56027e49653712a8fba1eb12600d2a83f3b7",
                 "shasum": ""
             },
             "require": {
@@ -2322,7 +2414,7 @@
                 }
             ],
             "description": "Flysystem adapter for the AWS S3 SDK v3.x",
-            "time": "2018-03-27T20:33:59+00:00"
+            "time": "2018-09-25T12:02:44+00:00"
         },
         {
             "name": "league/flysystem-cached-adapter",
@@ -2371,6 +2463,53 @@
             "description": "An adapter decorator to enable meta-data caching.",
             "time": "2018-07-09T20:51:04+00:00"
         },
+        {
+            "name": "league/flysystem-rackspace",
+            "version": "1.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem-rackspace.git",
+                "reference": "ba877e837f5dce60e78a0555de37eb9bfc7dd6b9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-rackspace/zipball/ba877e837f5dce60e78a0555de37eb9bfc7dd6b9",
+                "reference": "ba877e837f5dce60e78a0555de37eb9bfc7dd6b9",
+                "shasum": ""
+            },
+            "require": {
+                "league/flysystem": "~1.0",
+                "php": ">=5.4.0",
+                "rackspace/php-opencloud": "~1.16"
+            },
+            "require-dev": {
+                "mockery/mockery": "0.9.*",
+                "phpunit/phpunit": "~4.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\Rackspace\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frenky.net"
+                }
+            ],
+            "description": "Flysystem adapter for Rackspace",
+            "time": "2016-03-11T12:13:42+00:00"
+        },
         {
             "name": "league/flysystem-sftp",
             "version": "1.0.16",
@@ -2533,6 +2672,34 @@
             "time": "2015-06-03T03:35:16+00:00"
         },
         {
+            "name": "mikemccabe/json-patch-php",
+            "version": "0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mikemccabe/json-patch-php.git",
+                "reference": "b3af30a6aec7f6467c773cd49b2d974a70f7c0d4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mikemccabe/json-patch-php/zipball/b3af30a6aec7f6467c773cd49b2d974a70f7c0d4",
+                "reference": "b3af30a6aec7f6467c773cd49b2d974a70f7c0d4",
+                "shasum": ""
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "mikemccabe\\JsonPatch\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-3.0"
+            ],
+            "description": "Produce and apply json-patch objects",
+            "time": "2015-01-05T21:19:54+00:00"
+        },
+        {
+
             "name": "monolog/monolog",
             "version": "1.23.0",
             "source": {
@@ -2701,16 +2868,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "1.33.0",
+            "version": "1.34.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "55667c1007a99e82030874b1bb14d24d07108413"
+                "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/55667c1007a99e82030874b1bb14d24d07108413",
-                "reference": "55667c1007a99e82030874b1bb14d24d07108413",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33",
+                "reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33",
                 "shasum": ""
             },
             "require": {
@@ -2752,20 +2919,20 @@
                 "datetime",
                 "time"
             ],
-            "time": "2018-08-07T08:39:47+00:00"
+            "time": "2018-09-20T19:36:25+00:00"
         },
         {
             "name": "nikic/php-parser",
-            "version": "v4.0.3",
+            "version": "v4.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d"
+                "reference": "fa6ee28600d21d49b2b4e1006b48426cec8e579c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd088dc940a418f09cda079a9b5c7c478890fb8d",
-                "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fa6ee28600d21d49b2b4e1006b48426cec8e579c",
+                "reference": "fa6ee28600d21d49b2b4e1006b48426cec8e579c",
                 "shasum": ""
             },
             "require": {
@@ -2803,7 +2970,7 @@
                 "parser",
                 "php"
             ],
-            "time": "2018-07-15T17:25:16+00:00"
+            "time": "2018-09-18T07:03:24+00:00"
         },
         {
             "name": "paragonie/constant_time_encoding",
@@ -3768,6 +3935,63 @@
             ],
             "time": "2018-09-05T11:40:09+00:00"
         },
+        {
+            "name": "rackspace/php-opencloud",
+            "version": "v1.16.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/rackspace/php-opencloud.git",
+                "reference": "d6b71feed7f9e7a4b52e0240a79f06473ba69c8c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/rackspace/php-opencloud/zipball/d6b71feed7f9e7a4b52e0240a79f06473ba69c8c",
+                "reference": "d6b71feed7f9e7a4b52e0240a79f06473ba69c8c",
+                "shasum": ""
+            },
+            "require": {
+                "guzzle/guzzle": "~3.8",
+                "mikemccabe/json-patch-php": "~0.1",
+                "php": ">=5.4",
+                "psr/log": "~1.0"
+            },
+            "require-dev": {
+                "apigen/apigen": "~4.0",
+                "fabpot/php-cs-fixer": "1.0.*@dev",
+                "jakub-onderka/php-parallel-lint": "0.*",
+                "phpspec/prophecy": "~1.4",
+                "phpunit/phpunit": "4.3.*",
+                "satooshi/php-coveralls": "0.6.*@dev"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "OpenCloud": [
+                        "lib/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Jamie Hannaford",
+                    "email": "jamie.hannaford@rackspace.com",
+                    "homepage": "https://github.com/jamiehannaford"
+                }
+            ],
+            "description": "PHP SDK for Rackspace/OpenStack APIs",
+            "keywords": [
+                "Openstack",
+                "nova",
+                "opencloud",
+                "rackspace",
+                "swift"
+            ],
+            "time": "2016-01-29T10:34:57+00:00"
+        },
         {
             "name": "ramsey/uuid",
             "version": "3.8.0",
@@ -4277,16 +4501,16 @@
         },
         {
             "name": "spatie/db-dumper",
-            "version": "2.10.1",
+            "version": "2.11.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/spatie/db-dumper.git",
-                "reference": "1192bb0df9f49ee1f0bdecb7aa921d2647b4c7c7"
+                "reference": "858ea38e341e2e5f74a5b59cc8184c5c7e94b50d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/db-dumper/zipball/1192bb0df9f49ee1f0bdecb7aa921d2647b4c7c7",
-                "reference": "1192bb0df9f49ee1f0bdecb7aa921d2647b4c7c7",
+                "url": "https://api.github.com/repos/spatie/db-dumper/zipball/858ea38e341e2e5f74a5b59cc8184c5c7e94b50d",
+                "reference": "858ea38e341e2e5f74a5b59cc8184c5c7e94b50d",
                 "shasum": ""
             },
             "require": {
@@ -4323,7 +4547,7 @@
                 "mysqldump",
                 "spatie"
             ],
-            "time": "2018-08-30T12:10:16+00:00"
+            "time": "2018-09-27T06:30:34+00:00"
         },
         {
             "name": "spatie/laravel-backup",
@@ -4441,16 +4665,16 @@
         },
         {
             "name": "swiftmailer/swiftmailer",
-            "version": "v6.1.2",
+            "version": "v6.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/swiftmailer/swiftmailer.git",
-                "reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8"
+                "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/7d760881d266d63c5e7a1155cbcf2ac656a31ca8",
-                "reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8ddcb66ac10c392d3beb54829eef8ac1438595f4",
+                "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4",
                 "shasum": ""
             },
             "require": {
@@ -4496,7 +4720,7 @@
                 "mail",
                 "mailer"
             ],
-            "time": "2018-07-13T07:04:35+00:00"
+            "time": "2018-09-11T07:12:52+00:00"
         },
         {
             "name": "symfony/console",
@@ -6195,22 +6419,23 @@
         },
         {
             "name": "codeception/codeception",
-            "version": "2.4.5",
+            "version": "2.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Codeception/Codeception.git",
-                "reference": "5fee32d5c82791548931cbc34806b4de6aa1abfc"
+                "reference": "dee493561daf644134c95cf176fd2c25aff59ea9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Codeception/Codeception/zipball/5fee32d5c82791548931cbc34806b4de6aa1abfc",
-                "reference": "5fee32d5c82791548931cbc34806b4de6aa1abfc",
+                "url": "https://api.github.com/repos/Codeception/Codeception/zipball/dee493561daf644134c95cf176fd2c25aff59ea9",
+                "reference": "dee493561daf644134c95cf176fd2c25aff59ea9",
                 "shasum": ""
             },
             "require": {
                 "behat/gherkin": "^4.4.0",
                 "codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
                 "codeception/stub": "^2.0",
+                "ext-curl": "*",
                 "ext-json": "*",
                 "ext-mbstring": "*",
                 "facebook/webdriver": ">=1.1.3 <2.0",
@@ -6258,7 +6483,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Codeception\\": "src\\Codeception",
+                    "Codeception\\": "src/Codeception",
                     "Codeception\\Extension\\": "ext"
                 }
             },
@@ -6282,7 +6507,7 @@
                 "functional testing",
                 "unit testing"
             ],
-            "time": "2018-08-01T07:21:49+00:00"
+            "time": "2018-09-24T09:33:01+00:00"
         },
         {
             "name": "codeception/phpunit-wrapper",
@@ -6419,16 +6644,16 @@
         },
         {
             "name": "filp/whoops",
-            "version": "2.2.0",
+            "version": "2.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filp/whoops.git",
-                "reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a"
+                "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filp/whoops/zipball/181c4502d8f34db7aed7bfe88d4f87875b8e947a",
-                "reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311",
+                "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311",
                 "shasum": ""
             },
             "require": {
@@ -6447,7 +6672,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.1-dev"
+                    "dev-master": "2.2-dev"
                 }
             },
             "autoload": {
@@ -6476,7 +6701,7 @@
                 "throwable",
                 "whoops"
             ],
-            "time": "2018-03-03T17:56:25+00:00"
+            "time": "2018-06-30T13:14:06+00:00"
         },
         {
             "name": "fzaninotto/faker",
@@ -7127,6 +7352,17 @@
         {
             "name": "roave/security-advisories",
             "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Roave/SecurityAdvisories.git",
+                "reference": "8605f2e74f558d3e349b219e58414b75b0adc30e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/8605f2e74f558d3e349b219e58414b75b0adc30e",
+                "reference": "8605f2e74f558d3e349b219e58414b75b0adc30e",
+                "shasum": ""
+            },
             "conflict": {
                 "3f/pygmentize": "<1.2",
                 "adodb/adodb-php": "<5.20.12",
@@ -7134,6 +7370,7 @@
                 "amphp/http": "<1.0.1",
                 "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
                 "aws/aws-sdk-php": ">=3,<3.2.1",
+                "brightlocal/phpwhois": "<=4.2.5",
                 "bugsnag/bugsnag-laravel": ">=2,<2.0.2",
                 "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4",
                 "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
@@ -7145,6 +7382,7 @@
                 "contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8",
                 "contao/listing-bundle": ">=4,<4.4.8",
                 "contao/newsletter-bundle": ">=4,<4.1",
+                "david-garcia/phpwhois": "<=4.3.1",
                 "doctrine/annotations": ">=1,<1.2.7",
                 "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
                 "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
@@ -7159,6 +7397,7 @@
                 "drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3",
                 "erusev/parsedown": "<1.7",
                 "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1",
+                "ezyang/htmlpurifier": "<4.1.1",
                 "firebase/php-jwt": "<2",
                 "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
                 "friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
@@ -7170,7 +7409,11 @@
                 "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
                 "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29",
                 "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
+                "ivankristianto/phpwhois": "<=4.3",
+                "james-heinrich/getid3": "<1.9.9",
                 "joomla/session": "<1.3.1",
+                "jsmitty12/phpwhois": "<5.1",
+                "kazist/phpwhois": "<=4.2.6",
                 "kreait/firebase-php": ">=3.2,<3.8.1",
                 "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
                 "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
@@ -7180,6 +7423,7 @@
                 "monolog/monolog": ">=1.8,<1.12",
                 "namshi/jose": "<2.2",
                 "onelogin/php-saml": "<2.10.4",
+                "openid/php-openid": "<2.3",
                 "oro/crm": ">=1.7,<1.7.4",
                 "oro/platform": ">=1.7,<1.7.4",
                 "padraic/humbug_get_contents": "<1.1.2",
@@ -7188,21 +7432,25 @@
                 "paypal/merchant-sdk-php": "<3.12",
                 "phpmailer/phpmailer": ">=5,<5.2.24",
                 "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
+                "phpwhois/phpwhois": "<=4.2.5",
                 "phpxmlrpc/extras": "<0.6.1",
                 "propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
                 "propel/propel1": ">=1,<=1.7.1",
                 "pusher/pusher-php-server": "<2.2.1",
                 "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
                 "sensiolabs/connect": "<4.2.3",
+                "serluck/phpwhois": "<=4.2.6",
                 "shopware/shopware": "<5.3.7",
                 "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11",
                 "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
                 "silverstripe/framework": ">=3,<3.3",
                 "silverstripe/userforms": "<3",
+                "simple-updates/phpwhois": "<=1",
                 "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
                 "simplesamlphp/simplesamlphp": "<1.15.2",
                 "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
                 "slim/slim": "<2.6",
+                "smarty/smarty": "<3.1.33",
                 "socalnick/scn-social-auth": "<1.15.2",
                 "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
                 "stormpath/sdk": ">=0,<9.9.99",
@@ -7229,8 +7477,10 @@
                 "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
                 "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
                 "thelia/backoffice-default-template": ">=2.1,<2.1.2",
-                "thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
+                "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
+                "theonedemon/phpwhois": "<=4.2.5",
                 "titon/framework": ">=0,<9.9.99",
+                "truckersmp/phpwhois": "<=4.3.1",
                 "twig/twig": "<1.20",
                 "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2",
                 "typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2",
@@ -7283,7 +7533,7 @@
                 }
             ],
             "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
-            "time": "2018-08-14T15:39:17+00:00"
+            "time": "2018-09-17T20:20:31+00:00"
         },
         {
             "name": "sebastian/code-unit-reverse-lookup",
@@ -7610,16 +7860,16 @@
         },
         {
             "name": "squizlabs/php_codesniffer",
-            "version": "3.3.1",
+            "version": "3.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
-                "reference": "628a481780561150481a9ec74709092b9759b3ec"
+                "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/628a481780561150481a9ec74709092b9759b3ec",
-                "reference": "628a481780561150481a9ec74709092b9759b3ec",
+                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e",
+                "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e",
                 "shasum": ""
             },
             "require": {
@@ -7657,7 +7907,7 @@
                 "phpcs",
                 "standards"
             ],
-            "time": "2018-07-26T23:47:18+00:00"
+            "time": "2018-09-23T23:08:17+00:00"
         },
         {
             "name": "symfony/browser-kit",
diff --git a/config/backup.php b/config/backup.php
index bc45801f4..898f467ff 100644
--- a/config/backup.php
+++ b/config/backup.php
@@ -14,8 +14,7 @@ return [
     'backup' => [
 
         /*
-         * The name of this application. You can use this name to monitor
-         * the backups.
+         * I don't know why they call it name - it's used in the path for uploads
          */
         'name' => 'backups',
 
@@ -27,8 +26,6 @@ return [
                  * The list of directories and files that will be included in the backup.
                  */
                 'include' => [
-                    public_path('uploads'),
-                    storage_path('private_uploads'),
                     storage_path('oauth-private.key'),
                     storage_path('oauth-public.key'),
                     (env('BACKUP_ENV')=='true') ? base_path('.env') : base_path('.env.example'),
@@ -76,7 +73,7 @@ return [
              * The disk names on which the backups will be stored.
              */
             'disks' => [
-                'local',
+                env('FILESYSTEM_DISK'),
             ],
         ],
     ],
diff --git a/config/filesystems.php b/config/filesystems.php
index 6fcf1386b..dd64eda58 100644
--- a/config/filesystems.php
+++ b/config/filesystems.php
@@ -1,15 +1,6 @@
 <?php
 
-/*
- |--------------------------------------------------------------------------
- | DO NOT EDIT THIS FILE DIRECTLY.
- |--------------------------------------------------------------------------
- | This file reads from your .env configuration file and should not
- | be modified directly.
-*/
-
-
-return [
+$config = [
 
     /*
     |--------------------------------------------------------------------------
@@ -17,10 +8,8 @@ return [
     |--------------------------------------------------------------------------
     |
     | Here you may specify the default filesystem disk that should be used
-    | by the framework. A "local" driver, as well as a variety of cloud
-    | based drivers are available for your choosing. Just store away!
-    |
-    | Supported: "local", "ftp", "s3", "rackspace"
+    | by the framework. The "local" disk, as well as a variety of cloud
+    | based disks are available to your application. Just store away!
     |
     */
 
@@ -37,7 +26,7 @@ return [
     |
     */
 
-    'cloud' => 's3',
+    'cloud' => env('FILESYSTEM_CLOUD', 's3'),
 
     /*
     |--------------------------------------------------------------------------
@@ -48,52 +37,54 @@ return [
     | may even configure multiple disks of the same driver. Defaults have
     | been setup for each driver as an example of the required options.
     |
+    | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
+    |
     */
 
     'disks' => [
 
         'local' => [
             'driver' => 'local',
-            'root'   => base_path(),
-        ],
-
-        'ftp' => [
-            'driver'   => 'ftp',
-            'host'     => env('FTP_HOST', 'ftp.yourhost.com'),
-            'username' => env('FTP_USERNAME', 'ftp-user'),
-            'password' => env('FTP_PASSWORD', 'ftp-pass'),
-            'port'     => env('FTP_PORT', '21'),
-            'root'     => env('FTP_ROOT', ''),
-            'passive'  => env('FTP_PASSIVE', true),
-            'ssl'      => env('FTP_SSL', true),
-            'timeout'  => env('FTP_TIMEOUT', 30),
+            'root' => storage_path('app'),
         ],
 
-        'sftp' => [
-            'driver' => 'sftp',
-            'host'     => env('SFTP_HOST', 'sftp.yourhost.com'),
-            'username' => env('SFTP_USERNAME', 'sftp-user'),
-            'password' => env('SFTP_PASSWORD', 'sftp-pass'),
-            'port'     => env('SFTP_PORT', '22'),
-            'root'     => env('SFTP_ROOT', ''),
-            'timeout'  => env('SFTP_TIMEOUT', 30),
+        // This applies the LOCAL public only, not S3/FTP/etc
+        'public' => [
+            'driver' => 'local',
+            'root' => storage_path('app/public'),
+            'url' => env('APP_URL').'/storage',
+            'visibility' => 'public',
         ],
 
         's3' => [
             'driver' => 's3',
-            'key'    => env('AWS_KEY', null),
-            'secret' => env('AWS_SECRET', null),
-            'region' => env('AWS_REGION', null),
-            'bucket' => env('AWS_BUCKET', null),
-
-            'cache' => [
-                'store' => env('AWS_CACHE_STORE', 'memcached'),
-                'expire' => env('AWS_CACHE_EXPIRES', 600),
-                'prefix' =>  env('AWS_CACHE_PREFIX', 'cache-prefix'),
-            ],
+            'key' => env('AWS_ACCESS_KEY_ID'),
+            'secret' => env('AWS_SECRET_ACCESS_KEY'),
+            'region' => env('AWS_DEFAULT_REGION'),
+            'bucket' => env('AWS_BUCKET'),
+            'url' => env('AWS_URL'),
+            'root'   => env('AWS_BUCKET_ROOT'),
         ],
 
+        'rackspace' => [
+            'driver'    => 'rackspace',
+            'username'  => env('RACKSPACE_USERNAME'),
+            'key'       => env('RACKSPACE_KEY'),
+            'container' => env('RACKSPACE_CONTAINER'),
+            'endpoint'  => 'https://identity.api.rackspacecloud.com/v2.0/',
+            'region'    => env('RACKSPACE_REGION'),
+            'url_type'  => env('RACKSPACE_URL_TYPE'),
+        ],
 
     ],
 
 ];
+
+// When you're dealing with local file storage, the paths will be different than S3
+if  (env('FILESYSTEM_DISK')!='local')
+{
+    $config['disks']['public'] = $config['disks'][env('FILESYSTEM_DISK')];
+    $config['disks']['public']['visibility'] = 'public';
+}
+
+return $config;
diff --git a/database/seeds/AssetModelSeeder.php b/database/seeds/AssetModelSeeder.php
index fdb1adef0..03c7fb509 100755
--- a/database/seeds/AssetModelSeeder.php
+++ b/database/seeds/AssetModelSeeder.php
@@ -2,6 +2,7 @@
 
 use Illuminate\Database\Seeder;
 use App\Models\AssetModel;
+use Illuminate\Support\Facades\Storage;
 
 class AssetModelSeeder extends Seeder
 {
@@ -39,21 +40,30 @@ class AssetModelSeeder extends Seeder
         factory(AssetModel::class, 1)->states('ultrafine')->create(); // 17
         factory(AssetModel::class, 1)->states('ultrasharp')->create(); // 18
 
-        $src = public_path('/img/demo/models');
-        $dst =  public_path('/uploads/models');
-
-        $del_files = glob($dst."/*.*");
+        $src = public_path('/img/demo/models/');
+        $dst = 'assetmodels'.'/';
+        $del_files = Storage::files($dst);
 
         foreach($del_files as $del_file){ // iterate files
-            if(is_file($del_file))
-                unlink($del_file); // delete file
+            $file_to_delete = str_replace($src,'',$del_file);
+            \Log::debug('Deleting: '.$file_to_delete);
+            try  {
+                Storage::disk('public')->delete($dst.$del_file);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
 
         $add_files = glob($src."/*.*");
         foreach($add_files as $add_file){
-            $file_to_copy = str_replace($src,$dst,$add_file);
-            copy($add_file, $file_to_copy);
+            $file_to_copy = str_replace($src,'',$add_file);
+            \Log::debug('Copying: '.$file_to_copy);
+            try  {
+                Storage::disk('public')->put($dst.$file_to_copy, file_get_contents($src.$file_to_copy));
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
 
diff --git a/database/seeds/AssetSeeder.php b/database/seeds/AssetSeeder.php
index 79e47d611..f9c2f1fc8 100644
--- a/database/seeds/AssetSeeder.php
+++ b/database/seeds/AssetSeeder.php
@@ -1,7 +1,7 @@
 <?php
 use Illuminate\Database\Seeder;
 use App\Models\Asset;
-
+use Illuminate\Support\Facades\Storage;
 
 class AssetSeeder extends Seeder
 {
@@ -35,13 +35,14 @@ class AssetSeeder extends Seeder
       factory(Asset::class, 10)->states('ultrasharp')->create();
 
 
-      $dst =  public_path('/uploads/assets');
-
-      $del_files = glob($dst."/*.*");
-
+      $del_files = Storage::files('companies');
       foreach($del_files as $del_file){ // iterate files
-          if(is_file($del_file))
-              unlink($del_file); // delete file
+          \Log::debug('Deleting: '.$del_files);
+          try  {
+              Storage::disk('public')->delete('assets'.'/'.$del_files);
+          } catch (\Exception $e) {
+              \Log::debug($e);
+          }
       }
 
       DB::table('checkout_requests')->truncate();
diff --git a/database/seeds/CompanySeeder.php b/database/seeds/CompanySeeder.php
index 3885b939f..eeae5492b 100644
--- a/database/seeds/CompanySeeder.php
+++ b/database/seeds/CompanySeeder.php
@@ -12,26 +12,37 @@ class CompanySeeder extends Seeder
      */
     public function run()
     {
-        //
+        \Log::debug('Seed companies');
         Company::truncate();
         factory(Company::class, 4)->create();
 
-        $src = public_path('/img/demo/companies');
-        $dst =  public_path('/uploads/companies');
 
-        $del_files = glob($dst."/*.*");
+        $src = public_path('/img/demo/companies/');
+        $dst = 'companies'.'/';
+        $del_files = Storage::files('companies/'.$dst);
 
         foreach($del_files as $del_file){ // iterate files
-            if(is_file($del_file))
-                unlink($del_file); // delete file
+            $file_to_delete = str_replace($src,'',$del_file);
+            \Log::debug('Deleting: '.$file_to_delete);
+            try  {
+                Storage::disk('public')->delete($dst.$del_file);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
 
         $add_files = glob($src."/*.*");
         foreach($add_files as $add_file){
-            $file_to_copy = str_replace($src,$dst,$add_file);
-            copy($add_file, $file_to_copy);
+            $file_to_copy = str_replace($src,'',$add_file);
+            \Log::debug('Copying: '.$file_to_copy);
+            try  {
+                Storage::disk('public')->put($dst.$file_to_copy, file_get_contents($src.$file_to_copy));
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
+
     }
 }
diff --git a/database/seeds/LocationSeeder.php b/database/seeds/LocationSeeder.php
index 40d389792..f7d857f34 100644
--- a/database/seeds/LocationSeeder.php
+++ b/database/seeds/LocationSeeder.php
@@ -1,7 +1,7 @@
 <?php
 use Illuminate\Database\Seeder;
 use App\Models\Location;
-
+use Illuminate\Support\Facades\Storage;
 
 class LocationSeeder extends Seeder
 {
@@ -10,21 +10,30 @@ class LocationSeeder extends Seeder
         Location::truncate();
         factory(Location::class, 10)->create();
 
-        $src = public_path('/img/demo/locations');
-        $dst =  public_path('/uploads/locations');
-
-        $del_files = glob($dst."/*.*");
+        $src = public_path('/img/demo/locations/');
+        $dst = 'locations'.'/';
+        $del_files = Storage::files($dst);
 
         foreach($del_files as $del_file){ // iterate files
-            if(is_file($del_file))
-                unlink($del_file); // delete file
+            $file_to_delete = str_replace($src,'',$del_file);
+            \Log::debug('Deleting: '.$file_to_delete);
+            try  {
+                Storage::disk('public')->delete($dst.$del_file);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
 
         $add_files = glob($src."/*.*");
         foreach($add_files as $add_file){
-            $file_to_copy = str_replace($src,$dst,$add_file);
-            copy($add_file, $file_to_copy);
+            $file_to_copy = str_replace($src,'',$add_file);
+            \Log::debug('Copying: '.$file_to_copy);
+            try  {
+                Storage::disk('public')->put($dst.$file_to_copy, file_get_contents($src.$file_to_copy));
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
     }
diff --git a/database/seeds/ManufacturerSeeder.php b/database/seeds/ManufacturerSeeder.php
index f6d9a2451..a65d12a2e 100644
--- a/database/seeds/ManufacturerSeeder.php
+++ b/database/seeds/ManufacturerSeeder.php
@@ -1,6 +1,7 @@
 <?php
 use Illuminate\Database\Seeder;
 use App\Models\Manufacturer;
+use Illuminate\Support\Facades\Storage;
 
 class ManufacturerSeeder extends Seeder
 {
@@ -19,21 +20,30 @@ class ManufacturerSeeder extends Seeder
         factory(Manufacturer::class, 1)->states('avery')->create(); // 10
         factory(Manufacturer::class, 1)->states('crucial')->create(); // 10
 
-        $src = public_path('/img/demo/manufacturers');
-        $dst =  public_path('/uploads/manufacturers');
-
-        $del_files = glob($dst."/*.*");
+        $src = public_path('/img/demo/manufacturers/');
+        $dst = 'manufacturers'.'/';
+        $del_files = Storage::files($dst);
 
         foreach($del_files as $del_file){ // iterate files
-            if(is_file($del_file))
-                unlink($del_file); // delete file
+            $file_to_delete = str_replace($src,'',$del_file);
+            \Log::debug('Deleting: '.$file_to_delete);
+            try  {
+                Storage::disk('public')->delete($dst.$del_file);
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
 
         $add_files = glob($src."/*.*");
         foreach($add_files as $add_file){
-            $file_to_copy = str_replace($src,$dst,$add_file);
-            copy($add_file, $file_to_copy);
+            $file_to_copy = str_replace($src,'',$add_file);
+            \Log::debug('Copying: '.$file_to_copy);
+            try  {
+                Storage::disk('public')->put($dst.$file_to_copy, file_get_contents($src.$file_to_copy));
+            } catch (\Exception $e) {
+                \Log::debug($e);
+            }
         }
 
         
diff --git a/public/img/demo/logo.png b/public/img/demo/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..423a5b74906c4a1f67dab665a59a6731f0dbaa98
GIT binary patch
literal 22482
zcmeAS@N?(olHy`uVBq!ia0y~yVCZ3BV3@|i#=yY9)0=RZfkA=6)5S5QV$Pkt<uhW#
zE8qXG{Qffd+?Pd}Ql840YmBy~dY^FJ)Vs0pz>GNOpNxtQ9(sx~iqAbc{yuX2uEr?m
z#ChbT>XZYlv$LdoHl%v%Z3=Ze`l{3<_VV*D#n;~V-@SJ4`H5+{o-=f8X9a(|mAyB6
zZF%ke_rKR|{U*3n<iG6Y>0#g4TzAABtaknQl(*XK-Hwpb{8um6GE8G!&pz+oh3y~z
z$FAC?U&i%sA?pr_%*&_l@wIGcloz|vR`6!hmD`u4L%r6DPBdp;&m_lGSEu=EU&zb-
zQxD}t-IR9Q;mj#7yo2e)f*+!XzPPU4zTBMW3xmA)ld1)huJfDfe;t|EJF`3T`%=IE
zx+2G<HmnwX#jH_j-o&^dVe^8z%?sb3JLI~`oG*rZk8FjsfE$B^)0O3R7t7P{A6@aC
zf9AgzqG`eY`Nki@HSQ^$aB4Mj;pDJvoS$=}`1uXj6~=24bXR;|P$7CjM@eI;fMCEM
zj)`Z*cio%r^lNeG3}4&w(B?f}3+=Q{h;k%OVG<1Bnjn0jUoT^>_WM;1OSpenH-1(4
z+F`^HaO2b`kwfWbUvhn7PV9=;dfD%nX!iAvC~G9^r|<*PES%Z}Y(5MwTpC~N&ED+%
z+{ANhde}EN);yNV%|UxSTP(unc0}ZhHhoe4bGL0@?_=>r_ogTPS{yV(f9;;tVu{TM
zW;e8YX*%n;2nssPRA`oQc(PDD`u?(c_Y}HTyH?nL&{`VOt+2o+*3ls+q<Koyf9(x#
zk6!y7<X11k^?B*ky;qg)sBK_$<rfIi;5ZPI)8|t>Z`R_%fTjgOUOyQ36olVW+I)9`
z9or|Z1xy>J2nPpln0m}bqD7Z!w%M25Ikgkd)_N|VzU5Fv-lwP*eyyX@ES*}_8=Sg=
zQ~&13-aMuKcst{?NC8XLu4?l=4CQ6P{`n$TzAEIq7q*`ateLsw$?af;`t1wzA3x#F
zcqSiObyDlhvU$6u1b=FDZRgb4;_g1hDfD1+=kbbHFZiOQqF35P=fw#-YML>#&nvIh
zt`1kMVR`aY!|LsOQLaFzMXIh<X0B&Twz>xgED_kJw&H)8UdhTYlY(dX+V1^&V6DP@
zrmL+T3#YhBDH%lA9dTBUwzyQ^;h^A9p2GRi=R{d%y5PPao%?!seqN)^_oboA{)Baa
z)(V4U3x?JeNj5g;E`BKVn`d|M^{n{rA`YI83C>U45A4r<vHSD>(1v$0FI5*C%ntj;
z*0|N{hlJN%EhW)!A!34?L@UeE%Rm13cwExDT1?Q@yVm;c!7>$1jlhOo;S&}<Uvrx0
z%UZ{eajjKT70ynpPMx)TL(;0GS#yJTTNqR|Ox&1wuk`Ki&YqS6j-Hu*8b`(LH>N*k
z?f<$b<g&L@qS@CkW?DZcaJ(0K5!A3*BkO?ATb+KtywvX>W0!3H<|4MLI5Z^nQQ41F
zmM84ezs{YFHT(L7tub%PuN^`=0}XupSLQT0Y*RX(m#ptETRG|CN<pqxrq9+^FK6U5
z@3}EYT!HmVUDEku&vXCjx&69yYB!Idp@HBfhA@WMhK&pJAAi>mv8^{~y}4!6b%zz~
zc`Q|e*&lRV1qF>R@+{Z-_48q{y+Ztn==-z3A6GJr+xJFnNjw9W#?77&6(@I9RcQyT
zVZ7J(A#cJ4ZXqVeqb@0vgbxPi*nO~06E^PSx#%(FwbXib1IY`A^&}tMKESV^vD~JA
z%gX2LqFRrzN;OsqiZO*V+G^|)WDBSX=ZxPu;p@ML0&W$oEBF^Z2~!QZ!K`tu!^iy0
zryoC(-`u<WT%%k1M5xL2v&wdHdDBgK|D2IGxP7HKTtYQmc@Osv=8*2=OC-8NLfd2?
z`xj?CGg!{%Z)J3Y;rh)j4cETdxa|C{`9k=|v!x{q&A)!x#&Fj`dV|c8%R$px9h5z;
zJSwz&;P{}Mqrd)9q`>#qCElwHW>;15E^yZTS|@mK`Ghn<p6Wj$T}~S36TWinxBHXr
zwyf>sQ=flYi};s(*mQ2|i3!5uFN0Ui&;B}P=GPPVJ3kaHh)itz!1_7XY{tWsx02iB
zDqD=x&rdl0+=p|D!XkmjPZ6xyQr82_M4dOgayI%i{njtI&(gTzt36jq!lI+59H$$q
z7BDSc)Ny3viJjZ(LIs|PZ16m|cm9jp76pn=H(yo_mN@;pQuc#k!c1p_w`|f~Ge1Sn
z^RPX6dG|b}xqi{*U8!t2!An=HUAMe&&AEMZg1gq&C7qw!>1(_9>Vc{UTe-Ab^4V{#
zu@Vy1>=W<XTwEmX&M#9q!Nq0$=_@^byMF4NIP1=pROKEZ@Z`4iFSC39m3|*`2xK%-
zHc3))HSantu$3i6GHru^DwkvQ4Uy|Jq6*a;3RPb@I@)bsnE#kHG^Kvm3$EnSb6dTB
zY&an6wUX<il&;c>4M{7CI&_u$Kb+}g?znL|^5x&;`v*@|YIg>+s{ME)R8bV{|9-W>
zcF8--rmPYd^gili9x?TB;$s2p^Y5Ph_+V%>bIbCO^ShRYo-dWXen_EDQ%JR6spe<v
zm&4P;?p;+=@)pq%jOe_;vxVX83=WCXSB%GNx8GJgDx0V!l(k;rzx#x0eb)yc7HOVY
zHt*g7r&5kjbuIjiSGlhLVbEYUx+vn`UcPzjd%;OFRm>*s@HQzkvJW}F`X$eq;~o~`
z{Tf%Uv+fk@(6(;jPtY)OYuk9MP)@d@<#F?I&-BZFvJd!LHia4FF5S85x0lp8GmGo4
zPguNaFGjKIU%j`%$u%%YEns25T%}9RkGxt^IdmN&6u7jqzO~-yo)*TP8yWM6Kf$_C
zY7s*ZgT45Z?gJ}%pG#I(ZG5>%15}K@a=fQ_f<3TAd&*|M<Z^$-hz0gm2l|fimA${a
zQnMpMHch*)&!p>CfbQFcX57mhALQ=atD!KVTijxr?J47%&2Or!_-FdC*{(}YFZpiL
z9ULB-YHGVs&dF0-A%pKtxa*UHytUHYY0}lJ8_kx6Ebb^_kY)0o`tnp+_etY9uIkZl
zm*3o6#khziwN_(__NI+8Gizpbxv(zT=(}*82J3^s1mO=4+V=IX<hCq3KUHtVp@=1A
zYlCWHT5eBS#8a3)VRJ?}=k8Sge!1!?A75_Xap#~Z_d1~&^QQ($v>lxKdA*WB>I=Pf
zrSnsp4s~_@%G}16_w>OD#<cYGxu5o&%oh9l{`RTc8OwRO&h^xZ9R0iCTK=n-Zyi@I
zRp1tsa$O=ex!J|^?FAn$4R6OI(Yh@nJKLDjnT2H}EnNO5*voc{Z?L(*yLp?*BQ0K|
zbt3l#9@?9I$+h{y)c(?SDfc3SYkXVG0&@<``8X{zV8PDCtqF~rMTKq5eoIvMeVuqZ
zl~LzB%bd5I*Q)RCWnE|!cF-s?Yn@lNpowZ%jK%qioH@%cTi^V9#BbA2oz|vJHgXqz
z`nZ3awU=Dr>~K9*@pI8^PCnK<2SZ<RInHy?WLE6(5HN_TTzaEtLE(xCO5!>bPMk9o
z_nNT6({PS-+I3^=nRZsLjZ7OOB(ufVJnJgqzj)Fhj%7+@f_PVd*M;(xXZ%-wStNR_
zCGD%9<Gs}`v5kiqiXEo1{%s0a5%A{h`^Ovq9ha1nWQl3gTx6r>`91OM>u0~Sr^j~}
zUc2`oZSBh=EsZAxs?)x2c>lmI?Rnao-7zIr(-&3vPO8lPxaa7VzVJ#{ft3YkICm^_
zb#{yPTPniR>J&4PLsfE)&EbNg87Z!_4nAQ>@B423?Bc%ixLWSlQP(fdjb{=zi?ZUX
zVEDneqJF=`ZQuF%Re|8P$ZD4#Q-X>XC%kpqY%Oa1tkGeS)xm2wkKd@wVm~=$AE%$q
zsib{X_P151PM>~xVqS5+slwd}iLY;%eVc#t{EsQy^-C|UnQeZYed8;m^|OC!YisY^
zmZfX-cv4`#rJj`L>!!bvrxfo_NOkGm^!tS0xxV?T$tg4ad<>1P7jHctDza3>`+0eB
z@!_*q{IAY>w_8^@jKS}tXUo3nryf1y4g$3ya=kuk3f}8H`D^XHE%9d#o^<7w(YHRS
z&;NJM%a@tGUo`zI)6#$KFJHbRXv3DLMp9h8Pn21YrSvFoeEjFzM)oZ=i>9U?-Wk~!
zuNW&C)5^=jb4_nY+pm&l_EH-)ZxI(o*)s-{=cHL#9nP^i8IU#M?e6&syVYNxcxbxv
zU3pox)@kj?>wD*2?bM#gd3dLe601lp$KDygtMoKi)~@^FB)H7E#r|@v(}zjNZ{A|r
z9klz#wsh%}C6{)_?P88i)pV0ql<K`Cn73F!f5Xo&?=7vWr)=yD?6<ry)$zBOP1@np
zsU=@ltX`EKn4s8bxiMq<(lv>$>y{lzNt`5n`1p)DbCdLDrBq~1n7H`aqa~*sWBUCx
zx9jcB+srS*9VNDD+czmORWT*WbaPg(87?1#8};*F-2O4?PW)#l(KP!HOBAxt^oKoX
z^5W__Kl_RM?*H8<pQy~tIhM?|C+1M7On7Ea^Rs)xob8faJfE*DT>etty4Rbd@Lf6k
z8UK{Kn{rGpvY%I5+nptTX~JrCZOfvmmO-VFeZI2E$M?MzX%ms0ny6;ztTy?h;v(-G
zxsqpg?LEORz{Bz~vc~eY^7Y`UYn(pyy*$0pLUBdE@}{Rt_Y}Wx)jDJH!Su}Ky1?oN
zu8T~+AD#a&TXuh<p5fw3d%o%;VSFFhR@`X}`EmC0mop~)Z|lyS%D%sTa@5@EFT5U?
zpMU#1=BOZ}GmqBm)s;bI1xl4Y&b#@lo&<=!6%t%)vt2gM)zp6XMwQJy$9AP%+rIws
zra!3?o29gz?LXAE=;y!K{dv)v|1l?2^uHMVTQ=`r>Vfjc&@#cDn`HP`oweEdztErO
zsGP*z)UxzN^Y>S<|GzVD%DdD?>jQP4pXjfaxcTOj_rlr#UajR{n{#)HSaoIW+t@n+
z)y!{ShJ_qkY0sX+{MB`WZoSU)8F4++OE`Y;ZeR+LP?*6ha6TksnS(j=QA7R$_PcL0
zPQU)}^y@L}H#Sy=-zNF$M^#=tbLRb1^QB5>@9l~$xvadcu60Xl5LePgjqt7OAI<ud
ztvP#Z*q(_@1`L0+pItlmPu!4gy3O8%7RDbz=VR|S{ShnfXJcUgs90C@NWI5@-q)w!
zgfBgx|7XwhpHs`<{aLqq&En(T+M74-nkX%P_eiR-x5D!$GugH=%)fP^{H2_Ik>cg<
zuEQKM2W@tI75lyWmxt}sgGI**MUVAseOtrQ#dd1m-e;!!uP>R+BX0U;&%Y<;iDh@6
z8)dHZ{8;ziRp7gwvA^M=n5`wI;jUp9ZSJyIo_-zlg?WDPq4V|^w|}(!F1tVEa<`L2
zgRkx0>)I6#3wRnPJUaf^KJkCX$89`!&+5e84s`W;XfC{KrSW?0`H~mU_D{E{zCJl-
z-XpC>t%WgVarXKjcb)pSwJU=4dVCr4>PxmP!H&g=ftoBQ75;=A)MxQqa79IlQ-M`$
z>4Yf`$Kr0(Xf79DYjADlk==&o?h6|h{#34c{r$d!JM)LdEfs8G`<L;rlP~OIzx`Cx
ziu0@1RQZ{ITEbon@H*P8e(+%O_1zn@6SKu%OI<UxzuULOmb=X^KcMl%ngxEEs?JJ0
z49*7(44RT;5_y)k2}s_*u>IpAyW7uxE)(B7P32kLt=|E!!dy<VtT=z=*O{KTlf>?3
z@88VksJ{8sWcPTr57pYcx?hL#?LXAz7S}!1S^ea_U!_aG>P=|cuwrxfZK*iVyD7Sp
z%DKN*R8}<zYl-Lx7r$Pryh_MaTWPb#GQpW_%goolnak#<Fo(rY(?YS}5r64}|E|hB
z2bRsd=l8&VO3>@Kt(&VC*{7fX7h92df7O-~#ad;qdz)XC*PeaSzeH^J^;Isi58S6c
zpY|{&FnTlJVFLq$jLfXm)ay?}1l5fMRVH-^=&x4FY2kdr>v8Mpt`koc?>xvm=@O~^
zi7CKAQzS@WVM3=-XMxk1;Cap(eo9&PUP2t22|^wWE4g<@{%z6#yTqR%{(zOn{@t1K
z-}8QZa(;eLI&rTItM>fsB|E>r(s*F*de7B%z4w}~S082{DHePj^z8D!`|BO7K54Li
zJY^xPJ2!;oH0Sa|Axlopyne+gcFjBwyB0%Dk89k!|2>`d-0z;9Q%Y2Vj0Izl=F(%X
zPqqYQ#Y`}4VO)A;Mn_NXi|T*uAM}<S+R}KdebNr0qZ=O>?kj)syHD3#`pF*cgMnR%
zG0!FMt)24E=*yo5e#bi@K5^bx!%y+d+BEgkge5FOqNkOa4kk?K`s9^#P=Zm^A?U*8
zTFYG1w@0`OogOpxNLIVgyHO||9wo1}^Y8Pomo~gFRd-@s8YFgcUZ~g7BQ^GHUlv>N
zyqe<V*Rdj5VcSmai2oZof3gOHlYV@t*WaZb2I2D_OfTO5Xy)SI7ug;2m(1I9k55(b
z(EON7ufOj4<B|4!>$+(xR^L$meCk1bRKdy0jZVL(-mz9JQMqC{^Kb0yJ!WEC%LAoX
zC|k)YnaD2MxNPDCLA5!&vs$d)^9S2_2SrT2)_tJtcbAh~+O^15E434X4@3&2d|Y>3
zsIIElQF_miwOGq5Ce*6=A%EY`vz>FlM84^tGp+0Dj^>BotNzUEjhnvx@E(`#KkBZp
z5zCLf@O1NgZL{80F8`8(){1=LpY!a@gUscBCl<7vd*HO_pvJ}!7S98Vt{pwIdY-$A
zw3<ccf=fI0xL31ozWl|xBG111yQB5*0-r`LhpH(-w%4AEoLKC&a(+xk>&^bkSMPM)
zE-i?A#o2l&W%D~b!MPu*_VPw|{^<ztsrY;0Jzv*qnYbebuQmF%ia77C|MY6pi>}w(
z4q7+A-E;J*$n5yNG4_u-9Mon%e6TUyMq`8e&gmWoUJjBh+>Byd^phU$(OaeBmtx|Q
zq32;BaAZQm&z3bZeVxINuC2~jF5Omq!*-EJ=Lv}q0$sZWx5m31(_7)mbYsh=@3|cD
z&VkmKCq1zL_Rl(fxmzK-oBW?k%iR2rCRU3x?r}7~?lUDWW6SBwJKY0wXW9JI6`v9?
zt+=o&C_Cidr*6URU!-ntzFWP{Wc|+8pJ(TqOf|n8X*mDYV$pzt-?t3|kG|FIFjx@q
zn{_99G4phFt=fbAGc|5B1+lyA*j8iaWgzYl&h?(h{`;?9>B)j`?Y_tDz5Hcn*8Z>8
zf^&qtzHb+=+#?saaZc4=J*^ir|1d{;RqjpwnQT)xDfd+99rmioX6JMc_CqF5r44Pe
zA3XXKdXG(1q{u12KJ-I_#?7q{W%><vKHy;9keT|vUEphJgZip@kN(a5Zh8I7%up%D
zJrg7EZpql`C3G%m#e-=J`5WfXn5X@7;sw*Wbta#RMR&*Pzt=SLJo@5A{_CBopWEe=
zCQ7U=T^n<`Quni(ROhoKk9+6d>jyt|IM!e%azAi`Z_CE#R?kZc{p`5xT~00+m?a*r
z_sp(zKJ)H(KIX=+CcHWKD(E!xt!LT2%V%7l-z&Y-P`W(9v_daaX>ZzzsnaKMtyH&P
zZpgVmTuj!oWa-D*_OS~~E#K_hn7T@%|8nH*lc#Qp>KKU$N(gP2i4FREcumkMf0u0x
z-x+q#JO7zM|61V9%oh2kU$1Wzv{dYwG;`)mr5$aLBH7;YlwCaUFA~f2`mWZ>=hxTo
zto)iX{XJiw_^rDK-L?Jo?`zMWo?JOyV9&&~r@<n3U0(lvG%?J$ah=qf$d5+5nD1^`
zRoRl}G;8{j?<@;uxbBeuu~EUgAz43V<L5;)R6w;`w!>cw`2gAeBilcIxIEidMexsN
zu|0En>Vy|9ZkxNO`O&@bDmU@@{za!hXf>`&(9_(S`bm3tbl=~-``0A>D_VE8Ja%K(
z8IDGW39CM3S*@~)xW8%M4;NOqdj{dh-cHkQRbUNx+%d;#<$s4K(-*Kg#9dkS!?mWW
z*@|J)&44|-)ncFK^y=GMJTISc*1mf0^*=4a=ga@G-`w-()Vj;rYG0mwZ|f3`nS88x
zf1lR7@AsZ^uaEKl`gzBiZL^=6YOk2Tu2pbz(9$XU*rp0k3_h^lQI5?l|3>k1*60;`
zGB}twtX%$G_rUe@E^JxvC3m%N{AlQ(UUB%<kGQ`p9=MCy7k=Hgc!$pWe-9s7ef_HW
zbhrQh{ZrOF*ShYVmb>U*PIh!vbnfJc=-}hG)@4Ubc(K6ks-VYAnWOvPEeYu7{v_}9
zaR*1c-Z8s}-G6IlR5$WpKQ5J*(`9aKX7}u&XxXPCLF=h%^N!AIw-(5gTQB*EZ_)LT
zoy~7*zfOBDTTuVy`otSM`#$fTZoYHQ$@8r-SB#%_xhyi7VqS3dPv{zsH7XU?4$OBs
zsdGs1jQpox^AxQ0zNxM0US%Nt%Pei*mCM!T7J_>=?h0s4ln~*v3feLER}TA4FU=YM
zUfp~CJ?_u4hj-X-?m4ON|M8#X@6GaiV?NcqYtGqaG;94XfkTtdE!EMEKQ`$_(xS<N
z#XrwK3}kwCt@U@Kd&61jUwU^Z+vxuiUcpjopJ};i%hKK1&tLdW(ku?{Fpv8AhW%zq
z%SY|b+WoKfUaMS<zP6KZ)6CS$v+c`SrGj2^Jyd_ZjVJAHS@fQov(@vne>EKx_?-1@
z<GxzkvnSO~ZBF%Ynxk}Nf($EL!+U0XW<Jdse~zf$yH@#ee&O;NA&1JNd#3rfaj;HS
zk(r@aruf$J^P;ZWSa;d-2VZ{Qxml(6FX`TM+Y@R08|I&Tx#!5V!_$8MluOZ`C-ZFi
ztW{ECS9Bh9T?^gfzg1!KG$&0*rhrKK#hHO~u01t9E*2O0{bbjz6VFb3x>~<sxkXIK
zrR?RtwtKTfI^O>?sXaewullzKldSXwx4JmV*OYJYl23X4=EZ`&Tj%b2C6)A$<7385
zcBM37&t+-pme#f>XFja^b^c5Cyo*aMPlRbr6JFo5x#l0&v=w@{nBKCa^FEg|Y+1I>
zf_vSX<x6+ZI(ClB=_11c3$MRy6ZPGvt=IeM^Qe2S-pOE-sX^7M+R<TW-oLz6yyyId
z+->(&Zd_P5TU2nNPMDjH)WW4JJ7-^u^*?_}Pt43bC_2*9L`YGDCrN^hQTf42>-qW<
zPCq~Sw0MbeCR@Au&C(Yp)qOGvpRcvg@K%}WduHPK=d!6+luvK#S!P*N$9^-%_0mLr
z0fUI$kEFs{!vyEAR++-PfXgCk#gwF*ylZ1htF1q_X}EdZ_EB9GrkF1nG5_B7zu8>-
zdV`WLie~H0jNGLH$xEV#Ll^)5+B-LX{nzsj<;!-faVdy(U%YwI@%$vcYx{Fdr^j!b
za{AV+!WggC&lUz3(sw@1`*kP0H;>7{%I^5(^D<A%qqlEJ{;$Y4-{w?I(mC~=;n#}u
zwZF29{av57YQ>5N%lc+VNX2<YDz#a(-!XZ~v+(mNE4}?|=WaW_%8)7OO7e`5ABtxd
zZ{v5Jwtk<A|I%G4T%VWDyZ6B-;n%+EVEg)?8-tJAY~+~Euq)=l)$R8Vt-ZeP;V0GZ
z$Q#$3Dphi(KG8d8z4Aubk9|dFeI|OZY4OoJzww`--2JW7=iB_S-e&t%LeFc(qE979
zK1@o{->+3F@1P-)R_Dxa>pOk3(hi>FI|YY+`rT%E#A`V1u1WvA@GXLC3wj&%{}pk(
z2<?)03tzME#q-VjGY>J;JbXI8{;=@MxAyn$d|x2;)708rgzNI9D<|G=-`8ZF7vo;;
zF1^uXMnhtRt!`iT%Uyeat+-*Qb(CS5aMJuD%Sh2DT&!u&gls<C(A!u2e(x9C&GTK1
z9!^ONe>zL4cJs9Bwbx$j{k3IjR+M`5bxri1dEaiDT{b?|`TU$iK*p<8&sJS8xv+0h
zTfmJA>zckA%+5^xSMwlU&rFf8=GW!<`(`|?z9jtr+l?b9-ds4l{F&eR)6d_!AL8~F
z*MGKl`~I%|e?PESyw)|p6cz4mA#&t`;NedhN4OfqSp#zJI`(JZ&{(Gb;bG#+MR)Th
zoOEQ8jxOTM+xg5YD{Gacgk*YF+N_#=4?Z5a@T#zL_jHr$i)Vb-&5lb@Gd#TSUv1Bn
zUM0hYo0R+vgjrIzg^G$8Cwuz6kx-rA-gQgkV%LIWGg$%z9j|FD&HAjI&c`Ml{g?f=
ze#EXNT$|s{-?r=$_vfpJgAeP^pE-NlrcFinN{+v+d8Yqw&h<M5vTMI?y`_+KLVeaG
zj&~g|8x3m(WL-9$VP0f^=CbFx3$GsMEd3NQLwlEavFrDuw4g{nS?gCRpO~iRHr;Xh
zlec5F&C!;dYCj%NPPeoxoiq96<SARH1dFe0os#hX^m8sA`I$*CK8P&L==k-m$UNo2
z7eVbQ7iP*^es<Zg@#`X+DK93?Qfb&<e|`D7zem4SzkfI9{+5)(^Y{0k-u+CNi_KK^
zVzO*pg_&>r*&NMl412!q&B#6WUA$Ug?xya03#KT|*Z;6p{?DxZe;@uE6_xpLADSBV
z{F30Z8P0RHU&fpeXkPX!ZQa{F(^xxyPDwpIVU6nY20;<A^|_C_>@%0w)mb(+{7wlB
z6cMNlIvBn9bohL$^j3X?*q|217kbk_ty6uw{@;b$_itRfdaFh8-d}~PPcsDfGga<U
zes6kPcvJek)oM~Jx2(I_6}3nG)ZK8Uwt~v<PS3WN7Nw>1G%j>Jes{ae=Toa#KS@c?
z>NvjILq+I^`to%Fznsz?HPeKR-`H>N@BHNX=_1qBk6BGC8%htzpPM)D=^5i-38gDr
zrU>(NT`R~Go-tqA_H)RFjirxn9((+AnRl1L%i7!0fi=7j%R~Y{7}i-^u&<jNaBJ0?
zcShE_3{%3ojxWA?;e_X`S1&xC_TRo)xz%Q7&b+_wzki;1zW>C*!|a+G#(x%8$69H!
zEnHn|Xl{PrC(X=vm)Yrz#GbwG<;F%<OiZk)MUn+Od+VJmb)=S>g`L*b&Rd$hZ0dnE
z4{aosV#Jm#Uf#F*{fi|FH_IIUYue89A^*UA*J<njJ-%^o!SXBn-s(2}3V#s#Y{3tY
z*5n@_Cvv}@<*eg<;<aN<_{BMl<u+V<V^XUn=2dW=T5fvI-TeK+%gr_KvhP1U=)Qfz
z*;GxlrT1p9kKfTJedsmkvgR~NwiQ;ctBekJu6!(GS32S5A(>3&!zD#sFC{+<Ze8jp
zv}JqQhGmte-J7^OmoA=Q{4>@<EamHK@l6%E%u~M#uAa&CVgJ;idhyte&zfwWf1fmC
z$(MWT*@8cpXjB?IF>Lf$5oEXCEhhN!%aZxulckG)hn|mKQs8y^`C}Kc>e7p+)lP~$
zXBG&SeD!#0%*HoHeDmcV-8ebfFD^Fl%hRULJ0fe>t_@LL<rBQjLC7hai)TM<EkK5n
zhx4X+?>6OynXF0hd>eG@Q0|%4Gu*3h*JMe*@<<b25~R8O&&!#bd_1xVHdc;mvz9Jf
z))t`TVYl4k^BI=p<<B{eAG)&T$eMQ(<OKUzq@%y@TX696((XP`+#lBXC-kuR2ET03
ztux!@&Zl%Po+-Gr(kyQFLV?c>)7Bbqb9(UDcweg=FZ-I;vo=-wOiC4h`}(N&jfSNE
zAM5Ns-HiJtcf)_-gzsxhE5)5>XU(cSf2mwp*05eoQ-oKbi{(Tr_mj=6pLRBBhdC^C
znh+ZK%xLqH)ti=R8OzMJI<+vFeTMJZAOTl}1cCk|k-J|=iKU7Odb=5Za@t~a<kR%+
z7mBl`pI%MmnP}I-AJ_49d3T?|&x?)GB7eF$o|dUMdE4CGD0WxA^i22Z@I5ac9Z@`B
zJmaWfgm`30)Em`RUXu^2UD?KSN_%lwMQrFCQSV(hi=RjwUcC64YHjhf=sKgxDx#hj
z1Mm462rC4MCEeXUt>EZt>lNAh>T&XlBHV%;k|IW|A*&n=<W<~yPKB_VUJljqDc`i~
zSJpMXU2RY2YOmnDKEeB$gkP^gh+)sFrUhIA9;}i!21j4+o!pYl_~`4!WeGPj&h+x-
z@R@D<b=_`W_^uUPlkaV><?O0=i^%wDyC7PiIw2=jFve-s!tQqmJEoYV`h_jMySh>?
z?tJ)dht%U?YyP}wcz&XzyK0+~MyrIAbFOHqDX-0r($%FZH}>y)vg?8HNzGNyLNCwA
zRGF`3U^?pwSN7f&pS!HA!meH1wy14es_B*TW1V5HCzpO+^88M!(p2V|&6`$goV}^G
z>#_ICbuX9AOuHnkspK1Y=p%;_=gE~k>EHYftY<3T6NnaA%`un9bgSLhCiW@a8Iyv3
zZ#(W->o~!lU9_&Of?Y%<eRIp{CKjfsDOVn9&#FB5XjxyTQ19|-8u9sy<w`f(i=Rx&
z44){v>E!n79%-Lh_x;)%zv<=e_|0`IUDjXQz0pRh^V7W5|LkYE&z``fvwvsn*Y{CA
z200Oiij#{)KTS9<c4AranZ9%hJ2UV9`!@UVoS8W1+$7(pCztvfzv#4Oo$~YZ!pPN?
z97!Bgc?GB4zf-qpjnao%q4hs+iJwW=n{{Z(_uT!l2k$!UwOvsaB6Q(LlO@;p`nQtL
z;sf2Uzp5%eyX43NvFQtE8a}n_J!YtBcJg9Z;fij*K3SGe4iokJ*Luip=LzufIlu9v
z{Qh%$_wST1zIpg*$gZkRjc4ZNpW3FG3(Q}m5+wL&SGi8w&0lIg4xCS~9`5y;cvj;W
zyHL-(If;+X$V_hbT-G-E%sk&op3iK*|A<y@6FIf&aI}!{OMQ)_&iYTvr|WfjdcD7$
zr?GUOuE+Ll(<2Y%8m^0O3wUyJzRdF*!HXphD)e$|2_8NknDcHC>)SW)bA?sQY|B({
z?e&xFds&>i;r;i5*+TcG%5r@9AgLh5c{%3(k!`WHK0dw{)9>6q+tzg;r>M^%v}0R=
zv=-xKWzH!5)eG00`kSa5Yf)=?kb^_iG*QY*d*=OM@84Zfx5BSos&thteOstBHIa+e
zHB0Sv$@<H8xlXEmmOa3$k@DJH?r!nj_Vx8~@4mS@&bV^#ZNBr5c?)>_AIs`|_btp$
z*th?q=P|#tNh~c#ubUSCy)7O!_l5E?JL5+m=daoH<?Z}m5<fmLA1}WYaG`pBoviJd
z7cNb29YeY5zT9^IIa|MGUWwJ(sjP9T42KPVOrE;_*{UO=9&r&Hb~T3oJ8I+<$b4}B
zx0cWMV(m9E&8lj#Sg#=>(z-{<aAxX{A3EvtEKh%UsClW==A}!YkCM0IdV$Y@8>}17
zGd%zM;urTiP$?(fD8Ha$r>~Q3b>cx+4)3>9T~qegKQD9hKWAaQvN+T>``(6zwx9o6
z&E|_QS-MCxse6T$nAhhQZ}sQQ-~DlhpY%kXtwFPj7R+=_{T-Ml`7&o-`MsZ!X8E-e
z=}tGk-&DKtD<&}T-0ofXT`#*R3kj^Ne=elAe=Dou5yfX={0|R@Y|k}g6puEGiA!G^
zv+Tf;fJq;Xi+$$IOwF=5+c|gf@k_-!qZTwglIAFHw%WGv{kinJd&6sPJUyzmG;U$S
z)U(oGBAI5W9dr(0T<Wo$YuU5tw1pGG=iD$n)_niY`J4Zi7|)gwzo|B<?4}(5nP<|c
zE^-&91l+3sEjNFYh1Ap2TJP3e)3;*Q7T}bu`H{PR`M!1cCLRkFxxHn^*%@=^K3zDm
z-SgVAz{;cd?$1m6abk<+db5)<fnVxE^a85=w0F#XP_QfE#)5^5=cr~&SKO2qD>z&&
z{`uAZ$e#iqvI6Q?pOKILAN}B3ao_5@tl~n6mws>Cu5tA4g1pj|ofXl~l~;a?@a0{;
z^Lw}TOgYag1@XpDuQaajUEICSR84Z5;HjI-R+@X1*PFIpEP9}^$~Ueg_p?~qzN$M)
zAGa*z_}Z{DWtx87Yx|$q<?H9?m^~MHYQHv<`QR$n@WSjjVoE0sbWdkhJawNI7%5(P
z?%y|k*^KZD{x(yrB)N(>cBn2|n^C`Vx%sco=M{I3v${&OMsZ~I%0_>D=X){rYQXX%
z!lEwoPjU%O&XoK4PI2D9qne*8r7Lt(1geuo<K(iVMSia@_D#Oc$JLn}XQOh{%|QCB
z%NED$U)awuZt~L8=Po>c*4$wI!cHZV%YAchgua!&ar)s0L4l(W4sw3WE2}s2bPqgl
zS<p4r^<~^5Tm3B&Q}1S9`<?dS>94=%m+BNWin>j>&Jm)WZkE|1cp-g7hVrXYr;^kn
zYc0#UiO2Q*Ki%l>H#DDlG;U6@LbQ3QRMpH|OG>xgkWJTQ3j3~E{b1_nR~v+-T}|>5
z>ffKrjor-l>eJHCmA|v&+_Q_hA5Q2N`?iw#wvXmgkLAIC-raaVW1hMD!UZ>e?>3%u
z$N1p~!|joI?o*$boZC~dUNbgvs`hpbt%lc^es2pG5ifaHa`4WpEBoH2YJAmI(7W*>
ziFcaqU)^Qdb!)RZRnk7m)Rdg)$?D3UK6jHqNSt9wM%PDU&R14in(O&?KM}sm64e@2
z`fA-Kvt`%P*FUndTE^Hrw<z-Hn~GUJTK*<t1+!GDWUnn?X=YrvH%Zbwe&amXx85`5
z<~l1eUb;DD>)p$_dpJ~rHP4;-dO37|#{r*)l?zpLy;paJvDp@B`DV&$znr$jb=%#H
z9lEn`oNK!o5ZJ{fD92;Ajc@*Yi+F?9ll^>a#3u5032cf{oD=Tt@qErizQ18s))St5
z*p_H?a?WwlZSu(rXFoi-kR|=MaER&Aj_dBWvM(IPUvGYAdUIjz=Fc*B+`<i>+d3^w
zI8~PNTjG3<<dd20?JIIL7H?a6=34#sx_+5w&wu?Y+Vy<<re&|WUU9EI(ks;zs_1sC
z{o>Ca4wX%uO`(dnmh^sc;Zt?`y-BKPL9Ll*q|&Xpw2hHPKe{ffb$!ZsvRmki^1)-*
zYM)!4IsabacJJ%;{7lE3qvdo(-&D2+X}u|%cb92>=?DI0Yh8AR+_PHIzgovtZ)f&8
zHh!NCKjSa&d2^OKvLw`&QG3g~&gnPoD;m?Lt=VP!QS3AK6r<P+IacS-+~jdD?<uVM
zF0ncN@)BXoqM0_SR}-zKg-0euG3V_s_UXu&-}-5l!09ma%llSL%Pued{G+yAa?QSZ
zkBhq2*7i@(TH=v@=}A$foc%Y8wc*<~{&=JGE#J=ByPUWC`W4Gf;`#PpRr|lE%u<>A
z<JRn}zFNx;Y3$_uaq(v+!};^xy9)pAl6zprYF|@vTA6RR-}~Ef%N`t0%Iz!ST<u%Y
zT`Rh`kz>vc+k^T0_w_#sS@xo8qxS1h6EZ40R>$pbm}<UVppR81-(^eH`O*nzpQ)Uj
zsgv%1-q3JH!jBg`%<Sqjq`Ve*xu~qG%2mI<H&-!&d0}MK^h~YV%RBFtU5@kZU3T;H
z1IfNT`BWYAvlqV@^7+aoCFC_c+^Bf!@Y6l{Pk*nNyJp$0ojvwHUr)VK9x~;f<I_bO
z{<iM@>zv7zW){BFXxEQh`dvRKimpEY`pc8gwp!KFEBqJjc-Hpydi{fky8V5TM*1Ql
z-N$yByg#%({#seG?Ph1?rT5H4E1A>MZ*1p&xl_jfZgJ0-oN1xkw+pZ4$uyKQf5y10
zH++dOtKa*%2|r$lBri{sv^PF}$7Pn&x#yi3##Undn-fCkDlh4tVVBe*&ihuF|J$84
zSv{XNnU`(K@MYdDZ{hsrq(S%UT@q_$mhMk&P%du2X|}a@_USygHr}#-pG>ar-`u^a
zVnu}B#pR32{>2=b8RjRnWoq5?X=W{aXXH0moGZD<Rs8r@X)2eUmPac`xyFk9g@1SL
zXWeG|;cNXHhRkhM*OoFYQ0&#-@~-KYvC-sHk&V{o^Q-rNyD5CvWWSGk(VIV4J=^+x
zKX>u#sNNI!su8KT*yDVvr+U$xTlPm+-c9b2o2@wa#KiMr0kbr(h+cWZYf-bLG*b8K
z*>{Qc`5AKj`2{gicOMFGzkAT5p)$7c)$P-fb(d}C{rl;e)PC4RRXS2K;@F)%DnA88
z{6s81Ju%q&Ry3xxdiM0{n?|p;gwNiv%qVk5R_63Py|sU`D-<Dq;m@sH@?}=jqp-sh
zre&CTX^0q2I{D=5&75zu4@5V*Ex0Clw(eS&`|r1Azm!%^J92WR$<Lg7Z)5w{ubuj^
z{Pfz86WYJN&v|P8f7ATzd$(L4H+d~{n*^$ppB#~KZeK28Yxj0iR;*gA=hWOwA5I8#
zvCXKj<lT5`f!cgGE!(hg=kSe{ediZMq_!MldwY6SW}L|L2ipYs?5s{aSm=3Z`Qg5#
zl*^U#{{1X`79Z#B?7mZcZ*298jt2`_<VwmWo-c2C?sabRaSN{E!@FKLE4<%Pcz4%R
zj{Qy>pDuKlJIQcoLtSh{i+!()l8K3l00+yA*|Q(Nxw-kY-S3Cr@An3=DJ2GO3tsZ}
z-}jO|_eCP_|ID27&MAs{QGUy(+o^j$I=3(X@wc2WAW}TBOzH5Qimno+<yRN#hekB7
zd^2OiH1{p%!kto`d%iv0x=tzc(+#sra}A!!pI`8D{jQhW?zJefozBZxRO@QmzODDd
z_XC<~>PCI;Q)Zq0^rOGO`15>SRWbgkCD)`gzcp>vdX@FRttdTRVa)@Z$-+A}$6POK
z`M)sWyXM0Wy|35(|J8o)^EvB%pZTTVzj^m2LY}LYgN3PsV_`tYyPvWpTervcp3s`3
z_x-#|w8Q>wyUzxz-q^=I^OnxFF8xnMYreNK`OKO5IOM)Xy8qc3g|c^*qMjX{`7`Qg
z)f%TQMuHI=R`pdl9|`2CZd;vn(e%s3TROK)FHXI;>^;|EfmKqAV*bu5yZ2}3)tJ)b
zHII6)rRAy4xn+9lT>N~c>6#g#J5|ogF+M%xxW3>VhvjyQ?^l<9&t0#3anhnEa$V*B
zw3J17ShY``vT}O(p}lD5pYzX5uhc&~f4{&z*+xutrq6_vDJPa)j@etI`E=uq(1yLT
z8;|T%ynaz<-bt^Yp+39U@7TC3_uKu&Hu<uDG@h1aRm%29{a-G!jXTe+R@BWQqAGUt
z`QXD(nddFrb$!ab?GZuqPhL1{a^&@)nE%^a?|c$Jz2i-rSkl$RPnJjjwX<99t@qOQ
z5!IKEusOc&be{AnSBu)f;0au3mNq^2(K{3&C2qiEVqy|-KfpgZS@~v6-^NbQX{EXk
z^zVJDdUg8rj9D`lY+gA}dfl!`0R}J1CJFs{cIXL9+3hzBQ%u$Jx@XMxn0!6G&sihK
zPqEMF$It!GzfUVDJv+Cssv#z(GB&OEv;XYMBt^&1ld`g&9i8)A=H}Y}i;m=WyH#zp
zF<tv<(ceRUGq1(JmrGfg>N%(M{hLQq>vuLiTY7a#+9sQij~Ax|Rl0M=toP`Cmi1TR
z)JBD8mpWqGtqo5#WSvv4^jOby=%K;G4L@h}I#_f}Ja3iq^3_xComG|Fy+3^Us&xLb
zdC7^(ceC_&y|^&vyqL|oDYrGu`;RvZuAd}Q8xSS;QHr5fc#`o(Q@@4Bmo+6e&x?*a
z`*w0vWr8M`S>)xcf{d<Xkze{YPCTe6r>AB8sN?kNMNb{A!a^=@dcxIbXM615ef|w!
z+1+=1Tibo+#^mL%?{=2ywS3i+ZJ4pY=yrrsao{BpH$g6zWkow<6zBR$r*4#Z=`(BB
zCXKD3g~si!Q*!2o?^)<+@0PSRradY>_vGCd$>n{^JzaI;UNbxmmD#;%(TWZ4e%<<Z
z@EU)tNA%9MufI*>+P&}AwxU<JPRAZOd^Y=d*d15@_hnrF&spT3a10k*zS(Bp(%p`S
zrPgdXcqv;d^X<B4Pu^`l<D1qwC6iyOXph>)l#S}G(d~D&t#&C2v4tM1R9U`l{=diK
zy*FJJ)xLkY_}F^++BpY5a&omY<;QHF=AqG&8y%v@e{;>xtm7`HPETxzP&+P{@I8}x
zT})VV$(IkZzF*~B4$ocLS68uJ_14MtI?q(Tt?Lqh>iXJSefI2lo{Z=)-_qhU-Ad<j
zE?9KfD?AH%X5zEkfA#&!uTnwM2fVkgUZm#peOKD`Yt{#z9}L`{6EAV#ExYaRIoHpz
zx+k7mbn*4+<cs?=R;_-z%rxBC&ayR8;z~&9thp1<I%={0Y%*TVc*G#*a5M9HJCOqG
zKxc*YO<G)$u4b_xW-u8Cb9Qb$S9ne#^YW$53=x|cc3V$<zE8=7A?c$5cer`f?w_T1
z%F{CfcbqtxX3Z!T)Uo^K>ApX|O0F)qh<o~Z+i8_Y|8DeIcW!Bo^Ea=^S$}Qj5ljC|
z(kveDt2YHED0@U`wkkT+`fgn*@zX|YYLm~k{8xK>Kl5yBHTFB>c<0;|sooih|9q_c
zv&^0=bY5a#r19%{RoJdeJDd||E1do^mE)78ps?@9uVy#X7OdMlXIbmib)PifJDRok
zXQUl_#((PGqE+UOOEUJa-6wmHH)Gng+h_7SSB1XS34M|K<xaM8-p40fKS?%OtzS`Z
zus47A!Uv^Fo33r1ADY;9=DE;>>&hFJF}Mmk3)U7{R=mGa{(G~3Ly6JxkIRosSQ$Na
z<=?BLb7YhAZB?I%-I}{>p5HnY@v829DdV)b`%VTa8H<<rOVt0|SM~Oc+0Jh>jMu8I
z-hcPxi{oxjGv*v`F8a}-7IJc1#`l*Vi)~|~mb09n+O!~xwNh2!yUD%@?J1W6#iGOC
zObyt+@tW(D#Ue)wGVbL}PCa5HWLQ-+?e2cd!wc6oixizY9>2%<VoPa#eRX<r;EUV+
z2dbV&mfmnX{KT!yH{hm3>OoP{c^~%GKdas@Wznk}HRt+tsXcR?vgaBbZh0-``7Qr_
zfvrLOJ)yMAVKK{B_OS{ax0#pE)l{Mtv06V!bE(4Q)|_)MHTD|Uwh1of;$X~CdJ%g(
zpsf3>qo}Lh>KDIr?SGr`8(3OA&r$wRW%o-a_=oPceMzhN7o<DP_l;b`v(4`I#kAdb
z)=f7R>|(Wjw$8(CxkRu3OVR9QhjgyHc0XDo9J;<UXrEctFOTQlUbAOxD-!!CQU8D5
z?LSk!93MnAihXuF^D<Dw!76v_;U?$Y1}~qOSfQNjSD4o+rChFL<MZA8c)Ggf=K4c7
zy#hAvnWVSftl+u8q5Yyv{Y*bUp3Js7b5QhDwsOh0D?%J%yZ8N@tNtw1eEMpON713*
zwKlS+Oes&jS-E7*`5x<*o1ZtR$mVYORdZs+_tk4Nl*;sXM(fYhW^I(dbIxpa_)MKu
z590THn$;e(GD9pwI4eu#=)JSdZ|XA^WK0e@dC4Zuh12zFrC(==OtVI0r+ZoTGE==3
zOX})c+r6hcS^igFF5_>!N9+07cYa*U)vQATv#v#ZEzIw^#JM$igY8Y5BX>$2VvN(C
ziWfCmtykXcm@rd(l1R$tj(o1)6MovToz7{|((rpXGvT<tpHW4@q#8d%+1aTUR$j>q
zCjKa~oOJQM_4PS=&(s$w&hHKF%YLIV^Y>itpL#|W>$q8**xqVqpUvgDVJvk%r}WnH
zug&Kcx=cT+TF>|C#pRptPu*VbAbaJqz=g#%-&Fa-3*%!yd{Vj-qjh+n@^K4Oi!*2S
zqg{PdSrs_X%vY&9ClcaSYF+HX8Kf~o%~ReWwR~>Ty!Y?R#PirQq~@MK{9~qN+5c}m
zzw67TZig`)*%atEZLWg3{o(n458E4Dvp@IYUgENHUjs`M&rdm%{*;`1Z1j7tT5#MN
z&ZTEF3)v6K3CwZSH&ZTKe(P~iob<y@rJubNcFJa6dVPuQKIf*4XzL^0G2b37oBsHr
zEoW3#&@GPz-*+a=RJ+)AFmzQ@(2`<Sjy8_trzFomQH*lD-&y<TbNRo?>$Zu#+wsv#
zdIDF6)p~VHme|g<M>V4(OT@$G%T7Df7rww?>X}y#tWS!&_T8WJ@PM-O99z@iD>DN0
zJeGzS8W<e-@xvl~eKhN9g{fY~6-g6LJ{InIBfsqb2ZqhZm!0HU>OEWi_)`76h>0I3
zT)O_}UU+G6kH<{!2eQ7G1Wx&h9X&9IXI<!pot#Q>!Ec3czHhC3dL-24c*aka4?DkZ
z-pQ1i8gTW3OB|<AXW+F94w4hRmRfw;Jb&Wprx6<q>>e%<t*YE+dwrkCmBe6oe|Fys
zX`Q+=7CYbT;;K9v@n6RO{~ML#<vkO<Z=cr|oc}Z6%JWwe={?KmS9OJkuXWONRS`;a
zELYEZS!1Mse!>jD33E?=I^yhK@ZXj{z&OtLX3mrbmI+P0U2(+^%9g6-dj>x;4c(S)
zQ<gRDU;46)w|%?s@!#5EQF@Dc9q*cJ)87S3Ef?O~B60c4j&(b=7j}eg_<JMr>>rJ#
z8XB%<)0HQmEm~1O!BRBg>gjcgaly`#PAX!H?-<DZoEoGe#QE*ZSH%OSwx{p@3kVW;
zXk*@Z`|rz_A|Gyh&wc#D=Rn@=H#ber=SU`f|GV77Cw-4>qIP$06qi)`Yl}eH#M9Gs
z_k92RURi>t>Q$eMQp@YZ9?ctmuHOIHA<3TiZSRpohHAgnSIYHV4!G&zx?$3bm>ZRO
zxt`yHo!zQsZ2!3K);FA)_}lh)XZ?cN70yQ%n}i9*?R&0hY$d)iG}PqDMZu`x5EGG2
z4QFfF`l8E~CO<v%LSk|H@tf68B#yfupE+ml;|mK9A31gE$4TAof_mlrMpnx%RN2<O
zv2gE~Pp>Oho~!%KtD(Vw_e-&y=8H@YE}rj(PxzQGoSbTw%&H+GlK!oCbMa@1<z>B=
z8&%k=Tu<j}_i+S@F0~6k{@{Yb`8W5^pPDC^Yu5ez>yb|3n$NTEFWS3zuB>(02mAle
zk5_K^@A%C0>|(1B-%zb{m(DG{BKdVn|FM{zTP1U+KYyseW!$p9zR{qdVA9{{wuoAH
zb~g|Cj9&X60%!LnoR6Bmr&{oswB$A4uGoEx(-@W%Tb9XM9&B8EyrSl~U*9~*CubfA
zbbR2S|A#%V?x?ney!`Xx`M-4@KYkn%7FPAkfBol$_y5Z+70I4fF3i_z^88`t43(u<
zI0avpY`JKlAkZ*JG~<)`!A{8;Z-ZGSEDX+`oU3=zF8t~)ci}VaE6!gtl#+USegD4x
z)6;Z|x7F|ZyIev-LSd%QrCYbU5+!tEc1$>T&adq4t)mA5?3w2{y4<k6?e5`Z5@NC;
z=b+K7;<HE8wK&<GS-2cex4e|`$n?^cyZLD*Q!W3Tv^sy?&tk{7Uf7knJ@)dlnd--%
z?6Q6EW#wMsz{{exQhE9JJ<^L+f;H2GJ-5l*oLcPvKH;{ozk#K(yVA@Qy@&74?|(Kc
zd&kFRvomsXmMmP@n0+no@QW83bLY<8_h9KyD=VW@=VEuSSideQ^t%uf<KdZmxMqqj
zJ$K$)C{h2y%H8FwblPs5W@25tF>E<!L!#A$#s!OX<h~R#EkC_Q@z9pz=N4)&Gz<2w
zTry{G_4lF=4;-iI$H!fX5KK%-X<?V!G5=`y^bN(w`R3LAdZ~2OOXckHPCr#OOQRx*
zhRU;_GuGxWH@xfMy<}#^maa`Ml8tKuo8G^0=3O~cC%V3%#r~(fw#Irs>&m}h#g0c#
zam!g#?d79*J9w6liltq`qGQ6<{2N{$Q2h3;zU}4A%<VS4$v0W~`S><fU)Ou}`n9C2
z?9-EP{V&<%%dHMy|E((R)R!}6|KF9*k(GabOZ09@=@zR=kt?PJ8APk3bc%$W2y47u
z$QGp7#+aHqL4U!N^1~aMXPNyD?@Dl;;&5TXgv(0H8|-=3nM){4>%A~3|KWoVj&irR
z^{!i|rzH5-lfCQLuPQZl^_`#3S!d?tq-11t7^k1x@hPMEnSH8(fyIFZU!8?YO-n=E
z9v>;5s*@LaX3r+EthQA?{|fkgWGt=D{%dcK_`1rBX`zt4NuIEcef*}0-sbgD=T^E*
z%B}r<b7#4HEjwRPR>6#e69tzoU#>YdCu#li%gg;gzdT<vOa9;WdPBRqX>+a1KV9sv
z+tSi==)wg7f195wj0s;q<()d6wC+gSo#%fZ8!V~_;Y@D2@_JzrYYG=@nY_)M-`Dux
zd*<HXecof)q*R8lrdu!P?|eJ$!|S}Aig)f^$_X)<5_mV}*pq}Nr?_s@iZh$1``=iZ
zTP3INr2g}5zWkGAv-6Sy!>2Fb_^@C`bl%RX?`z-NzkL5*|J9!2z1wY#cfZ^C(eRkT
z@09;P>JA+=xc}pn`O5VfDNFKaTs+=3Q+B57(z~3KPK(_5eEYIVS=fb(!NE^@EjP_+
zX3|iYuD^h%Il<!4#f_f(zTSQR@pSzC<2go-YLiu`pBAl-U9{ip<onM*ZP@u_o;*0%
z+^}fhzKQGB9bLEb@`cpj-`>8ty?=h{T-liVr(W3~Z#-Mna3Uh*=d0&6W;_lL-rIj_
zoO2-bKvJ!N@JW&T|BwD{?XOv8zWeh5<J8N>n-{tm9gQ(MdE<!7lZS8pCH>#rn*BO%
zgF~tQdxKfKR-JvZLLx;d@>67ZVNUS#-ZhUV99|&!DCC*Rf{5y~x0Do5pFX|w|G(d!
zk@l0`mCf-!V4H1hBRw%#go}0B`iO(e?Y?V@t$*`qQ|VonsHQph3TGYii95}CGiBb(
ziz40EOoVu(cPv*fI9nWOy3S|$vrR0sZ?DXVcZl_t=FhEcao?V+I@vRtUp~NY>Gh8F
z9Y>i;jNi5ieKGs@a{j)_;roAGm6Ov@^6~NcaCLpn)FXFf>c3vQe(_R3{_ak`qYQO|
zIXSf(mbCqt#K@!h!*<1#<^^6GOOL<16Z`+y`_`E|Z>~_7%=I<*LGJ<fhO=C$Z>$Oo
z{@h$&dwIsp*+T2YxfvM58$ss+q{fA-X5Zg3A=<7)a{a&Aa?{r3FWhtNS1516mb*{N
z@2$vm-qg1%MwZ|9kAd~Px?69{Ue8;-Zdcd!{r`Abm>l02Z12czT9VQBYQ37_Ro~`-
z@aW^m?Y>=~GIi?AKj~&CAK$N>^Cm#*Zm;Qmtu{XYP45>n9#`ESIqUwD8&hxH?{bLL
zaIlb4mf#WMYOT2c`<{DpvhuI<lGWN*Y-PgJW+zn7+m~?n^39zM=KDVOwj6$_bh-5Z
z`uC5IoSeL7f01gp^{p=J6E(IcE0-O3zVDmvRB6j%u8CijwlMnmoEQ1`Z~i~k-)Al+
zC$_#4e`4EIV>;32&F}d5AMv{z<hg~I*GWmvH&~_h_~i81jW#WcE~lE0NH5Zf2|d3_
zIyxgJz*Q~N?!}FoqOI3uMOzw-Iy^0%vpR&C)pzbmSN&LVr}3JH%Au{-<4zwr!ctpX
zE5gP4e3q@jwo4Ybm0Y*Xd{H#_*RQI7zt-CyoB!{nH78qh4{zVcZv8)#J|1`9*niOC
zh5EAcj;79kmRV8SEAo1*PCN>gDV*lRayz#5(}IH^4lw)-nDVKM>(%SmnYo#%ueYsL
z5&9Q=^4>wcsPn?*i)Q2s&6+*y=kNXhRkq(PlWuJIJ^QYgW|_@blmBJk?{2wr^~1dD
zdnUEb$`YUY)z7)s?#7L(xIzhLg<VO$`wyrouut$=&RxsiucGsLBXfnpM4u-NLML4m
zC;F%~{Acn@-4yxw$^!?HYU4iMrEEvEoOO0CYrJiL@38j&ELQ#M%S^YzuLyR{SXf>g
zxKT|qJu!>1onP+Ry!rPY|9R4VH!w6bwC3C9`A=itSDA0!y7gYdtjCT&tm7(AWn^bR
zHlF{FNB++P_D&b29^Ssf`{D1>3%vJFz8{idZk6?DK~kBL@BMr~WAmvWr>(9PD%ig2
z))lvexXPA~i`gY5rQBS0{54(waP$11I<m5|a+Y^j=*$cMU;b@@xvA-<kLP;#{C%6R
zF2S=)gKv(k^yB}3pQxYl@&9~FdR?;PZ5xyICz|t4)i^w=RPFt>`nO}PeDU3`n0t}k
zUN=uY@|IL+t!#d1^E<vd#G3Um+u3fd9k2R+-ublf^p51mqB^@*_HKH$;pN20m6jJ>
ziZ{*t{cit!U4C1ig%7@7ShZ@^k3Y}t&xh~(BYJI3q_cs<l?liCByP!OYpqL^m@<9p
z=Xd4%+jqbJSAOqbU%5c{(HXOSKOFe~kJov>tiz^l>r<vLE#%nk%k}Gf&*uLR6Z@|+
z?MdH!R5~hv<6uI=wJrnU<9tSDMotzo&wTUijPL(>wmqWssTLFC`{a{*G#2UBM+hqm
za1=eAy86fS`hV&7{=WMz@^PBe!UOzuADGMD-8tF2TF<;wPwcti_S|a$vW|uK>@{9h
zE(oZ)|Ba9Je@R)=r*GTqzT_KQe|x`vgU_Yv#`c_}n%z@FHLkchzT;tII`+Tjf3=bH
z|37yF=j1W9|G23V{+eNT;>?hF!n==K?#b=gc)9pYkBX<)Ea$22GrRmhq}P9|%d334
z)<tQe((O5?pWgWOBCPJ~>iEJ34~%_$d<=|@UzfO*mYVwZ`mTxHJ?;9x|4-*u7sOnx
zJ#N3h_VwOrDJM7OL{6Ki8-2(yZ;9fO1RmMAg-1MjWpAl0U9$eme3kmNAIip_#=*-{
z)r>RSmrcGj>w*v0l!GirjZ0WGN*xY4Y-H`4@3bw&d)n8Cy=CFMf4`RhUi$9tRDnKU
zjz4KB_xFCEQyq8zbM@T&mgVo`%<}HMcxL_Y8t1(K?>?W|XPNstob3Q_t4796&1=)o
zf2(_}HS5;u+RWx<lO%iI*_;&R;_*EjxPRy5tJ&8UtU7b%Ou>Vb>Xsj_FtV|+S(Lw%
z;pWbq!@u8p(&9a9dQ5$Nw`|+CDgVCRyM4d&k~T&hsLq-D_xF{_>^J^@s9X2$*0Jz+
zdzw>1m+t?cbN9@(8}%aZ-~5~0&BWvI%;WyHGmjoM|NnR7^7We6^83%%R4KB^FxF-K
zkM9#LDdi8id+W}ef9K!-i%t1_Y+A?Vz#XyaGv>Vdt8(GQQJ;Aq7h1ZpEwlKw+R$&l
zWcq?v8aJ;>?)%cJUvT^Fe8rUFMG7w%o;`aeAuIdzP%HO}sM)u!ugOgM`s%9Pem;ly
z`c*G~Pq%y4cUIx&rGMhf{ihpki7LNVe0ciyfXM8<))@<T&h&0cepXa@?reJJ`bhs^
z@9x#*OM*1{<n7LUe0<!px~wH6>)6@g$VkWH&sJvJ^Ow~YTW{UEHLpJ6Y4qQn2Kx^P
z`~MN|xBDeAckSz+pU>B}J!`9KN-$%0e)zg`-MjaCHw78BDpMkt?a%-GVdv-jl@AuW
z=l%HTUq3CzW4ZGI8-vvu9uu+zJ58@#Te|=M+uusNtIOPaLfx*<jt)8NaGZ^KJ6EMd
z#ZQ^@{}UQ4FUhR8I+=5pXa3(mvUe)4&z&-L>d%I4U&46o7lce*$sH_H^Gvkw-v?Q-
z<9m)?{9YBl^7+Jyj(PSuk5@(8w8t6vEDWiZJtfZ7<8yXXMCj>dYj1ZPef-Y)z^9E7
z_v1F5*tlWZVjru+kNfS9E$+8F*49?FukgKmaCB^{y{LUdF5lt_LKDv)v)&ya@$D(w
zR2x_0OBZSu*3`XvZXW-A<;@I>ZF*9i>fEfUhSU4Q!a`hbUo&;jyIq_6Fn|9y^DjB~
z#Y7K&U+cEKzo}X1jm_%%x5pS-7EA~}_r-srzh-Io))Pq`;q1REen;4!OqtYnjLqrW
zroTZ6hPo?m-i&19`#Wp-`~RGW{pY%+bJ^8TxLx|_FV`kk@5-<5L_eMSae=4zt!Gx)
z@sD9kj!wVcbHe<uzoKB)sYfqjx*jiQ>zp!mvW9l?PB#k~HL2cR^~=5rFL7FUV0ZKT
zP4)ll>VBOuuK9H;_s`e4<pJ~8e7t_UV9BZ-*B(nB_~+sLxof}G?l%iNUjDn+p<vsb
zey*;pqU6oDD{o@5ZNwIDTxWJ|Utz6^SgDiHw0Se{B`r-pHq&^0#J}@?X+M89zc2Xp
zVaIME(}^>ZR=hD;n3j0GboY(D)#l+_;vaH%Zs_{7e*T_stFK#pJDtq)|GYs_Sg*-Z
zwZadwu4fH$6rX3F{$`c;J4$?`k@bU9rB_&P$L#TX_rh)SXYQUQ&pg#v{ctHa-x#qb
z#n$Up!%dy@{~ztI{B(d(ucxo*`TO^2{@?jlX=~T~?YA_H36&A3<oL4s<GFdFYn2aH
zGaOr3QXlU$Ma7A~Kz9T0jzjDG{aPj;2y9Jk{N31bHM8mA4xP@`N*hB1;%a_Kw9mJG
zJadvp<w@hoGama~<>(fbG%L+{6ujHc_4qYDEp2UG1+giuGg<j$ZH|1r?x)b+I7KK-
zQDkG<`pP9If}UK{4A_}4A<RN*(eux1-|X4jTA&hQ6`RR=JUmWszWUx7kN>l|dzfwC
zuy1W|*C{Wd&KCc0O%bjXBgwS%^vb^%UfX<sv$<!U?dfa0XW#6t6JMKsU7%B>cyUtU
z$`wYepRT%ue?R>GrXpMHrT*Y0zklBfkYm29={h$>Ytqv1hb+F|tIM1sE-#f}IQhH%
z_WyJH(`WSf8m!g)^wH+zEvckdjaF9IG^Z;mt2Iv_aootqd~0jlFEQ;68l`r<&)(*9
zE!DA2G)%7b=1?%+?V*=Fb+^IXuYW`j9+jEBDt!9J=lWI|FTH|JT{2p$(tdf0)s0&V
zA71>-!_zOgdX-{KoTG+Vagnj5>B$Ex9sT62y%Z;>y*?(kYkTR3PTkot?|cPT@NF-a
zTypwqfAbxg_iyYXHz|2v_-$KO8Yv_Z{?OO4Oe)T04qthaGfUUOq&wLetJQ?~cQ$-<
zf6Og9ljZ45wON@;+b6g$pIV^kvP0k-bKsO`=d9N4D;B=`)$qCxt2e*rZTb6Wbj2dJ
z*w;^wJu&fo<n@_1WugK;S*B)P`IQh>l{ayxXZGyFZ+<X!zm#!qSC8Dibe4zC8>Yjn
zb}W}(TcR9Y{5We?*!9A?qFJ9O2cPlRH!?|@`^Iknh6B4^dF}chbNJTPQj;}Nt|~Im
zlFT-({A9JLSz9)`UGF&iwtqoW*#*|>$eJabi_n-B-X-?nWB%TACk}}G6HQXS8>H6Z
z$UA%0&EkA^UTJNc?vpwvzY2(-_L<zf`q8^{B{G=_oem-@DV^%!#|8YYi`2RP8Ghbf
zaOJ>6%ab{UITi-aN-ZiWOADtM9=s6RG{-<ATvW8E>5kO<H*pu67JE+r#~fWCa8a>P
zI%o2)D|WjLAL*@-<exC%!j{yj&-a?V5jXx{6yP7?y0a=?x;NJ>g2_t#+?o=$X$?uQ
z9tfR&G--qCy+acPCa(A@-rL@(cE}|u(Y*P&=CL2KO)GDBO}g*2*_DIsgG)!tVV6UR
zhZYJba^BqS{l-pkyTWY`;q~jUGS9os7#6>$_0n#i@4BATWeiqXC4?TEnYpcA@q%Vq
z)|$rRx=QA4+mt1DJg@ATyC%sd{IQjYm|dYax9;t5$^0))+J7$;C_UdR%ld4qs+$kr
z^C^qpS<f|NS<E|koAvLBcY@YNCT&&Rko7hvMYuhC$Jy_9ey(%kyLW49{l=4i**Qx-
zM@<+0!QUcU``FN9x{N{Rx_L56{92Q~@&q1usk}L{>-e#&uM<L6#)rEd)lxUPB$1FG
z(tFe@pTS9R;p=5z-|SdAGk_!c!Uu+Qev!PrKHnZQUQ#hPIV|b2Rr_(=>figNnBNwd
z$A=^wFi+xe3V3>`q>DRPv)Ot!?{;pJZ`zd>U$k%Udsp;3Fh1<b$%^#vzyGlq#>h=%
z`7rAMx1CwWd8hPgD{Pr<Qg6)qeXi6*aABVF)`yy!V*c+QEvTsXjh^&o$IhGgdY<jQ
z95cswZp4oLx%VDd=bf)<zPtN<(NwQDGvDaObX_#t?z8)yqu^8CO_TIB-p{F;USIb{
zeNV{?-PLQ46)u)znPYESXC-sgFSF^=zNIJjtdN-?DkmJ@rN^BhH1{s+gX$Ga6dGza
zsCPd4YO(Fk*B$;Qg3A(<r_Q!pz_?TC&=bC=rh)5zCt067))L#I>15;A{A=fAi>|e|
z)YhL?v{7Ghl6B4o_BS<Q)@O{ai1O-Xo6b+<*7<tmjg#7GWBt8{nEP#xEsU36sv~&3
z@VRx5OV9Tozt6oC4lXR~DoYhVz_7?Z?&WlEuZyattN$)xXO#>8F{#7F#`f5UCMl7g
zv%M~@zrH>_a!NVndGR-iDzSFSEqnp{w2r;2wpx+D@<8eAnK4Xz{vSR4k~PZm{Mj#c
z@3q|IzE9WG)Jsynos!k|Pq_Kdn*{xKwl#P8-s---vGuXnVmmj%W7RR?-IpIJ#ZL^c
z7xZkrC;tA8<###e?K-h$2aZ@*t6g&c^-uKbYr)*ljE7`|KlntrU*B*!%zRq#MlHWG
zy>y-x-`6uQ@X&F&-uwDS!BX)RZ|%(4+?g0QS#%2;K6gC3PGZ`9jRoQs4mxGhYig8l
zANj(wUaqb^ynoN(iIbbpoLkPg)GqR{c;4QLr?`H%lrGL$-*02E<1D9@#K)<T0Z#=d
zOb<7yIDH}YiGf0f{)dJ`%uJmA>IUh(*B$ylN4%WWn;LTU=uDY;pLv%lhs~+cwSIM@
z^0rmBulwGuO7DH|`IP>gl)dd%Lg4+JlKbzMn0^(?KRm1IYC*b{MMKGbO)s^{s&mg4
zefz^&_wkkDJ&UTQlUI0N=3J{iK5LiNyS<Oa>hfQwZGU!fQ|+~7cgyc(E?|66ed?Q|
z<9_k?Q9oy03@V9a6n_8eWa_WqazZ<Vc7!X2y*XsW+Ey>7rloXcdq~l*4=n%IJ5*#!
ztzYr%SM@dl?QV&r*gM8yf8<h~Tg~3hPMx)S_qujV1wHR)#;=}Ps4frMJV(;{eCtb*
z_Wt>gPJ9gJnJ;fHQz-VpX`w)F_Vo|Tx8L_E4{twz=9}j6bNSapj+qz6Y|Oa7U2Pgq
z*N5JU@be7Q8}zgj7#_{N`_iZW{@<=^+?&L|SNNyD+g*HBT4u4Z)a}V0KTNV}G|zg@
z&sp=})o!!Ez~rM{9fps$W+*UM^?3HhiBv>AiPbyzta{$*r;=9Y$0jDLTiTY*d$_UC
z?U=s7#94`k;itMp7fm#{8*N^E-M9M1jT=e(!_TP9v-lJ_S5^B>N<okx<NeO^vj4{x
zomhC9PokkB{d>Z){qNVmu`JrHI<MwdQbNI=xQN|L+dNEM%%+!L=5|_Rb4cC(`l(;J
zo+>GyG@fgD96P{n5Fo^tC&hVZ+o|&@o6nrlH88e6-+5VCrs}zdd;2*9TXXj^LwCLT
z-+z~%DPJMP*Pgk?chmc}*EcTLigxZ0zLxOXwjo_jnrln6d3$q0w`x;THp>sSL&~b!
zg%iItGO#J!yJ<V|-TU8M1}s(l0k7HH4ZDs>gkEv+T(>sijmxRI<_iUKZf~B}=Wl*%
zd5QE-@1A|jkKfo|lR52y(l)s*J9eD-az>`|_m7)1e^&bS_7r73kzrnb@9Ev*#X2c}
zjvr?In||<hN~r4fcRMCUuY0*LH#XSeiR3Bm9~Rx*V%wY8o)>;`c%8`g(5}&4@0#Ow
zk=ld?Mvs!R{`6nf`+HBV=J?*cZPnTtm79-e?0Ne?<JP9Gi^7-REy%yIan|a**nZ)T
zFsm0QgBfb=xToi^UNbp=)ynbV&HuGi7he3_<G(!O%+ne19=ogDttO}D6m|6oIz{@_
zUB0uk&+X8gjQdBP=kJ-;cTMcnBg6W=R}2pG<~`hg+~@MmUvI1Rj96+u7d5c%__F${
z_R=pC_nC6Ui{DsX(CTpFP0VI#zrBVBFaQ6b7S*sdI(*~vd%9Q5*dJBTo%3pbZe8fj
zU*;0&&!28RHFwUuhtJpVIo6%O=jhFkoR=c|n^|fnT(dp=|IzMk4x3i3n)Gd2+PAwq
zW`E;-&C%}kfI&IHyIgRw%Tw?ATQ}B*L|uID^3?9Z+xtf>x6Ay!#=tzm@{+jYjlNIr
zT6a{u#FGkb=buli=v)5ppYEp5mU(|~m0inUYvz~1#WN}M)-;BG$>{FN^&VQB%E^!S
zRDNMO?$7`E+eyb`YRe)F&OA^GzO&9-MP}KyU0uAsy(M|KPHgMdEy=m#pd<B>zclc#
zPq37<N?GpQ*9@0(`7Am9cucMLDk<%c>Dn0CRkymKP~+}>ap4TsZOrj(cAT?9yyx<s
zT`pGn@nQ0nwd<cuuHP^(;Dk(-J;$`-LzZIgFIRkguB+=Kc1iNs@?|sq(=Cjxj-51q
zKEq?_jCpfYwM@NDgcfexH?7O1>DVom+0oZ0uUWTf*`lVDQq_k6D^}PoJ*4Jcz<d9%
zLrj3<)Fux9#lK`-?)8<I#b4q2@_QjaYeLhMm+x1z<ptbe&bi#QZl>JnE7QW=r5-&k
zds6N&yQG)p@T3Cei)Z}!Us*H0-^6cl&gZx`yQb-igL95OuzJtV&(OE7>DRl+pE=bU
z8hKY^gH9&u%I#aQ>bL8YsizmN)^U~hIxr)pdAVo=`z@|bNB8A1M|QuzTs&<-c~XS#
zfdfHxQ@(q@(h*~0H(7E0Mq2*Lf-|ant(GZ;F4@DNw0YGYl^5L{`in0~zyI~1;n9V5
zIRnR2U%pS%p2VQ#YP#@(g3|Q`yVxhbU2#q8NW+BG)ao~PwoW~Ip*W|?Ui#)6YwsuK
zJ0m$CpQ(HBDuHi@PTgc@Q*|ZFkj+{~{hzo#csIr+cwFps2|v%yC(>T`oME#}>aS{P
zhi{AC1eUaSlvtei`ODVyXjz2(r%#r46CO?cp6#t#(eA%e*UOZDPT-e03c;(aw3U=s
z@pKz3S(V>);)Iuf+ph&LlvyR(jsDh7U2xmMj(wMSigDSS{@oML=9O(c5#^O}!)@oI
z%^hpXC8|0$JG?9~zdrqumZtClVWm$>1u_zWB}yOd%qIUed#TI`HidHvTg&bSeWqN8
zr`0KoPZVh;Zj4yz)oQ`=F1m8FMl;9%wpW)G)I&XPH>T|m{xXrR$MfaCeN`7~HOjj^
z_%jY|4BPV~qHB%P`6i=UmAVN!$-bfuj1M#)9IQzHejzpQS?cnB-UOLbU%qc;G-oVl
z-d%7w#CGY8Xgv-Krs<0R&v7t33;pUTSjkZF`|z^v7@gWT49pYWz31&r&AiL<M{)ym
ziEhX4ZDFTgadIgJD{f;9W|%ARMD;;k=smBJT9bxH7mf=VsHOh;Ep))I^*l#R^V8gQ
zy5AV4UkjHBvS@x)%yeGs(-n7K4ZhkpjE@7B?KfxJ6qYzQV$rLpHL6`~*MEJKytKf>
t?*Z!r$qUT~9QJHp{-yAqyx_0;(1RNd%cQq7GB7YOc)I$ztaD0e0sw}F5#ay;

literal 0
HcmV?d00001

diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php
index ea339cf9a..69690be01 100644
--- a/resources/lang/en/general.php
+++ b/resources/lang/en/general.php
@@ -125,6 +125,7 @@
     'feature_disabled'      => 'This feature has been disabled for the demo installation.',
     'location'              => 'Location',
     'locations'				=> 'Locations',
+    'logo_size'				=> 'Square logos look best with Logo + Text. Logo maximum display size is 50px high x 500px wide.  ',
     'logout'				=> 'Logout',
     'lookup_by_tag'     => 'Lookup by Asset Tag',
     'maintenances'          => 'Maintenances',
diff --git a/resources/views/accessories/edit.blade.php b/resources/views/accessories/edit.blade.php
index 6b2065a08..9148c8b13 100755
--- a/resources/views/accessories/edit.blade.php
+++ b/resources/views/accessories/edit.blade.php
@@ -29,7 +29,7 @@
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
         <div class="col-md-5">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/accessories/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('accessories_upload_path').e($item->image)) }}" class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/account/profile.blade.php b/resources/views/account/profile.blade.php
index 18a828703..bbff2a602 100755
--- a/resources/views/account/profile.blade.php
+++ b/resources/views/account/profile.blade.php
@@ -90,7 +90,7 @@
             <label class="col-md-3 control-label" for="avatar_delete">{{ trans('general.avatar_delete') }}</label>
             <div class="col-md-8">
               {{ Form::checkbox('avatar_delete') }}
-              <img src="{{ url('/') }}/uploads/avatars/{{ $user->avatar }}" class="avatar img-circle">
+              <img src="{{ $user->present()->gravatar}}" class="avatar img-circle">
               {!! $errors->first('avatar_delete', '<span class="alert-msg">:message</span>') !!}
             </div>
           </div>
diff --git a/resources/views/categories/edit.blade.php b/resources/views/categories/edit.blade.php
index 88bc6457b..ca43c49bb 100755
--- a/resources/views/categories/edit.blade.php
+++ b/resources/views/categories/edit.blade.php
@@ -79,7 +79,7 @@
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
         <div class="col-md-9">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/categories/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('categories_upload_path').e($item->image)) }}" class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/companies/edit.blade.php b/resources/views/companies/edit.blade.php
index 8f63b05c4..ee77efc4f 100644
--- a/resources/views/companies/edit.blade.php
+++ b/resources/views/companies/edit.blade.php
@@ -16,7 +16,7 @@
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
         <div class="col-md-5">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/companies/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('companies_upload_path').e($item->image)) }}" class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/components/edit.blade.php b/resources/views/components/edit.blade.php
index 8e9be3738..9bfdf6a43 100644
--- a/resources/views/components/edit.blade.php
+++ b/resources/views/components/edit.blade.php
@@ -27,7 +27,7 @@
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
         <div class="col-md-5">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/components/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('components_upload_path').e($item->image)) }}"  class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/consumables/edit.blade.php b/resources/views/consumables/edit.blade.php
index 9496019e4..4392c1f1b 100644
--- a/resources/views/consumables/edit.blade.php
+++ b/resources/views/consumables/edit.blade.php
@@ -27,7 +27,7 @@
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
         <div class="col-md-5">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/consumables/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('consumables_upload_path').e($item->image)) }}"  class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/departments/edit.blade.php b/resources/views/departments/edit.blade.php
index ff5bbfd16..4d3952528 100644
--- a/resources/views/departments/edit.blade.php
+++ b/resources/views/departments/edit.blade.php
@@ -29,7 +29,7 @@
             <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
             <div class="col-md-5">
                 {{ Form::checkbox('image_delete') }}
-                <img src="{{ url('/') }}/uploads/departments/{{ $item->image }}" />
+                <img src="{{ Storage::disk('public')->url(app('departments_upload_path').e($item->image)) }}" class="img-responsive" />
                 {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
             </div>
         </div>
diff --git a/resources/views/hardware/edit.blade.php b/resources/views/hardware/edit.blade.php
index c3c5d9be2..708d296ea 100755
--- a/resources/views/hardware/edit.blade.php
+++ b/resources/views/hardware/edit.blade.php
@@ -86,7 +86,7 @@
           {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
           </label>
           <div style="margin-top: 0.5em">
-              <img src="{{ url('/') }}/uploads/assets/{{ $item->image }}" class="img-responsive"/>
+              <img src="{{ Storage::disk('public')->url(app('assets_upload_path').e($item->image)) }}" class="img-responsive" />
           </div>
       </div>
   </div>
@@ -170,7 +170,7 @@
             });
         }
     }
-    ;
+
 
     $(function () {
         //grab custom fields for this model whenever model changes.
@@ -184,135 +184,8 @@
             user_add($(".status_id").val());
         });
 
-        $("#create-form").submit(function (event) {
-            event.preventDefault();
-            return sendForm();
-        });
-
-        // Resize Files when chosen
-        //First check to see if there is a file before doing anything else
-
-        var imageData = "";
-        var $fileInput = $('#uploadFile');
-        $fileInput.on('change', function (e) {
-            if ($fileInput != '') {
-                if (window.File && window.FileReader && window.FormData) {
-                    var file = e.target.files[0];
-                    if (file) {
-                        if (/^image\//i.test(file.type)) {
-                            readFile(file);
-                        } else {
-                            alert('Invalid Image File :(');
-                        }
-                    }
-                }
-                else {
-                    console.log("File API not supported, not resizing");
-                }
-            }
-        });
-
-
-        function readFile(file) {
-            var reader = new FileReader();
-
-            reader.onloadend = function () {
-                processFile(reader.result, file.type);
-            }
-
-            reader.onerror = function () {
-                alert("Unable to read file");
-            }
-
-            reader.readAsDataURL(file);
-        }
-
-        function processFile(dataURL, fileType) {
-            var maxWidth = 800;
-            var maxHeight = 800;
-
-            var image = new Image();
-            image.src = dataURL;
-
-            image.onload = function () {
-                var width = image.width;
-                var height = image.height;
-                var shouldResize = (width > maxWidth) || (height > maxHeight);
-
-                if (!shouldResize) {
-                    imageData = dataURL;
-                    return;
-                }
-
-                var newWidth;
-                var newHeight;
-
-                if (width > height) {
-                    newHeight = height * (maxWidth / width);
-                    newWidth = maxWidth;
-                } else {
-                    newWidth = width * (maxHeight / height);
-                    newHeight = maxHeight;
-                }
-                var canvas = document.createElement('canvas');
-
-                canvas.width = newWidth;
-                canvas.height = newHeight;
-
-                var context = canvas.getContext('2d');
-
-                context.drawImage(this, 0, 0, newWidth, newHeight);
-
-                dataURL = canvas.toDataURL(fileType);
-
-                imageData = dataURL;
-
-            };
-
-            image.onerror = function () {
-                alert('Unable to process file :(');
-            }
-        }
-
-        function sendForm() {
-            var form = $("#create-form").get(0);
-            var formData = $('#create-form').serializeArray();
-            formData.push({name: 'image', value: imageData});
-            $.ajax({
-                type: 'POST',
-                url: form.action,
-                headers: {
-                    "X-Requested-With": 'XMLHttpRequest',
-                    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
-                },
-                data: formData,
-                dataType: 'json',
-                success: function (data) {
-                    // console.dir(data);
-                    // AssetController flashes success to session, redirect to hardware page.
-                    if (data.redirect_url) {
-                        window.location.href = data.redirect_url;
-                        return true;
-                    }
-                    window.location.reload(true);
-                    return false;
-
-                },
-                error: function (data) {
-                    // AssetRequest Validator will flash all errors to session, this just refreshes to see them.
-                    window.location.reload(true);
-                    // console.log(JSON.stringify(data));
-                    // console.log('error submitting');
-                }
-            });
-
-            return false;
-        }
-
     });
 
 
-
-
 </script>
 @stop
diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php
index dd8ea1b6e..f6b5ffc69 100755
--- a/resources/views/hardware/view.blade.php
+++ b/resources/views/hardware/view.blade.php
@@ -497,9 +497,9 @@
 
             <div class="col-md-4">
               @if ($asset->image)
-                <img src="{{ url('/') }}/uploads/assets/{{{ $asset->image }}}" class="assetimg img-responsive">
+                <img src="{{ Storage::disk('public')->url(app('assets_upload_path').e($asset->image)) }}" class="assetimg img-responsive">
               @elseif (($asset->model) && ($asset->model->image!=''))
-                <img src="{{ url('/') }}/uploads/models/{{{ $asset->model->image }}}" class="assetimg img-responsive">
+                <img src="{{ Storage::disk('public')->url(app('models_upload_url').e($asset->model->image )) }}" class="assetimg img-responsive">
               @endif
 
               @if  ($snipeSettings->qr_code=='1')
diff --git a/resources/views/layouts/basic.blade.php b/resources/views/layouts/basic.blade.php
index 1e9b3334b..4942c2404 100644
--- a/resources/views/layouts/basic.blade.php
+++ b/resources/views/layouts/basic.blade.php
@@ -45,7 +45,7 @@
 
     @if (($snipeSettings) && ($snipeSettings->logo!=''))
         <center>
-            <img id="login-logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
+            <img id="login-logo" src="{{ Storage::disk('public')->url('').e($snipeSettings->logo) }}">
         </center>
     @endif
   <!-- Content -->
diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php
index f74fc9ce6..ca06e2e6f 100644
--- a/resources/views/layouts/default.blade.php
+++ b/resources/views/layouts/default.blade.php
@@ -96,14 +96,14 @@
                  @if ($snipeSettings->brand == '3')
                       <a class="logo navbar-brand no-hover" href="{{ url('/') }}">
                           @if ($snipeSettings->logo!='')
-                          <img class="navbar-brand-img" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
+                          <img class="navbar-brand-img" src="{{ Storage::disk('public')->url('').e($snipeSettings->logo) }}">
                           @endif
                           {{ $snipeSettings->site_name }}
                       </a>
                   @elseif ($snipeSettings->brand == '2')
                       <a class="logo navbar-brand no-hover" href="{{ url('/') }}">
                           @if ($snipeSettings->logo!='')
-                          <img class="navbar-brand-img" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
+                            <img class="navbar-brand-img" src="{{ Storage::disk('public')->url('').e($snipeSettings->logo) }}">
                           @endif
                       </a>
                   @else
diff --git a/resources/views/locations/edit.blade.php b/resources/views/locations/edit.blade.php
index 253a069ce..3990c5b8f 100755
--- a/resources/views/locations/edit.blade.php
+++ b/resources/views/locations/edit.blade.php
@@ -54,9 +54,9 @@
 @if ($item->image)
     <div class="form-group {{ $errors->has('image_delete') ? 'has-error' : '' }}">
         <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
-        <div class="col-md-5">
+        <div class="col-md-9">
             {{ Form::checkbox('image_delete') }}
-            <img src="{{ url('/') }}/uploads/locations/{{ $item->image }}" />
+            <img src="{{ Storage::disk('public')->url(app('locations_upload_path').e($item->image)) }}" class="img-responsive" />
             {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
         </div>
     </div>
diff --git a/resources/views/manufacturers/edit.blade.php b/resources/views/manufacturers/edit.blade.php
index af212be8f..eb8fa88b4 100755
--- a/resources/views/manufacturers/edit.blade.php
+++ b/resources/views/manufacturers/edit.blade.php
@@ -56,7 +56,7 @@
             <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
             <div class="col-md-5">
                 {{ Form::checkbox('image_delete') }}
-                <img src="{{ url('/') }}/uploads/manufacturers/{{ $item->image }}" />
+                <img src="{{ Storage::disk('public')->url(app('manufacturers_upload_path').e($item->image)) }}" class="img-responsive" />
                 {!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
             </div>
         </div>
diff --git a/resources/views/models/edit.blade.php b/resources/views/models/edit.blade.php
index ae271c583..ccf8728c8 100755
--- a/resources/views/models/edit.blade.php
+++ b/resources/views/models/edit.blade.php
@@ -62,7 +62,7 @@
     <label class="col-md-3 control-label" for="image_delete">{{ trans('general.image_delete') }}</label>
     <div class="col-md-5">
         {{ Form::checkbox('image_delete') }}
-        <img src="{{ url('/') }}/uploads/models/{{ $item->image }}" />
+        <img src="{{ Storage::disk('public')->url(app('models_upload_path').e($item->image)) }}" class="img-responsive" />
         {!! $errors->first('image_delete', '<span class="alert-msg"><br>:message</span>') !!}
     </div>
 </div>
diff --git a/resources/views/partials/forms/edit/image-upload.blade.php b/resources/views/partials/forms/edit/image-upload.blade.php
index 32b1b3ce5..b0c7819b6 100644
--- a/resources/views/partials/forms/edit/image-upload.blade.php
+++ b/resources/views/partials/forms/edit/image-upload.blade.php
@@ -3,14 +3,14 @@
     <div class="col-md-9">
         <label class="btn btn-default">
             {{ trans('button.select_file')  }}
-            <input type="file" name="image" id="uploadFile" data-maxsize="{{ \App\Helpers\Helper::file_upload_max_size() }}" accept="image/gif,image/jpeg,image/png,image/svg" style="display:none">
+            <input type="file" name="image" id="uploadFile" data-maxsize="{{ \App\Helpers\Helper::file_upload_max_size() }}" accept="image/gif,image/jpeg,image/png,image/svg" style="display:none; max-width: 90%">
         </label>
         <span class='label label-default' id="upload-file-info"></span>
 
         <p class="help-block" id="upload-file-status">{{ trans('general.image_filetypes_help', ['size' => \App\Helpers\Helper::file_upload_max_size_readable()]) }}</p>
         {!! $errors->first('image', '<span class="alert-msg">:message</span>') !!}
     </div>
-    <div class="col-md-4">
+    <div class="col-md-9 col-md-offset-3">
         <img id="imagePreview" style="max-width: 200px;">
     </div>
 </div>
diff --git a/resources/views/settings/backups.blade.php b/resources/views/settings/backups.blade.php
index 534a29100..148c81967 100644
--- a/resources/views/settings/backups.blade.php
+++ b/resources/views/settings/backups.blade.php
@@ -29,7 +29,7 @@
             <tbody>
             @foreach ($files as $file)
             <tr>
-              <td><a href="backups/download/{{ $file['filename'] }}">{{ $file['filename'] }}</a></td>
+              <td><a href="{{ Storage::url('backups/'.e($file['filename'])) }}">{{ $file['filename'] }}</a></td>
               <td>{{ date("M d, Y g:i A", $file['modified']) }} </td>
               <td>{{ $file['filesize'] }}</td>
               <td>
diff --git a/resources/views/settings/branding.blade.php b/resources/views/settings/branding.blade.php
index 675657046..4a7170459 100644
--- a/resources/views/settings/branding.blade.php
+++ b/resources/views/settings/branding.blade.php
@@ -37,7 +37,7 @@
                 <div class="box-body">
 
 
-                    <div class="col-md-11 col-md-offset-1">
+                    <div class="col-md-12">
 
                         <!-- Site name -->
                         <div class="form-group {{ $errors->has('site_name') ? 'error' : '' }}">
@@ -60,23 +60,31 @@
                         <!-- Logo -->
 
                         <div class="form-group {{ $errors->has('image') ? 'has-error' : '' }}">
-                            <label class="col-md-3 control-label" for="image">
-                                {{ Form::label('logo', trans('admin/settings/general.logo')) }}</label>
+                            <label class="col-md-3" for="image">
+                                {{ Form::label('image', trans('admin/settings/general.logo')) }}</label>
+
                             <div class="col-md-9">
-                                @if (config('app.lock_passwords'))
-                                    <p class="help-block">{{ trans('general.lock_passwords') }}</p>
-                                @else
                                 <label class="btn btn-default">
                                     {{ trans('button.select_file')  }}
-                                    <input type="file" name="image" accept="image/gif,image/jpeg,image/png,image/svg" hidden>
+                                    <input type="file" name="image" id="uploadFile" data-maxsize="{{ \App\Helpers\Helper::file_upload_max_size() }}" accept="image/gif,image/jpeg,image/png,image/svg" style="display:none; max-width: 90%">
                                 </label>
+                                <span class='label label-default' id="upload-file-info"></span>
 
-                                    <p class="help-block" id="upload-file-status">{{ trans('general.image_filetypes_help', ['size' => \App\Helpers\Helper::file_upload_max_size_readable()]) }}</p>
-                                
+                                <p class="help-block" id="upload-file-status">{{ trans('general.image_filetypes_help', ['size' => \App\Helpers\Helper::file_upload_max_size_readable()]) }} {{ trans('general.logo_size') }}</p>
                                 {!! $errors->first('image', '<span class="alert-msg">:message</span>') !!}
-                                {{ Form::checkbox('clear_logo', '1', Input::old('clear_logo'),array('class' => 'minimal')) }} Remove
-                               @endif
+
+                            </div>
+                            <div class="col-md-9 col-md-offset-3">
+                                <img id="imagePreview" style="max-width: 500px; max-height: 50px">
                             </div>
+
+                            @if ($setting->logo!='')
+                            <div class="col-md-9 col-md-offset-3">
+
+                                {{ Form::checkbox('clear_logo', '1', Input::old('clear_logo'),array('class' => 'minimal')) }} Remove current image
+
+                            </div>
+                                @endif
                         </div>
 
 
@@ -157,7 +165,7 @@
                                     {{ Form::textarea('custom_css', Input::old('custom_css', $setting->custom_css), array('class' => 'form-control','placeholder' => 'Add your custom CSS')) }}
                                     {!! $errors->first('custom_css', '<span class="alert-msg">:message</span>') !!}
                                 @endif
-                                <p class="help-block">{{ trans('admin/settings/general.custom_css_help') }}</p>
+                                <p class="help-block">{!! trans('admin/settings/general.custom_css_help') !!}</p>
                             </div>
                         </div>
 
diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php
index 20b9b7fd4..09a572c05 100755
--- a/resources/views/users/view.blade.php
+++ b/resources/views/users/view.blade.php
@@ -115,11 +115,7 @@
               </div>
             @endif
             <div class="col-md-2 text-center">
-              @if ($user->avatar)
-                <img src="/uploads/avatars/{{ $user->avatar }}" class="avatar img-thumbnail hidden-print">
-              @else
-                <img src="{{ $user->present()->gravatar() }}" class="avatar img-circle hidden-print">
-              @endif
+                <img src="{{ $user->present()->gravatar }}" class="avatar img-thumbnail hidden-print">
             </div>
 
             <div class="col-md-8">
diff --git a/resources/views/vendor/mail/html/header.blade.php b/resources/views/vendor/mail/html/header.blade.php
index 686ee632f..fe93f44a9 100644
--- a/resources/views/vendor/mail/html/header.blade.php
+++ b/resources/views/vendor/mail/html/header.blade.php
@@ -4,13 +4,13 @@
 
             @if ($snipeSettings->brand == '3')
                 @if ($snipeSettings->logo!='')
-                    <img class="navbar-brand-img logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}"alt="{{ $snipeSettings->site_name }}">
+                    <img class="navbar-brand-img logo" src="{{ Storage::disk('public')->url('').e($snipeSettings->logo) }}"alt="{{ $snipeSettings->site_name }}">
                 @endif
                 {{ $snipeSettings->site_name }}
 
             @elseif ($snipeSettings->brand == '2')
                 @if ($snipeSettings->logo!='')
-                    <img class="navbar-brand-img logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}" alt="{{ $snipeSettings->site_name }}">
+                    <img class="navbar-brand-img logo" src="{{ Storage::disk('public')->url('').e($snipeSettings->logo) }}" alt="{{ $snipeSettings->site_name }}">
                 @endif
             @else
                 {{ $snipeSettings->site_name }}
diff --git a/upgrade.php b/upgrade.php
index 030d26207..08eafd6b2 100644
--- a/upgrade.php
+++ b/upgrade.php
@@ -174,16 +174,71 @@ echo "\n";
 
 
 echo "--------------------------------------------------------\n";
-echo "Step 9: Taking application out of maintenance mode:\n";
+echo "Step 10: Taking application out of maintenance mode:\n";
 echo "--------------------------------------------------------\n\n";
 
 $up = shell_exec('php artisan up');
 echo '-- '.$up."\n\n";
 
+
+echo "--------------------------------------------------------\n";
+echo "Step 11: Checking for v5 public storage directories:    \n";
+echo "--------------------------------------------------------\n\n";
+
+
+if ((!file_exists('storage/app/public')) && (!is_dir('storage/app/public'))) {
+    echo "- No public directory found in storage/app - creating one.\n\n";
+    if (!mkdir('storage/app/public', 0777, true)) {
+        echo "ERROR: Failed to create directory at storage/app/public. You should do this manually.\n\n";
+    }
+    $storage_simlink = shell_exec('php artisan storage:link');
+    echo $storage_simlink;
+
+} else {
+    echo "- Public storage directory already exists. Skipping...\n\n";
+}
+
+echo "- Copying files into storage/app/public.\n\n";
+if (rmove('public/uploads','storage/app/public')) {
+    echo "- Copy successful.\n\n";
+} else {
+    echo "- Copy failed - you should do this manually by copying the files from public/uploads into the storage/app/public directory.\n\n";
+}
+
 echo "--------------------------------------------------------\n";
 echo "FINISHED! Clear your browser cookies and re-login to use :\n";
 echo "your upgraded Snipe-IT.\n";
 echo "--------------------------------------------------------\n\n";
 
 
-
+/**
+ * Recursively move files from one directory to another
+ *
+ * @param String $src - Source of files being moved
+ * @param String $dest - Destination of files being moved
+ */
+function rmove($src, $dest){
+
+    // If source is not a directory stop processing
+    if(!is_dir($src)) return false;
+
+    // If the destination directory does not exist create it
+    if(!is_dir($dest)) {
+        if(!mkdir($dest)) {
+            // If the destination directory could not be created stop processing
+            return false;
+        }
+    }
+
+    // Open the source directory to read in files
+    $i = new DirectoryIterator($src);
+    foreach($i as $f) {
+        if($f->isFile()) {
+            rename($f->getRealPath(), "$dest/" . $f->getFilename());
+        } else if(!$f->isDot() && $f->isDir()) {
+            rmove($f->getRealPath(), "$dest/$f");
+            unlink($f->getRealPath());
+        }
+    }
+    unlink($src);
+}
-- 
GitLab