diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..031862b --- /dev/null +++ b/.env.example @@ -0,0 +1,23 @@ +APP_ENV=local +APP_DEBUG=true +APP_KEY=SomeRandomString + +DB_HOST=localhost +DB_DATABASE=homestead +DB_USERNAME=homestead +DB_PASSWORD=secret + +CACHE_DRIVER=file +SESSION_DRIVER=file +QUEUE_DRIVER=sync + +REDIS_HOST=localhost +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..95883de --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto +*.css linguist-vendored +*.less linguist-vendored diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c3a086 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/vendor +/node_modules +Homestead.yaml +Homestead.json +.env +*.log +.DS_Store diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..d3c5213 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,7 @@ +preset: laravel + +linting: true + +finder: + exclude: + - "tests" \ No newline at end of file diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..bea4788 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: vendor/bin/heroku-php-apache2 public \ No newline at end of file diff --git a/app/Categories.php b/app/Categories.php new file mode 100644 index 0000000..5b048f9 --- /dev/null +++ b/app/Categories.php @@ -0,0 +1,45 @@ +belongsTo('Soma\User'); + } + + /** + * A category has many videos. + * + * @return Illuminate\Database\Eloquent\Relations\HasMany + */ + public function videos() + { + return $this->hasMany('Soma\Videos', 'category_id'); + } +} diff --git a/app/Console/Commands/Inspire.php b/app/Console/Commands/Inspire.php index db9ab85..01806aa 100644 --- a/app/Console/Commands/Inspire.php +++ b/app/Console/Commands/Inspire.php @@ -1,6 +1,6 @@ 'required|max:255', - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:6', + 'email' => 'required|email|max:255|max:255', + 'password' => 'required|min:6', + 'confirm-password' => 'required|same:password', ]); } diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php index 1ceed97..e4fb346 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -1,8 +1,8 @@ redirect(); + } + + /** + * Obtain the user information from the provider. + * + * Specify true as the second parameter to "Auth::login()" + * " to set the "remember me" cookie. + * + * @return Response + */ + public function handleProviderCallback($provider) + { + try { + $user = Socialite::driver($provider)->user(); + } catch (\Exception $e) { + return redirect()->route('register'); + } + + $authUser = $this->findOrCreateUser($user); + Auth::login($authUser, true); + + return redirect()->route('dashboard'); + } + + /** + * Return user if exists; create and return if doesn't. + * + * @param $socialUser + * @return User + */ + private function findOrCreateUser($socialUser) + { + if ($authUser = User::where('email', $socialUser->getEmail())->first()) { + return $authUser; + } + + return User::create([ + 'name' => $socialUser->getName(), + 'email' => $socialUser->getEmail(), + 'provider_id' => $socialUser->getAvatar(), + 'avatar' => $socialUser->getAvatar(), + ]); + } +} diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php new file mode 100644 index 0000000..e167146 --- /dev/null +++ b/app/Http/Controllers/CategoryController.php @@ -0,0 +1,124 @@ +middleware('auth', [ + 'except' => [ + 'getVideosByCategory', + ], + ]); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + /*public function index() + { + $categories = Categories::all(); + + return view('categories.index')->with('categories', $categories); + }*/ + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + return view('categories.create'); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(CategoriesRequest $request) + { + $user = User::authorizedUser($request->email)->first(); + $user->categories()->create([ + 'title' => $request->title, + ]); + + // FLASH MESSAGE + + return redirect()->back(); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $category = Categories::find($id); + + return view('categories.edit')->with('category', $category); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(CategoriesRequest $request, $id) + { + $category = Categories::find($id); + $category->update([ + 'title' => $request->title, + ]); + + // FLASH MESSAGE + return redirect()->route('own.categories'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $category = Categories::find($id); + if ($category) { + Categories::destroy($id); + + return redirect()->back(); + } + + // REDIRECT WITH MESSAGE CATEGORY NOT FOUND + return redirect()->route('dashboard'); + } + + /** + * Get the categories of a particular user. + * + * @return \Illuminate\Http\Response + */ + public function getCategories() + { + $categories = Categories::where('user_id', auth()->user()->id)->get(); + + return view('categories.own')->with('categories', $categories); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 4eb37d5..8cec9ac 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -1,6 +1,6 @@ user()) { + return view('dashboard.index'); + } + + return view('auth.login'); + } + + /** + * Return the register view. + * + * @return view + */ + public function register() + { + return view('auth.register'); + } + + /** + * Return the dashboard view. + * + * @return view + */ + public function dashboard() + { + return view('dashboard.index'); + } +} diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..d787e56 --- /dev/null +++ b/app/Http/Controllers/ProfileController.php @@ -0,0 +1,74 @@ +middleware('auth'); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $user = User::find($id); + + return view('dashboard.edit')->with('user', $user); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(ProfileRequest $request, $id) + { + $user = User::find($id); + $user->update([ + 'name' => $request->name, + 'email' => $request->email, + ]); + + // FLASH MESSAGE + return redirect()->route('dashboard'); + } + + /** + * Update the avatar url. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function changeAvatar(Request $request, $id) + { + $baseDir = 'avatar'; + + $this->validate($request, [ + 'photo' => 'required|mimes:jpg,jpeg,png,bmp', + ]); + $file = $request->file('photo'); + $name = $file->getClientOriginalName(); + + $file->move($baseDir, $name); + + $user = User::find($id); + $user->avatar = '/'.$baseDir.'/'.$name; + $user->save(); + } +} diff --git a/app/Http/Controllers/VideoController.php b/app/Http/Controllers/VideoController.php new file mode 100644 index 0000000..09779a3 --- /dev/null +++ b/app/Http/Controllers/VideoController.php @@ -0,0 +1,186 @@ +middleware('auth', [ + 'except' => [ + 'index', + 'show', + ], + ]); + $this->getCategories = Categories::all(); + $this->user = auth()->user(); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + $videos = Videos::paginate(6); + $categories = $this->getCategories; + + return view('welcome', compact('videos', 'categories')); + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + $categories = $this->getCategories; + + return view('videos.create')->with('categories', $categories); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(VideoRequest $request) + { + $category = Categories::find($request->category_id); + + $link = $this->youtubeEmbedLink($request->youtube_link); + + $category->videos()->create([ + 'user_id' => $this->user->id, + 'youtube_link' => $link, + 'title' => $request->title, + 'description' => $request->description, + ]); + + // FLASH MESSAGE + + return redirect()->route('dashboard'); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + $video = Videos::find($id); + $category = Categories::find($video->category_id); + + return view('videos.show', compact('video', 'category')); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $categories = $this->getCategories; + $video = Videos::find($id); + + return view('videos.edit', compact('video', 'categories')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(VideoRequest $request, $id) + { + $video = Videos::find($id); + $video->update([ + 'category_id' => $request->category_id, + 'youtube_link' => $request->youtube_link, + 'title' => $request->title, + 'description' => $request->description, + ]); + + // FLASH MESSAGE + return redirect()->route('own.videos'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $video = Videos::find($id); + if ($video) { + Videos::destroy($id); + + return redirect()->route('dashboard'); + } + + // REDIRECT WITH MESSAGE VIDEO NOT FOUND + return redirect()->route('dashboard'); + } + + /** + * Get the videos of a particular user. + * + * @return \Illuminate\Http\Response + */ + public function getVideos() + { + $id = auth()->user()->id; + $videos = Videos::where('user_id', $id)->paginate(6); + + return view('videos.index')->with('videos', $videos); + } + + /** + * Get all the videos of a particular category. + * + * @return \Illuminate\Http\Response + */ + public function getVideosByCategory($id) + { + $categories = $this->getCategories; + $videos = Videos::where('category_id', $id)->paginate(6); + + return view('categories.video', compact('videos', 'categories')); + } + + /** + * Write the URL to allow the video to be embedded on page. + * + * @param string $youtubeLink + * @return \Illuminate\Http\Response + */ + private function youtubeEmbedLink($youtubeLink) + { + $search = "/^(?:https?:\/\/)?(www\.youtube\.com\/)(?:embed\/|watch\?v=)([\w-]{9,12})(?:.*)$/"; + $replace = 'https://www.youtube.com/embed/$2'; + $url = preg_replace($search, $replace, $youtubeLink); + + return $url; + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index ceea60a..b968ecc 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -1,6 +1,6 @@ \App\Http\Middleware\Authenticate::class, + 'auth' => \Soma\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'guest' => \Soma\Http\Middleware\RedirectIfAuthenticated::class, ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index a5ef9c6..d5e46c7 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -1,6 +1,6 @@ auth->check()) { - return redirect('/'); + return redirect('/dashboard'); } return $next($request); diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index a2c3541..91f88be 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -1,6 +1,6 @@ 'required', + ]; + } +} diff --git a/app/Http/Requests/ProfileRequest.php b/app/Http/Requests/ProfileRequest.php new file mode 100644 index 0000000..fa38abf --- /dev/null +++ b/app/Http/Requests/ProfileRequest.php @@ -0,0 +1,29 @@ + 'required|max:255', + 'email' => 'required|email|max:255|max:255', + ]; + } +} diff --git a/app/Http/Requests/Request.php b/app/Http/Requests/Request.php index 76b2ffd..fad959b 100644 --- a/app/Http/Requests/Request.php +++ b/app/Http/Requests/Request.php @@ -1,6 +1,6 @@ 'required|url', + 'title' => 'required', + 'description' => 'required', + ]; + } +} diff --git a/app/Http/routes.php b/app/Http/routes.php index 1ad3549..51c2676 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -10,7 +10,85 @@ | and give it the controller to call when that URI is requested. | */ +// homepage route +Route::get('/', [ + 'uses' => 'VideoController@index', + 'as' => 'homepage', +]); -Route::get('/', function () { - return view('welcome'); -}); +// Authentication routes... +Route::get('auth/login', [ + 'uses' => 'HomeController@login', + 'as' => 'login', +]); + +Route::post('auth/login', 'Auth\AuthController@postLogin'); + +// Logout route +Route::get('auth/logout', [ + 'uses' => 'Auth\AuthController@getLogout', + 'as' => 'logout', +]); + +// Registration routes... +Route::get('auth/register', [ + 'uses' => 'HomeController@register', + 'as' => 'register', +]); + +Route::post('auth/register', 'Auth\AuthController@postRegister'); + +// Social authentication routes +Route::get('auth/{provider}', [ + 'uses' => 'Auth\SocialAuthController@redirectToProvider', + 'as' => 'social.auth', +]); + +Route::get('auth/{provider}/callback', 'Auth\SocialAuthController@handleProviderCallback'); + +// Dashboard route +Route::get('dashboard', [ + 'middleware' => 'auth', + 'uses' => 'HomeController@dashboard', + 'as' => 'dashboard', +]); + +// Video route +Route::get('video/myvideos', [ + 'uses' => 'VideoController@getVideos', + 'as' => 'own.videos', +]); + +Route::resource('video', 'VideoController'); + +//Category route +Route::get('category/mycategories', [ + 'uses' => 'CategoryController@getCategories', + 'as' => 'own.categories', +]); +Route::resource( + 'category', + 'CategoryController', + ['except' => ['show', 'index']] +); + +// Profile route +Route::resource( + 'profile', + 'ProfileController', + [ + 'only' => ['edit', 'update'], + ] +); + +// change avatar +Route::post('profile/{id}/photo', [ + 'uses' => 'ProfileController@changeAvatar', + 'as' => 'change.avatar', +]); + +// Get videos by category +Route::get('categories/{id}/videos', [ + 'uses' => 'VideoController@getVideosByCategory', + 'as' => 'category.videos', +]); diff --git a/app/Jobs/Job.php b/app/Jobs/Job.php index 55ece29..3dc6e4a 100644 --- a/app/Jobs/Job.php +++ b/app/Jobs/Job.php @@ -1,6 +1,6 @@ id === $category->user_id; + } +} diff --git a/app/Policies/VideoAuthorizePolicy.php b/app/Policies/VideoAuthorizePolicy.php new file mode 100644 index 0000000..016f043 --- /dev/null +++ b/app/Policies/VideoAuthorizePolicy.php @@ -0,0 +1,24 @@ +id === $video->user_id; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 35471f6..0ac59e3 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -1,6 +1,6 @@ 'App\Policies\ModelPolicy', + 'Soma\Model' => 'Soma\Policies\ModelPolicy', + Categories::class => CategoryAuthorizePolicy::class, + Videos::class => VideoAuthorizePolicy::class, ]; /** diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 58ce962..fb10299 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -1,6 +1,6 @@ [ - 'App\Listeners\EventListener', + 'Soma\Events\SomeEvent' => [ + 'Soma\Listeners\EventListener', ], ]; diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index d50b1c0..a0f03a7 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -1,6 +1,6 @@ hasMany('Soma\Categories'); + } + + /** + * Scope a query to only include a particular user. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeAuthorizedUser($query, $email) + { + return $query->where('email', $email); + } } diff --git a/app/Videos.php b/app/Videos.php new file mode 100644 index 0000000..4c99d29 --- /dev/null +++ b/app/Videos.php @@ -0,0 +1,38 @@ +belongsTo('Soma\Categories'); + } +} diff --git a/app/helpers.php b/app/helpers.php new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/helpers.php @@ -0,0 +1 @@ + diff --git a/bootstrap/app.php b/bootstrap/app.php index f2801ad..8038b6f 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -28,17 +28,17 @@ $app->singleton( Illuminate\Contracts\Http\Kernel::class, - App\Http\Kernel::class + Soma\Http\Kernel::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, - App\Console\Kernel::class + Soma\Console\Kernel::class ); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, - App\Exceptions\Handler::class + Soma\Exceptions\Handler::class ); /* diff --git a/build/logs/clover.xml b/build/logs/clover.xml new file mode 100644 index 0000000..cb72258 --- /dev/null +++ b/build/logs/clover.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..a5f7566 --- /dev/null +++ b/circle.yml @@ -0,0 +1,17 @@ +machine: + php: + version: 5.6.14 +deployment: + staging: + branch: master + heroku: + appname: soma-tech +dependencies: + override: + - mkdir -p build/logs + - composer install --dev --no-interaction + - sudo apt-get install php5-xdebug + - sed -i 's/^;//' ~/.phpenv/versions/$(phpenv global)/etc/conf.d/xdebug.ini +test: + post: + - php vendor/bin/coveralls \ No newline at end of file diff --git a/composer.json b/composer.json index a6ced5e..5f98041 100644 --- a/composer.json +++ b/composer.json @@ -6,20 +6,27 @@ "type": "project", "require": { "php": ">=5.5.9", - "laravel/framework": "5.1.*" + "laravel/framework": "5.1.*", + "laravel/socialite": "^2.0", + "laravelcollective/html": "5.1.*", + "uxweb/sweet-alert": "~1.1" }, "require-dev": { "fzaninotto/faker": "~1.4", "mockery/mockery": "0.9.*", "phpunit/phpunit": "~4.0", - "phpspec/phpspec": "~2.1" + "phpspec/phpspec": "~2.1", + "satooshi/php-coveralls": "^0.7.0" }, "autoload": { "classmap": [ "database" ], + "files":[ + "app/helpers.php" + ], "psr-4": { - "App\\": "app/" + "Soma\\": "app/" } }, "autoload-dev": { diff --git a/composer.lock b/composer.lock index b060b6a..c1deedb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5c6026b96e6fa11a641b51a6ba976f5e", - "content-hash": "5bd58fd976f1ee3e9611bc37c006ec46", + "hash": "44bb33a44c9ba7210e3d3e99e59d5fa9", + "content-hash": "1ff23719cd7a07bfa6d841b75d04b25c", "packages": [ { "name": "classpreloader/classpreloader", @@ -217,6 +217,272 @@ ], "time": "2015-11-06 14:35:42" }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "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": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-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": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-03-18 18:23:50" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-11-23 00:47:50" + }, + { + "name": "guzzlehttp/promises", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2015-10-15 22:28:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982", + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2015-11-03 01:34:55" + }, { "name": "jakub-onderka/php-console-color", "version": "0.1", @@ -364,16 +630,16 @@ }, { "name": "laravel/framework", - "version": "v5.1.26", + "version": "v5.1.28", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "be7fbb60376bd61f07e9c637473e5b2cf7eebe5c" + "reference": "3f0fd27939dfdafb1e50058423cd24e640894ba2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/be7fbb60376bd61f07e9c637473e5b2cf7eebe5c", - "reference": "be7fbb60376bd61f07e9c637473e5b2cf7eebe5c", + "url": "https://api.github.com/repos/laravel/framework/zipball/3f0fd27939dfdafb1e50058423cd24e640894ba2", + "reference": "3f0fd27939dfdafb1e50058423cd24e640894ba2", "shasum": "" }, "require": { @@ -419,7 +685,6 @@ "illuminate/events": "self.version", "illuminate/exception": "self.version", "illuminate/filesystem": "self.version", - "illuminate/foundation": "self.version", "illuminate/hashing": "self.version", "illuminate/http": "self.version", "illuminate/log": "self.version", @@ -489,20 +754,124 @@ "framework", "laravel" ], - "time": "2015-12-02 21:59:57" + "time": "2015-12-31 17:41:30" + }, + { + "name": "laravel/socialite", + "version": "v2.0.14", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "b15f4be0ac739405120d74b837af423aa71502d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/b15f4be0ac739405120d74b837af423aa71502d9", + "reference": "b15f4be0ac739405120d74b837af423aa71502d9", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~5.0|~6.0", + "illuminate/contracts": "~5.0", + "illuminate/http": "~5.0", + "illuminate/support": "~5.0", + "league/oauth1-client": "~1.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "keywords": [ + "laravel", + "oauth" + ], + "time": "2015-10-16 15:39:46" + }, + { + "name": "laravelcollective/html", + "version": "v5.1.9", + "source": { + "type": "git", + "url": "https://github.com/LaravelCollective/html.git", + "reference": "f62269629b2a1093039733517bd7e75b3f98dffb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/LaravelCollective/html/zipball/f62269629b2a1093039733517bd7e75b3f98dffb", + "reference": "f62269629b2a1093039733517bd7e75b3f98dffb", + "shasum": "" + }, + "require": { + "illuminate/http": "5.1.*", + "illuminate/routing": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Collective\\Html\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + }, + { + "name": "Adam Engebretson", + "email": "adam@laravelcollective.com" + } + ], + "time": "2015-11-28 08:27:09" }, { "name": "league/flysystem", - "version": "1.0.15", + "version": "1.0.16", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4" + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/31525caf9e8772683672fefd8a1ca0c0736020f4", - "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/183e1a610664baf6dcd6fceda415baf43cbdc031", + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031", "shasum": "" }, "require": { @@ -516,7 +885,7 @@ "mockery/mockery": "~0.9", "phpspec/phpspec": "^2.2", "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4.8" }, "suggest": { "ext-fileinfo": "Required for MimeType", @@ -573,7 +942,70 @@ "sftp", "storage" ], - "time": "2015-09-30 22:26:59" + "time": "2015-12-19 20:16:43" + }, + { + "name": "league/oauth1-client", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/cef3ceda13c78f89c323e4d5e6301c0eb7cea422", + "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422", + "shasum": "" + }, + "require": { + "guzzle/guzzle": "3.*", + "php": ">=5.3.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "time": "2015-10-23 04:02:07" }, { "name": "monolog/monolog", @@ -796,16 +1228,16 @@ }, { "name": "paragonie/random_compat", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "d762ee5b099a29044603cd4649851e81aa66cb47" + "reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/d762ee5b099a29044603cd4649851e81aa66cb47", - "reference": "d762ee5b099a29044603cd4649851e81aa66cb47", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/dd8998b7c846f6909f4e7a5f67fabebfc412a4f7", + "reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7", "shasum": "" }, "require": { @@ -840,7 +1272,56 @@ "pseudorandom", "random" ], - "time": "2015-12-10 14:48:13" + "time": "2016-01-06 13:31:20" + }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04 20:22:00" }, { "name": "psr/log", @@ -1007,16 +1488,16 @@ }, { "name": "symfony/console", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "16bb1cb86df43c90931df65f529e7ebd79636750" + "reference": "4e35a78f932a4c07bd349efea647ac741c1419b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/16bb1cb86df43c90931df65f529e7ebd79636750", - "reference": "16bb1cb86df43c90931df65f529e7ebd79636750", + "url": "https://api.github.com/repos/symfony/console/zipball/4e35a78f932a4c07bd349efea647ac741c1419b6", + "reference": "4e35a78f932a4c07bd349efea647ac741c1419b6", "shasum": "" }, "require": { @@ -1062,20 +1543,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2015-11-18 09:54:26" + "time": "2015-12-23 11:17:38" }, { "name": "symfony/css-selector", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f" + "reference": "35bebec48d3d08e3138257419e3ca84070152012" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/abb47717fb88aebd9437da2fc8bb01a50a36679f", - "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/35bebec48d3d08e3138257419e3ca84070152012", + "reference": "35bebec48d3d08e3138257419e3ca84070152012", "shasum": "" }, "require": { @@ -1115,20 +1596,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:10:21" + "time": "2015-12-05 17:37:09" }, { "name": "symfony/debug", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa" + "reference": "08589346bd2ec9a8eb3d935e3b1fedba9bb6463f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa", - "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa", + "url": "https://api.github.com/repos/symfony/debug/zipball/08589346bd2ec9a8eb3d935e3b1fedba9bb6463f", + "reference": "08589346bd2ec9a8eb3d935e3b1fedba9bb6463f", "shasum": "" }, "require": { @@ -1172,11 +1653,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:10:21" + "time": "2015-12-26 14:05:15" }, { "name": "symfony/dom-crawler", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -1231,7 +1712,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.0", + "version": "v2.8.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -1291,16 +1772,16 @@ }, { "name": "symfony/finder", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9" + "reference": "937edcbac3f2dd3187c56cf90368867d55dee991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a06a0c0ff7db3736a50d530c908cca547bf13da9", - "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9", + "url": "https://api.github.com/repos/symfony/finder/zipball/937edcbac3f2dd3187c56cf90368867d55dee991", + "reference": "937edcbac3f2dd3187c56cf90368867d55dee991", "shasum": "" }, "require": { @@ -1336,20 +1817,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:10:21" + "time": "2015-12-05 11:06:38" }, { "name": "symfony/http-foundation", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35" + "reference": "cf11faac7df5384bb14774ad7266add227e10ec1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e83a3d105ddaf5a113e803c904fdec552d1f1c35", - "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cf11faac7df5384bb14774ad7266add227e10ec1", + "reference": "cf11faac7df5384bb14774ad7266add227e10ec1", "shasum": "" }, "require": { @@ -1391,20 +1872,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2015-11-20 17:41:18" + "time": "2015-12-18 15:35:58" }, { "name": "symfony/http-kernel", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941" + "reference": "2dea13800e1a48710cf23a2c60c804c88e72ed57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5570de31e8fbc03777a8c61eb24f9b626e5e5941", - "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2dea13800e1a48710cf23a2c60c804c88e72ed57", + "reference": "2dea13800e1a48710cf23a2c60c804c88e72ed57", "shasum": "" }, "require": { @@ -1473,20 +1954,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2015-11-23 11:57:49" + "time": "2015-12-26 15:01:55" }, { "name": "symfony/polyfill-php56", - "version": "v1.0.0", + "version": "v1.0.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php56.git", - "reference": "a6bd4770a6967517e6610529e14afaa3111094a3" + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/a6bd4770a6967517e6610529e14afaa3111094a3", - "reference": "a6bd4770a6967517e6610529e14afaa3111094a3", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", "shasum": "" }, "require": { @@ -1529,11 +2010,11 @@ "portable", "shim" ], - "time": "2015-11-04 20:28:58" + "time": "2015-12-18 15:10:25" }, { "name": "symfony/polyfill-util", - "version": "v1.0.0", + "version": "v1.0.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-util.git", @@ -1585,16 +2066,16 @@ }, { "name": "symfony/process", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5" + "reference": "a3fb8f4c4afc4f1b285de5df07e568602934f525" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f6290983c8725d0afa29bdc3e5295879de3e58f5", - "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5", + "url": "https://api.github.com/repos/symfony/process/zipball/a3fb8f4c4afc4f1b285de5df07e568602934f525", + "reference": "a3fb8f4c4afc4f1b285de5df07e568602934f525", "shasum": "" }, "require": { @@ -1630,20 +2111,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2015-11-19 16:11:24" + "time": "2015-12-23 11:03:39" }, { "name": "symfony/routing", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe" + "reference": "2c100bd94be50e2a1fce7fe1ac534e28776c24ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/7450f6196711b124fb8b04a12286d01a0401ddfe", - "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe", + "url": "https://api.github.com/repos/symfony/routing/zipball/2c100bd94be50e2a1fce7fe1ac534e28776c24ff", + "reference": "2c100bd94be50e2a1fce7fe1ac534e28776c24ff", "shasum": "" }, "require": { @@ -1703,20 +2184,20 @@ "uri", "url" ], - "time": "2015-11-18 13:41:01" + "time": "2015-12-23 06:54:35" }, { "name": "symfony/translation", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f" + "reference": "e7e95debf0465f7886d2994cd808f9382adb423c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", - "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", + "url": "https://api.github.com/repos/symfony/translation/zipball/e7e95debf0465f7886d2994cd808f9382adb423c", + "reference": "e7e95debf0465f7886d2994cd808f9382adb423c", "shasum": "" }, "require": { @@ -1766,20 +2247,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2015-11-18 13:41:01" + "time": "2015-12-05 17:37:09" }, { "name": "symfony/var-dumper", - "version": "v2.7.7", + "version": "v2.7.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8" + "reference": "ec3233d755578c56612c13d81d4ef141f8f94e9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/72bcb27411780eaee9469729aace73c0d46fb2b8", - "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ec3233d755578c56612c13d81d4ef141f8f94e9e", + "reference": "ec3233d755578c56612c13d81d4ef141f8f94e9e", "shasum": "" }, "require": { @@ -1825,7 +2306,53 @@ "debug", "dump" ], - "time": "2015-11-18 13:41:01" + "time": "2015-12-05 10:02:55" + }, + { + "name": "uxweb/sweet-alert", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/uxweb/sweet-alert.git", + "reference": "24a963cb788357b354a861a9b96484ade0e45b56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/uxweb/sweet-alert/zipball/24a963cb788357b354a861a9b96484ade0e45b56", + "reference": "24a963cb788357b354a861a9b96484ade0e45b56", + "shasum": "" + }, + "require": { + "illuminate/session": "~5.0", + "illuminate/support": "~5.0", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "UxWeb\\SweetAlert\\": "src/SweetAlert/" + }, + "files": [ + "src/SweetAlert/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Uziel Bueno", + "email": "ux.webs@gmail.com" + } + ], + "description": "A simple PHP package to show Sweet Alerts with the Laravel Framework", + "keywords": [ + "alert", + "laravel", + "sweet" + ], + "time": "2015-12-22 05:01:51" }, { "name": "vlucas/phpdotenv", @@ -2176,16 +2703,16 @@ }, { "name": "phpspec/phpspec", - "version": "2.4.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/phpspec/phpspec.git", - "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358" + "reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/phpspec/zipball/1d3938e6d9ffb1bd4805ea8ddac62ea48767f358", - "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358", + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/5528ce1e93a1efa090c9404aba3395c329b4e6ed", + "reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed", "shasum": "" }, "require": { @@ -2250,7 +2777,7 @@ "testing", "tests" ], - "time": "2015-11-29 02:03:49" + "time": "2016-01-01 10:17:54" }, { "name": "phpspec/prophecy", @@ -2680,6 +3207,69 @@ ], "time": "2015-10-02 06:51:40" }, + { + "name": "satooshi/php-coveralls", + "version": "v0.7.1", + "source": { + "type": "git", + "url": "https://github.com/satooshi/php-coveralls.git", + "reference": "01793ce60f1e259592ac3cb7c3fc183209800127" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/01793ce60f1e259592ac3cb7c3fc183209800127", + "reference": "01793ce60f1e259592ac3cb7c3fc183209800127", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzle/guzzle": "^2.8|^3.0", + "php": ">=5.3.3", + "psr/log": "^1.0", + "symfony/config": "^2.4|^3.0", + "symfony/console": "^2.1|^3.0", + "symfony/stopwatch": "^2.2|^3.0", + "symfony/yaml": "^2.1|^3.0" + }, + "suggest": { + "symfony/http-kernel": "Allows Symfony integration" + }, + "bin": [ + "bin/coveralls" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.8-dev" + } + }, + "autoload": { + "psr-4": { + "Satooshi\\": "src/Satooshi/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/satooshi/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "time": "2015-12-17 18:04:18" + }, { "name": "sebastian/comparator", "version": "1.2.0", @@ -3051,18 +3641,166 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2015-06-21 13:59:46" }, + { + "name": "symfony/config", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "58680a6516a457a6c65044fe33586c4a81fdff01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/58680a6516a457a6c65044fe33586c4a81fdff01", + "reference": "58680a6516a457a6c65044fe33586c4a81fdff01", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2015-12-26 13:39:53" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "c2e59d11dccd135dc8f00ee97f34fe1de842e70c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/c2e59d11dccd135dc8f00ee97f34fe1de842e70c", + "reference": "c2e59d11dccd135dc8f00ee97f34fe1de842e70c", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-12-22 10:39:06" + }, + { + "name": "symfony/stopwatch", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6aeac8907e3e1340a0033b0a9ec075f8e6524800", + "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2015-10-30 23:35:59" + }, { "name": "symfony/yaml", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002" + "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", - "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3df409958a646dad2bc5046c3fb671ee24a1a691", + "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691", "shasum": "" }, "require": { @@ -3098,7 +3836,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-11-30 12:36:17" + "time": "2015-12-26 13:39:53" } ], "aliases": [], diff --git a/config/app.php b/config/app.php index 036282a..2e1885d 100644 --- a/config/app.php +++ b/config/app.php @@ -140,10 +140,12 @@ /* * Application Service Providers... */ - App\Providers\AppServiceProvider::class, - App\Providers\AuthServiceProvider::class, - App\Providers\EventServiceProvider::class, - App\Providers\RouteServiceProvider::class, + Soma\Providers\AppServiceProvider::class, + Soma\Providers\AuthServiceProvider::class, + Soma\Providers\EventServiceProvider::class, + Soma\Providers\RouteServiceProvider::class, + Laravel\Socialite\SocialiteServiceProvider::class, + Collective\Html\HtmlServiceProvider::class, ], @@ -192,6 +194,9 @@ 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, + 'Socialite' => Laravel\Socialite\Facades\Socialite::class, + 'Form' => Collective\Html\FormFacade::class, + 'Html' => Collective\Html\HtmlFacade::class, ], diff --git a/config/auth.php b/config/auth.php index 99d0630..a824000 100644 --- a/config/auth.php +++ b/config/auth.php @@ -28,7 +28,7 @@ | */ - 'model' => App\User::class, + 'model' => Soma\User::class, /* |-------------------------------------------------------------------------- diff --git a/config/database.php b/config/database.php index 66e88a9..f5f7cbc 100644 --- a/config/database.php +++ b/config/database.php @@ -48,7 +48,7 @@ 'sqlite' => [ 'driver' => 'sqlite', - 'database' => database_path('database.sqlite'), + 'database' => ':memory:', 'prefix' => '', ], diff --git a/config/services.php b/config/services.php index 93eec86..3d79e60 100644 --- a/config/services.php +++ b/config/services.php @@ -30,9 +30,21 @@ ], 'stripe' => [ - 'model' => App\User::class, + 'model' => Soma\User::class, 'key' => env('STRIPE_KEY'), 'secret' => env('STRIPE_SECRET'), ], + 'github' => [ + 'client_id' => env('GITHUB_ID'), + 'client_secret' => env('GITHUB_SECRET'), + 'redirect' => env('GITHUB_URL'), + ], + + 'google' => [ + 'client_id' => env('GOOGLE_ID'), + 'client_secret' => env('GOOGLE_SECRET'), + 'redirect' => env('GOOGLE_URL'), + ], + ]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 0876c70..e81d157 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -11,11 +11,28 @@ | */ -$factory->define(App\User::class, function (Faker\Generator $faker) { +$factory->define(Soma\User::class, function (Faker\Generator $faker) { return [ - 'name' => $faker->name, + 'name' => $faker->word, 'email' => $faker->email, - 'password' => bcrypt(str_random(10)), + 'password' => bcrypt('somasoma'), 'remember_token' => str_random(10), ]; }); + +$factory->define(Soma\Categories::class, function (Faker\Generator $faker) { + return [ + 'user_id' => factory('Soma\User')->create()->id, + 'title' => $faker->sentence, + ]; +}); + +$factory->define(Soma\Videos::class, function (Faker\Generator $faker) { + return [ + 'category_id' => factory('Soma\Categories')->create()->id, + 'user_id' => factory('Soma\User')->create()->id, + 'youtube_link' => $faker->url, + 'title' => $faker->sentence, + 'description' => $faker->paragraph, + ]; +}); diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 65d3d08..8eef6d6 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -16,9 +16,11 @@ public function up() $table->increments('id'); $table->string('name'); $table->string('email')->unique(); - $table->string('password', 60); + $table->string('password', 60)->nullable(); + $table->string('provider_id')->unique()->nullable(); + $table->string('avatar')->nullable(); $table->rememberToken(); - $table->timestamps(); + $table->nullabletimestamps(); }); } diff --git a/database/migrations/2015_12_20_144810_create_categories_table.php b/database/migrations/2015_12_20_144810_create_categories_table.php new file mode 100644 index 0000000..fe44dc9 --- /dev/null +++ b/database/migrations/2015_12_20_144810_create_categories_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->integer('user_id')->unsigned(); + $table->string('title'); + $table->timestamps(); + + $table->foreign('user_id') + ->references('id')->on('users') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('categories'); + } +} diff --git a/database/migrations/2015_12_20_144836_create_videos_table.php b/database/migrations/2015_12_20_144836_create_videos_table.php new file mode 100644 index 0000000..ad217aa --- /dev/null +++ b/database/migrations/2015_12_20_144836_create_videos_table.php @@ -0,0 +1,43 @@ +increments('id'); + $table->integer('category_id')->unsigned(); + $table->integer('user_id')->unsigned(); + $table->string('youtube_link'); + $table->string('title'); + $table->text('description'); + $table->timestamps(); + + $table->foreign('category_id') + ->references('id')->on('categories') + ->onDelete('cascade'); + + $table->foreign('user_id') + ->references('id')->on('users') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('videos'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 988ea21..494e35f 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -14,7 +14,8 @@ public function run() { Model::unguard(); - // $this->call(UserTableSeeder::class); + $this->call(UsersTableSeeder::class); + $this->call(VideosTableSeeder::class); Model::reguard(); } diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php new file mode 100644 index 0000000..011393a --- /dev/null +++ b/database/seeds/UsersTableSeeder.php @@ -0,0 +1,29 @@ +create() + ->each(function ($category) { + $category->categories()->save(factory(Soma\Categories::class)->make()); + }); + + // a social user + factory(Soma\User::class) + ->create([ + 'name' => 'Jane Doe', + 'email' => 'doe@example.com', + 'provider_id' => str_random(32), + 'avatar' => 'public/image/person_avatar.png', + ]); + } +} diff --git a/database/seeds/VideosTableSeeder.php b/database/seeds/VideosTableSeeder.php new file mode 100644 index 0000000..e944e15 --- /dev/null +++ b/database/seeds/VideosTableSeeder.php @@ -0,0 +1,26 @@ +get(); + + if (! $categories) { + $categories = factory(Soma\Categories::class, 3)->create(); + } + + foreach ($categories as $category) { + $category->videos()->save(factory(Soma\Videos::class)->create()); + } + } +} diff --git a/gulpfile.js b/gulpfile.js index dc6f1eb..abf8dc9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,5 +12,6 @@ var elixir = require('laravel-elixir'); */ elixir(function(mix) { - mix.sass('app.scss'); + mix.sass('app.scss') + .phpUnit(); }); diff --git a/phpspec.yml b/phpspec.yml index eb57939..9a486a0 100644 --- a/phpspec.yml +++ b/phpspec.yml @@ -1,5 +1,5 @@ suites: main: - namespace: App - psr4_prefix: App + namespace: Soma + psr4_prefix: Soma src_path: app \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index cc0841c..fadf229 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,12 +16,22 @@ app/ + + app/Http/Controllers/Auth/ + app/Console/ + app/Exceptions/ + app/Http/Middleware/ + + + + + diff --git a/public/avatar/images.jpeg b/public/avatar/images.jpeg new file mode 100644 index 0000000..8b2802a Binary files /dev/null and b/public/avatar/images.jpeg differ diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..515f9f3 --- /dev/null +++ b/public/css/app.css @@ -0,0 +1,2 @@ + +/*# sourceMappingURL=app.css.map */ diff --git a/public/css/app.css.map b/public/css/app.css.map new file mode 100644 index 0000000..a49f386 --- /dev/null +++ b/public/css/app.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["app.css"],"names":[],"mappings":"AAAA","file":"app.css","sourceRoot":"/source/","sourcesContent":[]} \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..bfdb0dc --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,82 @@ +#pic { + height: 50px; + line-height: 40px; + padding-top: 5px; + padding-bottom: 5px +} +.social{ + overflow: auto; +} + +.social li { + list-style-type: none; + float: left; +} + +.social li a i { + background: #205D7A; + color: #fff; + width: 40px; + height: 40px; + border-radius: 20px; + font-size: 25px; + text-align: center; + margin-right: 10px; + padding-top: 15%; +} + +.social .fa-google-plus { + background: #dd4b39; +} + +.social .fa-github { + background: #404040; +} + +.social ul li a i { + transition: all 0.2s ease-in-out; +} +.social ul li a i:hover { + opacity: .7; +} + +.navbar-color { + background: #9ad3de; +} + +body,html{ + height:100%; +} + +body { + overflow-x:hidden; +} +.sticky-footer { + min-height:100%; + margin-bottom: 100px; +} + +footer{ + height:70px; + margin-top:-70px; + background: #9ad3de; + width: 100%; +} + +.affix-top,.affix{ + position: static; +} + +@media (min-width: 979px) { + #sidebar.affix-top { + position: static; + margin-top:30px; + width:228px; + } + + #sidebar.affix { + position: fixed; + top:70px; + width:228px; + } +} diff --git a/public/css/sweetalert.css b/public/css/sweetalert.css new file mode 100755 index 0000000..76f159d --- /dev/null +++ b/public/css/sweetalert.css @@ -0,0 +1,932 @@ +body.stop-scrolling { + height: 100%; + overflow: hidden; } + +.sweet-overlay { + background-color: black; + /* IE8 */ + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + /* IE8 */ + background-color: rgba(0, 0, 0, 0.4); + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + display: none; + z-index: 10000; } + +.sweet-alert { + background-color: white; + font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + width: 478px; + padding: 17px; + border-radius: 5px; + text-align: center; + position: fixed; + left: 50%; + top: 50%; + margin-left: -256px; + margin-top: -200px; + overflow: hidden; + display: none; + z-index: 99999; } + @media all and (max-width: 540px) { + .sweet-alert { + width: auto; + margin-left: 0; + margin-right: 0; + left: 15px; + right: 15px; } } + .sweet-alert h2 { + color: #575757; + font-size: 30px; + text-align: center; + font-weight: 600; + text-transform: none; + position: relative; + margin: 25px 0; + padding: 0; + line-height: 40px; + display: block; } + .sweet-alert p { + color: #797979; + font-size: 16px; + text-align: center; + font-weight: 300; + position: relative; + text-align: inherit; + float: none; + margin: 0; + padding: 0; + line-height: normal; } + .sweet-alert fieldset { + border: none; + position: relative; } + .sweet-alert .sa-error-container { + background-color: #f1f1f1; + margin-left: -17px; + margin-right: -17px; + overflow: hidden; + padding: 0 10px; + max-height: 0; + webkit-transition: padding 0.15s, max-height 0.15s; + transition: padding 0.15s, max-height 0.15s; } + .sweet-alert .sa-error-container.show { + padding: 10px 0; + max-height: 100px; + webkit-transition: padding 0.2s, max-height 0.2s; + transition: padding 0.25s, max-height 0.25s; } + .sweet-alert .sa-error-container .icon { + display: inline-block; + width: 24px; + height: 24px; + border-radius: 50%; + background-color: #ea7d7d; + color: white; + line-height: 24px; + text-align: center; + margin-right: 3px; } + .sweet-alert .sa-error-container p { + display: inline-block; } + .sweet-alert .sa-input-error { + position: absolute; + top: 29px; + right: 26px; + width: 20px; + height: 20px; + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); + -webkit-transform-origin: 50% 50%; + transform-origin: 50% 50%; + -webkit-transition: all 0.1s; + transition: all 0.1s; } + .sweet-alert .sa-input-error::before, .sweet-alert .sa-input-error::after { + content: ""; + width: 20px; + height: 6px; + background-color: #f06e57; + border-radius: 3px; + position: absolute; + top: 50%; + margin-top: -4px; + left: 50%; + margin-left: -9px; } + .sweet-alert .sa-input-error::before { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .sa-input-error::after { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); } + .sweet-alert .sa-input-error.show { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); } + .sweet-alert input { + width: 100%; + box-sizing: border-box; + border-radius: 3px; + border: 1px solid #d7d7d7; + height: 43px; + margin-top: 10px; + margin-bottom: 17px; + font-size: 18px; + box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.06); + padding: 0 12px; + display: none; + -webkit-transition: all 0.3s; + transition: all 0.3s; } + .sweet-alert input:focus { + outline: none; + box-shadow: 0px 0px 3px #c4e6f5; + border: 1px solid #b4dbed; } + .sweet-alert input:focus::-moz-placeholder { + transition: opacity 0.3s 0.03s ease; + opacity: 0.5; } + .sweet-alert input:focus:-ms-input-placeholder { + transition: opacity 0.3s 0.03s ease; + opacity: 0.5; } + .sweet-alert input:focus::-webkit-input-placeholder { + transition: opacity 0.3s 0.03s ease; + opacity: 0.5; } + .sweet-alert input::-moz-placeholder { + color: #bdbdbd; } + .sweet-alert input:-ms-input-placeholder { + color: #bdbdbd; } + .sweet-alert input::-webkit-input-placeholder { + color: #bdbdbd; } + .sweet-alert.show-input input { + display: block; } + .sweet-alert .sa-confirm-button-container { + display: inline-block; + position: relative; } + .sweet-alert .la-ball-fall { + position: absolute; + left: 50%; + top: 50%; + margin-left: -27px; + margin-top: 4px; + opacity: 0; + visibility: hidden; } + .sweet-alert button { + background-color: #8CD4F5; + color: white; + border: none; + box-shadow: none; + font-size: 17px; + font-weight: 500; + -webkit-border-radius: 4px; + border-radius: 5px; + padding: 10px 32px; + margin: 26px 5px 0 5px; + cursor: pointer; } + .sweet-alert button:focus { + outline: none; + box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); } + .sweet-alert button:hover { + background-color: #7ecff4; } + .sweet-alert button:active { + background-color: #5dc2f1; } + .sweet-alert button.cancel { + background-color: #C1C1C1; } + .sweet-alert button.cancel:hover { + background-color: #b9b9b9; } + .sweet-alert button.cancel:active { + background-color: #a8a8a8; } + .sweet-alert button.cancel:focus { + box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; } + .sweet-alert button[disabled] { + opacity: .6; + cursor: default; } + .sweet-alert button.confirm[disabled] { + color: transparent; } + .sweet-alert button.confirm[disabled] ~ .la-ball-fall { + opacity: 1; + visibility: visible; + transition-delay: 0s; } + .sweet-alert button::-moz-focus-inner { + border: 0; } + .sweet-alert[data-has-cancel-button=false] button { + box-shadow: none !important; } + .sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false] { + padding-bottom: 40px; } + .sweet-alert .sa-icon { + width: 80px; + height: 80px; + border: 4px solid gray; + -webkit-border-radius: 40px; + border-radius: 40px; + border-radius: 50%; + margin: 20px auto; + padding: 0; + position: relative; + box-sizing: content-box; } + .sweet-alert .sa-icon.sa-error { + border-color: #F27474; } + .sweet-alert .sa-icon.sa-error .sa-x-mark { + position: relative; + display: block; } + .sweet-alert .sa-icon.sa-error .sa-line { + position: absolute; + height: 5px; + width: 47px; + background-color: #F27474; + display: block; + top: 37px; + border-radius: 2px; } + .sweet-alert .sa-icon.sa-error .sa-line.sa-left { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + left: 17px; } + .sweet-alert .sa-icon.sa-error .sa-line.sa-right { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + right: 16px; } + .sweet-alert .sa-icon.sa-warning { + border-color: #F8BB86; } + .sweet-alert .sa-icon.sa-warning .sa-body { + position: absolute; + width: 5px; + height: 47px; + left: 50%; + top: 10px; + -webkit-border-radius: 2px; + border-radius: 2px; + margin-left: -2px; + background-color: #F8BB86; } + .sweet-alert .sa-icon.sa-warning .sa-dot { + position: absolute; + width: 7px; + height: 7px; + -webkit-border-radius: 50%; + border-radius: 50%; + margin-left: -3px; + left: 50%; + bottom: 10px; + background-color: #F8BB86; } + .sweet-alert .sa-icon.sa-info { + border-color: #C9DAE1; } + .sweet-alert .sa-icon.sa-info::before { + content: ""; + position: absolute; + width: 5px; + height: 29px; + left: 50%; + bottom: 17px; + border-radius: 2px; + margin-left: -2px; + background-color: #C9DAE1; } + .sweet-alert .sa-icon.sa-info::after { + content: ""; + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: -3px; + top: 19px; + background-color: #C9DAE1; } + .sweet-alert .sa-icon.sa-success { + border-color: #A5DC86; } + .sweet-alert .sa-icon.sa-success::before, .sweet-alert .sa-icon.sa-success::after { + content: ''; + -webkit-border-radius: 40px; + border-radius: 40px; + border-radius: 50%; + position: absolute; + width: 60px; + height: 120px; + background: white; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); } + .sweet-alert .sa-icon.sa-success::before { + -webkit-border-radius: 120px 0 0 120px; + border-radius: 120px 0 0 120px; + top: -7px; + left: -33px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 60px 60px; + transform-origin: 60px 60px; } + .sweet-alert .sa-icon.sa-success::after { + -webkit-border-radius: 0 120px 120px 0; + border-radius: 0 120px 120px 0; + top: -11px; + left: 30px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 0px 60px; + transform-origin: 0px 60px; } + .sweet-alert .sa-icon.sa-success .sa-placeholder { + width: 80px; + height: 80px; + border: 4px solid rgba(165, 220, 134, 0.2); + -webkit-border-radius: 40px; + border-radius: 40px; + border-radius: 50%; + box-sizing: content-box; + position: absolute; + left: -4px; + top: -4px; + z-index: 2; } + .sweet-alert .sa-icon.sa-success .sa-fix { + width: 5px; + height: 90px; + background-color: white; + position: absolute; + left: 28px; + top: 8px; + z-index: 1; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .sa-icon.sa-success .sa-line { + height: 5px; + background-color: #A5DC86; + display: block; + border-radius: 2px; + position: absolute; + z-index: 2; } + .sweet-alert .sa-icon.sa-success .sa-line.sa-tip { + width: 25px; + left: 14px; + top: 46px; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); } + .sweet-alert .sa-icon.sa-success .sa-line.sa-long { + width: 47px; + right: 8px; + top: 38px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .sa-icon.sa-custom { + background-size: contain; + border-radius: 0; + border: none; + background-position: center center; + background-repeat: no-repeat; } + +/* + * Animations + */ +@-webkit-keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-transform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } + +@keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-transform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } + +@-webkit-keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } + +@keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } + +@-webkit-keyframes slideFromTop { + 0% { + top: 0%; } + 100% { + top: 50%; } } + +@keyframes slideFromTop { + 0% { + top: 0%; } + 100% { + top: 50%; } } + +@-webkit-keyframes slideToTop { + 0% { + top: 50%; } + 100% { + top: 0%; } } + +@keyframes slideToTop { + 0% { + top: 50%; } + 100% { + top: 0%; } } + +@-webkit-keyframes slideFromBottom { + 0% { + top: 70%; } + 100% { + top: 50%; } } + +@keyframes slideFromBottom { + 0% { + top: 70%; } + 100% { + top: 50%; } } + +@-webkit-keyframes slideToBottom { + 0% { + top: 50%; } + 100% { + top: 70%; } } + +@keyframes slideToBottom { + 0% { + top: 50%; } + 100% { + top: 70%; } } + +.showSweetAlert[data-animation=pop] { + -webkit-animation: showSweetAlert 0.3s; + animation: showSweetAlert 0.3s; } + +.showSweetAlert[data-animation=none] { + -webkit-animation: none; + animation: none; } + +.showSweetAlert[data-animation=slide-from-top] { + -webkit-animation: slideFromTop 0.3s; + animation: slideFromTop 0.3s; } + +.showSweetAlert[data-animation=slide-from-bottom] { + -webkit-animation: slideFromBottom 0.3s; + animation: slideFromBottom 0.3s; } + +.hideSweetAlert[data-animation=pop] { + -webkit-animation: hideSweetAlert 0.2s; + animation: hideSweetAlert 0.2s; } + +.hideSweetAlert[data-animation=none] { + -webkit-animation: none; + animation: none; } + +.hideSweetAlert[data-animation=slide-from-top] { + -webkit-animation: slideToTop 0.4s; + animation: slideToTop 0.4s; } + +.hideSweetAlert[data-animation=slide-from-bottom] { + -webkit-animation: slideToBottom 0.3s; + animation: slideToBottom 0.3s; } + +@-webkit-keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } + +@keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } + +@-webkit-keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } + +@keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } + +@-webkit-keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } + +@keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } + +.animateSuccessTip { + -webkit-animation: animateSuccessTip 0.75s; + animation: animateSuccessTip 0.75s; } + +.animateSuccessLong { + -webkit-animation: animateSuccessLong 0.75s; + animation: animateSuccessLong 0.75s; } + +.sa-icon.sa-success.animate::after { + -webkit-animation: rotatePlaceholder 4.25s ease-in; + animation: rotatePlaceholder 4.25s ease-in; } + +@-webkit-keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } + +@keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } + +.animateErrorIcon { + -webkit-animation: animateErrorIcon 0.5s; + animation: animateErrorIcon 0.5s; } + +@-webkit-keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } + +@keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } + +.animateXMark { + -webkit-animation: animateXMark 0.5s; + animation: animateXMark 0.5s; } + +@-webkit-keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } + +@keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } + +.pulseWarning { + -webkit-animation: pulseWarning 0.75s infinite alternate; + animation: pulseWarning 0.75s infinite alternate; } + +@-webkit-keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } + +@keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } + +.pulseWarningIns { + -webkit-animation: pulseWarningIns 0.75s infinite alternate; + animation: pulseWarningIns 0.75s infinite alternate; } + +@-webkit-keyframes rotate-loading { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } + +@keyframes rotate-loading { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } + +/* Internet Explorer 9 has some special quirks that are fixed here */ +/* The icons are not animated. */ +/* This file is automatically merged into sweet-alert.min.js through Gulp */ +/* Error icon */ +.sweet-alert .sa-icon.sa-error .sa-line.sa-left { + -ms-transform: rotate(45deg) \9; } + +.sweet-alert .sa-icon.sa-error .sa-line.sa-right { + -ms-transform: rotate(-45deg) \9; } + +/* Success icon */ +.sweet-alert .sa-icon.sa-success { + border-color: transparent\9; } + +.sweet-alert .sa-icon.sa-success .sa-line.sa-tip { + -ms-transform: rotate(45deg) \9; } + +.sweet-alert .sa-icon.sa-success .sa-line.sa-long { + -ms-transform: rotate(-45deg) \9; } + +/*! + * Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/) + * Copyright 2015 Daniel Cardoso <@DanielCardoso> + * Licensed under MIT + */ +.la-ball-fall, +.la-ball-fall > div { + position: relative; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +.la-ball-fall { + display: block; + font-size: 0; + color: #fff; } + +.la-ball-fall.la-dark { + color: #333; } + +.la-ball-fall > div { + display: inline-block; + float: none; + background-color: currentColor; + border: 0 solid currentColor; } + +.la-ball-fall { + width: 54px; + height: 18px; } + +.la-ball-fall > div { + width: 10px; + height: 10px; + margin: 4px; + border-radius: 100%; + opacity: 0; + -webkit-animation: ball-fall 1s ease-in-out infinite; + -moz-animation: ball-fall 1s ease-in-out infinite; + -o-animation: ball-fall 1s ease-in-out infinite; + animation: ball-fall 1s ease-in-out infinite; } + +.la-ball-fall > div:nth-child(1) { + -webkit-animation-delay: -200ms; + -moz-animation-delay: -200ms; + -o-animation-delay: -200ms; + animation-delay: -200ms; } + +.la-ball-fall > div:nth-child(2) { + -webkit-animation-delay: -100ms; + -moz-animation-delay: -100ms; + -o-animation-delay: -100ms; + animation-delay: -100ms; } + +.la-ball-fall > div:nth-child(3) { + -webkit-animation-delay: 0ms; + -moz-animation-delay: 0ms; + -o-animation-delay: 0ms; + animation-delay: 0ms; } + +.la-ball-fall.la-sm { + width: 26px; + height: 8px; } + +.la-ball-fall.la-sm > div { + width: 4px; + height: 4px; + margin: 2px; } + +.la-ball-fall.la-2x { + width: 108px; + height: 36px; } + +.la-ball-fall.la-2x > div { + width: 20px; + height: 20px; + margin: 8px; } + +.la-ball-fall.la-3x { + width: 162px; + height: 54px; } + +.la-ball-fall.la-3x > div { + width: 30px; + height: 30px; + margin: 12px; } + +/* + * Animation + */ +@-webkit-keyframes ball-fall { + 0% { + opacity: 0; + -webkit-transform: translateY(-145%); + transform: translateY(-145%); } + 10% { + opacity: .5; } + 20% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); } + 80% { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); } + 90% { + opacity: .5; } + 100% { + opacity: 0; + -webkit-transform: translateY(145%); + transform: translateY(145%); } } + +@-moz-keyframes ball-fall { + 0% { + opacity: 0; + -moz-transform: translateY(-145%); + transform: translateY(-145%); } + 10% { + opacity: .5; } + 20% { + opacity: 1; + -moz-transform: translateY(0); + transform: translateY(0); } + 80% { + opacity: 1; + -moz-transform: translateY(0); + transform: translateY(0); } + 90% { + opacity: .5; } + 100% { + opacity: 0; + -moz-transform: translateY(145%); + transform: translateY(145%); } } + +@-o-keyframes ball-fall { + 0% { + opacity: 0; + -o-transform: translateY(-145%); + transform: translateY(-145%); } + 10% { + opacity: .5; } + 20% { + opacity: 1; + -o-transform: translateY(0); + transform: translateY(0); } + 80% { + opacity: 1; + -o-transform: translateY(0); + transform: translateY(0); } + 90% { + opacity: .5; } + 100% { + opacity: 0; + -o-transform: translateY(145%); + transform: translateY(145%); } } + +@keyframes ball-fall { + 0% { + opacity: 0; + -webkit-transform: translateY(-145%); + -moz-transform: translateY(-145%); + -o-transform: translateY(-145%); + transform: translateY(-145%); } + 10% { + opacity: .5; } + 20% { + opacity: 1; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); } + 80% { + opacity: 1; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + transform: translateY(0); } + 90% { + opacity: .5; } + 100% { + opacity: 0; + -webkit-transform: translateY(145%); + -moz-transform: translateY(145%); + -o-transform: translateY(145%); + transform: translateY(145%); } } diff --git a/public/css/video.css b/public/css/video.css new file mode 100644 index 0000000..479624f --- /dev/null +++ b/public/css/video.css @@ -0,0 +1,70 @@ +.btn-shape { + border-radius: 30px; + margin-right: 10px; +} + +.btn-space { + border-radius: 30px; + margin-right: 40px; +} + +.vid-thumbnail h6{ + opacity: 0.7; +} + +#desc, .vid-thumbnail h6 { + color: white; +} + +.vid-thumbnail h4 { + color: #aa863a; +} + +#desc { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +#align { + min-height:200px; + overflow-y: auto; + overflow-x:hidden; +} + +.thumbnail { + padding: 0; +} + +.caption{ + background-color:rgba(0,0,0,0.7); +} +.list-scrollable { + height: 500px; + overflow: auto; +} + +.box-shadow{ + border-style:hidden; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14),0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12); +} + +#single-video{ + max-height: auto; +} + +#description { + color: white; +} + +#back-button { + bottom: 0; +} + +#video-title { + color: #aa863a; +} +.vid-thumbnail label h5 { + opacity: 0.7; + color: white; +} diff --git a/public/image/person_avatar.png b/public/image/person_avatar.png new file mode 100644 index 0000000..61b2744 Binary files /dev/null and b/public/image/person_avatar.png differ diff --git a/public/index.php b/public/index.php index c582053..fc6eb49 100644 --- a/public/index.php +++ b/public/index.php @@ -1,9 +1,8 @@ */ diff --git a/public/js/sweetalert-dev.js b/public/js/sweetalert-dev.js new file mode 100755 index 0000000..7e294b8 --- /dev/null +++ b/public/js/sweetalert-dev.js @@ -0,0 +1,1285 @@ +;(function(window, document, undefined) { + "use strict"; + + (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o call showInputError with errorMessage + */ +sweetAlert.showInputError = swal.showInputError = function (errorMessage) { + var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal(); + + var $errorIcon = modal.querySelector('.sa-input-error'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass($errorIcon, 'show'); + + var $errorContainer = modal.querySelector('.sa-error-container'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass($errorContainer, 'show'); + + $errorContainer.querySelector('p').innerHTML = errorMessage; + + setTimeout(function () { + sweetAlert.enableButtons(); + }, 1); + + modal.querySelector('input').focus(); +}; + +/* + * Reset input error DOM elements + */ +sweetAlert.resetInputError = swal.resetInputError = function (event) { + // If press enter => ignore + if (event && event.keyCode === 13) { + return false; + } + + var $modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal(); + + var $errorIcon = $modal.querySelector('.sa-input-error'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorIcon, 'show'); + + var $errorContainer = $modal.querySelector('.sa-error-container'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorContainer, 'show'); +}; + +/* + * Disable confirm and cancel buttons + */ +sweetAlert.disableButtons = swal.disableButtons = function (event) { + var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal(); + var $confirmButton = modal.querySelector('button.confirm'); + var $cancelButton = modal.querySelector('button.cancel'); + $confirmButton.disabled = true; + $cancelButton.disabled = true; +}; + +/* + * Enable confirm and cancel buttons + */ +sweetAlert.enableButtons = swal.enableButtons = function (event) { + var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal(); + var $confirmButton = modal.querySelector('button.confirm'); + var $cancelButton = modal.querySelector('button.cancel'); + $confirmButton.disabled = false; + $cancelButton.disabled = false; +}; + +if (typeof window !== 'undefined') { + // The 'handle-click' module requires + // that 'sweetAlert' was set as global. + window.sweetAlert = window.swal = sweetAlert; +} else { + _extend$hexToRgb$isIE8$logStr$colorLuminance.logStr('SweetAlert is a frontend module!'); +} +module.exports = exports['default']; + +},{"./modules/default-params":2,"./modules/handle-click":3,"./modules/handle-dom":4,"./modules/handle-key":5,"./modules/handle-swal-dom":6,"./modules/set-params":8,"./modules/utils":9}],2:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +var defaultParams = { + title: '', + text: '', + type: null, + allowOutsideClick: false, + showConfirmButton: true, + showCancelButton: false, + closeOnConfirm: true, + closeOnCancel: true, + confirmButtonText: 'OK', + confirmButtonColor: '#8CD4F5', + cancelButtonText: 'Cancel', + imageUrl: null, + imageSize: null, + timer: null, + customClass: '', + html: false, + animation: true, + allowEscapeKey: true, + inputType: 'text', + inputPlaceholder: '', + inputValue: '', + showLoaderOnConfirm: false +}; + +exports['default'] = defaultParams; +module.exports = exports['default']; + +},{}],3:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _colorLuminance = require('./utils'); + +var _getModal = require('./handle-swal-dom'); + +var _hasClass$isDescendant = require('./handle-dom'); + +/* + * User clicked on "Confirm"/"OK" or "Cancel" + */ +var handleButton = function handleButton(event, params, modal) { + var e = event || window.event; + var target = e.target || e.srcElement; + + var targetedConfirm = target.className.indexOf('confirm') !== -1; + var targetedOverlay = target.className.indexOf('sweet-overlay') !== -1; + var modalIsVisible = _hasClass$isDescendant.hasClass(modal, 'visible'); + var doneFunctionExists = params.doneFunction && modal.getAttribute('data-has-done-function') === 'true'; + + // Since the user can change the background-color of the confirm button programmatically, + // we must calculate what the color should be on hover/active + var normalColor, hoverColor, activeColor; + if (targetedConfirm && params.confirmButtonColor) { + normalColor = params.confirmButtonColor; + hoverColor = _colorLuminance.colorLuminance(normalColor, -0.04); + activeColor = _colorLuminance.colorLuminance(normalColor, -0.14); + } + + function shouldSetConfirmButtonColor(color) { + if (targetedConfirm && params.confirmButtonColor) { + target.style.backgroundColor = color; + } + } + + switch (e.type) { + case 'mouseover': + shouldSetConfirmButtonColor(hoverColor); + break; + + case 'mouseout': + shouldSetConfirmButtonColor(normalColor); + break; + + case 'mousedown': + shouldSetConfirmButtonColor(activeColor); + break; + + case 'mouseup': + shouldSetConfirmButtonColor(hoverColor); + break; + + case 'focus': + var $confirmButton = modal.querySelector('button.confirm'); + var $cancelButton = modal.querySelector('button.cancel'); + + if (targetedConfirm) { + $cancelButton.style.boxShadow = 'none'; + } else { + $confirmButton.style.boxShadow = 'none'; + } + break; + + case 'click': + var clickedOnModal = modal === target; + var clickedOnModalChild = _hasClass$isDescendant.isDescendant(modal, target); + + // Ignore click outside if allowOutsideClick is false + if (!clickedOnModal && !clickedOnModalChild && modalIsVisible && !params.allowOutsideClick) { + break; + } + + if (targetedConfirm && doneFunctionExists && modalIsVisible) { + handleConfirm(modal, params); + } else if (doneFunctionExists && modalIsVisible || targetedOverlay) { + handleCancel(modal, params); + } else if (_hasClass$isDescendant.isDescendant(modal, target) && target.tagName === 'BUTTON') { + sweetAlert.close(); + } + break; + } +}; + +/* + * User clicked on "Confirm"/"OK" + */ +var handleConfirm = function handleConfirm(modal, params) { + var callbackValue = true; + + if (_hasClass$isDescendant.hasClass(modal, 'show-input')) { + callbackValue = modal.querySelector('input').value; + + if (!callbackValue) { + callbackValue = ''; + } + } + + params.doneFunction(callbackValue); + + if (params.closeOnConfirm) { + sweetAlert.close(); + } + // Disable cancel and confirm button if the parameter is true + if (params.showLoaderOnConfirm) { + sweetAlert.disableButtons(); + } +}; + +/* + * User clicked on "Cancel" + */ +var handleCancel = function handleCancel(modal, params) { + // Check if callback function expects a parameter (to track cancel actions) + var functionAsStr = String(params.doneFunction).replace(/\s/g, ''); + var functionHandlesCancel = functionAsStr.substring(0, 9) === 'function(' && functionAsStr.substring(9, 10) !== ')'; + + if (functionHandlesCancel) { + params.doneFunction(false); + } + + if (params.closeOnCancel) { + sweetAlert.close(); + } +}; + +exports['default'] = { + handleButton: handleButton, + handleConfirm: handleConfirm, + handleCancel: handleCancel +}; +module.exports = exports['default']; + +},{"./handle-dom":4,"./handle-swal-dom":6,"./utils":9}],4:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +var hasClass = function hasClass(elem, className) { + return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' '); +}; + +var addClass = function addClass(elem, className) { + if (!hasClass(elem, className)) { + elem.className += ' ' + className; + } +}; + +var removeClass = function removeClass(elem, className) { + var newClass = ' ' + elem.className.replace(/[\t\r\n]/g, ' ') + ' '; + if (hasClass(elem, className)) { + while (newClass.indexOf(' ' + className + ' ') >= 0) { + newClass = newClass.replace(' ' + className + ' ', ' '); + } + elem.className = newClass.replace(/^\s+|\s+$/g, ''); + } +}; + +var escapeHtml = function escapeHtml(str) { + var div = document.createElement('div'); + div.appendChild(document.createTextNode(str)); + return div.innerHTML; +}; + +var _show = function _show(elem) { + elem.style.opacity = ''; + elem.style.display = 'block'; +}; + +var show = function show(elems) { + if (elems && !elems.length) { + return _show(elems); + } + for (var i = 0; i < elems.length; ++i) { + _show(elems[i]); + } +}; + +var _hide = function _hide(elem) { + elem.style.opacity = ''; + elem.style.display = 'none'; +}; + +var hide = function hide(elems) { + if (elems && !elems.length) { + return _hide(elems); + } + for (var i = 0; i < elems.length; ++i) { + _hide(elems[i]); + } +}; + +var isDescendant = function isDescendant(parent, child) { + var node = child.parentNode; + while (node !== null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; +}; + +var getTopMargin = function getTopMargin(elem) { + elem.style.left = '-9999px'; + elem.style.display = 'block'; + + var height = elem.clientHeight, + padding; + if (typeof getComputedStyle !== 'undefined') { + // IE 8 + padding = parseInt(getComputedStyle(elem).getPropertyValue('padding-top'), 10); + } else { + padding = parseInt(elem.currentStyle.padding); + } + + elem.style.left = ''; + elem.style.display = 'none'; + return '-' + parseInt((height + padding) / 2) + 'px'; +}; + +var fadeIn = function fadeIn(elem, interval) { + if (+elem.style.opacity < 1) { + interval = interval || 16; + elem.style.opacity = 0; + elem.style.display = 'block'; + var last = +new Date(); + var tick = (function (_tick) { + function tick() { + return _tick.apply(this, arguments); + } + + tick.toString = function () { + return _tick.toString(); + }; + + return tick; + })(function () { + elem.style.opacity = +elem.style.opacity + (new Date() - last) / 100; + last = +new Date(); + + if (+elem.style.opacity < 1) { + setTimeout(tick, interval); + } + }); + tick(); + } + elem.style.display = 'block'; //fallback IE8 +}; + +var fadeOut = function fadeOut(elem, interval) { + interval = interval || 16; + elem.style.opacity = 1; + var last = +new Date(); + var tick = (function (_tick2) { + function tick() { + return _tick2.apply(this, arguments); + } + + tick.toString = function () { + return _tick2.toString(); + }; + + return tick; + })(function () { + elem.style.opacity = +elem.style.opacity - (new Date() - last) / 100; + last = +new Date(); + + if (+elem.style.opacity > 0) { + setTimeout(tick, interval); + } else { + elem.style.display = 'none'; + } + }); + tick(); +}; + +var fireClick = function fireClick(node) { + // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/ + // Then fixed for today's Chrome browser. + if (typeof MouseEvent === 'function') { + // Up-to-date approach + var mevt = new MouseEvent('click', { + view: window, + bubbles: false, + cancelable: true + }); + node.dispatchEvent(mevt); + } else if (document.createEvent) { + // Fallback + var evt = document.createEvent('MouseEvents'); + evt.initEvent('click', false, false); + node.dispatchEvent(evt); + } else if (document.createEventObject) { + node.fireEvent('onclick'); + } else if (typeof node.onclick === 'function') { + node.onclick(); + } +}; + +var stopEventPropagation = function stopEventPropagation(e) { + // In particular, make sure the space bar doesn't scroll the main window. + if (typeof e.stopPropagation === 'function') { + e.stopPropagation(); + e.preventDefault(); + } else if (window.event && window.event.hasOwnProperty('cancelBubble')) { + window.event.cancelBubble = true; + } +}; + +exports.hasClass = hasClass; +exports.addClass = addClass; +exports.removeClass = removeClass; +exports.escapeHtml = escapeHtml; +exports._show = _show; +exports.show = show; +exports._hide = _hide; +exports.hide = hide; +exports.isDescendant = isDescendant; +exports.getTopMargin = getTopMargin; +exports.fadeIn = fadeIn; +exports.fadeOut = fadeOut; +exports.fireClick = fireClick; +exports.stopEventPropagation = stopEventPropagation; + +},{}],5:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _stopEventPropagation$fireClick = require('./handle-dom'); + +var _setFocusStyle = require('./handle-swal-dom'); + +var handleKeyDown = function handleKeyDown(event, params, modal) { + var e = event || window.event; + var keyCode = e.keyCode || e.which; + + var $okButton = modal.querySelector('button.confirm'); + var $cancelButton = modal.querySelector('button.cancel'); + var $modalButtons = modal.querySelectorAll('button[tabindex]'); + + if ([9, 13, 32, 27].indexOf(keyCode) === -1) { + // Don't do work on keys we don't care about. + return; + } + + var $targetElement = e.target || e.srcElement; + + var btnIndex = -1; // Find the button - note, this is a nodelist, not an array. + for (var i = 0; i < $modalButtons.length; i++) { + if ($targetElement === $modalButtons[i]) { + btnIndex = i; + break; + } + } + + if (keyCode === 9) { + // TAB + if (btnIndex === -1) { + // No button focused. Jump to the confirm button. + $targetElement = $okButton; + } else { + // Cycle to the next button + if (btnIndex === $modalButtons.length - 1) { + $targetElement = $modalButtons[0]; + } else { + $targetElement = $modalButtons[btnIndex + 1]; + } + } + + _stopEventPropagation$fireClick.stopEventPropagation(e); + $targetElement.focus(); + + if (params.confirmButtonColor) { + _setFocusStyle.setFocusStyle($targetElement, params.confirmButtonColor); + } + } else { + if (keyCode === 13) { + if ($targetElement.tagName === 'INPUT') { + $targetElement = $okButton; + $okButton.focus(); + } + + if (btnIndex === -1) { + // ENTER/SPACE clicked outside of a button. + $targetElement = $okButton; + } else { + // Do nothing - let the browser handle it. + $targetElement = undefined; + } + } else if (keyCode === 27 && params.allowEscapeKey === true) { + $targetElement = $cancelButton; + _stopEventPropagation$fireClick.fireClick($targetElement, e); + } else { + // Fallback - let the browser handle it. + $targetElement = undefined; + } + } +}; + +exports['default'] = handleKeyDown; +module.exports = exports['default']; + +},{"./handle-dom":4,"./handle-swal-dom":6}],6:[function(require,module,exports){ +'use strict'; + +var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _hexToRgb = require('./utils'); + +var _removeClass$getTopMargin$fadeIn$show$addClass = require('./handle-dom'); + +var _defaultParams = require('./default-params'); + +var _defaultParams2 = _interopRequireWildcard(_defaultParams); + +/* + * Add modal + overlay to DOM + */ + +var _injectedHTML = require('./injected-html'); + +var _injectedHTML2 = _interopRequireWildcard(_injectedHTML); + +var modalClass = '.sweet-alert'; +var overlayClass = '.sweet-overlay'; + +var sweetAlertInitialize = function sweetAlertInitialize() { + var sweetWrap = document.createElement('div'); + sweetWrap.innerHTML = _injectedHTML2['default']; + + // Append elements to body + while (sweetWrap.firstChild) { + document.body.appendChild(sweetWrap.firstChild); + } +}; + +/* + * Get DOM element of modal + */ +var getModal = (function (_getModal) { + function getModal() { + return _getModal.apply(this, arguments); + } + + getModal.toString = function () { + return _getModal.toString(); + }; + + return getModal; +})(function () { + var $modal = document.querySelector(modalClass); + + if (!$modal) { + sweetAlertInitialize(); + $modal = getModal(); + } + + return $modal; +}); + +/* + * Get DOM element of input (in modal) + */ +var getInput = function getInput() { + var $modal = getModal(); + if ($modal) { + return $modal.querySelector('input'); + } +}; + +/* + * Get DOM element of overlay + */ +var getOverlay = function getOverlay() { + return document.querySelector(overlayClass); +}; + +/* + * Add box-shadow style to button (depending on its chosen bg-color) + */ +var setFocusStyle = function setFocusStyle($button, bgColor) { + var rgbColor = _hexToRgb.hexToRgb(bgColor); + $button.style.boxShadow = '0 0 2px rgba(' + rgbColor + ', 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)'; +}; + +/* + * Animation when opening modal + */ +var openModal = function openModal(callback) { + var $modal = getModal(); + _removeClass$getTopMargin$fadeIn$show$addClass.fadeIn(getOverlay(), 10); + _removeClass$getTopMargin$fadeIn$show$addClass.show($modal); + _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'showSweetAlert'); + _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'hideSweetAlert'); + + window.previousActiveElement = document.activeElement; + var $okButton = $modal.querySelector('button.confirm'); + $okButton.focus(); + + setTimeout(function () { + _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'visible'); + }, 500); + + var timer = $modal.getAttribute('data-timer'); + + if (timer !== 'null' && timer !== '') { + var timerCallback = callback; + $modal.timeout = setTimeout(function () { + var doneFunctionExists = (timerCallback || null) && $modal.getAttribute('data-has-done-function') === 'true'; + if (doneFunctionExists) { + timerCallback(null); + } else { + sweetAlert.close(); + } + }, timer); + } +}; + +/* + * Reset the styling of the input + * (for example if errors have been shown) + */ +var resetInput = function resetInput() { + var $modal = getModal(); + var $input = getInput(); + + _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'show-input'); + $input.value = _defaultParams2['default'].inputValue; + $input.setAttribute('type', _defaultParams2['default'].inputType); + $input.setAttribute('placeholder', _defaultParams2['default'].inputPlaceholder); + + resetInputError(); +}; + +var resetInputError = function resetInputError(event) { + // If press enter => ignore + if (event && event.keyCode === 13) { + return false; + } + + var $modal = getModal(); + + var $errorIcon = $modal.querySelector('.sa-input-error'); + _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorIcon, 'show'); + + var $errorContainer = $modal.querySelector('.sa-error-container'); + _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorContainer, 'show'); +}; + +/* + * Set "margin-top"-property on modal based on its computed height + */ +var fixVerticalPosition = function fixVerticalPosition() { + var $modal = getModal(); + $modal.style.marginTop = _removeClass$getTopMargin$fadeIn$show$addClass.getTopMargin(getModal()); +}; + +exports.sweetAlertInitialize = sweetAlertInitialize; +exports.getModal = getModal; +exports.getOverlay = getOverlay; +exports.getInput = getInput; +exports.setFocusStyle = setFocusStyle; +exports.openModal = openModal; +exports.resetInput = resetInput; +exports.resetInputError = resetInputError; +exports.fixVerticalPosition = fixVerticalPosition; + +},{"./default-params":2,"./handle-dom":4,"./injected-html":7,"./utils":9}],7:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var injectedHTML = + +// Dark overlay +"
" + + +// Modal +"
" + + +// Error icon +"
\n \n \n \n \n
" + + +// Warning icon +"
\n \n \n
" + + +// Info icon +"
" + + +// Success icon +"
\n \n \n\n
\n
\n
" + "
" + + +// Title, text and input +"

Title

\n

Text

\n
\n \n
\n
" + + +// Input errors +"
\n
!
\n

Not valid!

\n
" + + +// Cancel and confirm buttons +"
\n \n
\n " + + +// Loading animation +"
\n
\n
\n
\n
\n
\n
" + + +// End of modal +"
"; + +exports["default"] = injectedHTML; +module.exports = exports["default"]; + +},{}],8:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _isIE8 = require('./utils'); + +var _getModal$getInput$setFocusStyle = require('./handle-swal-dom'); + +var _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide = require('./handle-dom'); + +var alertTypes = ['error', 'warning', 'info', 'success', 'input', 'prompt']; + +/* + * Set type, text and actions on modal + */ +var setParameters = function setParameters(params) { + var modal = _getModal$getInput$setFocusStyle.getModal(); + + var $title = modal.querySelector('h2'); + var $text = modal.querySelector('p'); + var $cancelBtn = modal.querySelector('button.cancel'); + var $confirmBtn = modal.querySelector('button.confirm'); + + /* + * Title + */ + $title.innerHTML = params.html ? params.title : _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.title).split('\n').join('
'); + + /* + * Text + */ + $text.innerHTML = params.html ? params.text : _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.text || '').split('\n').join('
'); + if (params.text) _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($text); + + /* + * Custom class + */ + if (params.customClass) { + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass(modal, params.customClass); + modal.setAttribute('data-custom-class', params.customClass); + } else { + // Find previously set classes and remove them + var customClass = modal.getAttribute('data-custom-class'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.removeClass(modal, customClass); + modal.setAttribute('data-custom-class', ''); + } + + /* + * Icon + */ + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide(modal.querySelectorAll('.sa-icon')); + + if (params.type && !_isIE8.isIE8()) { + var _ret = (function () { + + var validType = false; + + for (var i = 0; i < alertTypes.length; i++) { + if (params.type === alertTypes[i]) { + validType = true; + break; + } + } + + if (!validType) { + logStr('Unknown alert type: ' + params.type); + return { + v: false + }; + } + + var typesWithIcons = ['success', 'error', 'warning', 'info']; + var $icon = undefined; + + if (typesWithIcons.indexOf(params.type) !== -1) { + $icon = modal.querySelector('.sa-icon.' + 'sa-' + params.type); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($icon); + } + + var $input = _getModal$getInput$setFocusStyle.getInput(); + + // Animate icon + switch (params.type) { + + case 'success': + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'animate'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-tip'), 'animateSuccessTip'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-long'), 'animateSuccessLong'); + break; + + case 'error': + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'animateErrorIcon'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-x-mark'), 'animateXMark'); + break; + + case 'warning': + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'pulseWarning'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-body'), 'pulseWarningIns'); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-dot'), 'pulseWarningIns'); + break; + + case 'input': + case 'prompt': + $input.setAttribute('type', params.inputType); + $input.value = params.inputValue; + $input.setAttribute('placeholder', params.inputPlaceholder); + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass(modal, 'show-input'); + setTimeout(function () { + $input.focus(); + $input.addEventListener('keyup', swal.resetInputError); + }, 400); + break; + } + })(); + + if (typeof _ret === 'object') { + return _ret.v; + } + } + + /* + * Custom image + */ + if (params.imageUrl) { + var $customIcon = modal.querySelector('.sa-icon.sa-custom'); + + $customIcon.style.backgroundImage = 'url(' + params.imageUrl + ')'; + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($customIcon); + + var _imgWidth = 80; + var _imgHeight = 80; + + if (params.imageSize) { + var dimensions = params.imageSize.toString().split('x'); + var imgWidth = dimensions[0]; + var imgHeight = dimensions[1]; + + if (!imgWidth || !imgHeight) { + logStr('Parameter imageSize expects value with format WIDTHxHEIGHT, got ' + params.imageSize); + } else { + _imgWidth = imgWidth; + _imgHeight = imgHeight; + } + } + + $customIcon.setAttribute('style', $customIcon.getAttribute('style') + 'width:' + _imgWidth + 'px; height:' + _imgHeight + 'px'); + } + + /* + * Show cancel button? + */ + modal.setAttribute('data-has-cancel-button', params.showCancelButton); + if (params.showCancelButton) { + $cancelBtn.style.display = 'inline-block'; + } else { + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide($cancelBtn); + } + + /* + * Show confirm button? + */ + modal.setAttribute('data-has-confirm-button', params.showConfirmButton); + if (params.showConfirmButton) { + $confirmBtn.style.display = 'inline-block'; + } else { + _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide($confirmBtn); + } + + /* + * Custom text on cancel/confirm buttons + */ + if (params.cancelButtonText) { + $cancelBtn.innerHTML = _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.cancelButtonText); + } + if (params.confirmButtonText) { + $confirmBtn.innerHTML = _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.confirmButtonText); + } + + /* + * Custom color on confirm button + */ + if (params.confirmButtonColor) { + // Set confirm button to selected background color + $confirmBtn.style.backgroundColor = params.confirmButtonColor; + + // Set the confirm button color to the loading ring + $confirmBtn.style.borderLeftColor = params.confirmLoadingButtonColor; + $confirmBtn.style.borderRightColor = params.confirmLoadingButtonColor; + + // Set box-shadow to default focused button + _getModal$getInput$setFocusStyle.setFocusStyle($confirmBtn, params.confirmButtonColor); + } + + /* + * Allow outside click + */ + modal.setAttribute('data-allow-outside-click', params.allowOutsideClick); + + /* + * Callback function + */ + var hasDoneFunction = params.doneFunction ? true : false; + modal.setAttribute('data-has-done-function', hasDoneFunction); + + /* + * Animation + */ + if (!params.animation) { + modal.setAttribute('data-animation', 'none'); + } else if (typeof params.animation === 'string') { + modal.setAttribute('data-animation', params.animation); // Custom animation + } else { + modal.setAttribute('data-animation', 'pop'); + } + + /* + * Timer + */ + modal.setAttribute('data-timer', params.timer); +}; + +exports['default'] = setParameters; +module.exports = exports['default']; + +},{"./handle-dom":4,"./handle-swal-dom":6,"./utils":9}],9:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +/* + * Allow user to pass their own params + */ +var extend = function extend(a, b) { + for (var key in b) { + if (b.hasOwnProperty(key)) { + a[key] = b[key]; + } + } + return a; +}; + +/* + * Convert HEX codes to RGB values (#000000 -> rgb(0,0,0)) + */ +var hexToRgb = function hexToRgb(hex) { + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) : null; +}; + +/* + * Check if the user is using Internet Explorer 8 (for fallbacks) + */ +var isIE8 = function isIE8() { + return window.attachEvent && !window.addEventListener; +}; + +/* + * IE compatible logging for developers + */ +var logStr = function logStr(string) { + if (window.console) { + // IE... + window.console.log('SweetAlert: ' + string); + } +}; + +/* + * Set hover, active and focus-states for buttons + * (source: http://www.sitepoint.com/javascript-generate-lighter-darker-color) + */ +var colorLuminance = function colorLuminance(hex, lum) { + // Validate hex string + hex = String(hex).replace(/[^0-9a-f]/gi, ''); + if (hex.length < 6) { + hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + } + lum = lum || 0; + + // Convert to decimal and change luminosity + var rgb = '#'; + var c; + var i; + + for (i = 0; i < 3; i++) { + c = parseInt(hex.substr(i * 2, 2), 16); + c = Math.round(Math.min(Math.max(0, c + c * lum), 255)).toString(16); + rgb += ('00' + c).substr(c.length); + } + + return rgb; +}; + +exports.extend = extend; +exports.hexToRgb = hexToRgb; +exports.isIE8 = isIE8; +exports.logStr = logStr; +exports.colorLuminance = colorLuminance; + +},{}]},{},[1]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvc3dlZXRhbGVydC5lczYuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy9kZWZhdWx0LXBhcmFtcy5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL2hhbmRsZS1jbGljay5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL2hhbmRsZS1kb20uanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy9oYW5kbGUta2V5LmpzIiwiL1VzZXJzL1RyaXN0YW4vZGV2L1N3ZWV0QWxlcnQvZGV2L21vZHVsZXMvaGFuZGxlLXN3YWwtZG9tLmpzIiwiL1VzZXJzL1RyaXN0YW4vZGV2L1N3ZWV0QWxlcnQvZGV2L21vZHVsZXMvaW5qZWN0ZWQtaHRtbC5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL3NldC1wYXJhbXMuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy91dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztzSkNnQk8sc0JBQXNCOzs7Ozs7MkRBV3RCLGlCQUFpQjs7Ozs7O3dIQWNqQiwyQkFBMkI7Ozs7dURBSXdCLHdCQUF3Qjs7NkJBQ3hELHNCQUFzQjs7Ozs7OzZCQUl0QiwwQkFBMEI7Ozs7NkJBQzFCLHNCQUFzQjs7Ozs7Ozs7QUFNaEQsSUFBSSxxQkFBcUIsQ0FBQztBQUMxQixJQUFJLGlCQUFpQixDQUFDOzs7Ozs7QUFPdEIsSUFBSSxVQUFVLEVBQUUsSUFBSSxDQUFDOztxQkFFTixVQUFVLEdBQUcsSUFBSSxHQUFHLFlBQVc7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RyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JFLE9BQUcsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUEsQ0FBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0dBQ3BDOztBQUVELFNBQU8sR0FBRyxDQUFDO0NBQ1osQ0FBQzs7UUFJQSxNQUFNLEdBQU4sTUFBTTtRQUNOLFFBQVEsR0FBUixRQUFRO1FBQ1IsS0FBSyxHQUFMLEtBQUs7UUFDTCxNQUFNLEdBQU4sTUFBTTtRQUNOLGNBQWMsR0FBZCxjQUFjIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8vIFN3ZWV0QWxlcnRcbi8vIDIwMTQtMjAxNSAoYykgLSBUcmlzdGFuIEVkd2FyZHNcbi8vIGdpdGh1Yi5jb20vdDR0NS9zd2VldGFsZXJ0XG5cbi8qXG4gKiBqUXVlcnktbGlrZSBmdW5jdGlvbnMgZm9yIG1hbmlwdWxhdGluZyB0aGUgRE9NXG4gKi9cbmltcG9ydCB7XG4gIGhhc0NsYXNzLCBhZGRDbGFzcywgcmVtb3ZlQ2xhc3MsXG4gIGVzY2FwZUh0bWwsXG4gIF9zaG93LCBzaG93LCBfaGlkZSwgaGlkZSxcbiAgaXNEZXNjZW5kYW50LFxuICBnZXRUb3BNYXJnaW4sXG4gIGZhZGVJbiwgZmFkZU91dCxcbiAgZmlyZUNsaWNrLFxuICBzdG9wRXZlbnRQcm9wYWdhdGlvblxufSBmcm9tICcuL21vZHVsZXMvaGFuZGxlLWRvbSc7XG5cbi8qXG4gKiBIYW5keSB1dGlsaXRpZXNcbiAqL1xuaW1wb3J0IHtcbiAgZXh0ZW5kLFxuICBoZXhUb1JnYixcbiAgaXNJRTgsXG4gIGxvZ1N0cixcbiAgY29sb3JMdW1pbmFuY2Vcbn0gZnJvbSAnLi9tb2R1bGVzL3V0aWxzJztcblxuLypcbiAqICBIYW5kbGUgc3dlZXRBbGVydCdzIERPTSBlbGVtZW50c1xuICovXG5pbXBvcnQge1xuICBzd2VldEFsZXJ0SW5pdGlhbGl6ZSxcbiAgZ2V0TW9kYWwsXG4gIGdldE92ZXJsYXksXG4gIGdldElucHV0LFxuICBzZXRGb2N1c1N0eWxlLFxuICBvcGVuTW9kYWwsXG4gIHJlc2V0SW5wdXQsXG4gIGZpeFZlcnRpY2FsUG9zaXRpb25cbn0gZnJvbSAnLi9tb2R1bGVzL2hhbmRsZS1zd2FsLWRvbSc7XG5cblxuLy8gSGFuZGxlIGJ1dHRvbiBldmVudHMgYW5kIGtleWJvYXJkIGV2ZW50c1xuaW1wb3J0IHsgaGFuZGxlQnV0dG9uLCBoYW5kbGVDb25maXJtLCBoYW5kbGVDYW5jZWwgfSBmcm9tICcuL21vZHVsZXMvaGFuZGxlLWNsaWNrJztcbmltcG9ydCBoYW5kbGVLZXlEb3duIGZyb20gJy4vbW9kdWxlcy9oYW5kbGUta2V5JztcblxuXG4vLyBEZWZhdWx0IHZhbHVlc1xuaW1wb3J0IGRlZmF1bHRQYXJhbXMgZnJvbSAnLi9tb2R1bGVzL2RlZmF1bHQtcGFyYW1zJztcbmltcG9ydCBzZXRQYXJhbWV0ZXJzIGZyb20gJy4vbW9kdWxlcy9zZXQtcGFyYW1zJztcblxuLypcbiAqIFJlbWVtYmVyIHN0YXRlIGluIGNhc2VzIHdoZXJlIG9wZW5pbmcgYW5kIGhhbmRsaW5nIGEgbW9kYWwgd2lsbCBmaWRkbGUgd2l0aCBpdC5cbiAqIChXZSBhbHNvIHVzZSB3aW5kb3cucHJldmlvdXNBY3RpdmVFbGVtZW50IGFzIGEgZ2xvYmFsIHZhcmlhYmxlKVxuICovXG52YXIgcHJldmlvdXNXaW5kb3dLZXlEb3duO1xudmFyIGxhc3RGb2N1c2VkQnV0dG9uO1xuXG5cbi8qXG4gKiBHbG9iYWwgc3dlZXRBbGVydCBmdW5jdGlvblxuICogKHRoaXMgaXMgd2hhdCB0aGUgdXNlciBjYWxscylcbiAqL1xudmFyIHN3ZWV0QWxlcnQsIHN3YWw7XG5cbmV4cG9ydCBkZWZhdWx0IHN3ZWV0QWxlcnQgPSBzd2FsID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjdXN0b21pemF0aW9ucyA9IGFyZ3VtZW50c1swXTtcblxuICBhZGRDbGFzcyhkb2N1bWVudC5ib2R5LCAnc3RvcC1zY3JvbGxpbmcnKTtcbiAgcmVzZXRJbnB1dCgpO1xuXG4gIC8qXG4gICAqIFVzZSBhcmd1bWVudCBpZiBkZWZpbmVkIG9yIGRlZmF1bHQgdmFsdWUgZnJvbSBwYXJhbXMgb2JqZWN0IG90aGVyd2lzZS5cbiAgICogU3VwcG9ydHMgdGhlIGNhc2Ugd2hlcmUgYSBkZWZhdWx0IHZhbHVlIGlzIGJvb2xlYW4gdHJ1ZSBhbmQgc2hvdWxkIGJlXG4gICAqIG92ZXJyaWRkZW4gYnkgYSBjb3JyZXNwb25kaW5nIGV4cGxpY2l0IGFyZ3VtZW50IHdoaWNoIGlzIGJvb2xlYW4gZmFsc2UuXG4gICAqL1xuICBmdW5jdGlvbiBhcmd1bWVudE9yRGVmYXVsdChrZXkpIHtcbiAgICB2YXIgYXJncyA9IGN1c3RvbWl6YXRpb25zO1xuICAgIHJldHVybiAoYXJnc1trZXldID09PSB1bmRlZmluZWQpID8gIGRlZmF1bHRQYXJhbXNba2V5XSA6IGFyZ3Nba2V5XTtcbiAgfVxuXG4gIGlmIChjdXN0b21pemF0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbG9nU3RyKCdTd2VldEFsZXJ0IGV4cGVjdHMgYXQgbGVhc3QgMSBhdHRyaWJ1dGUhJyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHBhcmFtcyA9IGV4dGVuZCh7fSwgZGVmYXVsdFBhcmFtcyk7XG5cbiAgc3dpdGNoICh0eXBlb2YgY3VzdG9taXphdGlvbnMpIHtcblxuICAgIC8vIEV4OiBzd2FsKFwiSGVsbG9cIiwgXCJKdXN0IHRlc3RpbmdcIiwgXCJpbmZvXCIpO1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBwYXJhbXMudGl0bGUgPSBjdXN0b21pemF0aW9ucztcbiAgICAgIHBhcmFtcy50ZXh0ICA9IGFyZ3VtZW50c1sxXSB8fCAnJztcbiAgICAgIHBhcmFtcy50eXBlICA9IGFyZ3VtZW50c1syXSB8fCAnJztcbiAgICAgIGJyZWFrO1xuXG4gICAgLy8gRXg6IHN3YWwoeyB0aXRsZTpcIkhlbGxvXCIsIHRleHQ6IFwiSnVzdCB0ZXN0aW5nXCIsIHR5cGU6IFwiaW5mb1wiIH0pO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoY3VzdG9taXphdGlvbnMudGl0bGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb2dTdHIoJ01pc3NpbmcgXCJ0aXRsZVwiIGFyZ3VtZW50IScpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHBhcmFtcy50aXRsZSA9IGN1c3RvbWl6YXRpb25zLnRpdGxlO1xuXG4gICAgICBmb3IgKGxldCBjdXN0b21OYW1lIGluIGRlZmF1bHRQYXJhbXMpIHtcbiAgICAgICAgcGFyYW1zW2N1c3RvbU5hbWVdID0gYXJndW1lbnRPckRlZmF1bHQoY3VzdG9tTmFtZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgXCJDb25maXJtXCIgaW5zdGVhZCBvZiBcIk9LXCIgaWYgY2FuY2VsIGJ1dHRvbiBpcyB2aXNpYmxlXG4gICAgICBwYXJhbXMuY29uZmlybUJ1dHRvblRleHQgPSBwYXJhbXMuc2hvd0NhbmNlbEJ1dHRvbiA/ICdDb25maXJtJyA6IGRlZmF1bHRQYXJhbXMuY29uZmlybUJ1dHRvblRleHQ7XG4gICAgICBwYXJhbXMuY29uZmlybUJ1dHRvblRleHQgPSBhcmd1bWVudE9yRGVmYXVsdCgnY29uZmlybUJ1dHRvblRleHQnKTtcblxuICAgICAgLy8gQ2FsbGJhY2sgZnVuY3Rpb24gd2hlbiBjbGlja2luZyBvbiBcIk9LXCIvXCJDYW5jZWxcIlxuICAgICAgcGFyYW1zLmRvbmVGdW5jdGlvbiA9IGFyZ3VtZW50c1sxXSB8fCBudWxsO1xuXG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBsb2dTdHIoJ1VuZXhwZWN0ZWQgdHlwZSBvZiBhcmd1bWVudCEgRXhwZWN0ZWQgXCJzdHJpbmdcIiBvciBcIm9iamVjdFwiLCBnb3QgJyArIHR5cGVvZiBjdXN0b21pemF0aW9ucyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgfVxuXG4gIHNldFBhcmFtZXRlcnMocGFyYW1zKTtcbiAgZml4VmVydGljYWxQb3NpdGlvbigpO1xuICBvcGVuTW9kYWwoYXJndW1lbnRzWzFdKTtcblxuICAvLyBNb2RhbCBpbnRlcmFjdGlvbnNcbiAgdmFyIG1vZGFsID0gZ2V0TW9kYWwoKTtcblxuXG4gIC8qXG4gICAqIE1ha2Ugc3VyZSBhbGwgbW9kYWwgYnV0dG9ucyByZXNwb25kIHRvIGFsbCBldmVudHNcbiAgICovXG4gIHZhciAkYnV0dG9ucyA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbicpO1xuICB2YXIgYnV0dG9uRXZlbnRzID0gWydvbmNsaWNrJywgJ29ubW91c2VvdmVyJywgJ29ubW91c2VvdXQnLCAnb25tb3VzZWRvd24nLCAnb25tb3VzZXVwJywgJ29uZm9jdXMnXTtcbiAgdmFyIG9uQnV0dG9uRXZlbnQgPSAoZSkgPT4gaGFuZGxlQnV0dG9uKGUsIHBhcmFtcywgbW9kYWwpO1xuXG4gIGZvciAobGV0IGJ0bkluZGV4ID0gMDsgYnRuSW5kZXggPCAkYnV0dG9ucy5sZW5ndGg7IGJ0bkluZGV4KyspIHtcbiAgICBmb3IgKGxldCBldnRJbmRleCA9IDA7IGV2dEluZGV4IDwgYnV0dG9uRXZlbnRzLmxlbmd0aDsgZXZ0SW5kZXgrKykge1xuICAgICAgbGV0IGJ0bkV2dCA9IGJ1dHRvbkV2ZW50c1tldnRJbmRleF07XG4gICAgICAkYnV0dG9uc1tidG5JbmRleF1bYnRuRXZ0XSA9IG9uQnV0dG9uRXZlbnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2xpY2tpbmcgb3V0c2lkZSB0aGUgbW9kYWwgZGlzbWlzc2VzIGl0IChpZiBhbGxvd2VkIGJ5IHVzZXIpXG4gIGdldE92ZXJsYXkoKS5vbmNsaWNrID0gb25CdXR0b25FdmVudDtcblxuICBwcmV2aW91c1dpbmRvd0tleURvd24gPSB3aW5kb3cub25rZXlkb3duO1xuXG4gIHZhciBvbktleUV2ZW50ID0gKGUpID0+IGhhbmRsZUtleURvd24oZSwgcGFyYW1zLCBtb2RhbCk7XG4gIHdpbmRvdy5vbmtleWRvd24gPSBvbktleUV2ZW50O1xuXG4gIHdpbmRvdy5vbmZvY3VzID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIFdoZW4gdGhlIHVzZXIgaGFzIGZvY3VzZWQgYXdheSBhbmQgZm9jdXNlZCBiYWNrIGZyb20gdGhlIHdob2xlIHdpbmRvdy5cbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFB1dCBpbiBhIHRpbWVvdXQgdG8ganVtcCBvdXQgb2YgdGhlIGV2ZW50IHNlcXVlbmNlLlxuICAgICAgLy8gQ2FsbGluZyBmb2N1cygpIGluIHRoZSBldmVudCBzZXF1ZW5jZSBjb25mdXNlcyB0aGluZ3MuXG4gICAgICBpZiAobGFzdEZvY3VzZWRCdXR0b24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsYXN0Rm9jdXNlZEJ1dHRvbi5mb2N1cygpO1xuICAgICAgICBsYXN0Rm9jdXNlZEJ1dHRvbiA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9LCAwKTtcbiAgfTtcbiAgXG4gIC8vIFNob3cgYWxlcnQgd2l0aCBlbmFibGVkIGJ1dHRvbnMgYWx3YXlzXG4gIHN3YWwuZW5hYmxlQnV0dG9ucygpO1xufTtcblxuXG5cbi8qXG4gKiBTZXQgZGVmYXVsdCBwYXJhbXMgZm9yIGVhY2ggcG9wdXBcbiAqIEBwYXJhbSB7T2JqZWN0fSB1c2VyUGFyYW1zXG4gKi9cbnN3ZWV0QWxlcnQuc2V0RGVmYXVsdHMgPSBzd2FsLnNldERlZmF1bHRzID0gZnVuY3Rpb24odXNlclBhcmFtcykge1xuICBpZiAoIXVzZXJQYXJhbXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXJQYXJhbXMgaXMgcmVxdWlyZWQnKTtcbiAgfVxuICBpZiAodHlwZW9mIHVzZXJQYXJhbXMgIT09ICdvYmplY3QnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2VyUGFyYW1zIGhhcyB0byBiZSBhIG9iamVjdCcpO1xuICB9XG5cbiAgZXh0ZW5kKGRlZmF1bHRQYXJhbXMsIHVzZXJQYXJhbXMpO1xufTtcblxuXG4vKlxuICogQW5pbWF0aW9uIHdoZW4gY2xvc2luZyBtb2RhbFxuICovXG5zd2VldEFsZXJ0LmNsb3NlID0gc3dhbC5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbW9kYWwgPSBnZXRNb2RhbCgpO1xuXG4gIGZhZGVPdXQoZ2V0T3ZlcmxheSgpLCA1KTtcbiAgZmFkZU91dChtb2RhbCwgNSk7XG4gIHJlbW92ZUNsYXNzKG1vZGFsLCAnc2hvd1N3ZWV0QWxlcnQnKTtcbiAgYWRkQ2xhc3MobW9kYWwsICdoaWRlU3dlZXRBbGVydCcpO1xuICByZW1vdmVDbGFzcyhtb2RhbCwgJ3Zpc2libGUnKTtcblxuICAvKlxuICAgKiBSZXNldCBpY29uIGFuaW1hdGlvbnNcbiAgICovXG4gIHZhciAkc3VjY2Vzc0ljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaWNvbi5zYS1zdWNjZXNzJyk7XG4gIHJlbW92ZUNsYXNzKCRzdWNjZXNzSWNvbiwgJ2FuaW1hdGUnKTtcbiAgcmVtb3ZlQ2xhc3MoJHN1Y2Nlc3NJY29uLnF1ZXJ5U2VsZWN0b3IoJy5zYS10aXAnKSwgJ2FuaW1hdGVTdWNjZXNzVGlwJyk7XG4gIHJlbW92ZUNsYXNzKCRzdWNjZXNzSWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtbG9uZycpLCAnYW5pbWF0ZVN1Y2Nlc3NMb25nJyk7XG5cbiAgdmFyICRlcnJvckljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaWNvbi5zYS1lcnJvcicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JJY29uLCAnYW5pbWF0ZUVycm9ySWNvbicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JJY29uLnF1ZXJ5U2VsZWN0b3IoJy5zYS14LW1hcmsnKSwgJ2FuaW1hdGVYTWFyaycpO1xuXG4gIHZhciAkd2FybmluZ0ljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaWNvbi5zYS13YXJuaW5nJyk7XG4gIHJlbW92ZUNsYXNzKCR3YXJuaW5nSWNvbiwgJ3B1bHNlV2FybmluZycpO1xuICByZW1vdmVDbGFzcygkd2FybmluZ0ljb24ucXVlcnlTZWxlY3RvcignLnNhLWJvZHknKSwgJ3B1bHNlV2FybmluZ0lucycpO1xuICByZW1vdmVDbGFzcygkd2FybmluZ0ljb24ucXVlcnlTZWxlY3RvcignLnNhLWRvdCcpLCAncHVsc2VXYXJuaW5nSW5zJyk7XG5cbiAgLy8gUmVzZXQgY3VzdG9tIGNsYXNzIChkZWxheSBzbyB0aGF0IFVJIGNoYW5nZXMgYXJlbid0IHZpc2libGUpXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGN1c3RvbUNsYXNzID0gbW9kYWwuZ2V0QXR0cmlidXRlKCdkYXRhLWN1c3RvbS1jbGFzcycpO1xuICAgIHJlbW92ZUNsYXNzKG1vZGFsLCBjdXN0b21DbGFzcyk7XG4gIH0sIDMwMCk7XG5cbiAgLy8gTWFrZSBwYWdlIHNjcm9sbGFibGUgYWdhaW5cbiAgcmVtb3ZlQ2xhc3MoZG9jdW1lbnQuYm9keSwgJ3N0b3Atc2Nyb2xsaW5nJyk7XG5cbiAgLy8gUmVzZXQgdGhlIHBhZ2UgdG8gaXRzIHByZXZpb3VzIHN0YXRlXG4gIHdpbmRvdy5vbmtleWRvd24gPSBwcmV2aW91c1dpbmRvd0tleURvd247XG4gIGlmICh3aW5kb3cucHJldmlvdXNBY3RpdmVFbGVtZW50KSB7XG4gICAgd2luZG93LnByZXZpb3VzQWN0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG4gIGxhc3RGb2N1c2VkQnV0dG9uID0gdW5kZWZpbmVkO1xuICBjbGVhclRpbWVvdXQobW9kYWwudGltZW91dCk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5cbi8qXG4gKiBWYWxpZGF0aW9uIG9mIHRoZSBpbnB1dCBmaWVsZCBpcyBkb25lIGJ5IHVzZXJcbiAqIElmIHNvbWV0aGluZyBpcyB3cm9uZyA9PiBjYWxsIHNob3dJbnB1dEVycm9yIHdpdGggZXJyb3JNZXNzYWdlXG4gKi9cbnN3ZWV0QWxlcnQuc2hvd0lucHV0RXJyb3IgPSBzd2FsLnNob3dJbnB1dEVycm9yID0gZnVuY3Rpb24oZXJyb3JNZXNzYWdlKSB7XG4gIHZhciBtb2RhbCA9IGdldE1vZGFsKCk7XG5cbiAgdmFyICRlcnJvckljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaW5wdXQtZXJyb3InKTtcbiAgYWRkQ2xhc3MoJGVycm9ySWNvbiwgJ3Nob3cnKTtcblxuICB2YXIgJGVycm9yQ29udGFpbmVyID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWVycm9yLWNvbnRhaW5lcicpO1xuICBhZGRDbGFzcygkZXJyb3JDb250YWluZXIsICdzaG93Jyk7XG5cbiAgJGVycm9yQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3AnKS5pbm5lckhUTUwgPSBlcnJvck1lc3NhZ2U7XG5cbiAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICBzd2VldEFsZXJ0LmVuYWJsZUJ1dHRvbnMoKTtcbiAgfSwgMSk7XG5cbiAgbW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXQnKS5mb2N1cygpO1xufTtcblxuXG4vKlxuICogUmVzZXQgaW5wdXQgZXJyb3IgRE9NIGVsZW1lbnRzXG4gKi9cbnN3ZWV0QWxlcnQucmVzZXRJbnB1dEVycm9yID0gc3dhbC5yZXNldElucHV0RXJyb3IgPSBmdW5jdGlvbihldmVudCkge1xuICAvLyBJZiBwcmVzcyBlbnRlciA9PiBpZ25vcmVcbiAgaWYgKGV2ZW50ICYmIGV2ZW50LmtleUNvZGUgPT09IDEzKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyICRtb2RhbCA9IGdldE1vZGFsKCk7XG5cbiAgdmFyICRlcnJvckljb24gPSAkbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWlucHV0LWVycm9yJyk7XG4gIHJlbW92ZUNsYXNzKCRlcnJvckljb24sICdzaG93Jyk7XG5cbiAgdmFyICRlcnJvckNvbnRhaW5lciA9ICRtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtZXJyb3ItY29udGFpbmVyJyk7XG4gIHJlbW92ZUNsYXNzKCRlcnJvckNvbnRhaW5lciwgJ3Nob3cnKTtcbn07XG5cbi8qXG4gKiBEaXNhYmxlIGNvbmZpcm0gYW5kIGNhbmNlbCBidXR0b25zXG4gKi9cbnN3ZWV0QWxlcnQuZGlzYWJsZUJ1dHRvbnMgPSBzd2FsLmRpc2FibGVCdXR0b25zID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIG1vZGFsID0gZ2V0TW9kYWwoKTtcbiAgdmFyICRjb25maXJtQnV0dG9uID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNvbmZpcm0nKTtcbiAgdmFyICRjYW5jZWxCdXR0b24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY2FuY2VsJyk7XG4gICRjb25maXJtQnV0dG9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgJGNhbmNlbEJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG59O1xuXG4vKlxuICogRW5hYmxlIGNvbmZpcm0gYW5kIGNhbmNlbCBidXR0b25zXG4gKi9cbnN3ZWV0QWxlcnQuZW5hYmxlQnV0dG9ucyA9IHN3YWwuZW5hYmxlQnV0dG9ucyA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHZhciBtb2RhbCA9IGdldE1vZGFsKCk7XG4gIHZhciAkY29uZmlybUJ1dHRvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG4gIHZhciAkY2FuY2VsQnV0dG9uID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNhbmNlbCcpO1xuICAkY29uZmlybUJ1dHRvbi5kaXNhYmxlZCA9IGZhbHNlO1xuICAkY2FuY2VsQnV0dG9uLmRpc2FibGVkID0gZmFsc2U7XG59O1xuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgLy8gVGhlICdoYW5kbGUtY2xpY2snIG1vZHVsZSByZXF1aXJlc1xuICAvLyB0aGF0ICdzd2VldEFsZXJ0JyB3YXMgc2V0IGFzIGdsb2JhbC5cbiAgd2luZG93LnN3ZWV0QWxlcnQgPSB3aW5kb3cuc3dhbCA9IHN3ZWV0QWxlcnQ7XG59IGVsc2Uge1xuICBsb2dTdHIoJ1N3ZWV0QWxlcnQgaXMgYSBmcm9udGVuZCBtb2R1bGUhJyk7XG59XG4iLCJ2YXIgZGVmYXVsdFBhcmFtcyA9IHtcbiAgdGl0bGU6ICcnLFxuICB0ZXh0OiAnJyxcbiAgdHlwZTogbnVsbCxcbiAgYWxsb3dPdXRzaWRlQ2xpY2s6IGZhbHNlLFxuICBzaG93Q29uZmlybUJ1dHRvbjogdHJ1ZSxcbiAgc2hvd0NhbmNlbEJ1dHRvbjogZmFsc2UsXG4gIGNsb3NlT25Db25maXJtOiB0cnVlLFxuICBjbG9zZU9uQ2FuY2VsOiB0cnVlLFxuICBjb25maXJtQnV0dG9uVGV4dDogJ09LJyxcbiAgY29uZmlybUJ1dHRvbkNvbG9yOiAnIzhDRDRGNScsXG4gIGNhbmNlbEJ1dHRvblRleHQ6ICdDYW5jZWwnLFxuICBpbWFnZVVybDogbnVsbCxcbiAgaW1hZ2VTaXplOiBudWxsLFxuICB0aW1lcjogbnVsbCxcbiAgY3VzdG9tQ2xhc3M6ICcnLFxuICBodG1sOiBmYWxzZSxcbiAgYW5pbWF0aW9uOiB0cnVlLFxuICBhbGxvd0VzY2FwZUtleTogdHJ1ZSxcbiAgaW5wdXRUeXBlOiAndGV4dCcsXG4gIGlucHV0UGxhY2Vob2xkZXI6ICcnLFxuICBpbnB1dFZhbHVlOiAnJyxcbiAgc2hvd0xvYWRlck9uQ29uZmlybTogZmFsc2Vcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmF1bHRQYXJhbXM7XG4iLCJpbXBvcnQgeyBjb2xvckx1bWluYW5jZSB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgZ2V0TW9kYWwgfSBmcm9tICcuL2hhbmRsZS1zd2FsLWRvbSc7XG5pbXBvcnQgeyBoYXNDbGFzcywgaXNEZXNjZW5kYW50IH0gZnJvbSAnLi9oYW5kbGUtZG9tJztcblxuXG4vKlxuICogVXNlciBjbGlja2VkIG9uIFwiQ29uZmlybVwiL1wiT0tcIiBvciBcIkNhbmNlbFwiXG4gKi9cbnZhciBoYW5kbGVCdXR0b24gPSBmdW5jdGlvbihldmVudCwgcGFyYW1zLCBtb2RhbCkge1xuICB2YXIgZSA9IGV2ZW50IHx8IHdpbmRvdy5ldmVudDtcbiAgdmFyIHRhcmdldCA9IGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDtcblxuICB2YXIgdGFyZ2V0ZWRDb25maXJtID0gdGFyZ2V0LmNsYXNzTmFtZS5pbmRleE9mKCdjb25maXJtJykgIT09IC0xO1xuICB2YXIgdGFyZ2V0ZWRPdmVybGF5ID0gdGFyZ2V0LmNsYXNzTmFtZS5pbmRleE9mKCdzd2VldC1vdmVybGF5JykgIT09IC0xO1xuICB2YXIgbW9kYWxJc1Zpc2libGUgID0gaGFzQ2xhc3MobW9kYWwsICd2aXNpYmxlJyk7XG4gIHZhciBkb25lRnVuY3Rpb25FeGlzdHMgPSAocGFyYW1zLmRvbmVGdW5jdGlvbiAmJiBtb2RhbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFzLWRvbmUtZnVuY3Rpb24nKSA9PT0gJ3RydWUnKTtcblxuICAvLyBTaW5jZSB0aGUgdXNlciBjYW4gY2hhbmdlIHRoZSBiYWNrZ3JvdW5kLWNvbG9yIG9mIHRoZSBjb25maXJtIGJ1dHRvbiBwcm9ncmFtbWF0aWNhbGx5LFxuICAvLyB3ZSBtdXN0IGNhbGN1bGF0ZSB3aGF0IHRoZSBjb2xvciBzaG91bGQgYmUgb24gaG92ZXIvYWN0aXZlXG4gIHZhciBub3JtYWxDb2xvciwgaG92ZXJDb2xvciwgYWN0aXZlQ29sb3I7XG4gIGlmICh0YXJnZXRlZENvbmZpcm0gJiYgcGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcikge1xuICAgIG5vcm1hbENvbG9yICA9IHBhcmFtcy5jb25maXJtQnV0dG9uQ29sb3I7XG4gICAgaG92ZXJDb2xvciAgID0gY29sb3JMdW1pbmFuY2Uobm9ybWFsQ29sb3IsIC0wLjA0KTtcbiAgICBhY3RpdmVDb2xvciAgPSBjb2xvckx1bWluYW5jZShub3JtYWxDb2xvciwgLTAuMTQpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvdWxkU2V0Q29uZmlybUJ1dHRvbkNvbG9yKGNvbG9yKSB7XG4gICAgaWYgKHRhcmdldGVkQ29uZmlybSAmJiBwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yKSB7XG4gICAgICB0YXJnZXQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29sb3I7XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlICdtb3VzZW92ZXInOlxuICAgICAgc2hvdWxkU2V0Q29uZmlybUJ1dHRvbkNvbG9yKGhvdmVyQ29sb3IpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdtb3VzZW91dCc6XG4gICAgICBzaG91bGRTZXRDb25maXJtQnV0dG9uQ29sb3Iobm9ybWFsQ29sb3IpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdtb3VzZWRvd24nOlxuICAgICAgc2hvdWxkU2V0Q29uZmlybUJ1dHRvbkNvbG9yKGFjdGl2ZUNvbG9yKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnbW91c2V1cCc6XG4gICAgICBzaG91bGRTZXRDb25maXJtQnV0dG9uQ29sb3IoaG92ZXJDb2xvcik7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2ZvY3VzJzpcbiAgICAgIGxldCAkY29uZmlybUJ1dHRvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG4gICAgICBsZXQgJGNhbmNlbEJ1dHRvbiAgPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY2FuY2VsJyk7XG5cbiAgICAgIGlmICh0YXJnZXRlZENvbmZpcm0pIHtcbiAgICAgICAgJGNhbmNlbEJ1dHRvbi5zdHlsZS5ib3hTaGFkb3cgPSAnbm9uZSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkY29uZmlybUJ1dHRvbi5zdHlsZS5ib3hTaGFkb3cgPSAnbm9uZSc7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NsaWNrJzpcbiAgICAgIGxldCBjbGlja2VkT25Nb2RhbCA9IChtb2RhbCA9PT0gdGFyZ2V0KTtcbiAgICAgIGxldCBjbGlja2VkT25Nb2RhbENoaWxkID0gaXNEZXNjZW5kYW50KG1vZGFsLCB0YXJnZXQpO1xuXG4gICAgICAvLyBJZ25vcmUgY2xpY2sgb3V0c2lkZSBpZiBhbGxvd091dHNpZGVDbGljayBpcyBmYWxzZVxuICAgICAgaWYgKCFjbGlja2VkT25Nb2RhbCAmJiAhY2xpY2tlZE9uTW9kYWxDaGlsZCAmJiBtb2RhbElzVmlzaWJsZSAmJiAhcGFyYW1zLmFsbG93T3V0c2lkZUNsaWNrKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodGFyZ2V0ZWRDb25maXJtICYmIGRvbmVGdW5jdGlvbkV4aXN0cyAmJiBtb2RhbElzVmlzaWJsZSkge1xuICAgICAgICBoYW5kbGVDb25maXJtKG1vZGFsLCBwYXJhbXMpO1xuICAgICAgfSBlbHNlIGlmIChkb25lRnVuY3Rpb25FeGlzdHMgJiYgbW9kYWxJc1Zpc2libGUgfHwgdGFyZ2V0ZWRPdmVybGF5KSB7XG4gICAgICAgIGhhbmRsZUNhbmNlbChtb2RhbCwgcGFyYW1zKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNEZXNjZW5kYW50KG1vZGFsLCB0YXJnZXQpICYmIHRhcmdldC50YWdOYW1lID09PSAnQlVUVE9OJykge1xuICAgICAgICBzd2VldEFsZXJ0LmNsb3NlKCk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuLypcbiAqICBVc2VyIGNsaWNrZWQgb24gXCJDb25maXJtXCIvXCJPS1wiXG4gKi9cbnZhciBoYW5kbGVDb25maXJtID0gZnVuY3Rpb24obW9kYWwsIHBhcmFtcykge1xuICB2YXIgY2FsbGJhY2tWYWx1ZSA9IHRydWU7XG5cbiAgaWYgKGhhc0NsYXNzKG1vZGFsLCAnc2hvdy1pbnB1dCcpKSB7XG4gICAgY2FsbGJhY2tWYWx1ZSA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0JykudmFsdWU7XG5cbiAgICBpZiAoIWNhbGxiYWNrVmFsdWUpIHtcbiAgICAgIGNhbGxiYWNrVmFsdWUgPSAnJztcbiAgICB9XG4gIH1cblxuICBwYXJhbXMuZG9uZUZ1bmN0aW9uKGNhbGxiYWNrVmFsdWUpO1xuXG4gIGlmIChwYXJhbXMuY2xvc2VPbkNvbmZpcm0pIHtcbiAgICBzd2VldEFsZXJ0LmNsb3NlKCk7XG4gIH1cbiAgLy8gRGlzYWJsZSBjYW5jZWwgYW5kIGNvbmZpcm0gYnV0dG9uIGlmIHRoZSBwYXJhbWV0ZXIgaXMgdHJ1ZVxuICBpZiAocGFyYW1zLnNob3dMb2FkZXJPbkNvbmZpcm0pIHtcbiAgICBzd2VldEFsZXJ0LmRpc2FibGVCdXR0b25zKCk7XG4gIH1cbn07XG5cbi8qXG4gKiAgVXNlciBjbGlja2VkIG9uIFwiQ2FuY2VsXCJcbiAqL1xudmFyIGhhbmRsZUNhbmNlbCA9IGZ1bmN0aW9uKG1vZGFsLCBwYXJhbXMpIHtcbiAgLy8gQ2hlY2sgaWYgY2FsbGJhY2sgZnVuY3Rpb24gZXhwZWN0cyBhIHBhcmFtZXRlciAodG8gdHJhY2sgY2FuY2VsIGFjdGlvbnMpXG4gIHZhciBmdW5jdGlvbkFzU3RyID0gU3RyaW5nKHBhcmFtcy5kb25lRnVuY3Rpb24pLnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gIHZhciBmdW5jdGlvbkhhbmRsZXNDYW5jZWwgPSBmdW5jdGlvbkFzU3RyLnN1YnN0cmluZygwLCA5KSA9PT0gJ2Z1bmN0aW9uKCcgJiYgZnVuY3Rpb25Bc1N0ci5zdWJzdHJpbmcoOSwgMTApICE9PSAnKSc7XG5cbiAgaWYgKGZ1bmN0aW9uSGFuZGxlc0NhbmNlbCkge1xuICAgIHBhcmFtcy5kb25lRnVuY3Rpb24oZmFsc2UpO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5jbG9zZU9uQ2FuY2VsKSB7XG4gICAgc3dlZXRBbGVydC5jbG9zZSgpO1xuICB9XG59O1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaGFuZGxlQnV0dG9uLFxuICBoYW5kbGVDb25maXJtLFxuICBoYW5kbGVDYW5jZWxcbn07XG4iLCJ2YXIgaGFzQ2xhc3MgPSBmdW5jdGlvbihlbGVtLCBjbGFzc05hbWUpIHtcbiAgcmV0dXJuIG5ldyBSZWdFeHAoJyAnICsgY2xhc3NOYW1lICsgJyAnKS50ZXN0KCcgJyArIGVsZW0uY2xhc3NOYW1lICsgJyAnKTtcbn07XG5cbnZhciBhZGRDbGFzcyA9IGZ1bmN0aW9uKGVsZW0sIGNsYXNzTmFtZSkge1xuICBpZiAoIWhhc0NsYXNzKGVsZW0sIGNsYXNzTmFtZSkpIHtcbiAgICBlbGVtLmNsYXNzTmFtZSArPSAnICcgKyBjbGFzc05hbWU7XG4gIH1cbn07XG5cbnZhciByZW1vdmVDbGFzcyA9IGZ1bmN0aW9uKGVsZW0sIGNsYXNzTmFtZSkge1xuICB2YXIgbmV3Q2xhc3MgPSAnICcgKyBlbGVtLmNsYXNzTmFtZS5yZXBsYWNlKC9bXFx0XFxyXFxuXS9nLCAnICcpICsgJyAnO1xuICBpZiAoaGFzQ2xhc3MoZWxlbSwgY2xhc3NOYW1lKSkge1xuICAgIHdoaWxlIChuZXdDbGFzcy5pbmRleE9mKCcgJyArIGNsYXNzTmFtZSArICcgJykgPj0gMCkge1xuICAgICAgbmV3Q2xhc3MgPSBuZXdDbGFzcy5yZXBsYWNlKCcgJyArIGNsYXNzTmFtZSArICcgJywgJyAnKTtcbiAgICB9XG4gICAgZWxlbS5jbGFzc05hbWUgPSBuZXdDbGFzcy5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XG4gIH1cbn07XG5cbnZhciBlc2NhcGVIdG1sID0gZnVuY3Rpb24oc3RyKSB7XG4gIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgZGl2LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0cikpO1xuICByZXR1cm4gZGl2LmlubmVySFRNTDtcbn07XG5cbnZhciBfc2hvdyA9IGZ1bmN0aW9uKGVsZW0pIHtcbiAgZWxlbS5zdHlsZS5vcGFjaXR5ID0gJyc7XG4gIGVsZW0uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG59O1xuXG52YXIgc2hvdyA9IGZ1bmN0aW9uKGVsZW1zKSB7XG4gIGlmIChlbGVtcyAmJiAhZWxlbXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIF9zaG93KGVsZW1zKTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgX3Nob3coZWxlbXNbaV0pO1xuICB9XG59O1xuXG52YXIgX2hpZGUgPSBmdW5jdGlvbihlbGVtKSB7XG4gIGVsZW0uc3R5bGUub3BhY2l0eSA9ICcnO1xuICBlbGVtLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59O1xuXG52YXIgaGlkZSA9IGZ1bmN0aW9uKGVsZW1zKSB7XG4gIGlmIChlbGVtcyAmJiAhZWxlbXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIF9oaWRlKGVsZW1zKTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgX2hpZGUoZWxlbXNbaV0pO1xuICB9XG59O1xuXG52YXIgaXNEZXNjZW5kYW50ID0gZnVuY3Rpb24ocGFyZW50LCBjaGlsZCkge1xuICB2YXIgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGU7XG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgaWYgKG5vZGUgPT09IHBhcmVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxudmFyIGdldFRvcE1hcmdpbiA9IGZ1bmN0aW9uKGVsZW0pIHtcbiAgZWxlbS5zdHlsZS5sZWZ0ID0gJy05OTk5cHgnO1xuICBlbGVtLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gIHZhciBoZWlnaHQgPSBlbGVtLmNsaWVudEhlaWdodCxcbiAgICAgIHBhZGRpbmc7XG4gIGlmICh0eXBlb2YgZ2V0Q29tcHV0ZWRTdHlsZSAhPT0gXCJ1bmRlZmluZWRcIikgeyAvLyBJRSA4XG4gICAgcGFkZGluZyA9IHBhcnNlSW50KGdldENvbXB1dGVkU3R5bGUoZWxlbSkuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy10b3AnKSwgMTApO1xuICB9IGVsc2Uge1xuICAgIHBhZGRpbmcgPSBwYXJzZUludChlbGVtLmN1cnJlbnRTdHlsZS5wYWRkaW5nKTtcbiAgfVxuXG4gIGVsZW0uc3R5bGUubGVmdCA9ICcnO1xuICBlbGVtLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJldHVybiAoJy0nICsgcGFyc2VJbnQoKGhlaWdodCArIHBhZGRpbmcpIC8gMikgKyAncHgnKTtcbn07XG5cbnZhciBmYWRlSW4gPSBmdW5jdGlvbihlbGVtLCBpbnRlcnZhbCkge1xuICBpZiAoK2VsZW0uc3R5bGUub3BhY2l0eSA8IDEpIHtcbiAgICBpbnRlcnZhbCA9IGludGVydmFsIHx8IDE2O1xuICAgIGVsZW0uc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgZWxlbS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB2YXIgbGFzdCA9ICtuZXcgRGF0ZSgpO1xuICAgIHZhciB0aWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSArZWxlbS5zdHlsZS5vcGFjaXR5ICsgKG5ldyBEYXRlKCkgLSBsYXN0KSAvIDEwMDtcbiAgICAgIGxhc3QgPSArbmV3IERhdGUoKTtcblxuICAgICAgaWYgKCtlbGVtLnN0eWxlLm9wYWNpdHkgPCAxKSB7XG4gICAgICAgIHNldFRpbWVvdXQodGljaywgaW50ZXJ2YWwpO1xuICAgICAgfVxuICAgIH07XG4gICAgdGljaygpO1xuICB9XG4gIGVsZW0uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7IC8vZmFsbGJhY2sgSUU4XG59O1xuXG52YXIgZmFkZU91dCA9IGZ1bmN0aW9uKGVsZW0sIGludGVydmFsKSB7XG4gIGludGVydmFsID0gaW50ZXJ2YWwgfHwgMTY7XG4gIGVsZW0uc3R5bGUub3BhY2l0eSA9IDE7XG4gIHZhciBsYXN0ID0gK25ldyBEYXRlKCk7XG4gIHZhciB0aWNrID0gZnVuY3Rpb24oKSB7XG4gICAgZWxlbS5zdHlsZS5vcGFjaXR5ID0gK2VsZW0uc3R5bGUub3BhY2l0eSAtIChuZXcgRGF0ZSgpIC0gbGFzdCkgLyAxMDA7XG4gICAgbGFzdCA9ICtuZXcgRGF0ZSgpO1xuXG4gICAgaWYgKCtlbGVtLnN0eWxlLm9wYWNpdHkgPiAwKSB7XG4gICAgICBzZXRUaW1lb3V0KHRpY2ssIGludGVydmFsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH1cbiAgfTtcbiAgdGljaygpO1xufTtcblxudmFyIGZpcmVDbGljayA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgLy8gVGFrZW4gZnJvbSBodHRwOi8vd3d3Lm5vbm9idHJ1c2l2ZS5jb20vMjAxMS8xMS8yOS9wcm9ncmFtYXRpY2FsbHktZmlyZS1jcm9zc2Jyb3dzZXItY2xpY2stZXZlbnQtd2l0aC1qYXZhc2NyaXB0L1xuICAvLyBUaGVuIGZpeGVkIGZvciB0b2RheSdzIENocm9tZSBicm93c2VyLlxuICBpZiAodHlwZW9mIE1vdXNlRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBVcC10by1kYXRlIGFwcHJvYWNoXG4gICAgdmFyIG1ldnQgPSBuZXcgTW91c2VFdmVudCgnY2xpY2snLCB7XG4gICAgICB2aWV3OiB3aW5kb3csXG4gICAgICBidWJibGVzOiBmYWxzZSxcbiAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICB9KTtcbiAgICBub2RlLmRpc3BhdGNoRXZlbnQobWV2dCk7XG4gIH0gZWxzZSBpZiAoIGRvY3VtZW50LmNyZWF0ZUV2ZW50ICkge1xuICAgIC8vIEZhbGxiYWNrXG4gICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO1xuICAgIGV2dC5pbml0RXZlbnQoJ2NsaWNrJywgZmFsc2UsIGZhbHNlKTtcbiAgICBub2RlLmRpc3BhdGNoRXZlbnQoZXZ0KTtcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5jcmVhdGVFdmVudE9iamVjdCkge1xuICAgIG5vZGUuZmlyZUV2ZW50KCdvbmNsaWNrJykgO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBub2RlLm9uY2xpY2sgPT09ICdmdW5jdGlvbicgKSB7XG4gICAgbm9kZS5vbmNsaWNrKCk7XG4gIH1cbn07XG5cbnZhciBzdG9wRXZlbnRQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uKGUpIHtcbiAgLy8gSW4gcGFydGljdWxhciwgbWFrZSBzdXJlIHRoZSBzcGFjZSBiYXIgZG9lc24ndCBzY3JvbGwgdGhlIG1haW4gd2luZG93LlxuICBpZiAodHlwZW9mIGUuc3RvcFByb3BhZ2F0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH0gZWxzZSBpZiAod2luZG93LmV2ZW50ICYmIHdpbmRvdy5ldmVudC5oYXNPd25Qcm9wZXJ0eSgnY2FuY2VsQnViYmxlJykpIHtcbiAgICB3aW5kb3cuZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgfVxufTtcblxuZXhwb3J0IHsgXG4gIGhhc0NsYXNzLCBhZGRDbGFzcywgcmVtb3ZlQ2xhc3MsIFxuICBlc2NhcGVIdG1sLCBcbiAgX3Nob3csIHNob3csIF9oaWRlLCBoaWRlLCBcbiAgaXNEZXNjZW5kYW50LCBcbiAgZ2V0VG9wTWFyZ2luLFxuICBmYWRlSW4sIGZhZGVPdXQsXG4gIGZpcmVDbGljayxcbiAgc3RvcEV2ZW50UHJvcGFnYXRpb25cbn07XG4iLCJpbXBvcnQgeyBzdG9wRXZlbnRQcm9wYWdhdGlvbiwgZmlyZUNsaWNrIH0gZnJvbSAnLi9oYW5kbGUtZG9tJztcbmltcG9ydCB7IHNldEZvY3VzU3R5bGUgfSBmcm9tICcuL2hhbmRsZS1zd2FsLWRvbSc7XG5cblxudmFyIGhhbmRsZUtleURvd24gPSBmdW5jdGlvbihldmVudCwgcGFyYW1zLCBtb2RhbCkge1xuICB2YXIgZSA9IGV2ZW50IHx8IHdpbmRvdy5ldmVudDtcbiAgdmFyIGtleUNvZGUgPSBlLmtleUNvZGUgfHwgZS53aGljaDtcblxuICB2YXIgJG9rQnV0dG9uICAgICA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG4gIHZhciAkY2FuY2VsQnV0dG9uID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNhbmNlbCcpO1xuICB2YXIgJG1vZGFsQnV0dG9ucyA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvblt0YWJpbmRleF0nKTtcblxuXG4gIGlmIChbOSwgMTMsIDMyLCAyN10uaW5kZXhPZihrZXlDb2RlKSA9PT0gLTEpIHtcbiAgICAvLyBEb24ndCBkbyB3b3JrIG9uIGtleXMgd2UgZG9uJ3QgY2FyZSBhYm91dC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgJHRhcmdldEVsZW1lbnQgPSBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7XG5cbiAgdmFyIGJ0bkluZGV4ID0gLTE7IC8vIEZpbmQgdGhlIGJ1dHRvbiAtIG5vdGUsIHRoaXMgaXMgYSBub2RlbGlzdCwgbm90IGFuIGFycmF5LlxuICBmb3IgKHZhciBpID0gMDsgaSA8ICRtb2RhbEJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoJHRhcmdldEVsZW1lbnQgPT09ICRtb2RhbEJ1dHRvbnNbaV0pIHtcbiAgICAgIGJ0bkluZGV4ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChrZXlDb2RlID09PSA5KSB7XG4gICAgLy8gVEFCXG4gICAgaWYgKGJ0bkluZGV4ID09PSAtMSkge1xuICAgICAgLy8gTm8gYnV0dG9uIGZvY3VzZWQuIEp1bXAgdG8gdGhlIGNvbmZpcm0gYnV0dG9uLlxuICAgICAgJHRhcmdldEVsZW1lbnQgPSAkb2tCdXR0b247XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEN5Y2xlIHRvIHRoZSBuZXh0IGJ1dHRvblxuICAgICAgaWYgKGJ0bkluZGV4ID09PSAkbW9kYWxCdXR0b25zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgJHRhcmdldEVsZW1lbnQgPSAkbW9kYWxCdXR0b25zWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJHRhcmdldEVsZW1lbnQgPSAkbW9kYWxCdXR0b25zW2J0bkluZGV4ICsgMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3RvcEV2ZW50UHJvcGFnYXRpb24oZSk7XG4gICAgJHRhcmdldEVsZW1lbnQuZm9jdXMoKTtcblxuICAgIGlmIChwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yKSB7XG4gICAgICBzZXRGb2N1c1N0eWxlKCR0YXJnZXRFbGVtZW50LCBwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGtleUNvZGUgPT09IDEzKSB7XG4gICAgICBpZiAoJHRhcmdldEVsZW1lbnQudGFnTmFtZSA9PT0gJ0lOUFVUJykge1xuICAgICAgICAkdGFyZ2V0RWxlbWVudCA9ICRva0J1dHRvbjtcbiAgICAgICAgJG9rQnV0dG9uLmZvY3VzKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChidG5JbmRleCA9PT0gLTEpIHtcbiAgICAgICAgLy8gRU5URVIvU1BBQ0UgY2xpY2tlZCBvdXRzaWRlIG9mIGEgYnV0dG9uLlxuICAgICAgICAkdGFyZ2V0RWxlbWVudCA9ICRva0J1dHRvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIERvIG5vdGhpbmcgLSBsZXQgdGhlIGJyb3dzZXIgaGFuZGxlIGl0LlxuICAgICAgICAkdGFyZ2V0RWxlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGtleUNvZGUgPT09IDI3ICYmIHBhcmFtcy5hbGxvd0VzY2FwZUtleSA9PT0gdHJ1ZSkge1xuICAgICAgJHRhcmdldEVsZW1lbnQgPSAkY2FuY2VsQnV0dG9uO1xuICAgICAgZmlyZUNsaWNrKCR0YXJnZXRFbGVtZW50LCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRmFsbGJhY2sgLSBsZXQgdGhlIGJyb3dzZXIgaGFuZGxlIGl0LlxuICAgICAgJHRhcmdldEVsZW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBoYW5kbGVLZXlEb3duO1xuIiwiaW1wb3J0IHsgaGV4VG9SZ2IgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IHJlbW92ZUNsYXNzLCBnZXRUb3BNYXJnaW4sIGZhZGVJbiwgc2hvdywgYWRkQ2xhc3MgfSBmcm9tICcuL2hhbmRsZS1kb20nO1xuaW1wb3J0IGRlZmF1bHRQYXJhbXMgZnJvbSAnLi9kZWZhdWx0LXBhcmFtcyc7XG5cbnZhciBtb2RhbENsYXNzICAgPSAnLnN3ZWV0LWFsZXJ0JztcbnZhciBvdmVybGF5Q2xhc3MgPSAnLnN3ZWV0LW92ZXJsYXknO1xuXG4vKlxuICogQWRkIG1vZGFsICsgb3ZlcmxheSB0byBET01cbiAqL1xuaW1wb3J0IGluamVjdGVkSFRNTCBmcm9tICcuL2luamVjdGVkLWh0bWwnO1xuXG52YXIgc3dlZXRBbGVydEluaXRpYWxpemUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHN3ZWV0V3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBzd2VldFdyYXAuaW5uZXJIVE1MID0gaW5qZWN0ZWRIVE1MO1xuXG4gIC8vIEFwcGVuZCBlbGVtZW50cyB0byBib2R5XG4gIHdoaWxlIChzd2VldFdyYXAuZmlyc3RDaGlsZCkge1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc3dlZXRXcmFwLmZpcnN0Q2hpbGQpO1xuICB9XG59O1xuXG4vKlxuICogR2V0IERPTSBlbGVtZW50IG9mIG1vZGFsXG4gKi9cbnZhciBnZXRNb2RhbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgJG1vZGFsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihtb2RhbENsYXNzKTtcblxuICBpZiAoISRtb2RhbCkge1xuICAgIHN3ZWV0QWxlcnRJbml0aWFsaXplKCk7XG4gICAgJG1vZGFsID0gZ2V0TW9kYWwoKTtcbiAgfVxuXG4gIHJldHVybiAkbW9kYWw7XG59O1xuXG4vKlxuICogR2V0IERPTSBlbGVtZW50IG9mIGlucHV0IChpbiBtb2RhbClcbiAqL1xudmFyIGdldElucHV0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciAkbW9kYWwgPSBnZXRNb2RhbCgpO1xuICBpZiAoJG1vZGFsKSB7XG4gICAgcmV0dXJuICRtb2RhbC5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpO1xuICB9XG59O1xuXG4vKlxuICogR2V0IERPTSBlbGVtZW50IG9mIG92ZXJsYXlcbiAqL1xudmFyIGdldE92ZXJsYXkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iob3ZlcmxheUNsYXNzKTtcbn07XG5cbi8qXG4gKiBBZGQgYm94LXNoYWRvdyBzdHlsZSB0byBidXR0b24gKGRlcGVuZGluZyBvbiBpdHMgY2hvc2VuIGJnLWNvbG9yKVxuICovXG52YXIgc2V0Rm9jdXNTdHlsZSA9IGZ1bmN0aW9uKCRidXR0b24sIGJnQ29sb3IpIHtcbiAgdmFyIHJnYkNvbG9yID0gaGV4VG9SZ2IoYmdDb2xvcik7XG4gICRidXR0b24uc3R5bGUuYm94U2hhZG93ID0gJzAgMCAycHggcmdiYSgnICsgcmdiQ29sb3IgKyAnLCAwLjgpLCBpbnNldCAwIDAgMCAxcHggcmdiYSgwLCAwLCAwLCAwLjA1KSc7XG59O1xuXG4vKlxuICogQW5pbWF0aW9uIHdoZW4gb3BlbmluZyBtb2RhbFxuICovXG52YXIgb3Blbk1vZGFsID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyICRtb2RhbCA9IGdldE1vZGFsKCk7XG4gIGZhZGVJbihnZXRPdmVybGF5KCksIDEwKTtcbiAgc2hvdygkbW9kYWwpO1xuICBhZGRDbGFzcygkbW9kYWwsICdzaG93U3dlZXRBbGVydCcpO1xuICByZW1vdmVDbGFzcygkbW9kYWwsICdoaWRlU3dlZXRBbGVydCcpO1xuXG4gIHdpbmRvdy5wcmV2aW91c0FjdGl2ZUVsZW1lbnQgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICB2YXIgJG9rQnV0dG9uID0gJG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG4gICRva0J1dHRvbi5mb2N1cygpO1xuXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGFkZENsYXNzKCRtb2RhbCwgJ3Zpc2libGUnKTtcbiAgfSwgNTAwKTtcblxuICB2YXIgdGltZXIgPSAkbW9kYWwuZ2V0QXR0cmlidXRlKCdkYXRhLXRpbWVyJyk7XG5cbiAgaWYgKHRpbWVyICE9PSAnbnVsbCcgJiYgdGltZXIgIT09ICcnKSB7XG4gICAgdmFyIHRpbWVyQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAkbW9kYWwudGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZG9uZUZ1bmN0aW9uRXhpc3RzID0gKCh0aW1lckNhbGxiYWNrIHx8IG51bGwpICYmICRtb2RhbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFzLWRvbmUtZnVuY3Rpb24nKSA9PT0gJ3RydWUnKTtcbiAgICAgIGlmIChkb25lRnVuY3Rpb25FeGlzdHMpIHsgXG4gICAgICAgIHRpbWVyQ2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc3dlZXRBbGVydC5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sIHRpbWVyKTtcbiAgfVxufTtcblxuLypcbiAqIFJlc2V0IHRoZSBzdHlsaW5nIG9mIHRoZSBpbnB1dFxuICogKGZvciBleGFtcGxlIGlmIGVycm9ycyBoYXZlIGJlZW4gc2hvd24pXG4gKi9cbnZhciByZXNldElucHV0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciAkbW9kYWwgPSBnZXRNb2RhbCgpO1xuICB2YXIgJGlucHV0ID0gZ2V0SW5wdXQoKTtcblxuICByZW1vdmVDbGFzcygkbW9kYWwsICdzaG93LWlucHV0Jyk7XG4gICRpbnB1dC52YWx1ZSA9IGRlZmF1bHRQYXJhbXMuaW5wdXRWYWx1ZTtcbiAgJGlucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsIGRlZmF1bHRQYXJhbXMuaW5wdXRUeXBlKTtcbiAgJGlucHV0LnNldEF0dHJpYnV0ZSgncGxhY2Vob2xkZXInLCBkZWZhdWx0UGFyYW1zLmlucHV0UGxhY2Vob2xkZXIpO1xuXG4gIHJlc2V0SW5wdXRFcnJvcigpO1xufTtcblxuXG52YXIgcmVzZXRJbnB1dEVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgLy8gSWYgcHJlc3MgZW50ZXIgPT4gaWdub3JlXG4gIGlmIChldmVudCAmJiBldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciAkbW9kYWwgPSBnZXRNb2RhbCgpO1xuXG4gIHZhciAkZXJyb3JJY29uID0gJG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zYS1pbnB1dC1lcnJvcicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JJY29uLCAnc2hvdycpO1xuXG4gIHZhciAkZXJyb3JDb250YWluZXIgPSAkbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWVycm9yLWNvbnRhaW5lcicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JDb250YWluZXIsICdzaG93Jyk7XG59O1xuXG5cbi8qXG4gKiBTZXQgXCJtYXJnaW4tdG9wXCItcHJvcGVydHkgb24gbW9kYWwgYmFzZWQgb24gaXRzIGNvbXB1dGVkIGhlaWdodFxuICovXG52YXIgZml4VmVydGljYWxQb3NpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB2YXIgJG1vZGFsID0gZ2V0TW9kYWwoKTtcbiAgJG1vZGFsLnN0eWxlLm1hcmdpblRvcCA9IGdldFRvcE1hcmdpbihnZXRNb2RhbCgpKTtcbn07XG5cblxuZXhwb3J0IHsgXG4gIHN3ZWV0QWxlcnRJbml0aWFsaXplLFxuICBnZXRNb2RhbCxcbiAgZ2V0T3ZlcmxheSxcbiAgZ2V0SW5wdXQsXG4gIHNldEZvY3VzU3R5bGUsXG4gIG9wZW5Nb2RhbCxcbiAgcmVzZXRJbnB1dCxcbiAgcmVzZXRJbnB1dEVycm9yLFxuICBmaXhWZXJ0aWNhbFBvc2l0aW9uXG59O1xuIiwidmFyIGluamVjdGVkSFRNTCA9IFxuXG4gIC8vIERhcmsgb3ZlcmxheVxuICBgPGRpdiBjbGFzcz1cInN3ZWV0LW92ZXJsYXlcIiB0YWJJbmRleD1cIi0xXCI+PC9kaXY+YCArXG5cbiAgLy8gTW9kYWxcbiAgYDxkaXYgY2xhc3M9XCJzd2VldC1hbGVydFwiPmAgK1xuXG4gICAgLy8gRXJyb3IgaWNvblxuICAgIGA8ZGl2IGNsYXNzPVwic2EtaWNvbiBzYS1lcnJvclwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYS14LW1hcmtcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzYS1saW5lIHNhLWxlZnRcIj48L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2EtbGluZSBzYS1yaWdodFwiPjwvc3Bhbj5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L2Rpdj5gICtcblxuICAgIC8vIFdhcm5pbmcgaWNvblxuICAgIGA8ZGl2IGNsYXNzPVwic2EtaWNvbiBzYS13YXJuaW5nXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInNhLWJvZHlcIj48L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInNhLWRvdFwiPjwvc3Bhbj5cbiAgICA8L2Rpdj5gICtcblxuICAgIC8vIEluZm8gaWNvblxuICAgIGA8ZGl2IGNsYXNzPVwic2EtaWNvbiBzYS1pbmZvXCI+PC9kaXY+YCArXG5cbiAgICAvLyBTdWNjZXNzIGljb25cbiAgICBgPGRpdiBjbGFzcz1cInNhLWljb24gc2Etc3VjY2Vzc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYS1saW5lIHNhLXRpcFwiPjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2EtbGluZSBzYS1sb25nXCI+PC9zcGFuPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwic2EtcGxhY2Vob2xkZXJcIj48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYS1maXhcIj48L2Rpdj5cbiAgICA8L2Rpdj5gICtcblxuICAgIGA8ZGl2IGNsYXNzPVwic2EtaWNvbiBzYS1jdXN0b21cIj48L2Rpdj5gICtcblxuICAgIC8vIFRpdGxlLCB0ZXh0IGFuZCBpbnB1dFxuICAgIGA8aDI+VGl0bGU8L2gyPlxuICAgIDxwPlRleHQ8L3A+XG4gICAgPGZpZWxkc2V0PlxuICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgdGFiSW5kZXg9XCIzXCIgLz5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYS1pbnB1dC1lcnJvclwiPjwvZGl2PlxuICAgIDwvZmllbGRzZXQ+YCArXG5cbiAgICAvLyBJbnB1dCBlcnJvcnNcbiAgICBgPGRpdiBjbGFzcz1cInNhLWVycm9yLWNvbnRhaW5lclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImljb25cIj4hPC9kaXY+XG4gICAgICA8cD5Ob3QgdmFsaWQhPC9wPlxuICAgIDwvZGl2PmAgK1xuXG4gICAgLy8gQ2FuY2VsIGFuZCBjb25maXJtIGJ1dHRvbnNcbiAgICBgPGRpdiBjbGFzcz1cInNhLWJ1dHRvbi1jb250YWluZXJcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJjYW5jZWxcIiB0YWJJbmRleD1cIjJcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYS1jb25maXJtLWJ1dHRvbi1jb250YWluZXJcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbmZpcm1cIiB0YWJJbmRleD1cIjFcIj5PSzwvYnV0dG9uPmAgKyBcblxuICAgICAgICAvLyBMb2FkaW5nIGFuaW1hdGlvblxuICAgICAgICBgPGRpdiBjbGFzcz1cImxhLWJhbGwtZmFsbFwiPlxuICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PmAgK1xuXG4gIC8vIEVuZCBvZiBtb2RhbFxuICBgPC9kaXY+YDtcblxuZXhwb3J0IGRlZmF1bHQgaW5qZWN0ZWRIVE1MO1xuIiwidmFyIGFsZXJ0VHlwZXMgPSBbJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdzdWNjZXNzJywgJ2lucHV0JywgJ3Byb21wdCddO1xuXG5pbXBvcnQge1xuICBpc0lFOFxufSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHtcbiAgZ2V0TW9kYWwsXG4gIGdldElucHV0LFxuICBzZXRGb2N1c1N0eWxlXG59IGZyb20gJy4vaGFuZGxlLXN3YWwtZG9tJztcblxuaW1wb3J0IHtcbiAgaGFzQ2xhc3MsIGFkZENsYXNzLCByZW1vdmVDbGFzcyxcbiAgZXNjYXBlSHRtbCxcbiAgX3Nob3csIHNob3csIF9oaWRlLCBoaWRlXG59IGZyb20gJy4vaGFuZGxlLWRvbSc7XG5cblxuLypcbiAqIFNldCB0eXBlLCB0ZXh0IGFuZCBhY3Rpb25zIG9uIG1vZGFsXG4gKi9cbnZhciBzZXRQYXJhbWV0ZXJzID0gZnVuY3Rpb24ocGFyYW1zKSB7XG4gIHZhciBtb2RhbCA9IGdldE1vZGFsKCk7XG5cbiAgdmFyICR0aXRsZSA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2gyJyk7XG4gIHZhciAkdGV4dCA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ3AnKTtcbiAgdmFyICRjYW5jZWxCdG4gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY2FuY2VsJyk7XG4gIHZhciAkY29uZmlybUJ0biA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG5cbiAgLypcbiAgICogVGl0bGVcbiAgICovXG4gICR0aXRsZS5pbm5lckhUTUwgPSBwYXJhbXMuaHRtbCA/IHBhcmFtcy50aXRsZSA6IGVzY2FwZUh0bWwocGFyYW1zLnRpdGxlKS5zcGxpdCgnXFxuJykuam9pbignPGJyPicpO1xuXG4gIC8qXG4gICAqIFRleHRcbiAgICovXG4gICR0ZXh0LmlubmVySFRNTCA9IHBhcmFtcy5odG1sID8gcGFyYW1zLnRleHQgOiBlc2NhcGVIdG1sKHBhcmFtcy50ZXh0IHx8ICcnKS5zcGxpdCgnXFxuJykuam9pbignPGJyPicpO1xuICBpZiAocGFyYW1zLnRleHQpIHNob3coJHRleHQpO1xuXG4gIC8qXG4gICAqIEN1c3RvbSBjbGFzc1xuICAgKi9cbiAgaWYgKHBhcmFtcy5jdXN0b21DbGFzcykge1xuICAgIGFkZENsYXNzKG1vZGFsLCBwYXJhbXMuY3VzdG9tQ2xhc3MpO1xuICAgIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1jdXN0b20tY2xhc3MnLCBwYXJhbXMuY3VzdG9tQ2xhc3MpO1xuICB9IGVsc2Uge1xuICAgIC8vIEZpbmQgcHJldmlvdXNseSBzZXQgY2xhc3NlcyBhbmQgcmVtb3ZlIHRoZW1cbiAgICBsZXQgY3VzdG9tQ2xhc3MgPSBtb2RhbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY3VzdG9tLWNsYXNzJyk7XG4gICAgcmVtb3ZlQ2xhc3MobW9kYWwsIGN1c3RvbUNsYXNzKTtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY3VzdG9tLWNsYXNzJywgJycpO1xuICB9XG5cbiAgLypcbiAgICogSWNvblxuICAgKi9cbiAgaGlkZShtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCcuc2EtaWNvbicpKTtcblxuICBpZiAocGFyYW1zLnR5cGUgJiYgIWlzSUU4KCkpIHtcblxuICAgIGxldCB2YWxpZFR5cGUgPSBmYWxzZTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWxlcnRUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSBhbGVydFR5cGVzW2ldKSB7XG4gICAgICAgIHZhbGlkVHlwZSA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdmFsaWRUeXBlKSB7XG4gICAgICBsb2dTdHIoJ1Vua25vd24gYWxlcnQgdHlwZTogJyArIHBhcmFtcy50eXBlKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgdHlwZXNXaXRoSWNvbnMgPSBbJ3N1Y2Nlc3MnLCAnZXJyb3InLCAnd2FybmluZycsICdpbmZvJ107XG4gICAgbGV0ICRpY29uO1xuXG4gICAgaWYgKHR5cGVzV2l0aEljb25zLmluZGV4T2YocGFyYW1zLnR5cGUpICE9PSAtMSkge1xuICAgICAgJGljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaWNvbi4nICsgJ3NhLScgKyBwYXJhbXMudHlwZSk7XG4gICAgICBzaG93KCRpY29uKTtcbiAgICB9XG5cbiAgICBsZXQgJGlucHV0ID0gZ2V0SW5wdXQoKTtcblxuICAgIC8vIEFuaW1hdGUgaWNvblxuICAgIHN3aXRjaCAocGFyYW1zLnR5cGUpIHtcblxuICAgICAgY2FzZSAnc3VjY2Vzcyc6XG4gICAgICAgIGFkZENsYXNzKCRpY29uLCAnYW5pbWF0ZScpO1xuICAgICAgICBhZGRDbGFzcygkaWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtdGlwJyksICdhbmltYXRlU3VjY2Vzc1RpcCcpO1xuICAgICAgICBhZGRDbGFzcygkaWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtbG9uZycpLCAnYW5pbWF0ZVN1Y2Nlc3NMb25nJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIGFkZENsYXNzKCRpY29uLCAnYW5pbWF0ZUVycm9ySWNvbicpO1xuICAgICAgICBhZGRDbGFzcygkaWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EteC1tYXJrJyksICdhbmltYXRlWE1hcmsnKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3dhcm5pbmcnOlxuICAgICAgICBhZGRDbGFzcygkaWNvbiwgJ3B1bHNlV2FybmluZycpO1xuICAgICAgICBhZGRDbGFzcygkaWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtYm9keScpLCAncHVsc2VXYXJuaW5nSW5zJyk7XG4gICAgICAgIGFkZENsYXNzKCRpY29uLnF1ZXJ5U2VsZWN0b3IoJy5zYS1kb3QnKSwgJ3B1bHNlV2FybmluZ0lucycpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaW5wdXQnOlxuICAgICAgY2FzZSAncHJvbXB0JzpcbiAgICAgICAgJGlucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsIHBhcmFtcy5pbnB1dFR5cGUpO1xuICAgICAgICAkaW5wdXQudmFsdWUgPSBwYXJhbXMuaW5wdXRWYWx1ZTtcbiAgICAgICAgJGlucHV0LnNldEF0dHJpYnV0ZSgncGxhY2Vob2xkZXInLCBwYXJhbXMuaW5wdXRQbGFjZWhvbGRlcik7XG4gICAgICAgIGFkZENsYXNzKG1vZGFsLCAnc2hvdy1pbnB1dCcpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAkaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAkaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCBzd2FsLnJlc2V0SW5wdXRFcnJvcik7XG4gICAgICAgIH0sIDQwMCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIEN1c3RvbSBpbWFnZVxuICAgKi9cbiAgaWYgKHBhcmFtcy5pbWFnZVVybCkge1xuICAgIGxldCAkY3VzdG9tSWNvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zYS1pY29uLnNhLWN1c3RvbScpO1xuXG4gICAgJGN1c3RvbUljb24uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gJ3VybCgnICsgcGFyYW1zLmltYWdlVXJsICsgJyknO1xuICAgIHNob3coJGN1c3RvbUljb24pO1xuXG4gICAgbGV0IF9pbWdXaWR0aCA9IDgwO1xuICAgIGxldCBfaW1nSGVpZ2h0ID0gODA7XG5cbiAgICBpZiAocGFyYW1zLmltYWdlU2l6ZSkge1xuICAgICAgbGV0IGRpbWVuc2lvbnMgPSBwYXJhbXMuaW1hZ2VTaXplLnRvU3RyaW5nKCkuc3BsaXQoJ3gnKTtcbiAgICAgIGxldCBpbWdXaWR0aCA9IGRpbWVuc2lvbnNbMF07XG4gICAgICBsZXQgaW1nSGVpZ2h0ID0gZGltZW5zaW9uc1sxXTtcblxuICAgICAgaWYgKCFpbWdXaWR0aCB8fCAhaW1nSGVpZ2h0KSB7XG4gICAgICAgIGxvZ1N0cignUGFyYW1ldGVyIGltYWdlU2l6ZSBleHBlY3RzIHZhbHVlIHdpdGggZm9ybWF0IFdJRFRIeEhFSUdIVCwgZ290ICcgKyBwYXJhbXMuaW1hZ2VTaXplKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pbWdXaWR0aCA9IGltZ1dpZHRoO1xuICAgICAgICBfaW1nSGVpZ2h0ID0gaW1nSGVpZ2h0O1xuICAgICAgfVxuICAgIH1cblxuICAgICRjdXN0b21JY29uLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAkY3VzdG9tSWNvbi5nZXRBdHRyaWJ1dGUoJ3N0eWxlJykgKyAnd2lkdGg6JyArIF9pbWdXaWR0aCArICdweDsgaGVpZ2h0OicgKyBfaW1nSGVpZ2h0ICsgJ3B4Jyk7XG4gIH1cblxuICAvKlxuICAgKiBTaG93IGNhbmNlbCBidXR0b24/XG4gICAqL1xuICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtaGFzLWNhbmNlbC1idXR0b24nLCBwYXJhbXMuc2hvd0NhbmNlbEJ1dHRvbik7XG4gIGlmIChwYXJhbXMuc2hvd0NhbmNlbEJ1dHRvbikge1xuICAgICRjYW5jZWxCdG4uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoJGNhbmNlbEJ0bik7XG4gIH1cblxuICAvKlxuICAgKiBTaG93IGNvbmZpcm0gYnV0dG9uP1xuICAgKi9cbiAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLWhhcy1jb25maXJtLWJ1dHRvbicsIHBhcmFtcy5zaG93Q29uZmlybUJ1dHRvbik7XG4gIGlmIChwYXJhbXMuc2hvd0NvbmZpcm1CdXR0b24pIHtcbiAgICAkY29uZmlybUJ0bi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gIH0gZWxzZSB7XG4gICAgaGlkZSgkY29uZmlybUJ0bik7XG4gIH1cblxuICAvKlxuICAgKiBDdXN0b20gdGV4dCBvbiBjYW5jZWwvY29uZmlybSBidXR0b25zXG4gICAqL1xuICBpZiAocGFyYW1zLmNhbmNlbEJ1dHRvblRleHQpIHtcbiAgICAkY2FuY2VsQnRuLmlubmVySFRNTCA9IGVzY2FwZUh0bWwocGFyYW1zLmNhbmNlbEJ1dHRvblRleHQpO1xuICB9XG4gIGlmIChwYXJhbXMuY29uZmlybUJ1dHRvblRleHQpIHtcbiAgICAkY29uZmlybUJ0bi5pbm5lckhUTUwgPSBlc2NhcGVIdG1sKHBhcmFtcy5jb25maXJtQnV0dG9uVGV4dCk7XG4gIH1cblxuICAvKlxuICAgKiBDdXN0b20gY29sb3Igb24gY29uZmlybSBidXR0b25cbiAgICovXG4gIGlmIChwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yKSB7XG4gICAgLy8gU2V0IGNvbmZpcm0gYnV0dG9uIHRvIHNlbGVjdGVkIGJhY2tncm91bmQgY29sb3JcbiAgICAkY29uZmlybUJ0bi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yO1xuXG4gICAgLy8gU2V0IHRoZSBjb25maXJtIGJ1dHRvbiBjb2xvciB0byB0aGUgbG9hZGluZyByaW5nXG4gICAgJGNvbmZpcm1CdG4uc3R5bGUuYm9yZGVyTGVmdENvbG9yID0gcGFyYW1zLmNvbmZpcm1Mb2FkaW5nQnV0dG9uQ29sb3I7XG4gICAgJGNvbmZpcm1CdG4uc3R5bGUuYm9yZGVyUmlnaHRDb2xvciA9IHBhcmFtcy5jb25maXJtTG9hZGluZ0J1dHRvbkNvbG9yO1xuXG4gICAgLy8gU2V0IGJveC1zaGFkb3cgdG8gZGVmYXVsdCBmb2N1c2VkIGJ1dHRvblxuICAgIHNldEZvY3VzU3R5bGUoJGNvbmZpcm1CdG4sIHBhcmFtcy5jb25maXJtQnV0dG9uQ29sb3IpO1xuICB9XG5cbiAgLypcbiAgICogQWxsb3cgb3V0c2lkZSBjbGlja1xuICAgKi9cbiAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLWFsbG93LW91dHNpZGUtY2xpY2snLCBwYXJhbXMuYWxsb3dPdXRzaWRlQ2xpY2spO1xuXG4gIC8qXG4gICAqIENhbGxiYWNrIGZ1bmN0aW9uXG4gICAqL1xuICB2YXIgaGFzRG9uZUZ1bmN0aW9uID0gcGFyYW1zLmRvbmVGdW5jdGlvbiA/IHRydWUgOiBmYWxzZTtcbiAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLWhhcy1kb25lLWZ1bmN0aW9uJywgaGFzRG9uZUZ1bmN0aW9uKTtcblxuICAvKlxuICAgKiBBbmltYXRpb25cbiAgICovXG4gIGlmICghcGFyYW1zLmFuaW1hdGlvbikge1xuICAgIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1hbmltYXRpb24nLCAnbm9uZScpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwYXJhbXMuYW5pbWF0aW9uID09PSAnc3RyaW5nJykge1xuICAgIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1hbmltYXRpb24nLCBwYXJhbXMuYW5pbWF0aW9uKTsgLy8gQ3VzdG9tIGFuaW1hdGlvblxuICB9IGVsc2Uge1xuICAgIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1hbmltYXRpb24nLCAncG9wJyk7XG4gIH1cblxuICAvKlxuICAgKiBUaW1lclxuICAgKi9cbiAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLXRpbWVyJywgcGFyYW1zLnRpbWVyKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHNldFBhcmFtZXRlcnM7XG4iLCIvKlxuICogQWxsb3cgdXNlciB0byBwYXNzIHRoZWlyIG93biBwYXJhbXNcbiAqL1xudmFyIGV4dGVuZCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgZm9yICh2YXIga2V5IGluIGIpIHtcbiAgICBpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBhW2tleV0gPSBiW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBhO1xufTtcblxuLypcbiAqIENvbnZlcnQgSEVYIGNvZGVzIHRvIFJHQiB2YWx1ZXMgKCMwMDAwMDAgLT4gcmdiKDAsMCwwKSlcbiAqL1xudmFyIGhleFRvUmdiID0gZnVuY3Rpb24oaGV4KSB7XG4gIHZhciByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcbiAgcmV0dXJuIHJlc3VsdCA/IHBhcnNlSW50KHJlc3VsdFsxXSwgMTYpICsgJywgJyArIHBhcnNlSW50KHJlc3VsdFsyXSwgMTYpICsgJywgJyArIHBhcnNlSW50KHJlc3VsdFszXSwgMTYpIDogbnVsbDtcbn07XG5cbi8qXG4gKiBDaGVjayBpZiB0aGUgdXNlciBpcyB1c2luZyBJbnRlcm5ldCBFeHBsb3JlciA4IChmb3IgZmFsbGJhY2tzKVxuICovXG52YXIgaXNJRTggPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICh3aW5kb3cuYXR0YWNoRXZlbnQgJiYgIXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKTtcbn07XG5cbi8qXG4gKiBJRSBjb21wYXRpYmxlIGxvZ2dpbmcgZm9yIGRldmVsb3BlcnNcbiAqL1xudmFyIGxvZ1N0ciA9IGZ1bmN0aW9uKHN0cmluZykge1xuICBpZiAod2luZG93LmNvbnNvbGUpIHtcbiAgICAvLyBJRS4uLlxuICAgIHdpbmRvdy5jb25zb2xlLmxvZygnU3dlZXRBbGVydDogJyArIHN0cmluZyk7XG4gIH1cbn07XG5cbi8qXG4gKiBTZXQgaG92ZXIsIGFjdGl2ZSBhbmQgZm9jdXMtc3RhdGVzIGZvciBidXR0b25zIFxuICogKHNvdXJjZTogaHR0cDovL3d3dy5zaXRlcG9pbnQuY29tL2phdmFzY3JpcHQtZ2VuZXJhdGUtbGlnaHRlci1kYXJrZXItY29sb3IpXG4gKi9cbnZhciBjb2xvckx1bWluYW5jZSA9IGZ1bmN0aW9uKGhleCwgbHVtKSB7XG4gIC8vIFZhbGlkYXRlIGhleCBzdHJpbmdcbiAgaGV4ID0gU3RyaW5nKGhleCkucmVwbGFjZSgvW14wLTlhLWZdL2dpLCAnJyk7XG4gIGlmIChoZXgubGVuZ3RoIDwgNikge1xuICAgIGhleCA9IGhleFswXSArIGhleFswXSArIGhleFsxXSArIGhleFsxXSArIGhleFsyXSArIGhleFsyXTtcbiAgfVxuICBsdW0gPSBsdW0gfHwgMDtcblxuICAvLyBDb252ZXJ0IHRvIGRlY2ltYWwgYW5kIGNoYW5nZSBsdW1pbm9zaXR5XG4gIHZhciByZ2IgPSAnIyc7XG4gIHZhciBjO1xuICB2YXIgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgYyA9IHBhcnNlSW50KGhleC5zdWJzdHIoaSAqIDIsIDIpLCAxNik7XG4gICAgYyA9IE1hdGgucm91bmQoTWF0aC5taW4oTWF0aC5tYXgoMCwgYyArIGMgKiBsdW0pLCAyNTUpKS50b1N0cmluZygxNik7XG4gICAgcmdiICs9ICgnMDAnICsgYykuc3Vic3RyKGMubGVuZ3RoKTtcbiAgfVxuXG4gIHJldHVybiByZ2I7XG59O1xuXG5cbmV4cG9ydCB7XG4gIGV4dGVuZCxcbiAgaGV4VG9SZ2IsXG4gIGlzSUU4LFxuICBsb2dTdHIsXG4gIGNvbG9yTHVtaW5hbmNlXG59O1xuIl19 + + + /* + * Use SweetAlert with RequireJS + */ + + if (typeof define === 'function' && define.amd) { + define(function () { + return sweetAlert; + }); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = sweetAlert; + } + +})(window, document); \ No newline at end of file diff --git a/readme.md b/readme.md index f67a6cf..fa377f9 100644 --- a/readme.md +++ b/readme.md @@ -1,27 +1,32 @@ -## Laravel PHP Framework +# soma-tech +![CircleCI Badge](https://circleci.com/gh/andela-sachungo/soma-tech.svg?style=shield&circle-token=eab6015ece8c084d689495dcbbf2bd5bd22c50cb) +[![Coverage Status](https://coveralls.io/repos/andela-sachungo/soma-tech/badge.svg?branch=master&service=github)](https://coveralls.io/github/andela-sachungo/soma-tech?branch=master) +![StyleCI Badge](https://styleci.io/repos/48097337/shield) -[![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework) -[![Total Downloads](https://poser.pugx.org/laravel/framework/d/total.svg)](https://packagist.org/packages/laravel/framework) -[![Latest Stable Version](https://poser.pugx.org/laravel/framework/v/stable.svg)](https://packagist.org/packages/laravel/framework) -[![Latest Unstable Version](https://poser.pugx.org/laravel/framework/v/unstable.svg)](https://packagist.org/packages/laravel/framework) -[![License](https://poser.pugx.org/laravel/framework/license.svg)](https://packagist.org/packages/laravel/framework) +Soma-tech is a learning management system that helps people learn various technologies. -Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching. +**NOTE:** It is highly recommended that you use [Homestead virtual machine](http://laravel.com/docs/5.1/homestead). -Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked. +##Installation instructions +* Clone the repository `git clone ` +* Run `composer install` +* Rename `.env.example` to `.env` +* Run `php artisan key:generate` to generate the *application key* -## Official Documentation +##Defining the site in Homestead +[Laravel](http://laravel.com/docs/5.1/homestead#connecting-via-ssh) explains how to configure **Homestead**. -Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs). +In summary: -## Contributing + 1. Identify which folder(s) you want to share with Homestead as + explained in [Configuring Shared Folders](http://laravel.com/docs/5.1/homestead#configuring-homestead). + 2. Map a domain to a folder on your Homestead environment as explained in [Configuring Nginx Sites](http://laravel.com/docs/5.1/homestead#configuring-homestead). + 3. Then add the domain to your Nginx site to the `hosts` file on your machine, as explained in [The Hosts File](http://laravel.com/docs/5.1/homestead#configuring-homestead). + 4. Run the `vagrant up` command from your Homestead directory. -Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions). +**NOTE:** When your Homestead environment is provisioned and running, to add an additional Nginx site ; add it on `Homestead.yaml` file and then run `vagrant provision`. -## Security Vulnerabilities - -If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed. - -### License - -The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) +## Testing +* Create a database called `testing`. +* If you are not using `mysql`, then change the `DB_CONNECTION` value in `phpunit.xml` accordingly. +* Run `phpunit` in *vagrant*. \ No newline at end of file diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..8a2d41c --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,44 @@ +@extends('layouts.master') + +@section('title', 'Login') + +@section('content') +
+
+
+ {!! csrf_field() !!} + @include('partials.error') + +
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+
+
Alternatively...
+ +
+
+@endsection + +@section('styles') + +@endsection \ No newline at end of file diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php new file mode 100644 index 0000000..83fc470 --- /dev/null +++ b/resources/views/auth/register.blade.php @@ -0,0 +1,53 @@ +@extends('layouts.master') + +@section('title', 'Register') + +@section('content') +
+
+
+ {!! csrf_field() !!} + @include('partials.error') + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+
+
Alternatively...
+ +
+
+@endsection + +@section('styles') + +@endsection \ No newline at end of file diff --git a/resources/views/categories/create.blade.php b/resources/views/categories/create.blade.php new file mode 100644 index 0000000..a82720e --- /dev/null +++ b/resources/views/categories/create.blade.php @@ -0,0 +1,24 @@ +@extends('layouts.master') + +@section('title', 'Create category') + +@section('content') +
+
+

Create a Category

+
+ {!! csrf_field() !!} + @include('partials.error') + +
+ + +
+
+ +
+ +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/categories/edit.blade.php b/resources/views/categories/edit.blade.php new file mode 100644 index 0000000..5061691 --- /dev/null +++ b/resources/views/categories/edit.blade.php @@ -0,0 +1,25 @@ +@extends('layouts.master') + +@section('title', 'Edit category') + +@section('content') +
+ @include('partials.sidebar') + +
+

Edit Category

+ + {!! Form::model($category,['method' => 'PATCH', 'route' => ['category.update', $category->id]]) !!} + @include('partials.error') + +
+ {!! Form::label('title', 'Title', ['class' => 'control-label']) !!} + {!! Form::text('title', null, ['class' => 'form-control']) !!} +
+
+ {!! Form::submit('Save', ['class' => 'btn btn-primary']) !!} +
+ {!! Form::close() !!} +
+
+@endsection diff --git a/resources/views/categories/own.blade.php b/resources/views/categories/own.blade.php new file mode 100644 index 0000000..53176df --- /dev/null +++ b/resources/views/categories/own.blade.php @@ -0,0 +1,86 @@ +@extends('layouts.master') + +@section('title', 'My category') + +@section('styles') + +@endsection + +@section('content') +
+ @include('partials.sidebar') + +
+
+
+

Categories

+
+ + + @foreach ($categories as $category) + + + @can('userCategory', $category) + + @endcan + + @endforeach + +
+ + {{ $category->title }} + + + + + + + + {!! Form::open(array('route' => array('category.destroy', $category->id), 'method' => 'delete')) !!} + + {!! Form::close() !!} +
+ + @include('partials.category_modal') + + @include('partials.category_add_modal') +
+
+
+@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/categories/video.blade.php b/resources/views/categories/video.blade.php new file mode 100644 index 0000000..6589efc --- /dev/null +++ b/resources/views/categories/video.blade.php @@ -0,0 +1,29 @@ +@extends('layouts.master') + +@section('title', 'Videos of a single category') + +@section('styles') + +@endsection + +@section('content') +
+ @if (isset($videos)) +
+ @include('partials.category_list') +
+ +
+ @foreach ($videos as $video) + @include('partials.video_display') + @endforeach + {!! $videos->render() !!} +
+ @else + +
+

There are no videos in this category

+
+ @endif +
+@endsection diff --git a/resources/views/dashboard/edit.blade.php b/resources/views/dashboard/edit.blade.php new file mode 100644 index 0000000..88d2b48 --- /dev/null +++ b/resources/views/dashboard/edit.blade.php @@ -0,0 +1,81 @@ +@extends('layouts.master') + +@section('title', 'Edit profile') + +@section('styles') + + +@endsection + +@section('content') +
+ @include('partials.sidebar') +
+
+
+

Edit Profile

+
+
+
+
+
+
+ avatar +

Upload a different photo...

+
+ {!! csrf_field() !!} +
+
+
+
+ {!! Form::model($user,['method' => 'PATCH', 'route' => ['profile.update', $user->id]]) !!} + @include('partials.error') + +
+ {!! Form::label('name', 'Full name', ['class' => 'control-label']) !!} + {!! Form::text('name', null, ['class' => 'form-control']) !!} +
+
+ {!! Form::label('name', 'Email', ['class' => 'control-label']) !!} + {!! Form::email('email', null, ['class' => 'form-control']) !!} +
+
+ {!! Form::submit('Update', ['class' => 'btn btn-primary']) !!} +
+ {!! Form::close() !!} +
+
+
+
+@endsection + +@section('scripts') + + +@endsection diff --git a/resources/views/dashboard/index.blade.php b/resources/views/dashboard/index.blade.php new file mode 100644 index 0000000..ae02529 --- /dev/null +++ b/resources/views/dashboard/index.blade.php @@ -0,0 +1,55 @@ +@extends('layouts.master') + +@section('title', 'Dashboard') + +@section('styles') + +@endsection + +@section('content') +
+ @include('partials.sidebar') + +
+
+
+

{{ auth()->user()->name}}

+
+
+
+
+ @if(auth()->user()->avatar) + + @else + + @endif +
+
+
+
+ Name:{{ auth()->user()->name}}
+ Email: {{ auth()->user()->email}}
+ Created on: {{ substr(auth()->user()->created_at, 0, 10) }}
+
+
+
+
+
+
+
+
+@endsection diff --git a/resources/views/layouts/master.blade.php b/resources/views/layouts/master.blade.php new file mode 100644 index 0000000..c150edd --- /dev/null +++ b/resources/views/layouts/master.blade.php @@ -0,0 +1,37 @@ + + + + Soma-Tech » @yield('title') + + + + + + + + + + @yield('styles') + + + @include('partials.navbar') + + @yield('sidebar') + + +
+
+ Copyright © 2015 soma-tech.app | All rights reserved. +
+
+ + + + + @yield('scripts') + + \ No newline at end of file diff --git a/resources/views/partials/category_add_modal.blade.php b/resources/views/partials/category_add_modal.blade.php new file mode 100644 index 0000000..6dee1b6 --- /dev/null +++ b/resources/views/partials/category_add_modal.blade.php @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/resources/views/partials/category_list.blade.php b/resources/views/partials/category_list.blade.php new file mode 100644 index 0000000..7caec7e --- /dev/null +++ b/resources/views/partials/category_list.blade.php @@ -0,0 +1,10 @@ +
+
+

Categories

+
+
+ @foreach ($categories as $category) + {{ $category->title }} + @endforeach +
+
diff --git a/resources/views/partials/category_modal.blade.php b/resources/views/partials/category_modal.blade.php new file mode 100644 index 0000000..56697b7 --- /dev/null +++ b/resources/views/partials/category_modal.blade.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/resources/views/partials/error.blade.php b/resources/views/partials/error.blade.php new file mode 100644 index 0000000..dac56d2 --- /dev/null +++ b/resources/views/partials/error.blade.php @@ -0,0 +1,10 @@ +@if (count($errors) > 0) +
This thing is hit + +
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+@endif diff --git a/resources/views/partials/navbar.blade.php b/resources/views/partials/navbar.blade.php new file mode 100644 index 0000000..01bd902 --- /dev/null +++ b/resources/views/partials/navbar.blade.php @@ -0,0 +1,45 @@ + diff --git a/resources/views/partials/sidebar.blade.php b/resources/views/partials/sidebar.blade.php new file mode 100644 index 0000000..01f3b56 --- /dev/null +++ b/resources/views/partials/sidebar.blade.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/resources/views/partials/video_display.blade.php b/resources/views/partials/video_display.blade.php new file mode 100644 index 0000000..b5781c6 --- /dev/null +++ b/resources/views/partials/video_display.blade.php @@ -0,0 +1,31 @@ +
+
+ +
+ +
+
+

{{ $video->title }}

+
{{ substr($video->created_at, 0, 10) }}
+

{{ $video->description }}

+ More Info + @can('userVideo', $video) +
+
+ + + +
+
+ + {!! Form::open(array('route' => array('video.destroy', $video->id), 'method' => 'delete')) !!} + + {!! Form::close() !!} +
+
+ @endcan +
+
+
\ No newline at end of file diff --git a/resources/views/videos/create.blade.php b/resources/views/videos/create.blade.php new file mode 100644 index 0000000..d6b8bda --- /dev/null +++ b/resources/views/videos/create.blade.php @@ -0,0 +1,43 @@ +@extends('layouts.master') + +@section('title', 'Create video') + +@section('content') +
+ @include('partials.sidebar') + +
+

Add a Video

+
+ {!! csrf_field() !!} + @include('partials.error') + +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/videos/edit.blade.php b/resources/views/videos/edit.blade.php new file mode 100644 index 0000000..54aceeb --- /dev/null +++ b/resources/views/videos/edit.blade.php @@ -0,0 +1,42 @@ +@extends('layouts.master') + +@section('title', 'Edit video') + +@section('content') +
+ @include('partials.sidebar') + +
+

Edit Video

+
+ + {!! Form::model($video,['method' => 'PATCH', 'route' => ['video.update', $video->id]]) !!} + @include('partials.error') + +
+ {!! Form::label('link', 'Video URL', ['class' => 'control-label']) !!} + {!! Form::url('youtube_link', null, ['class' => 'form-control']) !!} +
+
+ {!! Form::label('title', 'Title', ['class' => 'control-label']) !!} + {!! Form::text('title', null, ['class' => 'form-control']) !!} +
+
+ {!! Form::label('describe', 'Description', ['class' => 'control-label']) !!} + {!! Form::textarea('description', null, ['class' => 'form-control', 'rows' => '5']) !!} +
+
+ {!! Form::label('category', 'Category', ['class' => 'control-label']) !!} + +
+
+ {!! Form::submit('Save', ['class' => 'btn btn-primary']) !!} +
+ {!! Form::close() !!} +
+
+@endsection diff --git a/resources/views/videos/index.blade.php b/resources/views/videos/index.blade.php new file mode 100644 index 0000000..8e12517 --- /dev/null +++ b/resources/views/videos/index.blade.php @@ -0,0 +1,20 @@ +@extends('layouts.master') + +@section('title', 'My videos') + +@section('styles') + +@endsection + +@section('content') +
+ @include('partials.sidebar') + +
+ @foreach ($videos as $video) + @include('partials.video_display') + @endforeach + {!! $videos->render() !!} +
+
+@endsection diff --git a/resources/views/videos/show.blade.php b/resources/views/videos/show.blade.php new file mode 100644 index 0000000..52a50d0 --- /dev/null +++ b/resources/views/videos/show.blade.php @@ -0,0 +1,57 @@ +@extends('layouts.master') + +@section('title', 'Show a video') + +@section('styles') + + +@endsection + +@section('content') +
+
+
+

{{ $video->title }}

+
+
+ +
+ +
+
+

{{ $video->description }}

+
+ {{ $category->title }} + @can('userVideo', $video) +
+
+ Homepage +
+
+ + + +
+
+ + {!! Form::open(array('route' => array('video.destroy', $video->id), 'method' => 'delete')) !!} + + {!! Form::close() !!} +
+
+ @endcan +
+
+
+
+
+@endsection diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index 87710ac..61a3895 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -1,45 +1,36 @@ - - - - Laravel +@extends('layouts.master') - +@section('title', 'Welcome') - +@endsection - body { - margin: 0; - padding: 0; - width: 100%; - display: table; - font-weight: 100; - font-family: 'Lato'; - } +@section('content') +
+ @if (isset($videos, $categories)) +
+ @include('partials.category_list') +
- .container { - text-align: center; - display: table-cell; - vertical-align: middle; - } - - .content { - text-align: center; - display: inline-block; - } - - .title { - font-size: 96px; - } - - - -
-
-
Laravel 5
+
+ @foreach ($videos as $video) + @include('partials.video_display') + @endforeach + {!! $videos->render() !!} +
+ @else +
+

Welcome, to soma-tech!

+

A place to learn via YouTube videos.

+

Sorry, currently there are no videos uploaded.

+

Upload a video to start the learning movement.Thank you.

-
- - + @endif +
+@endsection diff --git a/server.php b/server.php index f65c7c4..1b4655b 100644 --- a/server.php +++ b/server.php @@ -1,12 +1,10 @@ */ - $uri = urldecode( parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ); diff --git a/tests/AuthenticationTest.php b/tests/AuthenticationTest.php new file mode 100644 index 0000000..09b48f9 --- /dev/null +++ b/tests/AuthenticationTest.php @@ -0,0 +1,45 @@ +visit('auth/register') + ->type('Atea Nazhrah', 'name') + ->type('ateaN@example.com', 'email') + ->type('testing', 'password') + ->type('testing', 'confirm-password') + ->press('Register') + ->seePageIs('/dashboard'); + } + + /** + * Test user can login traditionally. + * + * @return void + */ + public function testTraditionalLogin() + { + factory(Soma\User::class)->create([ + 'email' => 'aloraleigh@example.com', + 'password' => bcrypt('testing'), + ]); + + $this->visit('auth/login') + ->type('aloraleigh@example.com', 'email') + ->type('testing', 'password') + ->press('Log In') + ->seePageIs('/dashboard'); + } +} diff --git a/tests/DashboardTest.php b/tests/DashboardTest.php new file mode 100644 index 0000000..eddd9ff --- /dev/null +++ b/tests/DashboardTest.php @@ -0,0 +1,160 @@ +create(); + + $this->actingAs($user) + ->visit('/dashboard') + ->see('Dashboard'); + + $this->actingAs($user) + ->visit('/dashboard') + ->see('Edit Profile'); + + $this->actingAs($user) + ->visit('/dashboard') + ->see('My videos'); + } + + /** + * Test the user profile can be seen. + * + * @return void + */ + public function testUserProfileSeen() + { + $user = factory(Soma\User::class)->create([ + 'name' => 'Zaria Zinzi', + 'email' => 'zaria@example.com', + ]); + + //$this->seeInDatabase('categories', ['title' => 'Abigail']); + $this->actingAs($user) + ->visit('/dashboard') + ->see('Zaria Zinzi') + ->see('zaria@example.com'); + } + + /** + * Test the user updated data is saved in the database. + * + * @return void + */ + public function testUserUpdatedDataSaved() + { + $user = factory(Soma\User::class)->create(); + + $this->actingAs($user) + ->visit("profile/{$user->id}/edit") + ->type('Zulia Dexa', 'name') + ->type('zuliadexa@example.com', 'email') + ->press('Update') + ->seePageIs('/dashboard'); + + $this->seeInDatabase('users', ['email' => 'zuliadexa@example.com']); + } + + /** + * Test the user can view their own categories. + * + * @return void + */ + public function testCategoriesBelongingToSelfViewed() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class, 5)->create([ + 'user_id' => $user->id, + ]); + + $category = factory(Soma\Categories::class)->create([ + 'user_id' => $user->id, + 'title' => 'Tuli', + ]); + + $this->actingAs($user) + ->visit('category/mycategories') + ->see('Tuli'); + } + + /** + * Test the user can add categories. + * + * @return void + */ + public function testNewCategoriesCreated() + { + $user = factory(Soma\User::class)->create(); + factory(Soma\Categories::class, 3)->create([ + 'user_id' => $user->id, + ]); + + $this->actingAs($user) + ->visit('category/mycategories') + ->press('Add') + ->type('Testing', 'title') + ->press('Add') + ->seePageIs('category/mycategories'); + + $this->seeInDatabase('categories', ['title' => 'Testing']); + } + + /** + * Test the user can edit their own categories. + * + * 'edit-btn' is the id of the edit button. + * + * @return void + */ + public function testCategoriesEdited() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class)->create([ + 'user_id' => $user->id, + 'title' => 'Exalted', + ]); + + $this->seeInDatabase('categories', ['title' => 'Exalted']); + + $this->actingAs($user) + ->visit("category/{$category->id}/edit") + ->see('Exalted') + ->type('God is Exalted ', 'title') + ->press('Save') + ->seePageIs('category/mycategories') + ->see('God is Exalted'); + } + + /** + * Test the user can delete their own categories. + * + * @return void + */ + public function testCategoriesDeleted() + { + $category = factory(Soma\Categories::class)->create([ + 'title' => 'Praise', + ]); + + $this->seeInDatabase('categories', ['title' => 'Praise']); + + $this->withoutMiddleware(); + $response = $this->call('DELETE', "/category/$category->id"); + $this->assertEquals(302, $response->getStatusCode()); + + $this->notSeeInDatabase('categories', ['title' => 'Praise']); + } +} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php deleted file mode 100644 index 7e81d37..0000000 --- a/tests/ExampleTest.php +++ /dev/null @@ -1,19 +0,0 @@ -visit('/') - ->see('Laravel 5'); - } -} diff --git a/tests/HomeControllerTest.php b/tests/HomeControllerTest.php new file mode 100644 index 0000000..03e4124 --- /dev/null +++ b/tests/HomeControllerTest.php @@ -0,0 +1,43 @@ +call('GET', 'auth/login'); + $this->assertResponseStatus(200); + } + + /** + * Test the auth/register route is accessible. + * + * @return void + */ + public function testRegister() + { + $this->call('GET', 'auth/register'); + $this->assertResponseStatus(200); + } + + /** + * Test the dashboard route is accessible. + * + * @return void + */ + public function testDashboard() + { + $this->call('GET', 'dashboard'); + $this->assertResponseStatus(302); + } +} diff --git a/tests/HomepageTest.php b/tests/HomepageTest.php new file mode 100644 index 0000000..0a36db1 --- /dev/null +++ b/tests/HomepageTest.php @@ -0,0 +1,73 @@ +visit('/') + ->see('Categories'); + } + + /** + * Test the categories lists are clickable. + * + * @return void + */ + public function testCategoriesListsCanBeClicked() + { + factory(Soma\Categories::class)->create([ + 'title' => 'Abigail', + ]); + + $this->seeInDatabase('categories', ['title' => 'Abigail']); + + $category_id = factory(Soma\Categories::class)->create([ + 'title' => 'Osuofia', + ])->id; + + $this->visit('/') + ->click('Osuofia') + ->seePageIs("categories/{$category_id}/videos"); + } + + /** + * Test $videos and $categories variables returned to view. + * + * @return void + */ + public function testVariablesReturnedToView() + { + factory(Soma\Categories::class, 5)->create(); + factory(Soma\Videos::class, 5)->create(); + + $this->call('GET', '/'); + $this->assertViewHasAll(['videos', 'categories']); + } + + /** + * Test videos are paginated. + * + * @return void + */ + public function testVideosPaginated() + { + factory(Soma\Videos::class, 24)->create(); + + $results = Videos::paginate(6); + + $this->assertEquals(6, $results->perPage()); + } +} diff --git a/tests/VideosTest.php b/tests/VideosTest.php new file mode 100644 index 0000000..4b6c99f --- /dev/null +++ b/tests/VideosTest.php @@ -0,0 +1,151 @@ +create(); + $category = factory(Soma\Categories::class)->create(); + + $this->actingAs($user) + ->visit('video/create') + ->type('https://www.youtube.com/embed/qVM7cwqGTTU&index=4&list=RDH1XrbuOoKFw', 'youtube_link') + ->type('I will worship you', 'title') + ->type('Gospel worship video', 'description') + ->select($category->id, 'category_id') + ->press('Add'); + + $this->seeInDatabase('videos', ['title' => 'I will worship you']); + } + + /** + * Test the user can see their uploaded videos. + * + * @return void + */ + public function testPersonallyUploadedVideosViewed() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class)->create(); + + factory(Soma\Videos::class, 3)->create([ + 'category_id' => $category->id, + 'user_id' => $user->id, + ]); + + factory(Soma\Videos::class)->create([ + 'category_id' => $category->id, + 'user_id' => $user->id, + 'youtube_link' => 'https://www.youtube.com/embed/6R0YdAnASc8&index=23&list=RDH1XrbuOoKFw', + 'title' => 'MERCY SAID NO!', + 'description' => 'Judy Jacobs sings MERCY SAID NO!', + ]); + + $this->actingAs($user) + ->visit('video/myvideos') + ->see('MERCY SAID NO!'); + } + + /** + * Test the videos can be edited. + * + * @return void + */ + public function testVideosEdited() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class)->create(); + + $video = factory(Soma\Videos::class)->create([ + 'category_id' => $category->id, + 'user_id' => $user->id, + 'youtube_link' => 'https://www.youtube.com/embed/6R0YdAnASc8&index=23&list=RDH1XrbuOoKFw', + 'title' => 'MERCY SAID NO!', + 'description' => 'Judy Jacobs sings MERCY SAID NO!', + ]); + + $this->actingAs($user) + ->visit("video/{$video->id}/edit") + ->see('MERCY SAID NO!') + ->type('Gospel - Mercy Said No!', 'title') + ->type('Mercy Said No song as sang by Judy Jacobs', 'description') + ->press('Save'); + + $this->seeInDatabase( + 'videos', + [ + 'title' => 'Gospel - Mercy Said No!', + 'description' => 'Mercy Said No song as sang by Judy Jacobs', + ] + ); + } + + /** + * Test the videos can be deleted. + * + * @return void + */ + public function testVideosDeleted() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class)->create(); + + $video = factory(Soma\Videos::class)->create([ + 'category_id' => $category->id, + 'user_id' => $user->id, + 'youtube_link' => 'https://www.youtube.com/embed/z3wwWFsSlNQ&list=RDH1XrbuOoKFw&index=27', + 'title' => 'Still - Hillsong United with Lyrics!', + 'description' => "Appreciating God's love for us as Jesus died on the cross to save our souls", + ]); + + $this->withoutMiddleware(); + $response = $this->call('DELETE', "/video/$video->id"); + $this->assertEquals(302, $response->getStatusCode()); + + + $this->notSeeInDatabase( + 'videos', + [ + 'title' => 'Still - Hillsong United with Lyrics!', + 'description' => "Appreciating God's love for us as Jesus died on the cross to save our souls", + ] + ); + } + + + /** + * Test a video can be viewed on its own page. + * + * @return void + */ + public function testSingleVideoViewed() + { + $user = factory(Soma\User::class)->create(); + $category = factory(Soma\Categories::class)->create(); + + $video = factory(Soma\Videos::class)->create([ + 'category_id' => $category->id, + 'user_id' => $user->id, + 'youtube_link' => 'https://www.youtube.com/embed/gIPMllUV12o&list=RDH1XrbuOoKFw&index=27', + 'title' => 'My life is in your hands', + 'description' => "Kirk Franklin's Gospel song," + ]); + + $this->actingAs($user) + ->visit('video/myvideos') + ->see('My life is in your hands') + ->click('More Info') + ->seePageIs("video/{$video->id}"); + } +}