├── .idea ├── .name ├── misc.xml ├── scopes │ └── scope_settings.xml ├── encodings.xml ├── vcs.xml ├── modules.xml └── hotel.iml ├── public ├── favicon.ico ├── robots.txt ├── hotel │ ├── .bowerrc │ ├── app │ │ ├── view1 │ │ │ ├── view1.html │ │ │ ├── view1.js │ │ │ └── view1_test.js │ │ ├── view2 │ │ │ ├── view2.html │ │ │ ├── view2.js │ │ │ └── view2_test.js │ │ ├── components │ │ │ └── version │ │ │ │ ├── version.js │ │ │ │ ├── version-directive.js │ │ │ │ ├── interpolate-filter.js │ │ │ │ ├── version_test.js │ │ │ │ ├── interpolate-filter_test.js │ │ │ │ └── version-directive_test.js │ │ ├── app.js │ │ ├── book │ │ │ ├── book.js │ │ │ ├── finalize.js │ │ │ ├── book.html │ │ │ └── finalize.html │ │ ├── room_admin │ │ │ ├── room_admin.js │ │ │ └── room_admin.html │ │ ├── payment │ │ │ ├── pay.js │ │ │ └── pay.html │ │ ├── index.html │ │ ├── index-async.html │ │ └── app.css │ ├── .gitignore │ ├── .jshintrc │ ├── e2e-tests │ │ ├── protractor.conf.js │ │ └── scenarios.js │ ├── .travis.yml │ ├── bower.json │ ├── karma.conf.js │ ├── LICENSE │ ├── package.json │ └── README.md ├── .htaccess └── index.php ├── app ├── Listeners │ └── .gitkeep ├── Events │ └── Event.php ├── Http │ ├── Requests │ │ └── Request.php │ ├── Controllers │ │ ├── Controller.php │ │ ├── RoomTypeController.php │ │ ├── Auth │ │ │ ├── PasswordController.php │ │ │ └── AuthController.php │ │ ├── PaymentController.php │ │ ├── ReservationController.php │ │ └── RoomCalendarController.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── VerifyCsrfToken.php │ │ ├── RedirectIfAuthenticated.php │ │ └── Authenticate.php │ ├── Kernel.php │ └── routes.php ├── RoomType.php ├── RoomCalendar.php ├── Customer.php ├── ReservationNight.php ├── Reservation.php ├── Providers │ ├── AppServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── Jobs │ └── Job.php ├── Console │ ├── Commands │ │ └── Inspire.php │ └── Kernel.php ├── User.php └── Exceptions │ └── Handler.php ├── database ├── seeds │ ├── .gitkeep │ └── DatabaseSeeder.php ├── migrations │ ├── .gitkeep │ ├── 2015_08_04_170359_create_table_customers.php │ ├── 2015_08_04_170329_create_table_reservation_nights.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2015_08_04_170246_create_table_room_type.php │ ├── 2015_08_04_170254_create_table_reservations.php │ ├── 2015_08_04_170250_create_table_room_calendar.php │ └── 2014_10_12_000000_create_users_table.php ├── .gitignore └── factories │ └── ModelFactory.php ├── resources ├── views │ ├── vendor │ │ └── .gitkeep │ ├── welcome.blade.php │ └── errors │ │ └── 503.blade.php ├── assets │ └── sass │ │ └── app.scss └── lang │ └── en │ ├── pagination.php │ ├── passwords.php │ └── validation.php ├── storage ├── app │ └── .gitignore ├── logs │ └── .gitignore └── framework │ ├── cache │ └── .gitignore │ ├── views │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── bootstrap ├── cache │ └── .gitignore ├── autoload.php └── app.php ├── .gitattributes ├── phpspec.yml ├── package.json ├── .gitignore ├── .env.example ├── tests ├── ExampleTest.php └── TestCase.php ├── gulpfile.js ├── server.php ├── readme.md ├── phpunit.xml ├── config ├── services.php ├── compile.php ├── view.php ├── broadcasting.php ├── cache.php ├── auth.php ├── filesystems.php ├── queue.php ├── database.php ├── mail.php ├── session.php └── app.php ├── composer.json └── artisan /.idea/.name: -------------------------------------------------------------------------------- 1 | hotel -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/Listeners/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/seeds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/migrations/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /resources/views/vendor/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/hotel/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } -------------------------------------------------------------------------------- /public/hotel/app/view1/view1.html: -------------------------------------------------------------------------------- 1 |

This is the partial for view 1.

2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.less linguist-vendored 4 | -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | // @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; 2 | 3 | -------------------------------------------------------------------------------- /app/Events/Event.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /public/hotel/app/view2/view2.html: -------------------------------------------------------------------------------- 1 |

This is the partial for view 2.

2 |

3 | Showing of 'interpolate' filter: 4 | {{ 'Current version is v%VERSION%.' | interpolate }} 5 |

6 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/Http/Requests/Request.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/hotel.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/hotel/app/components/version/interpolate-filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.version.interpolate-filter', []) 4 | 5 | .filter('interpolate', ['version', function(version) { 6 | return function(text) { 7 | return String(text).replace(/\%VERSION\%/mg, version); 8 | }; 9 | }]); 10 | -------------------------------------------------------------------------------- /app/RoomCalendar.php: -------------------------------------------------------------------------------- 1 | hasOne('App\RoomType'); 13 | } 14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /public/hotel/app/view1/view1.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.view1', ['ngRoute']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/view1', { 7 | templateUrl: 'view1/view1.html', 8 | controller: 'View1Ctrl' 9 | }); 10 | }]) 11 | 12 | .controller('View1Ctrl', [function() { 13 | 14 | }]); -------------------------------------------------------------------------------- /public/hotel/app/view2/view2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.view2', ['ngRoute']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/view2', { 7 | templateUrl: 'view2/view2.html', 8 | controller: 'View2Ctrl' 9 | }); 10 | }]) 11 | 12 | .controller('View2Ctrl', [function() { 13 | 14 | }]); -------------------------------------------------------------------------------- /public/hotel/app/components/version/version_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.version module', function() { 4 | beforeEach(module('myApp.version')); 5 | 6 | describe('version service', function() { 7 | it('should return current version', inject(function(version) { 8 | expect(version).toEqual('0.1'); 9 | })); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /app/Customer.php: -------------------------------------------------------------------------------- 1 | hasOne('App\Reservation'); 14 | } 15 | 16 | function RoomType() 17 | { 18 | return $this->hasOne('App\RoomType'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UserTableSeeder::class); 18 | 19 | Model::reguard(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Reservation.php: -------------------------------------------------------------------------------- 1 | hasMany('App\ReservationNight'); 14 | } 15 | 16 | function Customer(){ 17 | return $this->belongsTo('App\Customer'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/hotel/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | before_script: 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start 8 | - npm start > /dev/null & 9 | - npm run update-webdriver 10 | - sleep 1 # give server time to start 11 | 12 | script: 13 | - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox 14 | - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox 15 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes If Not A Folder... 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ /$1 [L,R=301] 11 | 12 | # Handle Front Controller... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_FILENAME} !-f 15 | RewriteRule ^ index.php [L] 16 | 17 | -------------------------------------------------------------------------------- /tests/ExampleTest.php: -------------------------------------------------------------------------------- 1 | visit('/') 17 | ->see('Laravel 5'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/hotel/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-seed", 3 | "description": "A starter project for AngularJS", 4 | "version": "0.0.0", 5 | "homepage": "https://github.com/angular/angular-seed", 6 | "license": "MIT", 7 | "private": true, 8 | "dependencies": { 9 | "angular": "~1.4.0", 10 | "angular-route": "~1.4.0", 11 | "angular-loader": "~1.4.0", 12 | "angular-mocks": "~1.4.0", 13 | "html5-boilerplate": "~5.2.0", 14 | "angular-materialize": "*", 15 | "angular-payments": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/hotel/app/components/version/interpolate-filter_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.version module', function() { 4 | beforeEach(module('myApp.version')); 5 | 6 | describe('interpolate filter', function() { 7 | beforeEach(module(function($provide) { 8 | $provide.value('version', 'TEST_VER'); 9 | })); 10 | 11 | it('should replace VERSION', inject(function(interpolateFilter) { 12 | expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after'); 13 | })); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | ')($rootScope); 13 | expect(element.text()).toEqual('TEST_VER'); 14 | }); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /app/Http/Controllers/RoomTypeController.php: -------------------------------------------------------------------------------- 1 | all()); 24 | $room_type->save(); 25 | 26 | return $room_type; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Jobs/Job.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); 22 | 23 | return $app; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /database/factories/ModelFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function ($faker) { 15 | return [ 16 | 'name' => $faker->name, 17 | 'email' => $faker->email, 18 | 'password' => str_random(10), 19 | 'remember_token' => str_random(10), 20 | ]; 21 | }); 22 | -------------------------------------------------------------------------------- /database/migrations/2015_08_04_170359_create_table_customers.php: -------------------------------------------------------------------------------- 1 | increments('id'); 13 | $table->string('first_name'); 14 | $table->string('last_name'); 15 | $table->string('email'); 16 | $table->date('created_at'); 17 | $table->date('updated_at'); 18 | }); 19 | } 20 | 21 | public function down() 22 | { 23 | Schema::drop('customers'); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Console/Commands/Inspire.php: -------------------------------------------------------------------------------- 1 | comment(PHP_EOL.Inspiring::quote().PHP_EOL); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /public/hotel/app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Declare app level module which depends on views, and components 4 | angular.module('myApp', [ 5 | 'ngRoute', 6 | 'myApp.view1', 7 | 'myApp.view2', 8 | 'myApp.version', 9 | 'myApp.roomAdmin', 10 | 'myApp.book', 11 | 'myApp.finalize', 12 | 'myApp.pay','angularPayments' 13 | ]). 14 | config(['$routeProvider', function($routeProvider) { 15 | 16 | $routeProvider.otherwise({redirectTo: '/room_type'}); 17 | 18 | }]) 19 | 20 | 21 | 22 | .service('reservationData', function () { 23 | 24 | var hashtable = {}; 25 | 26 | return { 27 | setValue: function (key, value) { 28 | hashtable[key] = value; 29 | }, 30 | getValue: function (key) { 31 | return hashtable[key]; 32 | } 33 | } 34 | }); -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | ->hourly(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2015_08_04_170329_create_table_reservation_nights.php: -------------------------------------------------------------------------------- 1 | increments('id'); 13 | $table->float('rate'); 14 | $table->date('day'); 15 | $table->integer('room_type_id'); 16 | $table->integer('reservation_id'); 17 | $table->date('created_at'); 18 | $table->date('updated_at'); 19 | }); 20 | } 21 | 22 | 23 | public function down() 24 | { 25 | Schema::drop('reservation_nights'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 17 | $table->string('token')->index(); 18 | $table->timestamp('created_at'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::drop('password_resets'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/migrations/2015_08_04_170246_create_table_room_type.php: -------------------------------------------------------------------------------- 1 | increments('id'); 12 | $table->string('name', 100); 13 | $table->string('short_name',10); 14 | $table->float('base_price'); 15 | $table->integer('base_availability'); 16 | $table->integer('max_occupancy'); 17 | $table->date('created_at'); 18 | $table->date('updated_at'); 19 | }); 20 | 21 | } 22 | 23 | public function down() 24 | { 25 | Schema::drop('room_types'); 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /database/migrations/2015_08_04_170254_create_table_reservations.php: -------------------------------------------------------------------------------- 1 | increments('id'); 13 | $table->float('total_price'); 14 | $table->integer('occupancy'); 15 | $table->date('checkin'); 16 | $table->date('checkout'); 17 | $table->string('customer_id'); 18 | $table->date('created_at'); 19 | $table->date('updated_at'); 20 | }); 21 | } 22 | 23 | public function down() 24 | { 25 | Schema::drop('reservations'); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/hotel/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config){ 2 | config.set({ 3 | 4 | basePath : './', 5 | 6 | files : [ 7 | 'app/bower_components/angular/angular.js', 8 | 'app/bower_components/angular-route/angular-route.js', 9 | 'app/bower_components/angular-mocks/angular-mocks.js', 10 | 'app/components/**/*.js', 11 | 'app/view*/**/*.js' 12 | ], 13 | 14 | autoWatch : true, 15 | 16 | frameworks: ['jasmine'], 17 | 18 | browsers : ['Chrome'], 19 | 20 | plugins : [ 21 | 'karma-chrome-launcher', 22 | 'karma-firefox-launcher', 23 | 'karma-jasmine', 24 | 'karma-junit-reporter' 25 | ], 26 | 27 | junitReporter : { 28 | outputFile: 'test_out/unit.xml', 29 | suite: 'unit' 30 | } 31 | 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /database/migrations/2015_08_04_170250_create_table_room_calendar.php: -------------------------------------------------------------------------------- 1 | increments('id'); 13 | $table->integer('room_type_id'); 14 | $table->integer('availability'); 15 | $table->integer('reservations'); 16 | $table->float('rate'); 17 | $table->date('day'); 18 | $table->date('created_at'); 19 | $table->date('updated_at'); 20 | }); 21 | } 22 | 23 | 24 | public function down() 25 | { 26 | Schema::drop('room_calendars'); 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'user' => "We can't find a user with that e-mail address.", 18 | 'token' => 'This password reset token is invalid.', 19 | 'sent' => 'We have e-mailed your password reset link!', 20 | 'reset' => 'Your password has been reset!', 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'App\Listeners\EventListener', 18 | ], 19 | ]; 20 | 21 | /** 22 | * Register any other events for your application. 23 | * 24 | * @param \Illuminate\Contracts\Events\Dispatcher $events 25 | * @return void 26 | */ 27 | public function boot(DispatcherContract $events) 28 | { 29 | parent::boot($events); 30 | 31 | // 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 17 | $table->string('name'); 18 | $table->string('email')->unique(); 19 | $table->string('password', 60); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::drop('users'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## How to build an hotel booking system with Laravel 5.1 and AngularJS 2 | A tutorial series from [CODETutorial.io](http://codetutorial.io) . 3 | 4 | The tutorial will explain how to create an hotel booking system from scratch using Laravel 5.1 and AngularJS. For this booking engine we will use AngularJS to create a single page application, the front end, where the final user can make reservations and the hotel owner can manage rooms, price and reservations. On the backend side we will use Laravel to create all the needed REST API to serve the application. 5 | 6 | ## Tutorial articles 7 | * [Part 1 - Setup Laravel and Datamodel](http://www.codetutorial.io/hotel-booking-with-laravel-5-and-angularjs-p1/) 8 | * [Part 2 - Setup AngularJS](http://www.codetutorial.io/hotel-booking-engine-with-laravel-5-and-angularjs-p2/) 9 | * [Part 3 - Complete the reservation system ](http://www.codetutorial.io/hotel-booking-engine-with-laravel-5-and-angularjs-part-3/) 10 | 11 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/PasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 26 | } 27 | 28 | /** 29 | * Handle an incoming request. 30 | * 31 | * @param \Illuminate\Http\Request $request 32 | * @param \Closure $next 33 | * @return mixed 34 | */ 35 | public function handle($request, Closure $next) 36 | { 37 | if ($this->auth->check()) { 38 | return redirect('/home'); 39 | } 40 | 41 | return $next($request); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Controllers/PaymentController.php: -------------------------------------------------------------------------------- 1 | charge($total_price, 23 | [ 24 | 'source' => $token, 25 | 'receipt_email' => $customer->email 26 | ])) 27 | { 28 | $mess = ['status' => "OK","message" =>"Payment ok"]; 29 | return $mess; 30 | }else{ 31 | $mess = ['status' => "ERROR","message" =>"Error submitting payment"]; 32 | return $mess; 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/User.php: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | app/ 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => '', 19 | 'secret' => '', 20 | ], 21 | 22 | 'mandrill' => [ 23 | 'secret' => '', 24 | ], 25 | 26 | 'ses' => [ 27 | 'key' => '', 28 | 'secret' => '', 29 | 'region' => 'us-east-1', 30 | ], 31 | 32 | 'stripe' => [ 33 | 'model' => App\Customer::class, 34 | 'key' => 'pk_test_p0QQDCeJQA7W9X9y0VP7QOz5', 35 | 'secret' => 'sk_test_vkLyPOI6CcWC2xtrSa2r90up', 36 | ], 37 | 38 | ]; 39 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 26 | } 27 | 28 | /** 29 | * Handle an incoming request. 30 | * 31 | * @param \Illuminate\Http\Request $request 32 | * @param \Closure $next 33 | * @return mixed 34 | */ 35 | public function handle($request, Closure $next) 36 | { 37 | if ($this->auth->guest()) { 38 | if ($request->ajax()) { 39 | return response('Unauthorized.', 401); 40 | } else { 41 | return redirect()->guest('auth/login'); 42 | } 43 | } 44 | 45 | return $next($request); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | \App\Http\Middleware\Authenticate::class, 30 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 31 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 32 | ]; 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/routes.php: -------------------------------------------------------------------------------- 1 | 'api'], function() { 19 | Route::post('searchavailabity', 'RoomCalendarController@searchAvailability'); 20 | Route::post('createreservation', 'ReservationController@createReservation'); 21 | Route::get('reservation/{id}', 'ReservationController@show'); 22 | Route::post('payreservation', 'PaymentController@pay'); 23 | 24 | }); 25 | 26 | Route::group(['prefix' => 'adminapi'], function() 27 | { 28 | Route::resource('room_type', 'RoomTypeController'); 29 | Route::post('setpriceinrange', 'RoomCalendarController@setPriceInRangeForRoomType'); 30 | 31 | 32 | }); -------------------------------------------------------------------------------- /config/compile.php: -------------------------------------------------------------------------------- 1 | [ 17 | // 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled File Providers 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may list service providers which define a "compiles" function 26 | | that returns additional files that should be compiled, providing an 27 | | easy way to get common files from any packages you are utilizing. 28 | | 29 | */ 30 | 31 | 'providers' => [ 32 | // 33 | ], 34 | 35 | ]; 36 | -------------------------------------------------------------------------------- /public/hotel/e2e-tests/scenarios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* https://github.com/angular/protractor/blob/master/docs/toc.md */ 4 | 5 | describe('my app', function() { 6 | 7 | 8 | it('should automatically redirect to /view1 when location hash/fragment is empty', function() { 9 | browser.get('index.html'); 10 | expect(browser.getLocationAbsUrl()).toMatch("/view1"); 11 | }); 12 | 13 | 14 | describe('view1', function() { 15 | 16 | beforeEach(function() { 17 | browser.get('index.html#/view1'); 18 | }); 19 | 20 | 21 | it('should render view1 when user navigates to /view1', function() { 22 | expect(element.all(by.css('[ng-view] p')).first().getText()). 23 | toMatch(/partial for view 1/); 24 | }); 25 | 26 | }); 27 | 28 | 29 | describe('view2', function() { 30 | 31 | beforeEach(function() { 32 | browser.get('index.html#/view2'); 33 | }); 34 | 35 | 36 | it('should render view2 when user navigates to /view2', function() { 37 | expect(element.all(by.css('[ng-view] p')).first().getText()). 38 | toMatch(/partial for view 2/); 39 | }); 40 | 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | realpath(base_path('resources/views')), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Laravel 5 | 6 | 7 | 8 | 37 | 38 | 39 |
40 |
41 |
Laravel 5
42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | group(['namespace' => $this->namespace], function ($router) { 41 | require app_path('Http/routes.php'); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Be right back. 5 | 6 | 7 | 8 | 39 | 40 | 41 |
42 |
43 |
Be right back.
44 |
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /public/hotel/app/book/book.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.book', ['ngRoute','ui.materialize']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/book', { 7 | templateUrl: 'book/book.html', 8 | controller: 'BookController' 9 | }); 10 | }]) 11 | 12 | .controller('BookController', function($scope,$http,reservationData,$location) { 13 | 14 | 15 | $scope.select_occupancy = [1,2,3,4,5]; 16 | $scope.available_room_types; 17 | $scope.search_param={}; 18 | 19 | $scope.search = function(){ 20 | 21 | $http.post('/api/searchavailabity',$scope.search_param).success(function(data){ 22 | $scope.available_room_types = data; 23 | }); 24 | 25 | }; 26 | 27 | $scope.book = function (id) { 28 | 29 | console.log($scope.search_param); 30 | 31 | reservationData.setValue('start_dt',$scope.search_param.start_dt); 32 | reservationData.setValue('end_dt',$scope.search_param.end_dt); 33 | reservationData.setValue('occupancy',$scope.search_param.min_occupancy); 34 | reservationData.setValue('room_info', $scope.available_room_types[id]); 35 | 36 | 37 | $location.path( "/finalize" ); 38 | 39 | }; 40 | 41 | } 42 | ); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "description": "The Laravel Framework.", 4 | "keywords": ["framework", "laravel"], 5 | "license": "MIT", 6 | "type": "project", 7 | "require": { 8 | "php": ">=5.5.9", 9 | "laravel/framework": "5.1.*" 10 | }, 11 | "require-dev": { 12 | "fzaninotto/faker": "~1.4", 13 | "mockery/mockery": "0.9.*", 14 | "phpunit/phpunit": "~4.0", 15 | "phpspec/phpspec": "~2.1", 16 | "laravel/cashier": "~5.0" 17 | }, 18 | "autoload": { 19 | "classmap": [ 20 | "database" 21 | ], 22 | "psr-4": { 23 | "App\\": "app/" 24 | } 25 | }, 26 | "autoload-dev": { 27 | "classmap": [ 28 | "tests/TestCase.php" 29 | ] 30 | }, 31 | "scripts": { 32 | "post-install-cmd": [ 33 | "php artisan clear-compiled", 34 | "php artisan optimize" 35 | ], 36 | "pre-update-cmd": [ 37 | "php artisan clear-compiled" 38 | ], 39 | "post-update-cmd": [ 40 | "php artisan optimize" 41 | ], 42 | "post-root-package-install": [ 43 | "php -r \"copy('.env.example', '.env');\"" 44 | ], 45 | "post-create-project-cmd": [ 46 | "php artisan key:generate" 47 | ] 48 | }, 49 | "config": { 50 | "preferred-install": "dist" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'pusher'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Broadcast Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may define all of the broadcast connections that will be used 24 | | to broadcast events to other systems or over websockets. Samples of 25 | | each available type of connection are provided inside this array. 26 | | 27 | */ 28 | 29 | 'connections' => [ 30 | 31 | 'pusher' => [ 32 | 'driver' => 'pusher', 33 | 'key' => env('PUSHER_KEY'), 34 | 'secret' => env('PUSHER_SECRET'), 35 | 'app_id' => env('PUSHER_APP_ID'), 36 | ], 37 | 38 | 'redis' => [ 39 | 'driver' => 'redis', 40 | 'connection' => 'default', 41 | ], 42 | 43 | 'log' => [ 44 | 'driver' => 'log', 45 | ], 46 | 47 | ], 48 | 49 | ]; 50 | -------------------------------------------------------------------------------- /public/hotel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-seed", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "A starter project for AngularJS", 6 | "repository": "https://github.com/angular/angular-seed", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "bower": "^1.3.1", 10 | "http-server": "^0.6.1", 11 | "jasmine-core": "^2.3.4", 12 | "karma": "~0.12", 13 | "karma-chrome-launcher": "^0.1.12", 14 | "karma-firefox-launcher": "^0.1.6", 15 | "karma-jasmine": "^0.3.5", 16 | "karma-junit-reporter": "^0.2.2", 17 | "protractor": "^2.1.0", 18 | "shelljs": "^0.2.6" 19 | }, 20 | "scripts": { 21 | "postinstall": "bower install", 22 | 23 | "prestart": "npm install", 24 | "start": "http-server -a localhost -p 8000 -c-1", 25 | 26 | "pretest": "npm install", 27 | "test": "karma start karma.conf.js", 28 | "test-single-run": "karma start karma.conf.js --single-run", 29 | 30 | "preupdate-webdriver": "npm install", 31 | "update-webdriver": "webdriver-manager update", 32 | 33 | "preprotractor": "npm run update-webdriver", 34 | "protractor": "protractor e2e-tests/protractor.conf.js", 35 | 36 | "update-index-async": "node -e \"require('shelljs/global'); sed('-i', /\\/\\/@@NG_LOADER_START@@[\\s\\S]*\\/\\/@@NG_LOADER_END@@/, '//@@NG_LOADER_START@@\\n' + sed(/sourceMappingURL=angular-loader.min.js.map/,'sourceMappingURL=bower_components/angular-loader/angular-loader.min.js.map','app/bower_components/angular-loader/angular-loader.min.js') + '\\n//@@NG_LOADER_END@@', 'app/index-async.html');\"" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 32 | 33 | $status = $kernel->handle( 34 | $input = new Symfony\Component\Console\Input\ArgvInput, 35 | new Symfony\Component\Console\Output\ConsoleOutput 36 | ); 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Shutdown The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once Artisan has finished running. We will fire off the shutdown events 44 | | so that any final work may be done by the application before we shut 45 | | down the process. This is the last thing to happen to the request. 46 | | 47 | */ 48 | 49 | $kernel->terminate($input, $status); 50 | 51 | exit($status); 52 | -------------------------------------------------------------------------------- /public/hotel/app/room_admin/room_admin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.roomAdmin', ['ngRoute','ui.materialize']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/room_admin', { 7 | templateUrl: 'room_admin/room_admin.html', 8 | controller: 'RoomAdminCtrl' 9 | }); 10 | }]) 11 | 12 | .controller('RoomAdminCtrl', function($scope,$http,$location) { 13 | 14 | $scope.room_types = []; 15 | $scope.new_type = {}; 16 | $scope.selected_idx; 17 | $scope.selected_type= {}; 18 | $scope.message=null; 19 | $scope.update_data= {}; 20 | 21 | $scope.init = function(){ 22 | $http.get('/adminapi/room_type').success(function(data){ 23 | $scope.room_types=data; 24 | }); 25 | } 26 | 27 | $scope.init(); 28 | 29 | $scope.create = function(){ 30 | $http.post('/adminapi/room_type',$scope.new_type).success(function(data){ 31 | 32 | $scope.room_types.push(data); 33 | $scope.new_type.name=""; 34 | $scope.new_type.short_name=""; 35 | $scope.new_type.base_price=""; 36 | $scope.new_type.base_availability=""; 37 | $scope.new_type.max_occupancy=""; 38 | 39 | }); 40 | }; 41 | 42 | $scope.select_type = function(index){ 43 | $scope.selected_idx=index; 44 | $scope.selected_type =$scope.room_types[index]; 45 | $scope.update_data.room_type= $scope.selected_type.id; 46 | $scope.message = null; 47 | 48 | }; 49 | 50 | $scope.setprice = function(){ 51 | 52 | $http.post('/adminapi/setpriceinrange',$scope.update_data).success(function(data){ 53 | $scope.selected_idx=-1; 54 | $scope.selected_type=null; 55 | $scope.update_data={}; 56 | 57 | $scope.message = data; 58 | }); 59 | 60 | } 61 | 62 | } 63 | ); -------------------------------------------------------------------------------- /public/hotel/app/payment/pay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.pay', ['ngRoute','ui.materialize']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/pay/:reserv_id', { 7 | templateUrl: 'payment/pay.html', 8 | controller: 'PayController' 9 | }); 10 | }]) 11 | 12 | .controller('PayController', function($scope,$http,reservationData,$location,$routeParams) { 13 | 14 | $scope.res_id = $routeParams.reserv_id; 15 | $scope.paid = false; 16 | 17 | $scope.handleStripe = function(status, response){ 18 | if(response.error) { 19 | $scope.paid= false; 20 | $scope.message = "Error from Stripe.com" 21 | } else { 22 | console.log(response.id); 23 | var $payInfo = { 24 | 'token' : response.id, 25 | 'customer_id' : $scope.reservation_info.customer_id, 26 | 'total':$scope.reservation_info.total_price 27 | }; 28 | 29 | $http.post('/api/payreservation', $payInfo).success(function(data){ 30 | if(data.status=="OK"){ 31 | $scope.paid= true; 32 | $scope.message = data.message; 33 | }else{ 34 | $scope.paid= false; 35 | $scope.message = data.message; 36 | } 37 | }); 38 | 39 | } 40 | }; 41 | 42 | $scope.init = function(){ 43 | 44 | $scope.loaded = false; 45 | 46 | $http.get('/api/reservation/'+$scope.res_id).success(function(data){ 47 | $scope.reservation_info = data; 48 | console.log(data); 49 | $scope.loaded=true; 50 | }); 51 | }; 52 | 53 | $scope.init(); 54 | 55 | } 56 | ); -------------------------------------------------------------------------------- /public/hotel/app/book/finalize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by andreaterzani on 06/08/15. 3 | */ 4 | 'use strict'; 5 | 6 | angular.module('myApp.finalize', ['ngRoute','ui.materialize']) 7 | 8 | .config(['$routeProvider', function($routeProvider) { 9 | $routeProvider.when('/finalize', { 10 | templateUrl: 'book/finalize.html', 11 | controller: 'FinalizeController' 12 | }); 13 | }]) 14 | 15 | .controller('FinalizeController', function($scope,$http,reservationData,$location) { 16 | 17 | $scope.start_dt; 18 | $scope.end_dt; 19 | $scope.room_info; 20 | $scope.occupancy; 21 | $scope.reservation_info; 22 | $scope.reser_done; 23 | $scope.customer={}; 24 | 25 | $scope.init = function(){ 26 | 27 | 28 | $scope.start_dt = reservationData.getValue('start_dt'); 29 | $scope.end_dt = reservationData.getValue('end_dt'); 30 | $scope.occupancy=reservationData.getValue('occupancy');; 31 | $scope.room_info=reservationData.getValue('room_info'); 32 | 33 | if($scope.room_info==null){ 34 | $location.path('/book'); 35 | } 36 | }; 37 | 38 | $scope.init(); 39 | 40 | $scope.book = function(){ 41 | 42 | var reservationInfo; 43 | console.log($scope.customer); 44 | 45 | reservationInfo = { 46 | 'customer':$scope.customer, 47 | 'room_info':$scope.room_info, 48 | 'start_dt':$scope.start_dt, 49 | 'end_dt':$scope.end_dt, 50 | 'occupancy':$scope.occupancy 51 | }; 52 | 53 | 54 | $http.post('/api/createreservation',reservationInfo).success(function(data){ 55 | 56 | $scope.reser_done=true; 57 | $scope.reservation_info = data; 58 | 59 | 60 | }); 61 | 62 | 63 | } 64 | 65 | 66 | } 67 | ); -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | /* 11 | |-------------------------------------------------------------------------- 12 | | Register The Auto Loader 13 | |-------------------------------------------------------------------------- 14 | | 15 | | Composer provides a convenient, automatically generated class loader for 16 | | our application. We just need to utilize it! We'll simply require it 17 | | into the script here so that we don't have to worry about manual 18 | | loading any of our classes later on. It feels nice to relax. 19 | | 20 | */ 21 | 22 | require __DIR__.'/../bootstrap/autoload.php'; 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Turn On The Lights 27 | |-------------------------------------------------------------------------- 28 | | 29 | | We need to illuminate PHP development, so let us turn on the lights. 30 | | This bootstraps the framework and gets it ready for use, then it 31 | | will load up this application so that we can run it and send 32 | | the responses back to the browser and delight our users. 33 | | 34 | */ 35 | 36 | $app = require_once __DIR__.'/../bootstrap/app.php'; 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Run The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once we have the application, we can handle the incoming request 44 | | through the kernel, and send the associated response back to 45 | | the client's browser allowing them to enjoy the creative 46 | | and wonderful application we have prepared for them. 47 | | 48 | */ 49 | 50 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 51 | 52 | $response = $kernel->handle( 53 | $request = Illuminate\Http\Request::capture() 54 | ); 55 | 56 | $response->send(); 57 | 58 | $kernel->terminate($request, $response); 59 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/AuthController.php: -------------------------------------------------------------------------------- 1 | middleware('guest', ['except' => 'getLogout']); 34 | } 35 | 36 | /** 37 | * Get a validator for an incoming registration request. 38 | * 39 | * @param array $data 40 | * @return \Illuminate\Contracts\Validation\Validator 41 | */ 42 | protected function validator(array $data) 43 | { 44 | return Validator::make($data, [ 45 | 'name' => 'required|max:255', 46 | 'email' => 'required|email|max:255|unique:users', 47 | 'password' => 'required|confirmed|min:6', 48 | ]); 49 | } 50 | 51 | /** 52 | * Create a new user instance after a valid registration. 53 | * 54 | * @param array $data 55 | * @return User 56 | */ 57 | protected function create(array $data) 58 | { 59 | return User::create([ 60 | 'name' => $data['name'], 61 | 'email' => $data['email'], 62 | 'password' => bcrypt($data['password']), 63 | ]); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /public/hotel/app/book/book.html: -------------------------------------------------------------------------------- 1 |
2 |

Search your room

3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 12 | 13 |
14 |
15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 | 23 | 26 |
27 |
28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 | {{room_type.name}} 43 |

Total price : {{room_type.total_price}}

44 |
45 |
46 | Book this 47 |
48 |
49 |
50 |
-------------------------------------------------------------------------------- /public/hotel/app/payment/pay.html: -------------------------------------------------------------------------------- 1 |
2 |

Pay reservation number {{res_id}}

3 |
4 | 5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |

{{message}}

44 |
45 |
46 |
-------------------------------------------------------------------------------- /app/Http/Controllers/ReservationController.php: -------------------------------------------------------------------------------- 1 | toDateString(); 27 | $end_dt= Carbon::createFromFormat('d-m-Y', $request['end_dt'])->toDateString(); 28 | 29 | $customer = Customer::firstOrCreate($request['customer']); 30 | 31 | $reservation = Reservation::create(); 32 | $reservation->total_price=$room_info['total_price']; 33 | $reservation->occupancy=$request['occupancy']; 34 | $reservation->customer_id=$customer->id; 35 | $reservation->checkin=$start_dt; 36 | $reservation->checkout=$end_dt; 37 | 38 | $reservation->save(); 39 | 40 | 41 | $date=$start_dt; 42 | 43 | while (strtotime($date) < strtotime($end_dt)) { 44 | 45 | $room_calendar = RoomCalendar::where('day','=',$date) 46 | ->where('room_type_id','=',$room_info['id'])->first(); 47 | 48 | $night = ReservationNight::create(); 49 | $night->day=$date; 50 | 51 | $night->rate=$room_calendar->rate; 52 | $night->room_type_id=$room_info['id']; 53 | $night->reservation_id=$reservation->id; 54 | 55 | $room_calendar->availability--; 56 | $room_calendar->reservations++; 57 | 58 | $room_calendar->save(); 59 | $night->save(); 60 | 61 | $date = date ("Y-m-d", strtotime("+1 day", strtotime($date))); 62 | 63 | 64 | 65 | } 66 | 67 | $nights = $reservation->nights; 68 | $customer = $reservation->customer; 69 | 70 | 71 | return $reservation; 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Cache Stores 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may define all of the cache "stores" for your application as 24 | | well as their drivers. You may even define multiple stores for the 25 | | same cache driver to group types of items stored in your caches. 26 | | 27 | */ 28 | 29 | 'stores' => [ 30 | 31 | 'apc' => [ 32 | 'driver' => 'apc', 33 | ], 34 | 35 | 'array' => [ 36 | 'driver' => 'array', 37 | ], 38 | 39 | 'database' => [ 40 | 'driver' => 'database', 41 | 'table' => 'cache', 42 | 'connection' => null, 43 | ], 44 | 45 | 'file' => [ 46 | 'driver' => 'file', 47 | 'path' => storage_path('framework/cache'), 48 | ], 49 | 50 | 'memcached' => [ 51 | 'driver' => 'memcached', 52 | 'servers' => [ 53 | [ 54 | 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100, 55 | ], 56 | ], 57 | ], 58 | 59 | 'redis' => [ 60 | 'driver' => 'redis', 61 | 'connection' => 'default', 62 | ], 63 | 64 | ], 65 | 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Cache Key Prefix 69 | |-------------------------------------------------------------------------- 70 | | 71 | | When utilizing a RAM based store such as APC or Memcached, there might 72 | | be other applications utilizing the same cache. So, we'll specify a 73 | | value to get prefixed to all our keys so we can avoid collisions. 74 | | 75 | */ 76 | 77 | 'prefix' => 'laravel', 78 | 79 | ]; 80 | -------------------------------------------------------------------------------- /config/auth.php: -------------------------------------------------------------------------------- 1 | 'eloquent', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Authentication Model 23 | |-------------------------------------------------------------------------- 24 | | 25 | | When using the "Eloquent" authentication driver, we need to know which 26 | | Eloquent model should be used to retrieve your users. Of course, it 27 | | is often just the "User" model but you may use whatever you like. 28 | | 29 | */ 30 | 31 | 'model' => App\User::class, 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Authentication Table 36 | |-------------------------------------------------------------------------- 37 | | 38 | | When using the "Database" authentication driver, we need to know which 39 | | table should be used to retrieve your users. We have chosen a basic 40 | | default value but you may easily change it to any table you like. 41 | | 42 | */ 43 | 44 | 'table' => 'users', 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Password Reset Settings 49 | |-------------------------------------------------------------------------- 50 | | 51 | | Here you may set the options for resetting passwords including the view 52 | | that is your password reset e-mail. You can also set the name of the 53 | | table that maintains all of the reset tokens for your application. 54 | | 55 | | The expire time is the number of minutes that the reset token should be 56 | | considered valid. This security feature keeps tokens short-lived so 57 | | they have less time to be guessed. You may change this as needed. 58 | | 59 | */ 60 | 61 | 'password' => [ 62 | 'email' => 'emails.password', 63 | 'table' => 'password_resets', 64 | 'expire' => 60, 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /app/Http/Controllers/RoomCalendarController.php: -------------------------------------------------------------------------------- 1 | $room_type, 'day'=>$date)); 29 | 30 | if(!$room_day->id){ 31 | $room_day->availability = $base_room->base_availability; 32 | } 33 | 34 | $room_day->rate = $price; 35 | $room_day->save(); 36 | $date = date ("Y-m-d", strtotime("+1 day", strtotime($date))); 37 | $i++; 38 | } 39 | 40 | return response("Success updated ".$i." dates",200); 41 | } 42 | 43 | 44 | public function searchAvailability(Request $request){ 45 | 46 | 47 | $start_dt = Carbon::createFromFormat('d-m-Y', $request['start_dt'])->toDateTimeString(); 48 | $end_dt = Carbon::createFromFormat('d-m-Y', $request['end_dt'])->toDateTimeString(); 49 | 50 | $min_occupancy = $request['min_occupancy']; 51 | 52 | $room_types = RoomType::where('max_occupancy','>=',$min_occupancy)->get(); 53 | 54 | $available_room_types=array(); 55 | 56 | foreach( $room_types as $room_type){ 57 | 58 | $count = RoomCalendar::where('day','>=',$start_dt) 59 | ->where('day','<',$end_dt) 60 | ->where('room_type_id','=',$room_type->id) 61 | ->where('availability','<=',0)->count(); 62 | 63 | 64 | if($count==0){ 65 | 66 | $total_price = RoomCalendar::where('day','>=',$start_dt) 67 | ->where('day','<',$end_dt) 68 | ->where('room_type_id','=',$room_type->id) 69 | ->sum('rate'); 70 | 71 | $room_type->total_price = $total_price; 72 | 73 | 74 | array_push($available_room_types,$room_type); 75 | } 76 | 77 | } 78 | 79 | return $available_room_types; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /public/hotel/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | My AngularJS App 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 33 | 34 |
35 | 36 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | 'local', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Default Cloud Filesystem Disk 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Many applications store files both locally and in the cloud. For this 26 | | reason, you may specify a default "cloud" driver here. This driver 27 | | will be bound as the Cloud disk implementation in the container. 28 | | 29 | */ 30 | 31 | 'cloud' => 's3', 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Filesystem Disks 36 | |-------------------------------------------------------------------------- 37 | | 38 | | Here you may configure as many filesystem "disks" as you wish, and you 39 | | may even configure multiple disks of the same driver. Defaults have 40 | | been setup for each driver as an example of the required options. 41 | | 42 | */ 43 | 44 | 'disks' => [ 45 | 46 | 'local' => [ 47 | 'driver' => 'local', 48 | 'root' => storage_path('app'), 49 | ], 50 | 51 | 'ftp' => [ 52 | 'driver' => 'ftp', 53 | 'host' => 'ftp.example.com', 54 | 'username' => 'your-username', 55 | 'password' => 'your-password', 56 | 57 | // Optional FTP Settings... 58 | // 'port' => 21, 59 | // 'root' => '', 60 | // 'passive' => true, 61 | // 'ssl' => true, 62 | // 'timeout' => 30, 63 | ], 64 | 65 | 's3' => [ 66 | 'driver' => 's3', 67 | 'key' => 'your-key', 68 | 'secret' => 'your-secret', 69 | 'region' => 'your-region', 70 | 'bucket' => 'your-bucket', 71 | ], 72 | 73 | 'rackspace' => [ 74 | 'driver' => 'rackspace', 75 | 'username' => 'your-username', 76 | 'key' => 'your-key', 77 | 'container' => 'your-container', 78 | 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/', 79 | 'region' => 'IAD', 80 | 'url_type' => 'publicURL', 81 | ], 82 | 83 | ], 84 | 85 | ]; 86 | -------------------------------------------------------------------------------- /public/hotel/app/book/finalize.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 | Booking recap 7 |

Check-in : {{start_dt}}

8 |

Check-out : {{end_dt}}

9 |

Passenger : {{occupancy}}

10 |

Room : {{room_info.name}}

11 |

Total price : {{room_info.total_price}}

12 |
13 |
14 |
15 |
16 |
17 |
18 |

Customer info

19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 |
43 |
44 |
45 |

Reservation

46 |

Customer info

47 |

Name : {{reservation_info.customer.first_name}}

48 |

Last name : {{reservation_info.customer.last_name}}

49 |

Email : {{reservation_info.customer.email}}

50 |

Reservation info

51 |

Check-in : {{reservation_info.checkin}}

52 |

Check-out : {{reservation_info.checkout}}

53 |

Adults : {{reservation_info.occupancy}}

54 |

Total Price : {{reservation_info.total_price}}

55 |

Nights info

56 |

57 | Day {{night.day}} - Rate : {{night.rate}} 58 |

59 | 60 |
61 |
62 |
63 |
64 | 65 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_DRIVER', 'sync'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Queue Connections 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may configure the connection information for each server that 27 | | is used by your application. A default configuration has been added 28 | | for each back-end shipped with Laravel. You are free to add more. 29 | | 30 | */ 31 | 32 | 'connections' => [ 33 | 34 | 'sync' => [ 35 | 'driver' => 'sync', 36 | ], 37 | 38 | 'database' => [ 39 | 'driver' => 'database', 40 | 'table' => 'jobs', 41 | 'queue' => 'default', 42 | 'expire' => 60, 43 | ], 44 | 45 | 'beanstalkd' => [ 46 | 'driver' => 'beanstalkd', 47 | 'host' => 'localhost', 48 | 'queue' => 'default', 49 | 'ttr' => 60, 50 | ], 51 | 52 | 'sqs' => [ 53 | 'driver' => 'sqs', 54 | 'key' => 'your-public-key', 55 | 'secret' => 'your-secret-key', 56 | 'queue' => 'your-queue-url', 57 | 'region' => 'us-east-1', 58 | ], 59 | 60 | 'iron' => [ 61 | 'driver' => 'iron', 62 | 'host' => 'mq-aws-us-east-1.iron.io', 63 | 'token' => 'your-token', 64 | 'project' => 'your-project-id', 65 | 'queue' => 'your-queue-name', 66 | 'encrypt' => true, 67 | ], 68 | 69 | 'redis' => [ 70 | 'driver' => 'redis', 71 | 'connection' => 'default', 72 | 'queue' => 'default', 73 | 'expire' => 60, 74 | ], 75 | 76 | ], 77 | 78 | /* 79 | |-------------------------------------------------------------------------- 80 | | Failed Queue Jobs 81 | |-------------------------------------------------------------------------- 82 | | 83 | | These options configure the behavior of failed queue job logging so you 84 | | can control which database and table are used to store the jobs that 85 | | have failed. You may change them to any database / table you wish. 86 | | 87 | */ 88 | 89 | 'failed' => [ 90 | 'database' => 'mysql', 'table' => 'failed_jobs', 91 | ], 92 | 93 | ]; 94 | -------------------------------------------------------------------------------- /public/hotel/app/index-async.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 44 | My AngularJS App 45 | 46 | 47 | 48 | 52 | 53 |
54 | 55 |
Angular seed app: v
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /public/hotel/app/room_admin/room_admin.html: -------------------------------------------------------------------------------- 1 |
2 |

Room admin

3 |
4 |
5 |
6 |
7 |
Create new room Type
8 |
9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 |
17 |
18 |
19 |
20 | 21 | 22 |
23 |
24 | 25 | 26 |
27 |
28 |
29 |
30 | 31 | 32 |
33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 |
Set price for room Types
41 |
42 | {{room_type.name}} 43 |
44 |
45 | Set price for {{ selected_type.name}} 46 |
47 | 48 | 49 |
50 |
51 | 52 | 53 |
54 |
55 | 56 | 57 |
58 | 59 |
60 |
61 |
62 | {{message}} 63 |
64 |
65 |
66 |
67 |
68 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | PDO::FETCH_CLASS, 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Default Database Connection Name 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may specify which of the database connections below you wish 24 | | to use as your default connection for all database work. Of course 25 | | you may use many connections at once using the Database library. 26 | | 27 | */ 28 | 29 | 'default' => env('DB_CONNECTION', 'mysql'), 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Database Connections 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here are each of the database connections setup for your application. 37 | | Of course, examples of configuring each database platform that is 38 | | supported by Laravel is shown below to make development simple. 39 | | 40 | | 41 | | All database work in Laravel is done through the PHP PDO facilities 42 | | so make sure you have the driver for your particular database of 43 | | choice installed on your machine before you begin development. 44 | | 45 | */ 46 | 47 | 'connections' => [ 48 | 49 | 'sqlite' => [ 50 | 'driver' => 'sqlite', 51 | 'database' => storage_path('database.sqlite'), 52 | 'prefix' => '', 53 | ], 54 | 55 | 'mysql' => [ 56 | 'driver' => 'mysql', 57 | 'host' => env('DB_HOST', 'localhost'), 58 | 'database' => env('DB_DATABASE', 'forge'), 59 | 'username' => env('DB_USERNAME', 'forge'), 60 | 'password' => env('DB_PASSWORD', ''), 61 | 'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock', 62 | 'charset' => 'utf8', 63 | 'collation' => 'utf8_unicode_ci', 64 | 'prefix' => '', 65 | 'strict' => false, 66 | ], 67 | 68 | 'pgsql' => [ 69 | 'driver' => 'pgsql', 70 | 'host' => env('DB_HOST', 'localhost'), 71 | 'database' => env('DB_DATABASE', 'forge'), 72 | 'username' => env('DB_USERNAME', 'forge'), 73 | 'password' => env('DB_PASSWORD', ''), 74 | 'charset' => 'utf8', 75 | 'prefix' => '', 76 | 'schema' => 'public', 77 | ], 78 | 79 | 'sqlsrv' => [ 80 | 'driver' => 'sqlsrv', 81 | 'host' => env('DB_HOST', 'localhost'), 82 | 'database' => env('DB_DATABASE', 'forge'), 83 | 'username' => env('DB_USERNAME', 'forge'), 84 | 'password' => env('DB_PASSWORD', ''), 85 | 'charset' => 'utf8', 86 | 'prefix' => '', 87 | ], 88 | 89 | ], 90 | 91 | /* 92 | |-------------------------------------------------------------------------- 93 | | Migration Repository Table 94 | |-------------------------------------------------------------------------- 95 | | 96 | | This table keeps track of all the migrations that have already run for 97 | | your application. Using this information, we can determine which of 98 | | the migrations on disk haven't actually been run in the database. 99 | | 100 | */ 101 | 102 | 'migrations' => 'migrations', 103 | 104 | /* 105 | |-------------------------------------------------------------------------- 106 | | Redis Databases 107 | |-------------------------------------------------------------------------- 108 | | 109 | | Redis is an open source, fast, and advanced key-value store that also 110 | | provides a richer set of commands than a typical key-value systems 111 | | such as APC or Memcached. Laravel makes it easy to dig right in. 112 | | 113 | */ 114 | 115 | 'redis' => [ 116 | 117 | 'cluster' => false, 118 | 119 | 'default' => [ 120 | 'host' => '127.0.0.1', 121 | 'port' => 6379, 122 | 'database' => 0, 123 | ], 124 | 125 | ], 126 | 127 | ]; 128 | -------------------------------------------------------------------------------- /config/mail.php: -------------------------------------------------------------------------------- 1 | env('MAIL_DRIVER', 'smtp'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | SMTP Host Address 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may provide the host address of the SMTP server used by your 26 | | applications. A default option is provided that is compatible with 27 | | the Mailgun mail service which will provide reliable deliveries. 28 | | 29 | */ 30 | 31 | 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | SMTP Host Port 36 | |-------------------------------------------------------------------------- 37 | | 38 | | This is the SMTP port used by your application to deliver e-mails to 39 | | users of the application. Like the host we have set this value to 40 | | stay compatible with the Mailgun e-mail application by default. 41 | | 42 | */ 43 | 44 | 'port' => env('MAIL_PORT', 587), 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Global "From" Address 49 | |-------------------------------------------------------------------------- 50 | | 51 | | You may wish for all e-mails sent by your application to be sent from 52 | | the same address. Here, you may specify a name and address that is 53 | | used globally for all e-mails that are sent by your application. 54 | | 55 | */ 56 | 57 | 'from' => ['address' => null, 'name' => null], 58 | 59 | /* 60 | |-------------------------------------------------------------------------- 61 | | E-Mail Encryption Protocol 62 | |-------------------------------------------------------------------------- 63 | | 64 | | Here you may specify the encryption protocol that should be used when 65 | | the application send e-mail messages. A sensible default using the 66 | | transport layer security protocol should provide great security. 67 | | 68 | */ 69 | 70 | 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 71 | 72 | /* 73 | |-------------------------------------------------------------------------- 74 | | SMTP Server Username 75 | |-------------------------------------------------------------------------- 76 | | 77 | | If your SMTP server requires a username for authentication, you should 78 | | set it here. This will get used to authenticate with your server on 79 | | connection. You may also set the "password" value below this one. 80 | | 81 | */ 82 | 83 | 'username' => env('MAIL_USERNAME'), 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | SMTP Server Password 88 | |-------------------------------------------------------------------------- 89 | | 90 | | Here you may set the password required by your SMTP server to send out 91 | | messages from your application. This will be given to the server on 92 | | connection so that the application will be able to send messages. 93 | | 94 | */ 95 | 96 | 'password' => env('MAIL_PASSWORD'), 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | Sendmail System Path 101 | |-------------------------------------------------------------------------- 102 | | 103 | | When using the "sendmail" driver to send e-mails, we will need to know 104 | | the path to where Sendmail lives on this server. A default path has 105 | | been provided here, which will work well on most of your systems. 106 | | 107 | */ 108 | 109 | 'sendmail' => '/usr/sbin/sendmail -bs', 110 | 111 | /* 112 | |-------------------------------------------------------------------------- 113 | | Mail "Pretend" 114 | |-------------------------------------------------------------------------- 115 | | 116 | | When this option is enabled, e-mail will not actually be sent over the 117 | | web and will instead be written to your application's logs files so 118 | | you may inspect the message. This is great for local development. 119 | | 120 | */ 121 | 122 | 'pretend' => false, 123 | 124 | ]; 125 | -------------------------------------------------------------------------------- /config/session.php: -------------------------------------------------------------------------------- 1 | env('SESSION_DRIVER', 'file'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Session Lifetime 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may specify the number of minutes that you wish the session 27 | | to be allowed to remain idle before it expires. If you want them 28 | | to immediately expire on the browser closing, set that option. 29 | | 30 | */ 31 | 32 | 'lifetime' => 120, 33 | 34 | 'expire_on_close' => false, 35 | 36 | /* 37 | |-------------------------------------------------------------------------- 38 | | Session Encryption 39 | |-------------------------------------------------------------------------- 40 | | 41 | | This option allows you to easily specify that all of your session data 42 | | should be encrypted before it is stored. All encryption will be run 43 | | automatically by Laravel and you can use the Session like normal. 44 | | 45 | */ 46 | 47 | 'encrypt' => false, 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Session File Location 52 | |-------------------------------------------------------------------------- 53 | | 54 | | When using the native session driver, we need a location where session 55 | | files may be stored. A default has been set for you but a different 56 | | location may be specified. This is only needed for file sessions. 57 | | 58 | */ 59 | 60 | 'files' => storage_path('framework/sessions'), 61 | 62 | /* 63 | |-------------------------------------------------------------------------- 64 | | Session Database Connection 65 | |-------------------------------------------------------------------------- 66 | | 67 | | When using the "database" or "redis" session drivers, you may specify a 68 | | connection that should be used to manage these sessions. This should 69 | | correspond to a connection in your database configuration options. 70 | | 71 | */ 72 | 73 | 'connection' => null, 74 | 75 | /* 76 | |-------------------------------------------------------------------------- 77 | | Session Database Table 78 | |-------------------------------------------------------------------------- 79 | | 80 | | When using the "database" session driver, you may specify the table we 81 | | should use to manage the sessions. Of course, a sensible default is 82 | | provided for you; however, you are free to change this as needed. 83 | | 84 | */ 85 | 86 | 'table' => 'sessions', 87 | 88 | /* 89 | |-------------------------------------------------------------------------- 90 | | Session Sweeping Lottery 91 | |-------------------------------------------------------------------------- 92 | | 93 | | Some session drivers must manually sweep their storage location to get 94 | | rid of old sessions from storage. Here are the chances that it will 95 | | happen on a given request. By default, the odds are 2 out of 100. 96 | | 97 | */ 98 | 99 | 'lottery' => [2, 100], 100 | 101 | /* 102 | |-------------------------------------------------------------------------- 103 | | Session Cookie Name 104 | |-------------------------------------------------------------------------- 105 | | 106 | | Here you may change the name of the cookie used to identify a session 107 | | instance by ID. The name specified here will get used every time a 108 | | new session cookie is created by the framework for every driver. 109 | | 110 | */ 111 | 112 | 'cookie' => 'laravel_session', 113 | 114 | /* 115 | |-------------------------------------------------------------------------- 116 | | Session Cookie Path 117 | |-------------------------------------------------------------------------- 118 | | 119 | | The session cookie path determines the path for which the cookie will 120 | | be regarded as available. Typically, this will be the root path of 121 | | your application but you are free to change this when necessary. 122 | | 123 | */ 124 | 125 | 'path' => '/', 126 | 127 | /* 128 | |-------------------------------------------------------------------------- 129 | | Session Cookie Domain 130 | |-------------------------------------------------------------------------- 131 | | 132 | | Here you may change the domain of the cookie used to identify a session 133 | | in your application. This will determine which domains the cookie is 134 | | available to in your application. A sensible default has been set. 135 | | 136 | */ 137 | 138 | 'domain' => null, 139 | 140 | /* 141 | |-------------------------------------------------------------------------- 142 | | HTTPS Only Cookies 143 | |-------------------------------------------------------------------------- 144 | | 145 | | By setting this option to true, session cookies will only be sent back 146 | | to the server if the browser has a HTTPS connection. This will keep 147 | | the cookie from being sent to you if it can not be done securely. 148 | | 149 | */ 150 | 151 | 'secure' => false, 152 | 153 | ]; 154 | -------------------------------------------------------------------------------- /resources/lang/en/validation.php: -------------------------------------------------------------------------------- 1 | 'The :attribute must be accepted.', 17 | 'active_url' => 'The :attribute is not a valid URL.', 18 | 'after' => 'The :attribute must be a date after :date.', 19 | 'alpha' => 'The :attribute may only contain letters.', 20 | 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', 21 | 'alpha_num' => 'The :attribute may only contain letters and numbers.', 22 | 'array' => 'The :attribute must be an array.', 23 | 'before' => 'The :attribute must be a date before :date.', 24 | 'between' => [ 25 | 'numeric' => 'The :attribute must be between :min and :max.', 26 | 'file' => 'The :attribute must be between :min and :max kilobytes.', 27 | 'string' => 'The :attribute must be between :min and :max characters.', 28 | 'array' => 'The :attribute must have between :min and :max items.', 29 | ], 30 | 'boolean' => 'The :attribute field must be true or false.', 31 | 'confirmed' => 'The :attribute confirmation does not match.', 32 | 'date' => 'The :attribute is not a valid date.', 33 | 'date_format' => 'The :attribute does not match the format :format.', 34 | 'different' => 'The :attribute and :other must be different.', 35 | 'digits' => 'The :attribute must be :digits digits.', 36 | 'digits_between' => 'The :attribute must be between :min and :max digits.', 37 | 'email' => 'The :attribute must be a valid email address.', 38 | 'filled' => 'The :attribute field is required.', 39 | 'exists' => 'The selected :attribute is invalid.', 40 | 'image' => 'The :attribute must be an image.', 41 | 'in' => 'The selected :attribute is invalid.', 42 | 'integer' => 'The :attribute must be an integer.', 43 | 'ip' => 'The :attribute must be a valid IP address.', 44 | 'max' => [ 45 | 'numeric' => 'The :attribute may not be greater than :max.', 46 | 'file' => 'The :attribute may not be greater than :max kilobytes.', 47 | 'string' => 'The :attribute may not be greater than :max characters.', 48 | 'array' => 'The :attribute may not have more than :max items.', 49 | ], 50 | 'mimes' => 'The :attribute must be a file of type: :values.', 51 | 'min' => [ 52 | 'numeric' => 'The :attribute must be at least :min.', 53 | 'file' => 'The :attribute must be at least :min kilobytes.', 54 | 'string' => 'The :attribute must be at least :min characters.', 55 | 'array' => 'The :attribute must have at least :min items.', 56 | ], 57 | 'not_in' => 'The selected :attribute is invalid.', 58 | 'numeric' => 'The :attribute must be a number.', 59 | 'regex' => 'The :attribute format is invalid.', 60 | 'required' => 'The :attribute field is required.', 61 | 'required_if' => 'The :attribute field is required when :other is :value.', 62 | 'required_with' => 'The :attribute field is required when :values is present.', 63 | 'required_with_all' => 'The :attribute field is required when :values is present.', 64 | 'required_without' => 'The :attribute field is required when :values is not present.', 65 | 'required_without_all' => 'The :attribute field is required when none of :values are present.', 66 | 'same' => 'The :attribute and :other must match.', 67 | 'size' => [ 68 | 'numeric' => 'The :attribute must be :size.', 69 | 'file' => 'The :attribute must be :size kilobytes.', 70 | 'string' => 'The :attribute must be :size characters.', 71 | 'array' => 'The :attribute must contain :size items.', 72 | ], 73 | 'string' => 'The :attribute must be a string.', 74 | 'timezone' => 'The :attribute must be a valid zone.', 75 | 'unique' => 'The :attribute has already been taken.', 76 | 'url' => 'The :attribute format is invalid.', 77 | 78 | /* 79 | |-------------------------------------------------------------------------- 80 | | Custom Validation Language Lines 81 | |-------------------------------------------------------------------------- 82 | | 83 | | Here you may specify custom validation messages for attributes using the 84 | | convention "attribute.rule" to name the lines. This makes it quick to 85 | | specify a specific custom language line for a given attribute rule. 86 | | 87 | */ 88 | 89 | 'custom' => [ 90 | 'attribute-name' => [ 91 | 'rule-name' => 'custom-message', 92 | ], 93 | ], 94 | 95 | /* 96 | |-------------------------------------------------------------------------- 97 | | Custom Validation Attributes 98 | |-------------------------------------------------------------------------- 99 | | 100 | | The following language lines are used to swap attribute place-holders 101 | | with something more reader friendly such as E-Mail Address instead 102 | | of "email". This simply helps us make messages a little cleaner. 103 | | 104 | */ 105 | 106 | 'attributes' => [], 107 | 108 | ]; 109 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | env('APP_DEBUG', false), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Application URL 21 | |-------------------------------------------------------------------------- 22 | | 23 | | This URL is used by the console to properly generate URLs when using 24 | | the Artisan command line tool. You should set this to the root of 25 | | your application so that it is used when running Artisan tasks. 26 | | 27 | */ 28 | 29 | 'url' => 'http://localhost', 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Application Timezone 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here you may specify the default timezone for your application, which 37 | | will be used by the PHP date and date-time functions. We have gone 38 | | ahead and set this to a sensible default for you out of the box. 39 | | 40 | */ 41 | 42 | 'timezone' => 'UTC', 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Application Locale Configuration 47 | |-------------------------------------------------------------------------- 48 | | 49 | | The application locale determines the default locale that will be used 50 | | by the translation service provider. You are free to set this value 51 | | to any of the locales which will be supported by the application. 52 | | 53 | */ 54 | 55 | 'locale' => 'en', 56 | 57 | /* 58 | |-------------------------------------------------------------------------- 59 | | Application Fallback Locale 60 | |-------------------------------------------------------------------------- 61 | | 62 | | The fallback locale determines the locale to use when the current one 63 | | is not available. You may change the value to correspond to any of 64 | | the language folders that are provided through your application. 65 | | 66 | */ 67 | 68 | 'fallback_locale' => 'en', 69 | 70 | /* 71 | |-------------------------------------------------------------------------- 72 | | Encryption Key 73 | |-------------------------------------------------------------------------- 74 | | 75 | | This key is used by the Illuminate encrypter service and should be set 76 | | to a random, 32 character string, otherwise these encrypted strings 77 | | will not be safe. Please do this before deploying an application! 78 | | 79 | */ 80 | 81 | 'key' => env('APP_KEY', 'SomeRandomString'), 82 | 83 | 'cipher' => 'AES-256-CBC', 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | Logging Configuration 88 | |-------------------------------------------------------------------------- 89 | | 90 | | Here you may configure the log settings for your application. Out of 91 | | the box, Laravel uses the Monolog PHP logging library. This gives 92 | | you a variety of powerful log handlers / formatters to utilize. 93 | | 94 | | Available Settings: "single", "daily", "syslog", "errorlog" 95 | | 96 | */ 97 | 98 | 'log' => 'single', 99 | 100 | /* 101 | |-------------------------------------------------------------------------- 102 | | Autoloaded Service Providers 103 | |-------------------------------------------------------------------------- 104 | | 105 | | The service providers listed here will be automatically loaded on the 106 | | request to your application. Feel free to add your own services to 107 | | this array to grant expanded functionality to your applications. 108 | | 109 | */ 110 | 111 | 'providers' => [ 112 | 113 | /* 114 | * Laravel Framework Service Providers... 115 | */ 116 | Illuminate\Foundation\Providers\ArtisanServiceProvider::class, 117 | Illuminate\Auth\AuthServiceProvider::class, 118 | Illuminate\Broadcasting\BroadcastServiceProvider::class, 119 | Illuminate\Bus\BusServiceProvider::class, 120 | Illuminate\Cache\CacheServiceProvider::class, 121 | Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, 122 | Illuminate\Routing\ControllerServiceProvider::class, 123 | Illuminate\Cookie\CookieServiceProvider::class, 124 | Illuminate\Database\DatabaseServiceProvider::class, 125 | Illuminate\Encryption\EncryptionServiceProvider::class, 126 | Illuminate\Filesystem\FilesystemServiceProvider::class, 127 | Illuminate\Foundation\Providers\FoundationServiceProvider::class, 128 | Illuminate\Hashing\HashServiceProvider::class, 129 | Illuminate\Mail\MailServiceProvider::class, 130 | Illuminate\Pagination\PaginationServiceProvider::class, 131 | Illuminate\Pipeline\PipelineServiceProvider::class, 132 | Illuminate\Queue\QueueServiceProvider::class, 133 | Illuminate\Redis\RedisServiceProvider::class, 134 | Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, 135 | Illuminate\Session\SessionServiceProvider::class, 136 | Illuminate\Translation\TranslationServiceProvider::class, 137 | Illuminate\Validation\ValidationServiceProvider::class, 138 | Illuminate\View\ViewServiceProvider::class, 139 | /* 140 | * Application Service Providers... 141 | */ 142 | App\Providers\AppServiceProvider::class, 143 | App\Providers\EventServiceProvider::class, 144 | App\Providers\RouteServiceProvider::class, 145 | ], 146 | 147 | /* 148 | |-------------------------------------------------------------------------- 149 | | Class Aliases 150 | |-------------------------------------------------------------------------- 151 | | 152 | | This array of class aliases will be registered when this application 153 | | is started. However, feel free to register as many as you wish as 154 | | the aliases are "lazy" loaded so they don't hinder performance. 155 | | 156 | */ 157 | 158 | 'aliases' => [ 159 | 160 | 'App' => Illuminate\Support\Facades\App::class, 161 | 'Artisan' => Illuminate\Support\Facades\Artisan::class, 162 | 'Auth' => Illuminate\Support\Facades\Auth::class, 163 | 'Blade' => Illuminate\Support\Facades\Blade::class, 164 | 'Bus' => Illuminate\Support\Facades\Bus::class, 165 | 'Cache' => Illuminate\Support\Facades\Cache::class, 166 | 'Config' => Illuminate\Support\Facades\Config::class, 167 | 'Cookie' => Illuminate\Support\Facades\Cookie::class, 168 | 'Crypt' => Illuminate\Support\Facades\Crypt::class, 169 | 'DB' => Illuminate\Support\Facades\DB::class, 170 | 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 171 | 'Event' => Illuminate\Support\Facades\Event::class, 172 | 'File' => Illuminate\Support\Facades\File::class, 173 | 'Hash' => Illuminate\Support\Facades\Hash::class, 174 | 'Input' => Illuminate\Support\Facades\Input::class, 175 | 'Inspiring' => Illuminate\Foundation\Inspiring::class, 176 | 'Lang' => Illuminate\Support\Facades\Lang::class, 177 | 'Log' => Illuminate\Support\Facades\Log::class, 178 | 'Mail' => Illuminate\Support\Facades\Mail::class, 179 | 'Password' => Illuminate\Support\Facades\Password::class, 180 | 'Queue' => Illuminate\Support\Facades\Queue::class, 181 | 'Redirect' => Illuminate\Support\Facades\Redirect::class, 182 | 'Redis' => Illuminate\Support\Facades\Redis::class, 183 | 'Request' => Illuminate\Support\Facades\Request::class, 184 | 'Response' => Illuminate\Support\Facades\Response::class, 185 | 'Route' => Illuminate\Support\Facades\Route::class, 186 | 'Schema' => Illuminate\Support\Facades\Schema::class, 187 | 'Session' => Illuminate\Support\Facades\Session::class, 188 | 'Storage' => Illuminate\Support\Facades\Storage::class, 189 | 'URL' => Illuminate\Support\Facades\URL::class, 190 | 'Validator' => Illuminate\Support\Facades\Validator::class, 191 | 'View' => Illuminate\Support\Facades\View::class, 192 | 193 | ], 194 | 195 | ]; 196 | -------------------------------------------------------------------------------- /public/hotel/README.md: -------------------------------------------------------------------------------- 1 | # angular-seed — the seed for AngularJS apps 2 | 3 | This project is an application skeleton for a typical [AngularJS](http://angularjs.org/) web app. 4 | You can use it to quickly bootstrap your angular webapp projects and dev environment for these 5 | projects. 6 | 7 | The seed contains a sample AngularJS application and is preconfigured to install the Angular 8 | framework and a bunch of development and testing tools for instant web development gratification. 9 | 10 | The seed app doesn't do much, just shows how to wire two controllers and views together. 11 | 12 | 13 | ## Getting Started 14 | 15 | To get you started you can simply clone the angular-seed repository and install the dependencies: 16 | 17 | ### Prerequisites 18 | 19 | You need git to clone the angular-seed repository. You can get git from 20 | [http://git-scm.com/](http://git-scm.com/). 21 | 22 | We also use a number of node.js tools to initialize and test angular-seed. You must have node.js and 23 | its package manager (npm) installed. You can get them from [http://nodejs.org/](http://nodejs.org/). 24 | 25 | ### Clone angular-seed 26 | 27 | Clone the angular-seed repository using [git][git]: 28 | 29 | ``` 30 | git clone https://github.com/angular/angular-seed.git 31 | cd angular-seed 32 | ``` 33 | 34 | If you just want to start a new project without the angular-seed commit history then you can do: 35 | 36 | ```bash 37 | git clone --depth=1 https://github.com/angular/angular-seed.git 38 | ``` 39 | 40 | The `depth=1` tells git to only pull down one commit worth of historical data. 41 | 42 | ### Install Dependencies 43 | 44 | We have two kinds of dependencies in this project: tools and angular framework code. The tools help 45 | us manage and test the application. 46 | 47 | * We get the tools we depend upon via `npm`, the [node package manager][npm]. 48 | * We get the angular code via `bower`, a [client-side code package manager][bower]. 49 | 50 | We have preconfigured `npm` to automatically run `bower` so we can simply do: 51 | 52 | ``` 53 | npm install 54 | ``` 55 | 56 | Behind the scenes this will also call `bower install`. You should find that you have two new 57 | folders in your project. 58 | 59 | * `node_modules` - contains the npm packages for the tools we need 60 | * `app/bower_components` - contains the angular framework files 61 | 62 | *Note that the `bower_components` folder would normally be installed in the root folder but 63 | angular-seed changes this location through the `.bowerrc` file. Putting it in the app folder makes 64 | it easier to serve the files by a webserver.* 65 | 66 | ### Run the Application 67 | 68 | We have preconfigured the project with a simple development web server. The simplest way to start 69 | this server is: 70 | 71 | ``` 72 | npm start 73 | ``` 74 | 75 | Now browse to the app at `http://localhost:8000/app/index.html`. 76 | 77 | 78 | 79 | ## Directory Layout 80 | 81 | ``` 82 | app/ --> all of the source files for the application 83 | app.css --> default stylesheet 84 | components/ --> all app specific modules 85 | version/ --> version related components 86 | version.js --> version module declaration and basic "version" value service 87 | version_test.js --> "version" value service tests 88 | version-directive.js --> custom directive that returns the current app version 89 | version-directive_test.js --> version directive tests 90 | interpolate-filter.js --> custom interpolation filter 91 | interpolate-filter_test.js --> interpolate filter tests 92 | view1/ --> the view1 view template and logic 93 | view1.html --> the partial template 94 | room_admin.js --> the controller logic 95 | view1_test.js --> tests of the controller 96 | view2/ --> the view2 view template and logic 97 | view2.html --> the partial template 98 | view2.js --> the controller logic 99 | view2_test.js --> tests of the controller 100 | app.js --> main application module 101 | index.html --> app layout file (the main html template file of the app) 102 | index-async.html --> just like index.html, but loads js files asynchronously 103 | karma.conf.js --> config file for running unit tests with Karma 104 | e2e-tests/ --> end-to-end tests 105 | protractor-conf.js --> Protractor config file 106 | scenarios.js --> end-to-end scenarios to be run by Protractor 107 | ``` 108 | 109 | ## Testing 110 | 111 | There are two kinds of tests in the angular-seed application: Unit tests and End to End tests. 112 | 113 | ### Running Unit Tests 114 | 115 | The angular-seed app comes preconfigured with unit tests. These are written in 116 | [Jasmine][jasmine], which we run with the [Karma Test Runner][karma]. We provide a Karma 117 | configuration file to run them. 118 | 119 | * the configuration is found at `karma.conf.js` 120 | * the unit tests are found next to the code they are testing and are named as `..._test.js`. 121 | 122 | The easiest way to run the unit tests is to use the supplied npm script: 123 | 124 | ``` 125 | npm test 126 | ``` 127 | 128 | This script will start the Karma test runner to execute the unit tests. Moreover, Karma will sit and 129 | watch the source and test files for changes and then re-run the tests whenever any of them change. 130 | This is the recommended strategy; if your unit tests are being run every time you save a file then 131 | you receive instant feedback on any changes that break the expected code functionality. 132 | 133 | You can also ask Karma to do a single run of the tests and then exit. This is useful if you want to 134 | check that a particular version of the code is operating as expected. The project contains a 135 | predefined script to do this: 136 | 137 | ``` 138 | npm run test-single-run 139 | ``` 140 | 141 | 142 | ### End to end testing 143 | 144 | The angular-seed app comes with end-to-end tests, again written in [Jasmine][jasmine]. These tests 145 | are run with the [Protractor][protractor] End-to-End test runner. It uses native events and has 146 | special features for Angular applications. 147 | 148 | * the configuration is found at `e2e-tests/protractor-conf.js` 149 | * the end-to-end tests are found in `e2e-tests/scenarios.js` 150 | 151 | Protractor simulates interaction with our web app and verifies that the application responds 152 | correctly. Therefore, our web server needs to be serving up the application, so that Protractor 153 | can interact with it. 154 | 155 | ``` 156 | npm start 157 | ``` 158 | 159 | In addition, since Protractor is built upon WebDriver we need to install this. The angular-seed 160 | project comes with a predefined script to do this: 161 | 162 | ``` 163 | npm run update-webdriver 164 | ``` 165 | 166 | This will download and install the latest version of the stand-alone WebDriver tool. 167 | 168 | Once you have ensured that the development web server hosting our application is up and running 169 | and WebDriver is updated, you can run the end-to-end tests using the supplied npm script: 170 | 171 | ``` 172 | npm run protractor 173 | ``` 174 | 175 | This script will execute the end-to-end tests against the application being hosted on the 176 | development server. 177 | 178 | 179 | ## Updating Angular 180 | 181 | Previously we recommended that you merge in changes to angular-seed into your own fork of the project. 182 | Now that the angular framework library code and tools are acquired through package managers (npm and 183 | bower) you can use these tools instead to update the dependencies. 184 | 185 | You can update the tool dependencies by running: 186 | 187 | ``` 188 | npm update 189 | ``` 190 | 191 | This will find the latest versions that match the version ranges specified in the `package.json` file. 192 | 193 | You can update the Angular dependencies by running: 194 | 195 | ``` 196 | bower update 197 | ``` 198 | 199 | This will find the latest versions that match the version ranges specified in the `bower.json` file. 200 | 201 | 202 | ## Loading Angular Asynchronously 203 | 204 | The angular-seed project supports loading the framework and application scripts asynchronously. The 205 | special `index-async.html` is designed to support this style of loading. For it to work you must 206 | inject a piece of Angular JavaScript into the HTML page. The project has a predefined script to help 207 | do this. 208 | 209 | ``` 210 | npm run update-index-async 211 | ``` 212 | 213 | This will copy the contents of the `angular-loader.js` library file into the `index-async.html` page. 214 | You can run this every time you update the version of Angular that you are using. 215 | 216 | 217 | ## Serving the Application Files 218 | 219 | While angular is client-side-only technology and it's possible to create angular webapps that 220 | don't require a backend server at all, we recommend serving the project files using a local 221 | webserver during development to avoid issues with security restrictions (sandbox) in browsers. The 222 | sandbox implementation varies between browsers, but quite often prevents things like cookies, xhr, 223 | etc to function properly when an html page is opened via `file://` scheme instead of `http://`. 224 | 225 | 226 | ### Running the App during Development 227 | 228 | The angular-seed project comes preconfigured with a local development webserver. It is a node.js 229 | tool called [http-server][http-server]. You can start this webserver with `npm start` but you may choose to 230 | install the tool globally: 231 | 232 | ``` 233 | sudo npm install -g http-server 234 | ``` 235 | 236 | Then you can start your own development web server to serve static files from a folder by 237 | running: 238 | 239 | ``` 240 | http-server -a localhost -p 8000 241 | ``` 242 | 243 | Alternatively, you can choose to configure your own webserver, such as apache or nginx. Just 244 | configure your server to serve the files under the `app/` directory. 245 | 246 | 247 | ### Running the App in Production 248 | 249 | This really depends on how complex your app is and the overall infrastructure of your system, but 250 | the general rule is that all you need in production are all the files under the `app/` directory. 251 | Everything else should be omitted. 252 | 253 | Angular apps are really just a bunch of static html, css and js files that just need to be hosted 254 | somewhere they can be accessed by browsers. 255 | 256 | If your Angular app is talking to the backend server via xhr or other means, you need to figure 257 | out what is the best way to host the static files to comply with the same origin policy if 258 | applicable. Usually this is done by hosting the files by the backend server or through 259 | reverse-proxying the backend server(s) and webserver(s). 260 | 261 | 262 | ## Continuous Integration 263 | 264 | ### Travis CI 265 | 266 | [Travis CI][travis] is a continuous integration service, which can monitor GitHub for new commits 267 | to your repository and execute scripts such as building the app or running tests. The angular-seed 268 | project contains a Travis configuration file, `.travis.yml`, which will cause Travis to run your 269 | tests when you push to GitHub. 270 | 271 | You will need to enable the integration between Travis and GitHub. See the Travis website for more 272 | instruction on how to do this. 273 | 274 | ### CloudBees 275 | 276 | CloudBees have provided a CI/deployment setup: 277 | 278 | 279 | 280 | 281 | If you run this, you will get a cloned version of this repo to start working on in a private git repo, 282 | along with a CI service (in Jenkins) hosted that will run unit and end to end tests in both Firefox and Chrome. 283 | 284 | 285 | ## Contact 286 | 287 | For more information on AngularJS please check out http://angularjs.org/ 288 | 289 | [git]: http://git-scm.com/ 290 | [bower]: http://bower.io 291 | [npm]: https://www.npmjs.org/ 292 | [node]: http://nodejs.org 293 | [protractor]: https://github.com/angular/protractor 294 | [jasmine]: http://jasmine.github.io 295 | [karma]: http://karma-runner.github.io 296 | [travis]: https://travis-ci.org/ 297 | [http-server]: https://github.com/nodeapps/http-server 298 | -------------------------------------------------------------------------------- /public/hotel/app/app.css: -------------------------------------------------------------------------------- 1 | /* app css stylesheet */ 2 | 3 | .menu { 4 | list-style: none; 5 | border-bottom: 0.1em solid black; 6 | margin-bottom: 2em; 7 | padding: 0 0 0.5em; 8 | } 9 | 10 | .menu:before { 11 | content: "["; 12 | } 13 | 14 | .menu:after { 15 | content: "]"; 16 | } 17 | 18 | .menu > li { 19 | display: inline; 20 | } 21 | 22 | .menu > li:before { 23 | content: "|"; 24 | padding-right: 0.3em; 25 | } 26 | 27 | .menu > li:nth-child(1):before { 28 | content: ""; 29 | padding: 0; 30 | } 31 | 32 | 33 | 34 | .ng-invalid { 35 | border-color: #f00 !important; 36 | } 37 | .visa { 38 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iNjU5LjA1NXB4IiBoZWlnaHQ9IjIwMi4wNjlweCIgdmlld0JveD0iMCAwIDY1OS4wNTUgMjAyLjA2OSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjU5LjA1NSAyMDIuMDY5Ig0KCSB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxnPg0KCQk8cG9seWdvbiBmaWxsPSIjMDAyNDlGIiBwb2ludHM9IjIzMi4xNzgsMTk5LjE2NCAyNjUuNTM5LDMuNDAyIDMxOC44OTgsMy40MDIgMjg1LjUxNCwxOTkuMTY0IAkJIi8+DQoJCTxwYXRoIGZpbGw9IiMwMDI0OUYiIGQ9Ik00NzkuMDQsOC4yMjJDNDY4LjQ2OCw0LjI1Niw0NTEuOTA0LDAsNDMxLjIxNywwYy01Mi43MjQsMC04OS44NjMsMjYuNTUyLTkwLjE4LDY0LjYwNA0KCQkJYy0wLjI5NywyOC4xMjksMjYuNTE0LDQzLjgyLDQ2Ljc1NCw1My4xODVjMjAuNzcsOS41OTUsMjcuNzUyLDE1LjcxNSwyNy42NTIsMjQuMjgzYy0wLjEzMSwxMy4xMjItMTYuNTg2LDE5LjExNy0zMS45MjIsMTkuMTE3DQoJCQljLTIxLjM1NywwLTMyLjcwMy0yLjk2Ny01MC4yMjctMTAuMjc2bC02Ljg3Ni0zLjExMWwtNy40ODksNDMuODIzYzEyLjQ2Miw1LjQ2NCwzNS41MDksMTAuMTk5LDU5LjQzOCwxMC40NDQNCgkJCWM1Ni4wODksMCw5Mi41MDEtMjYuMjQ3LDkyLjkxNS02Ni44ODJjMC4yMDEtMjIuMjctMTQuMDE2LTM5LjIxNy00NC43OTktNTMuMTg4Yy0xOC42NTEtOS4wNTYtMzAuMDczLTE1LjA5OS0yOS45NTItMjQuMjY5DQoJCQljMC04LjEzNyw5LjY2OC0xNi44MzgsMzAuNTU3LTE2LjgzOGMxNy40NDktMC4yNzEsMzAuMDg4LDMuNTM0LDM5LjkzNyw3LjVsNC43ODEsMi4yNTlMNDc5LjA0LDguMjIyIi8+DQoJCTxwYXRoIGZpbGw9IiMwMDI0OUYiIGQ9Ik02MTUuODY3LDMuNTg5aC00MS4yMzFjLTEyLjc3MiwwLTIyLjMzMSwzLjQ4Ni0yNy45NCwxNi4yMzRMNDY3LjQ1LDE5OS4yMjZoNTYuMDMxDQoJCQljMCwwLDkuMTYxLTI0LjEyMiwxMS4yMzMtMjkuNDE4YzYuMTIzLDAsNjAuNTU1LDAuMDg0LDY4LjMzNiwwLjA4NGMxLjU5Nyw2Ljg1Myw2LjQ5MiwyOS4zMzQsNi40OTIsMjkuMzM0aDQ5LjUxMkw2MTUuODY3LDMuNTg5DQoJCQkgTTU1MC4wNywxMjkuNzY3YzQuNDEzLTExLjI3OSwyMS4yNTktNTQuNzI0LDIxLjI1OS01NC43MjRjLTAuMzE1LDAuNTIxLDQuMzgtMTEuMzM0LDcuMDc1LTE4LjY4NGwzLjYwNiwxNi44NzgNCgkJCWMwLDAsMTAuMjE3LDQ2LjcyOSwxMi4zNTMsNTYuNTI4TDU1MC4wNywxMjkuNzY3TDU1MC4wNywxMjkuNzY3eiIvPg0KCQk8cGF0aCBmaWxsPSIjMDAyNDlGIiBkPSJNMTg3LjQyNSwzLjU0NWwtNTIuMjQsMTMzLjQ5NWwtNS41NjYtMjcuMTI5Yy05LjcyNS0zMS4yNzMtNDAuMDI1LTY1LjE1Ni03My44OTktODIuMTE5bDQ3Ljc2NywxNzEuMjAzDQoJCQlsNTYuNDU1LTAuMDY0TDI0My45NDYsMy41NDVIMTg3LjQyNSIvPg0KCQk8cGF0aCBmaWxsPSIjRkZBMDAwIiBkPSJNODYuNzIyLDMuNDI0SDAuNjgxTDAsNy40OTdDNjYuOTM5LDIzLjcwMSwxMTEuMjMyLDYyLjg2LDEyOS42MTgsMTA5LjkxMWwtMTguNzA5LTg5Ljk2DQoJCQlDMTA3LjY3OSw3LjU1NSw5OC4zMTEsMy44NTYsODYuNzIyLDMuNDI0Ii8+DQoJPC9nPg0KPC9nPg0KPC9zdmc+DQo='); 39 | background-size: auto 50%; 40 | background-repeat: no-repeat; 41 | background-position-x: 98%; 42 | background-position-y: 50%; 43 | } 44 | .amex { 45 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iMjgxLjg5MDAxIgogICBoZWlnaHQ9IjEzMC40MjM2MyIKICAgdmlld0JveD0iMCAwIDI4MS44OTAwMSAxMzAuNDIzNjMiCiAgIGlkPSJMYXllcl8xIgogICB4bWw6c3BhY2U9InByZXNlcnZlIj48bWV0YWRhdGEKICAgaWQ9Im1ldGFkYXRhMzgiPjxyZGY6UkRGPjxjYzpXb3JrCiAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUKICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48ZGM6dGl0bGU+PC9kYzp0aXRsZT48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgaWQ9ImRlZnMzNiIgLz4KPHJhZGlhbEdyYWRpZW50CiAgIGN4PSI1Ny4zODgxOTkiCiAgIGN5PSI1Ny4wMjEiCiAgIHI9IjI2NC41Nzk3MSIKICAgaWQ9IlNWR0lEXzFfIgogICBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjAwMTA3NTQsMCwwLDAuNDYwOTE2MjQsLTcuNjQ3MjE1MSwtMy41MDIwNDMpIj4KCTxzdG9wCiAgIGlkPSJzdG9wNCIKICAgc3R5bGU9InN0b3AtY29sb3I6IzlkZDVmNjtzdG9wLW9wYWNpdHk6MSIKICAgb2Zmc2V0PSIwIiAvPgoJPHN0b3AKICAgaWQ9InN0b3A2IgogICBzdHlsZT0ic3RvcC1jb2xvcjojOThkM2Y1O3N0b3Atb3BhY2l0eToxIgogICBvZmZzZXQ9IjAuMDcxMSIgLz4KCTxzdG9wCiAgIGlkPSJzdG9wOCIKICAgc3R5bGU9InN0b3AtY29sb3I6Izg5Y2VmMztzdG9wLW9wYWNpdHk6MSIKICAgb2Zmc2V0PSIwLjE1NzUiIC8+Cgk8c3RvcAogICBpZD0ic3RvcDEwIgogICBzdHlsZT0ic3RvcC1jb2xvcjojNzBjNmVmO3N0b3Atb3BhY2l0eToxIgogICBvZmZzZXQ9IjAuMjUxNiIgLz4KCTxzdG9wCiAgIGlkPSJzdG9wMTIiCiAgIHN0eWxlPSJzdG9wLWNvbG9yOiM0ZWJiZWE7c3RvcC1vcGFjaXR5OjEiCiAgIG9mZnNldD0iMC4zNTEzOTk5OSIgLz4KCTxzdG9wCiAgIGlkPSJzdG9wMTQiCiAgIHN0eWxlPSJzdG9wLWNvbG9yOiMyM2FkZTM7c3RvcC1vcGFjaXR5OjEiCiAgIG9mZnNldD0iMC40NTQ2MDAwMSIgLz4KCTxzdG9wCiAgIGlkPSJzdG9wMTYiCiAgIHN0eWxlPSJzdG9wLWNvbG9yOiMwZGE2ZTA7c3RvcC1vcGFjaXR5OjEiCiAgIG9mZnNldD0iMC41IiAvPgoJPHN0b3AKICAgaWQ9InN0b3AxOCIKICAgc3R5bGU9InN0b3AtY29sb3I6IzJlNzdiYztzdG9wLW9wYWNpdHk6MSIKICAgb2Zmc2V0PSIxIiAvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cGF0aAogICBkPSJNIDI4Mi4yNDgyMSwwIEggMCBWIDEzMC40MjM2MyBIIDI4Mi4yNDgyMSBWIDg3LjM4MDUwNyBjIDEuMTIxMiwtMC43NDYyMiAxLjY3NDgsLTEuNzAwNzggMS42NzQ4LC0yLjg2NzgyIDAsLTEuMzM1NzQgLTAuNTUzNiwtMi4xNjMwOSAtMS42NzQ4LC0yLjg2IgogICBpZD0icGF0aDIwIgogICBzdHlsZT0iZmlsbDp1cmwoI1NWR0lEXzFfKSIgLz4KPGcKICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTcuNjM5LC04OC45NTM5MzMpIgogICBpZD0iZzIyIj4KCTxkZWZzCiAgIGlkPSJkZWZzMjQiPgoJCTxwYXRoCiAgIGQ9Ik0gMjg5LjU4NCw3LjU5OCBIIDcuNjM5IHYgMjgyLjk2NiBoIDI4MS45NDUgdiAtOTMuMzg2IGMgMS4xMiwtMS42MTkgMS42NzMsLTMuNjkgMS42NzMsLTYuMjIyIDAsLTIuODk4IC0wLjU1MywtNC42OTMgLTEuNjczLC02LjIwNSIKICAgaWQ9IlNWR0lEXzJfIiAvPgoJPC9kZWZzPgoJPGNsaXBQYXRoCiAgIGlkPSJTVkdJRF8zXyI+CgkJPHVzZQogICBpZD0idXNlMjgiCiAgIHN0eWxlPSJvdmVyZmxvdzp2aXNpYmxlIgogICB4PSIwIgogICB5PSIwIgogICB3aWR0aD0iMzAwIgogICBoZWlnaHQ9IjMwMCIKICAgeGxpbms6aHJlZj0iI1NWR0lEXzJfIiAvPgoJPC9jbGlwUGF0aD4KPC9nPgo8cGF0aAogICBkPSJtIDI1LjQxNCw0MS4wODgwNjcgLTUuNDI0LC0xMy4yMTcgLTUuMzkzLDEzLjIxNyBtIDEzMC4zMDcsLTUuMjYzIGMgLTEuMDg5LDAuNjYxIC0yLjM3NywwLjY4MyAtMy45MiwwLjY4MyBoIC05LjYyNyB2IC03LjM2NCBoIDkuNzU4IGMgMS4zODEsMCAyLjgyMiwwLjA2MiAzLjc1OCwwLjU5OCAxLjAyOCwwLjQ4MyAxLjY2NCwxLjUxMSAxLjY2NCwyLjkzMSAwLDEuNDQ5IC0wLjYwNSwyLjYxNSAtMS42MzMsMy4xNTIgeiBtIDY4LjY3OCw1LjI2MyAtNS40ODQsLTEzLjIxNyAtNS40NTQsMTMuMjE3IGggMTAuOTM4IHogbSAtMTI4LjAyLDE0LjMwNiBoIC04LjEyNCBsIC0wLjAzLC0yNS45NjYgLTExLjQ5MSwyNS45NjYgaCAtNi45NTggbCAtMTEuNTIxLC0yNS45ODkgdiAyNS45ODkgSCAzMS4zMiBsIC0zLjA0NSwtNy4zOTUgaCAtMTYuNSBsIC0zLjA3Niw3LjM5NSBIIDAuMDkyIGwgMTQuMTkxLC0zMy4xNTQgaCAxMS43NzQgbCAxMy40NzgsMzEuMzkgdiAtMzEuMzkgaCAxMi45MzQgbCAxMC4zNzEsMjIuNDkxIDkuNTI3LC0yMi40OTEgaCAxMy4xOTQgdiAzMy4xNTQgeiBtIDMyLjM3OSwwIEggOTEuNDY4IHYgLTMzLjE1NCBoIDI2LjQ3MyB2IDYuOTA0IEggOTkuMzkzIHYgNS45NzYgaCAxOC4xMDMgdiA2Ljc5NiBIIDk5LjM5MyB2IDYuNjIxIGggMTguNTQ4IHYgNi44NTcgeiBtIDM3LjMyNiwtMjQuMjI1IGMgMCw1LjI4NiAtMy41MjgsOC4wMTcgLTUuNTg0LDguODM3IDEuNzM0LDAuNjYgMy4yMTUsMS44MjYgMy45MiwyLjc5MiAxLjExOSwxLjY0OSAxLjMxMiwzLjEyMiAxLjMxMiw2LjA4MyB2IDYuNTEzIGggLTcuOTkzIGwgLTAuMDMsLTQuMTgxIGMgMCwtMS45OTUgMC4xOTEsLTQuODY0IC0xLjI1MSwtNi40NTkgLTEuMTU4LC0xLjE2NiAtMi45MjMsLTEuNDE5IC01Ljc3NiwtMS40MTkgaCAtOC41MDcgdiAxMi4wNTkgaCAtNy45MjQgdiAtMzMuMTU0IGggMTguMjI3IGMgNC4wNSwwIDcuMDM0LDAuMTA3IDkuNTk2LDEuNTg4IDIuNTA3LDEuNDgxIDQuMDEsMy42NDMgNC4wMSw3LjM0MSB6IG0gMTIuNjgyLDI0LjIyNSBoIC04LjA4NiB2IC0zMy4xNTQgaCA4LjA4NiB2IDMzLjE1NCB6IG0gOTMuODA4LDAgaCAtMTEuMjMgbCAtMTUuMDIxLC0yNC44ODQgdiAyNC44ODQgaCAtMTYuMTM5IGwgLTMuMDg0LC03LjM5NSBoIC0xNi40NjIgbCAtMi45OTIsNy4zOTUgaCAtOS4yNzMgYyAtMy44NTIsMCAtOC43MjksLTAuODUyIC0xMS40OTEsLTMuNjY3IC0yLjc4NSwtMi44MTUgLTQuMjM0LC02LjYyOCAtNC4yMzQsLTEyLjY1NyAwLC00LjkxNyAwLjg2NiwtOS40MTIgNC4yNzIsLTEyLjk2NCAyLjU2MiwtMi42NDYgNi41NzQsLTMuODY2IDEyLjAzNSwtMy44NjYgaCA3LjY3MiB2IDcuMTA0IGggLTcuNTExIGMgLTIuODkyLDAgLTQuNTI1LDAuNDMgLTYuMDk4LDEuOTY0IC0xLjM1MSwxLjM5NiAtMi4yNzgsNC4wMzUgLTIuMjc4LDcuNTEgMCwzLjU1MiAwLjcwNiw2LjExMyAyLjE3OSw3Ljc4NiAxLjIyLDEuMzEyIDMuNDM3LDEuNzEgNS41MjMsMS43MSBoIDMuNTU5IGwgMTEuMTY5LC0yNi4wNzMgaCAxMS44NzQgbCAxMy40MTcsMzEuMzU5IHYgLTMxLjM1OSBoIDEyLjA2NiBsIDEzLjkzLDIzLjA5IHYgLTIzLjA5IGggOC4xMTcgdiAzMy4xNTMgeiBNIDAsNjEuOTA2MDY3IGggMTMuNTQgbCAzLjA1MywtNy4zNjQgaCA2LjgzNSBsIDMuMDQ1LDcuMzY0IGggMjYuNjQxIHYgLTUuNjMgbCAyLjM3OCw1LjY1NCBoIDEzLjgzIGwgMi4zNzgsLTUuNzM4IHYgNS43MTQgaCA2Ni4yMDggbCAtMC4wMzEsLTEyLjA4OCBoIDEuMjgxIGMgMC44OTcsMC4wMzEgMS4xNTksMC4xMTQgMS4xNTksMS41OTUgdiAxMC40OTMgaCAzNC4yNDMgdiAtMi44MTQgYyAyLjc2MiwxLjQ4IDcuMDU4LDIuODE0IDEyLjcxMSwyLjgxNCBoIDE0LjQwNiBsIDMuMDgzLC03LjM2NCBoIDYuODM1IGwgMy4wMTUsNy4zNjQgaCAyNy43NjEgdiAtNi45OTUgbCA0LjIwNCw2Ljk5NSBoIDIyLjI0NiB2IC00Ni4yNCBoIC0yMi4wMTYgdiA1LjQ2MSBsIC0zLjA4MywtNS40NjEgaCAtMjIuNTkxIHYgNS40NjEgbCAtMi44MzEsLTUuNDYxIGggLTMwLjUxNSBjIC01LjEwOCwwIC05LjU5OCwwLjcxMyAtMTMuMjI1LDIuNyB2IC0yLjcgaCAtMjEuMDU4IHYgMi43IGMgLTIuMzA4LC0yLjA0OCAtNS40NTMsLTIuNyAtOC45NSwtMi43IEggNjcuNjE5IGwgLTUuMTYyLDExLjk0MyAtNS4zMDEsLTExLjk0MyBIIDMyLjkyNCB2IDUuNDYxIGwgLTIuNjYyLC01LjQ2MSBIIDkuNTk2IGwgLTkuNTk3LDIxLjk4NSB2IDI0LjI1NSB6IgogICBpZD0icGF0aDMwIgogICBzdHlsZT0iZmlsbDojZmZmZmZmIiAvPgo8cGF0aAogICBkPSJtIDI4MS45NDUsODYuMzYxMDY3IGggLTE0LjQ0MyBjIC0xLjQ0MiwwIC0yLjQsMC4wNTQgLTMuMjA3LDAuNTk5IC0wLjgzNiwwLjUzNyAtMS4xNTgsMS4zMzQgLTEuMTU4LDIuMzg2IDAsMS4yNTEgMC43MDYsMi4xMDIgMS43MzMsMi40NyAwLjgzNiwwLjI5MSAxLjczNCwwLjM3NiAzLjA1NCwwLjM3NiBsIDQuMjk1LDAuMTE1IGMgNC4zMzQsMC4xMDcgNy4yMjcsMC44NTIgOC45OTEsMi42NjkgMC4zMjEsMC4yNTMgMC41MTQsMC41MzcgMC43MzUsMC44MjEgbSAwLDEyLjQyNzAwMyBjIC0xLjkyNSwyLjgxNSAtNS42NzYsNC4yNDIgLTEwLjc1NCw0LjI0MiBoIC0xNS4zMDQgdiAtNy4xMTEgaCAxNS4yNDIgYyAxLjUxMiwwIDIuNTcsLTAuMTk5IDMuMjA3LC0wLjgyMSAwLjU1MiwtMC41MTMgMC45MzcsLTEuMjU4IDAuOTM3LC0yLjE2MyAwLC0wLjk2NiAtMC4zODUsLTEuNzMzIC0wLjk2OCwtMi4xOTMgLTAuNTc1LC0wLjUwNjAwMyAtMS40MTIsLTAuNzM2MDAzIC0yLjc5MiwtMC43MzYwMDMgLTcuNDQxLC0wLjI1MyAtMTYuNzI0LDAuMjMgLTE2LjcyNCwtMTAuMjY0IDAsLTQuODEgMy4wNTQsLTkuODczIDExLjM3LC05Ljg3MyBoIDE1Ljc4NSB2IC02LjU5OCBoIC0xNC42NjYgYyAtNC40MjYsMCAtNy42NDEsMS4wNiAtOS45MTgsMi43MDggdiAtMi43MDggaCAtMjEuNjkzIGMgLTMuNDY5LDAgLTcuNTQxLDAuODYgLTkuNDY3LDIuNzA4IHYgLTIuNzA4IGggLTM4LjczOCB2IDIuNzA4IGMgLTMuMDgzLC0yLjIyNCAtOC4yODUsLTIuNzA4IC0xMC42ODYsLTIuNzA4IGggLTI1LjU1MiB2IDIuNzA4IGMgLTIuNDM5LC0yLjM2MiAtNy44NjMsLTIuNzA4IC0xMS4xNjksLTIuNzA4IGggLTI4LjU5NyBsIC02LjU0NCw3LjA4MiAtNi4xMjksLTcuMDgyIEggNTYuMDY3IHYgNDYuMjcyMDAzIGggNDEuOTE0IGwgNi43NDMsLTcuMTk0IDYuMzUyLDcuMTk0IDI1LjgzNiwwLjAyMyB2IC0xMC44ODUgaCAyLjU0IGMgMy40MjgsMC4wNTMgNy40NzEsLTAuMDg1IDExLjAzOCwtMS42MjcgdiAxMi40ODggaCAyMS4zMSB2IC0xMi4wNiBoIDEuMDI4IGMgMS4zMTIsMCAxLjQ0MSwwLjA1NCAxLjQ0MSwxLjM2NSB2IDEwLjY5NCBoIDY0LjczNiBjIDQuMTEsMCA4LjQwNiwtMS4wNTIgMTAuNzg1LC0yLjk2MSB2IDIuOTYxIGggMjAuNTM0IGMgNC4yNzMsMCA4LjQ0NiwtMC41OTkgMTEuNjIxLC0yLjEzMyB2IC04LjYyIHogTSAyNTAuMzM0LDk0Ljk3NjA2NyBjIDEuNTQzLDEuNTk3IDIuMzcsMy42MTMgMi4zNyw3LjAyNjAwMyAwLDcuMTM0IC00LjQ1NywxMC40NjQgLTEyLjQ0OSwxMC40NjQgSCAyMjQuODIgdiAtNy4xMTEgaCAxNS4zNzMgYyAxLjUwMywwIDIuNTY5LC0wLjE5OSAzLjIzNywtMC44MjEgMC41NDUsLTAuNTEzIDAuOTM2LC0xLjI1OCAwLjkzNiwtMi4xNjMgMCwtMC45NjYgLTAuNDIzLC0xLjczMyAtMC45NjcsLTIuMTkzIC0wLjYwNiwtMC41MDYwMDMgLTEuNDQyLC0wLjczNjAwMyAtMi44MjIsLTAuNzM2MDAzIC03LjQxMSwtMC4yNTMgLTE2LjY5MiwwLjIzIC0xNi42OTIsLTEwLjI2NCAwLC00LjgxIDMuMDIyLC05Ljg3MyAxMS4zMywtOS44NzMgaCAxNS44ODcgdiA3LjA1OCBoIC0xNC41MzcgYyAtMS40NDEsMCAtMi4zNzgsMC4wNTQgLTMuMTc1LDAuNTk5IC0wLjg2OCwwLjUzNyAtMS4xOSwxLjMzNCAtMS4xOSwyLjM4NiAwLDEuMjUxIDAuNzM3LDIuMTAyIDEuNzM0LDIuNDcgMC44MzYsMC4yOTEgMS43MzQsMC4zNzYgMy4wODQsMC4zNzYgbCA0LjI2NiwwLjExNSBjIDQuMzAyLDAuMTA1IDcuMjU1LDAuODQ5IDkuMDUsMi42NjcgeiBtIC03MS41MDgsLTIuMDQ4IGMgLTEuMDYsMC42MjkgLTIuMzcxLDAuNjgzIC0zLjkxMywwLjY4MyBoIC05LjYyNyB2IC03LjQ0OCBoIDkuNzU4IGMgMS40MTEsMCAyLjgyMywwLjAzIDMuNzgyLDAuNTk5IDEuMDI3LDAuNTM3IDEuNjQxLDEuNTY0IDEuNjQxLDIuOTgzIDAsMS40MTkgLTAuNjE0LDIuNTYyIC0xLjY0MSwzLjE4MyB6IG0gNC43ODYsNC4xMjcgYyAxLjc2NCwwLjY1MSAzLjIwNiwxLjgxOCAzLjg4MiwyLjc4NCAxLjExOSwxLjYxOTAwMyAxLjI4MSwzLjEzMDAwMyAxLjMxMyw2LjA1MzAwMyB2IDYuNTc0IGggLTcuOTU2IHYgLTQuMTQ5IGMgMCwtMS45OTUgMC4xOTIsLTQuOTQ5IC0xLjI4MSwtNi40OTEgLTEuMTU4LC0xLjE4OCAtMi45MjMsLTEuNDcyIC01LjgxNCwtMS40NzIgaCAtOC40NjkgdiAxMi4xMTIgaCAtNy45NjMgViA3OS4zMDQwNjcgaCAxOC4yOTYgYyA0LjAxMiwwIDYuOTM0LDAuMTc3IDkuNTM1LDEuNTY1IDIuNTAxLDEuNTExIDQuMDc0LDMuNTgxIDQuMDc0LDcuMzY0IC0wLjAwMSw1LjI5MyAtMy41MzEsNy45OTQgLTUuNjE3LDguODIyIHogbSAxMC4wMTEsLTE3Ljc1MSBoIDI2LjQ0OSB2IDYuODU4IGggLTE4LjU1NyB2IDYuMDI5IGggMTguMTA0IHYgNi43NjYgaCAtMTguMTA0IHYgNi41OTgwMDMgbCAxOC41NTcsMC4wMyB2IDYuODgxIEggMTkzLjYyMyBWIDc5LjMwNDA2NyB6IG0gLTUzLjQ2NywxNS4zMDQgaCAtMTAuMjQxIHYgLTguNDQ1IGggMTAuMzMzIGMgMi44NjEsMCA0Ljg0NywxLjE2NiA0Ljg0Nyw0LjA2NiAwLDIuODY4IC0xLjg5NCw0LjM3OSAtNC45MzksNC4zNzkgeiBtIC0xOC4xMzQsMTQuODQyMDAzIC0xMi4xNjcsLTEzLjUwODAwMyAxMi4xNjcsLTEzLjA3OSB2IDI2LjU4NzAwMyB6IG0gLTMxLjQyMSwtMy44OTUgSCA3MS4xMTcgdiAtNi41OTgwMDMgaCAxNy4zOTggdiAtNi43NjYgSCA3MS4xMTcgdiAtNi4wMjkgaCAxOS44NjggbCA4LjY2OCw5LjY2NCAtOS4wNTIsOS43MjkwMDMgeiBtIDYzLjAwMiwtMTUuMzI2MDAzIGMgMCw5LjIxMiAtNi44NzMsMTEuMTE0MDAzIC0xMy44LDExLjExNDAwMyBoIC05Ljg4OCB2IDExLjEyMyBoIC0xNS40MDMgbCAtOS43NTgsLTEwLjk3OCAtMTAuMTQxLDEwLjk3OCBIIDYzLjIyMyBWIDc5LjMwNDA2NyBoIDMxLjg3MyBsIDkuNzUsMTAuODcgMTAuMDgsLTEwLjg3IGggMjUuMzIyIGMgNi4yODksMCAxMy4zNTUsMS43NDEgMTMuMzU1LDEwLjkyNSB6IgogICBpZD0icGF0aDMyIgogICBzdHlsZT0iZmlsbDojZmZmZmZmIiAvPgo8L3N2Zz4='); 46 | background-size: auto 80%; 47 | background-repeat: no-repeat; 48 | background-position-x: 98%; 49 | background-position-y: 50%; 50 | } 51 | .mastercard { 52 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDEzLjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMTQ5NDgpICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMzAwcHgiIGhlaWdodD0iMTgwcHgiIHZpZXdCb3g9IjAgMCAzMDAgMTgwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzMDAgMTgwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8ZyBpZD0ibGF5ZXIxIj4NCgk8ZyBpZD0iZzEwMzA1Ij4NCgkJPHBhdGggaWQ9InBhdGgyMjY4IiBzdHlsZT0iZmlsbDojRkY5OTAwOyIgZD0iTTI5OC4wMzIsOTAuNWMwLjAxNCw0OC45MzYtMzkuNjQ2LDg4LjYxNC04OC41ODIsODguNjI3DQoJCQljLTQ4LjkzNywwLjAxMi04OC42MTQtMzkuNjQ2LTg4LjYyNy04OC41ODJjMC0wLjAxNiwwLTAuMDI5LDAtMC4wNDVjLTAuMDEzLTQ4LjkzNSwzOS42NDctODguNjE1LDg4LjU4MS04OC42MjgNCgkJCWM0OC45MzctMC4wMTMsODguNjE1LDM5LjY0Nyw4OC42MjgsODguNTgzQzI5OC4wMzIsOTAuNDcsMjk4LjAzMiw5MC40ODQsMjk4LjAzMiw5MC41eiIvPg0KCQk8cGF0aCBpZD0icGF0aDEzNTAiIHN0eWxlPSJmaWxsOiNDQzAwMDA7IiBkPSJNOTAuMDAxLDEuODk1QzQxLjM1NSwyLjIwNCwxLjk2Nyw0MS43ODEsMS45NjcsOTAuNQ0KCQkJYzAsNDguOTA5LDM5LjY5NSw4OC42MDQsODguNjA1LDg4LjYwNGMyMi45NTUsMCw0My44NzktOC43NDgsNTkuNjI0LTIzLjA4NmMtMC4wMDEsMC0wLjAwMy0wLjAwMi0wLjAwNy0wLjAwNGgwLjAxOQ0KCQkJYzMuMjI0LTIuOTM4LDYuMjMxLTYuMTA4LDguOTk1LTkuNDg4SDE0MS4wNWMtMi40MjQtMi45MjgtNC42MjctNS45NzktNi42MDYtOS4xMjdoMzEuMzA4YzEuOTA0LTMuMDQ3LDMuNjI4LTYuMjExLDUuMTU4LTkuNDg4DQoJCQloLTQxLjYzNWMtMS40MTktMy4wNDItMi42NTEtNi4xNTMtMy43MDMtOS4zMDloNDkuMDQ1YzIuOTU2LTguODMyLDQuNTYtMTguMjgxLDQuNTYtMjguMTAzYzAtNi41MTItMC43MDYtMTIuODYxLTIuMDQyLTE4Ljk3NA0KCQkJaC01NC4xNjRjMC42NzEtMy4xNDYsMS41MTgtNi4yNTQsMi41MjgtOS4zMDhoNDkuMDYzYy0xLjA5Ny0zLjI1LTIuMzcxLTYuNDE3LTMuODItOS40ODdIMTI5LjI3DQoJCQljMS40OTYtMy4xOTYsMy4xOTEtNi4zMDUsNS4wODQtOS4zMDdoMzEuMjg1Yy0yLjA4Mi0zLjMxNy00LjM4Ni02LjQ4Ni02Ljg3Ny05LjQ4OGgtMTcuNDQzYzIuNjk3LTMuMTc0LDUuNjY2LTYuMTYzLDguODg5LTguOTUNCgkJCWMtMTUuNzQ2LTE0LjM0LTM2LjY3Ni0yMy4wOS01OS42MzYtMjMuMDlDOTAuMzgxLDEuODk1LDkwLjE5MiwxLjg5NCw5MC4wMDEsMS44OTV6Ii8+DQoJCTxwYXRoIGlkPSJ1c2U5NDEyIiBzdHlsZT0iZmlsbDojRkNCMzQwOyIgZD0iTTI4OS4xNDMsMTM2LjgyYzAuNDgyLDAsMC45NTEsMC4xMjUsMS40MDksMC4zNzFjMC40NiwwLjI0NiwwLjgxNCwwLjYwMSwxLjA3LDEuMDYyDQoJCQljMC4yNTYsMC40NTYsMC4zODQsMC45MzcsMC4zODQsMS40MzVjMCwwLjQ5Mi0wLjEyNywwLjk2OC0wLjM3OSwxLjQyNGMtMC4yNTEsMC40NTUtMC42MDUsMC44MS0xLjA2MSwxLjA2Mw0KCQkJYy0wLjQ1MSwwLjI0OS0wLjkyOCwwLjM3NS0xLjQyNCwwLjM3NXMtMC45NzItMC4xMjYtMS40MjYtMC4zNzVjLTAuNDU1LTAuMjU0LTAuODA3LTAuNjA3LTEuMDYzLTEuMDYzDQoJCQljLTAuMjUyLTAuNDU2LTAuMzc3LTAuOTMyLTAuMzc3LTEuNDI0YzAtMC40OTgsMC4xMjctMC45NzksMC4zODQtMS40MzVjMC4yNTgtMC40NjEsMC42MTQtMC44MTMsMS4wNzEtMS4wNjINCgkJCUMyODguMTkzLDEzNi45NDUsMjg4LjY2MiwxMzYuODIsMjg5LjE0MywxMzYuODIgTTI4OS4xNDMsMTM3LjI5NWMtMC40MDEsMC0wLjc5MywwLjEwNC0xLjE3NiwwLjMxMQ0KCQkJYy0wLjM4LDAuMjA3LTAuNjc3LDAuNS0wLjg5MSwwLjg4OGMtMC4yMTcsMC4zODItMC4zMjUsMC43NzgtMC4zMjUsMS4xOTRjMCwwLjQxMiwwLjEwNiwwLjgxLDAuMzE1LDEuMTg4DQoJCQljMC4yMTQsMC4zNzcsMC41MSwwLjY3MywwLjg4OCwwLjg4NWMwLjM4MSwwLjIxMSwwLjc3NiwwLjMxNSwxLjE4OCwwLjMxNWMwLjQxNCwwLDAuODEtMC4xMDQsMS4xODktMC4zMTUNCgkJCWMwLjM3OC0wLjIxMiwwLjY3My0wLjUwOCwwLjg4NC0wLjg4NWMwLjIwOS0wLjM3OCwwLjMxMy0wLjc3NSwwLjMxMy0xLjE4OGMwLTAuNDE2LTAuMTA2LTAuODEzLTAuMzIxLTEuMTk0DQoJCQljLTAuMjEzLTAuMzg4LTAuNTExLTAuNjgxLTAuODk0LTAuODg4QzI4OS45MzQsMTM3LjM5OCwyODkuNTQ0LDEzNy4yOTUsMjg5LjE0MywxMzcuMjk1IE0yODcuODg3LDE0MS4yN3YtMy4wODJoMS4wNjINCgkJCWMwLjM2LDAsMC42MjIsMC4wMjgsMC43ODQsMC4wODhjMC4xNjIsMC4wNTcsMC4yOTEsMC4xNTQsMC4zODgsMC4yOTdjMC4wOTUsMC4xNDEsMC4xNDQsMC4yOTEsMC4xNDQsMC40NTENCgkJCWMwLDAuMjI2LTAuMDgsMC40MjItMC4yNDIsMC41ODhjLTAuMTU4LDAuMTY2LTAuMzczLDAuMjYxLTAuNjM5LDAuMjgxYzAuMTA5LDAuMDQ1LDAuMTk2LDAuMTAyLDAuMjY0LDAuMTY0DQoJCQljMC4xMjUsMC4xMiwwLjI3NSwwLjMyMywwLjQ1NSwwLjYxbDAuMzc1LDAuNjAzaC0wLjYwNmwtMC4yNzItMC40ODVjLTAuMjE1LTAuMzgyLTAuMzg4LTAuNjItMC41MjEtMC43MTgNCgkJCWMtMC4wOTEtMC4wNjktMC4yMjQtMC4xMDUtMC4zOTctMC4xMDVoLTAuMjkzdjEuMzExaC0wLjUgTTI4OC4zODUsMTM5LjUzNWgwLjYwNGMwLjI4OCwwLDAuNDgzLTAuMDQ0LDAuNTg4LTAuMTI5DQoJCQljMC4xMDYtMC4wODgsMC4xNTktMC4yLDAuMTU5LTAuMzQyYzAtMC4wOTItMC4wMjQtMC4xNzQtMC4wNzUtMC4yNDRjLTAuMDUyLTAuMDczLTAuMTIyLTAuMTI1LTAuMjEzLTAuMTYyDQoJCQljLTAuMDg5LTAuMDM1LTAuMjU1LTAuMDU1LTAuNDk3LTAuMDU1aC0wLjU2NHYwLjkzMiIvPg0KCTwvZz4NCgk8ZyBpZD0iZzE2NDgwIj4NCgkJPGcgaWQ9ImcxMzgwMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzLjc0NDA1LDE1Ljk5MzkpIj4NCgkJCTxwYXRoIGlkPSJwYXRoMTM4MDQiIHN0eWxlPSJmaWxsOiMwMDAwNjY7IiBkPSJNMTMzLjcxOSw5OS45MjZsMS4xOC04LjAyYy0wLjY0NSwwLTEuNTkzLDAuMjc5LTIuNDMxLDAuMjc5DQoJCQkJYy0zLjI4NCwwLTMuNjk0LTEuNzU1LTMuNDM2LTMuMDM3bDMuMjM2LTE2LjEzaDQuOTkybDEuMDI5LTkuMTAzaC00LjcwNWwwLjk1OC01LjUxNkgxMjQuNw0KCQkJCWMtMC4yMDgsMC4yMDgtNS41NjgsMzEuMDIyLTUuNTY4LDM0Ljc3NmMwLDUuNTU1LDMuMTE4LDguMDI3LDcuNTE2LDcuOTg4QzEzMC4wOSwxMDEuMTM0LDEzMi43NzMsMTAwLjE4MSwxMzMuNzE5LDk5LjkyNnoiLz4NCgkJCTxwYXRoIGlkPSJwYXRoMTM4MDYiIHN0eWxlPSJmaWxsOiMwMDAwNjY7IiBkPSJNMTM2LjcwNiw4NC42MzhjMCwxMy4zMzIsOC43OTksMTYuNDk5LDE2LjI5NywxNi40OTkNCgkJCQljNi45MjEsMCwxMC41NS0xLjYwNCwxMC41NS0xLjYwNGwxLjY2Mi05LjFjMCwwLTUuODQ4LDIuMzc4LTEwLjYwMSwyLjM3OGMtMTAuMTMxLDAtOC4zNTUtNy41NTQtOC4zNTUtNy41NTRsMTkuNDYzLDAuMDU5DQoJCQkJYzAsMCwxLjIzOS02LjExMSwxLjIzOS04LjYwMmMwLTYuMjE3LTMuMzg3LTEzLjg0OS0xMy43NDUtMTMuODQ5QzE0My43Myw2Mi44NjcsMTM2LjcwNiw3My4wODgsMTM2LjcwNiw4NC42Mzh6IE0xNTMuMjUyLDcxLjMxMw0KCQkJCWM1LjMyNCwwLDQuMzQyLDUuOTg0LDQuMzQyLDYuNDY5SDE0Ny4xMkMxNDcuMTIsNzcuMTYyLDE0OC4xMDksNzEuMzEzLDE1My4yNTIsNzEuMzEzeiIvPg0KCQkJPHBhdGggaWQ9InBhdGgxMzgwOCIgc3R5bGU9ImZpbGw6IzAwMDA2NjsiIGQ9Ik0yMTIuOTksOTkuOTIzbDEuNjg5LTEwLjI4NGMwLDAtNC42MzIsMi4zMjEtNy44MDcsMi4zMjENCgkJCQljLTYuNjkzLDAtOS4zNzgtNS4xMS05LjM3OC0xMC42MDFjMC0xMS4xMzcsNS43NTgtMTcuMjY1LDEyLjE2OC0xNy4yNjVjNC44MDgsMCw4LjY2NSwyLjY5OSw4LjY2NSwyLjY5OWwxLjU0LTkuOTkzDQoJCQkJYzAsMC00LjU1NC0zLjI4OS05LjQ1Ni0zLjMwOGMtMTQuNzQ1LTAuMDU4LTIzLjE4MiwxMC4yMDgtMjMuMTgyLDI3Ljk1NWMwLDExLjc2Myw2LjI0OCwxOS43NjgsMTcuNTA2LDE5Ljc2OA0KCQkJCUMyMDcuOTE4LDEwMS4yMTUsMjEyLjk5LDk5LjkyMywyMTIuOTksOTkuOTIzeiIvPg0KCQkJPHBhdGggaWQ9InBhdGgxMzgxMCIgc3R5bGU9ImZpbGw6IzAwMDA2NjsiIGQ9Ik04MS44Myw2My4wMTJjLTYuNDY5LDAtMTEuNDI3LDIuMDc5LTExLjQyNywyLjA3OWwtMS4zNyw4LjEyNw0KCQkJCWMwLDAsNC4wOTMtMS42NjMsMTAuMjgxLTEuNjYzYzMuNTEzLDAsNi4wODMsMC4zOTUsNi4wODMsMy4yNWMwLDEuNzM0LTAuMzE0LDIuMzc0LTAuMzE0LDIuMzc0cy0yLjc3Mi0wLjIzMS00LjA1Ni0wLjIzMQ0KCQkJCWMtOS4yMSwwLTE2LjcyOSwzLjQ4Mi0xNi43MjksMTMuOThjMCw4LjI3Myw1LjYyMywxMC4xNyw5LjEwOCwxMC4xN2M2LjY1NywwLDkuMjkyLTQuMjAzLDkuNDQ0LTQuMjE1bC0wLjA3NywzLjQ4OA0KCQkJCWMwLDAsOC4zMDYsMCw4LjMwNywwbDMuNzA2LTI1Ljk4Qzk0Ljc4Niw2My4zNjYsODUuMTcsNjMuMDEyLDgxLjgzLDYzLjAxMnogTTgzLjI2OCw4NC4xMDhjMC4xODEsMS41ODYtMC40MSw5LjA4Ni02LjA5Miw5LjA4Ng0KCQkJCWMtMi45MywwLTMuNjkxLTIuMjQtMy42OTEtMy41NjJjMC0yLjU4NCwxLjQwMy01LjY4Myw4LjMxNS01LjY4M0M4My40MSw4My45NDksODIuOTk3LDg0LjA2NSw4My4yNjgsODQuMTA4eiIvPg0KCQkJPHBhdGggaWQ9InBhdGgxMzgxMiIgc3R5bGU9ImZpbGw6IzAwMDA2NjsiIGQ9Ik0xMDMuNjE1LDEwMC45MDZjMi4xMjUsMCwxNC4yNzIsMC41NDEsMTQuMjcyLTExLjk5NA0KCQkJCWMwLTExLjcyMS0xMS4yNDQtOS40MDQtMTEuMjQ0LTE0LjExNGMwLTIuMzQyLDEuODMzLTMuMDgsNS4xODQtMy4wOGMxLjMyOSwwLDYuNDQ3LDAuNDIzLDYuNDQ3LDAuNDIzbDEuMTg5LTguMzMNCgkJCQljMCwwLjAwMS0zLjMxMi0wLjc0MS04LjcwNC0wLjc0MWMtNi45NzksMC0xNC4wNjMsMi43ODYtMTQuMDYzLDEyLjMxOGMwLDEwLjgwMiwxMS44MTIsOS43MTcsMTEuODEyLDE0LjI2Nw0KCQkJCWMwLDMuMDM3LTMuMywzLjI4Ny01Ljg0NCwzLjI4N2MtNC40MDEsMC04LjM2My0xLjUxMS04LjM3Ny0xLjQzOGwtMS4yNTksOC4yNDVDOTMuMjU3LDk5LjgxOSw5NS43MDIsMTAwLjkwNiwxMDMuNjE1LDEwMC45MDZ6Ig0KCQkJCS8+DQoJCQk8cGF0aCBpZD0icGF0aDEzODE0IiBzdHlsZT0iZmlsbDojMDAwMDY2OyIgZD0iTTI5MC44MDcsNTUuNDU1bC0xLjcwNSwxMi43MDljMCwwLTMuNTUzLTQuOTA1LTkuMTEyLTQuOTA1DQoJCQkJYy0xMC40NTksMC0xNS44NDksMTAuNDIzLTE1Ljg0OSwyMi4zOTZjMCw3LjczLDMuODQ0LDE1LjMwNywxMS42OTksMTUuMzA3YzUuNjUxLDAsOC43ODQtMy45NDEsOC43ODQtMy45NDFsLTAuNDE1LDMuMzY1aDkuMTc4DQoJCQkJbDcuMjA3LTQ0Ljg2MkwyOTAuODA3LDU1LjQ1NXogTTI4Ni43NTUsODAuMTU2YzAsNC45ODMtMi40NjgsMTEuNjQtNy41ODEsMTEuNjRjLTMuMzk2LDAtNC45ODgtMi44NTEtNC45ODgtNy4zMjQNCgkJCQljMC03LjMxNSwzLjI4NS0xMi4xNCw3LjQzMi0xMi4xNEMyODUuMDEyLDcyLjMzMiwyODYuNzU1LDc0LjY2MiwyODYuNzU1LDgwLjE1NnoiLz4NCgkJCTxwYXRoIGlkPSJwYXRoMTM4MTYiIHN0eWxlPSJmaWxsOiMwMDAwNjY7IiBkPSJNMzAuNzQ5LDEwMC40MjNsNS43NDMtMzMuODdsMC44NDQsMzMuODdoNi40OTlsMTIuMTI1LTMzLjg3bC01LjM3MSwzMy44N2g5LjY1OA0KCQkJCWw3LjQzNy00NC45MjJsLTE1LjM0Mi0wLjExN2wtOS4xMjYsMjcuNTA0bC0wLjI1LTI3LjM4N2gtMTQuMDZsLTcuNTQ0LDQ0LjkyMkgzMC43NDlMMzAuNzQ5LDEwMC40MjN6Ii8+DQoJCQk8cGF0aCBpZD0icGF0aDEzODE4IiBzdHlsZT0iZmlsbDojMDAwMDY2OyIgZD0iTTE3Ni4xMDEsMTAwLjQ4N2MyLjc0Ni0xNS42MTUsMy43MjQtMjcuOTQ3LDExLjczMi0yNS4zOTMNCgkJCQljMS4xNS02LjA0NCwzLjg5MS0xMS4zLDUuMTQzLTEzLjg1OGMwLDAtMC4zOTYtMC41ODktMi44NzEtMC41ODljLTQuMjI1LDAtOS44NjYsOC41NzQtOS44NjYsOC41NzRsMC44NDMtNS4zMDFoLTguNzg2DQoJCQkJbC01Ljg4NCwzNi41NjZIMTc2LjEwMXoiLz4NCgkJCTxnIGlkPSJ1c2UxNDY5OSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoODQ1LjMwMDEsMCkiPg0KCQkJCTxwYXRoIGlkPSJwYXRoMTM4MTBfMV8iIHN0eWxlPSJmaWxsOiMwMDAwNjY7IiBkPSJNLTYxMi41NSw2My4wMTJjLTYuNDcyLDAtMTEuNDMsMi4wNzktMTEuNDMsMi4wNzlsLTEuMzY5LDguMTI3DQoJCQkJCWMwLDAsNC4wOTUtMS42NjMsMTAuMjgtMS42NjNjMy41MTQsMCw2LjA4MywwLjM5NSw2LjA4MywzLjI1YzAsMS43MzQtMC4zMTMsMi4zNzQtMC4zMTMsMi4zNzRzLTIuNzcxLTAuMjMxLTQuMDU1LTAuMjMxDQoJCQkJCWMtOS4yMTEsMC0xNi43MjksMy40ODItMTYuNzI5LDEzLjk4YzAsOC4yNzMsNS42MjIsMTAuMTcsOS4xMDcsMTAuMTdjNi42NTUsMCw5LjI5Mi00LjIwMyw5LjQ0My00LjIxNWwtMC4wNzgsMy40ODhoOC4zMDkNCgkJCQkJbDMuNzA1LTI1Ljk4Qy01OTkuNTk2LDYzLjM2Ni02MDkuMjEyLDYzLjAxMi02MTIuNTUsNjMuMDEyeiBNLTYxMS4xMTQsODQuMTA4YzAuMTgsMS41ODYtMC40MTEsOS4wODYtNi4wOTIsOS4wODYNCgkJCQkJYy0yLjkzMiwwLTMuNjkyLTIuMjQtMy42OTItMy41NjJjMC0yLjU4NCwxLjQwMi01LjY4Myw4LjMxNS01LjY4M0MtNjEwLjk3Miw4My45NDktNjExLjM4NCw4NC4wNjUtNjExLjExNCw4NC4xMDh6Ii8+DQoJCQk8L2c+DQoJCQk8cGF0aCBpZD0idXNlMTQ3MDEiIHN0eWxlPSJmaWxsOiMwMDAwNjY7IiBkPSJNMjU1LjI2NiwxMDAuNDg3YzEuNTA4LTExLjQ4OCw0LjI5OS0yNy42MTYsMTEuNzMxLTI1LjM5Mw0KCQkJCWMxLjE0OS02LjA0NCwwLjA0MS02LjAyOC0yLjQzMy02LjAyOGMtNC4yMjgsMC01LjE2NCwwLjE1NC01LjE2NCwwLjE1NGwwLjg0NC01LjMwMWgtOC43ODVsLTUuODg0LDM2LjU2N0gyNTUuMjY2DQoJCQkJTDI1NS4yNjYsMTAwLjQ4N3oiLz4NCgkJPC9nPg0KCQk8ZyBpZD0iZzEwMjg5Ij4NCgkJCTxwYXRoIGlkPSJwYXRoNDE1NyIgc3R5bGU9ImZpbGw6I0ZGRkZGRjsiIGQ9Ik0xMjIuNDM0LDExMy4wNTlsMS4xODEtOC4wMTljLTAuNjQ1LDAtMS41OTQsMC4yNzYtMi40MzEsMC4yNzYNCgkJCQljLTMuMjg0LDAtMy42NDYtMS43NDYtMy40MzctMy4wMzdsMi42NTMtMTYuMzYyaDQuOTkxbDEuMjA1LTguODdoLTQuNzA2bDAuOTU4LTUuNTE2aC05LjQzNA0KCQkJCWMtMC4yMDgsMC4yMDgtNS41NjksMzEuMDIzLTUuNTY5LDM0Ljc3NWMwLDUuNTU1LDMuMTE5LDguMDI5LDcuNTE3LDcuOTg5QzExOC44MDYsMTE0LjI2NiwxMjEuNDg4LDExMy4zMTMsMTIyLjQzNCwxMTMuMDU5eiIvPg0KCQkJPHBhdGggaWQ9InBhdGg0MTU1IiBzdHlsZT0iZmlsbDojRkZGRkZGOyIgZD0iTTEyNS40MjMsOTcuNzdjMCwxMy4zMzIsOC44LDE2LjUsMTYuMjk3LDE2LjVjNi45MiwwLDkuOTY1LTEuNTQ3LDkuOTY1LTEuNTQ3DQoJCQkJbDEuNjYyLTkuMDk5YzAsMC01LjI2NCwyLjMxOS0xMC4wMTgsMi4zMTljLTEwLjEzLDAtOC4zNTYtNy41NTMtOC4zNTYtNy41NTNoMTkuMTcyYzAsMCwxLjIzOC02LjExMywxLjIzOC04LjYwNA0KCQkJCWMwLTYuMjE2LTMuMDk0LTEzLjc5LTEzLjQ1Mi0xMy43OUMxMzIuNDQ1LDc1Ljk5OCwxMjUuNDIzLDg2LjIxOSwxMjUuNDIzLDk3Ljc3eiBNMTQxLjk2Nyw4NC40NDUNCgkJCQljNS4zMjQsMCw0LjM0Miw1Ljk4Myw0LjM0Miw2LjQ2N2gtMTAuNDc0QzEzNS44MzUsOTAuMjk0LDEzNi44MjUsODQuNDQ1LDE0MS45NjcsODQuNDQ1eiIvPg0KCQkJPHBhdGggaWQ9InBhdGg0MTUxIiBzdHlsZT0iZmlsbDojRkZGRkZGOyIgZD0iTTIwMS43MDcsMTEzLjA1NWwxLjY4OC0xMC4yODVjMCwwLTQuNjI5LDIuMzIxLTcuODA2LDIuMzIxDQoJCQkJYy02LjY5MiwwLTkuMzc2LTUuMTEtOS4zNzYtMTAuNmMwLTExLjEzNyw1Ljc1OC0xNy4yNjQsMTIuMTY4LTE3LjI2NGM0LjgwNywwLDguNjY1LDIuNjk5LDguNjY1LDIuNjk5bDEuNTQtOS45OTMNCgkJCQljMCwwLTUuNzIxLTIuMzE1LTEwLjYyNS0yLjMxNWMtMTAuODkxLDAtMjEuNDg2LDkuNDQ4LTIxLjQ4NiwyNy4xOTJjMCwxMS43NjYsNS43MjEsMTkuNTM3LDE2Ljk3OSwxOS41MzcNCgkJCQlDMTk2LjYzNywxMTQuMzQ4LDIwMS43MDcsMTEzLjA1NSwyMDEuNzA3LDExMy4wNTV6Ii8+DQoJCQk8cGF0aCBpZD0icGF0aDQxNDkiIHN0eWxlPSJmaWxsOiNGRkZGRkY7IiBkPSJNNzAuNTQ3LDc2LjE0M2MtNi40NjksMC0xMS40MjgsMi4wNzktMTEuNDI4LDIuMDc5bC0xLjM2OSw4LjEyNw0KCQkJCWMwLDAsNC4wOTMtMS42NjMsMTAuMjgtMS42NjNjMy41MTMsMCw2LjA4MywwLjM5NSw2LjA4MywzLjI1YzAsMS43MzQtMC4zMTUsMi4zNzQtMC4zMTUsMi4zNzRzLTIuNzcxLTAuMjMyLTQuMDU0LTAuMjMyDQoJCQkJYy04LjE1OSwwLTE2LjczLDMuNDgyLTE2LjczLDEzLjk4YzAsOC4yNzIsNS42MjMsMTAuMTcsOS4xMDgsMTAuMTdjNi42NTYsMCw5LjUyNS00LjMxOSw5LjY3OC00LjMzMmwtMC4zMTEsMy42MDVoOC4zMDcNCgkJCQlsMy43MDYtMjUuOTgxQzgzLjUwMiw3Ni40OTgsNzMuODg3LDc2LjE0Myw3MC41NDcsNzYuMTQzeiBNNzIuNTY4LDk3LjI5N2MwLjE4LDEuNTg3LTAuOTk1LDkuMDI2LTYuNjc1LDkuMDI2DQoJCQkJYy0yLjkzLDAtMy42OTItMi4yMzgtMy42OTItMy41NjJjMC0yLjU4MiwxLjQwMy01LjY4Miw4LjMxNi01LjY4MkM3Mi4xMjUsOTcuMDgxLDcyLjI5Nyw5Ny4yNTMsNzIuNTY4LDk3LjI5N3oiLz4NCgkJCTxwYXRoIGlkPSJwYXRoNDE0NSIgc3R5bGU9ImZpbGw6I0ZGRkZGRjsiIGQ9Ik05Mi4zMzEsMTE0LjAzOGMyLjEyNSwwLDE0LjI3MywwLjU0LDE0LjI3My0xMS45OTUNCgkJCQljMC0xMS43MTktMTEuMjQ1LTkuNDA0LTExLjI0NS0xNC4xMTJjMC0yLjM0NCwxLjgzMy0zLjA4Miw1LjE4My0zLjA4MmMxLjMzLDAsNi40NDcsMC40MjMsNi40NDcsMC40MjNsMS4xOS04LjMzDQoJCQkJYzAsMC4wMDEtMy4zMTItMC43NDEtOC43MDQtMC43NDFjLTYuOTc5LDAtMTQuMDYzLDIuNzg2LTE0LjA2MywxMi4zMThjMCwxMC44MDEsMTEuODEyLDkuNzE3LDExLjgxMiwxNC4yNjcNCgkJCQljMCwzLjAzNy0zLjMsMy4yODQtNS44NDMsMy4yODRjLTQuNDAxLDAtOC4zNjQtMS41MS04LjM3OC0xLjQzOGwtMS4yNTgsOC4yNDZDODEuOTczLDExMi45NDgsODQuNDE3LDExNC4wMzgsOTIuMzMxLDExNC4wMzh6Ii8+DQoJCQk8cGF0aCBpZD0icGF0aDQxMzkiIHN0eWxlPSJmaWxsOiNGRkZGRkY7IiBkPSJNMjc5Ljg1Miw2OC42NjhsLTIuMDM1LDEyLjYyN2MwLDAtMy41NTEtNC45MDUtOS4xMS00LjkwNQ0KCQkJCWMtOC42NDQsMC0xNS44NDksMTAuNDIyLTE1Ljg0OSwyMi4zOTdjMCw3LjczLDMuODQzLDE1LjMwNCwxMS42OTksMTUuMzA0YzUuNjUxLDAsOC43ODQtMy45NCw4Ljc4NC0zLjk0bC0wLjQxNSwzLjM2NWg5LjE3Ng0KCQkJCWw3LjIwNy00NC44NjNMMjc5Ljg1Miw2OC42Njh6IE0yNzUuNDcxLDkzLjI4OGMwLDQuOTgzLTIuNDY3LDExLjYzOS03LjU4MiwxMS42MzljLTMuMzk1LDAtNC45ODYtMi44NS00Ljk4Ni03LjMyMw0KCQkJCWMwLTcuMzE0LDMuMjg1LTEyLjE0LDcuNDMtMTIuMTRDMjczLjcyOSw4NS40NjMsMjc1LjQ3MSw4Ny43OTYsMjc1LjQ3MSw5My4yODh6Ii8+DQoJCQk8cGF0aCBpZD0icGF0aDQxMzMiIHN0eWxlPSJmaWxsOiNGRkZGRkY7IiBkPSJNMTkuNDY2LDExMy41NTVsNS43NDMtMzMuODdsMC44NDMsMzMuODdoNi41bDEyLjEyNS0zMy44N2wtNS4zNzEsMzMuODdoOS42NTgNCgkJCQlsNy40MzgtNDQuOTIzSDQxLjQ2N2wtOS4zMDEsMjcuNTYzbC0wLjQ4NC0yNy41NjNIMTcuOTE1bC03LjU0NSw0NC45MjNIMTkuNDY2eiIvPg0KCQkJPHBhdGggaWQ9InBhdGg0MTMxIiBzdHlsZT0iZmlsbDojRkZGRkZGOyIgZD0iTTE2NC44MTgsMTEzLjYxN2MyLjc0Ni0xNS42MTYsMy4yNTUtMjguMjk2LDkuODA4LTI1Ljk3NQ0KCQkJCWMxLjE0Ny02LjA0NCwyLjI1NC04LjM4MiwzLjUwNi0xMC45NGMwLDAtMC41ODctMC4xMjMtMS44MTktMC4xMjNjLTQuMjI1LDAtNy4zNTUsNS43NzItNy4zNTUsNS43NzJsMC44NDEtNS4zMDFoLTguNzg0DQoJCQkJbC01Ljg4NSwzNi41NjdIMTY0LjgxOHoiLz4NCgkJCTxnIGlkPSJ1c2U4NTIzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4NDcuMDA2MiwwKSI+DQoJCQkJPHBhdGggaWQ9InBhdGg0MTQ5XzFfIiBzdHlsZT0iZmlsbDojRkZGRkZGOyIgZD0iTS02MjMuNTMxLDc2LjE0M2MtNi40NjksMC0xMS40MjgsMi4wNzktMTEuNDI4LDIuMDc5bC0xLjM2OCw4LjEyNw0KCQkJCQljMCwwLDQuMDkzLTEuNjYzLDEwLjI4LTEuNjYzYzMuNTEzLDAsNi4wODEsMC4zOTUsNi4wODEsMy4yNWMwLDEuNzM0LTAuMzEzLDIuMzc0LTAuMzEzLDIuMzc0cy0yLjc3MS0wLjIzMi00LjA1NS0wLjIzMg0KCQkJCQljLTguMTU4LDAtMTYuNzI5LDMuNDgyLTE2LjcyOSwxMy45OGMwLDguMjcyLDUuNjIyLDEwLjE3LDkuMTA3LDEwLjE3YzYuNjU2LDAsOS41MjUtNC4zMTksOS42NzctNC4zMzJsLTAuMzA5LDMuNjA1DQoJCQkJCWMwLDAsOC4zMDQsMCw4LjMwNywwbDMuNzA1LTI1Ljk4MUMtNjEwLjU3NSw3Ni40OTgtNjIwLjE5MSw3Ni4xNDMtNjIzLjUzMSw3Ni4xNDN6IE0tNjIxLjUwNyw5Ny4yOTcNCgkJCQkJYzAuMTgsMS41ODctMC45OTYsOS4wMjYtNi42NzgsOS4wMjZjLTIuOTMsMC0zLjY5LTIuMjM4LTMuNjktMy41NjJjMC0yLjU4MiwxLjQwMy01LjY4Miw4LjMxNS01LjY4Mg0KCQkJCQlDLTYyMS45NTIsOTcuMDgxLTYyMS43ODEsOTcuMjUzLTYyMS41MDcsOTcuMjk3eiIvPg0KCQkJPC9nPg0KCQkJPGcgaWQ9InVzZTg1MjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0Mi4yODU3LDApIj4NCgkJCQk8cGF0aCBpZD0icGF0aDQxMzFfMV8iIHN0eWxlPSJmaWxsOiNGRkZGRkY7IiBkPSJNLTE5OC4yNjMsMTEzLjYxN2MyLjc0Ny0xNS42MTYsMy4yNTYtMjguMjk2LDkuODA3LTI1Ljk3NQ0KCQkJCQljMS4xNDktNi4wNDQsMi4yNTctOC4zODIsMy41MDgtMTAuOTRjMCwwLTAuNTg3LTAuMTIzLTEuODE5LTAuMTIzYy00LjIyNSwwLTcuMzU1LDUuNzcyLTcuMzU1LDUuNzcybDAuODQxLTUuMzAxaC04Ljc4NA0KCQkJCQlsLTUuODg1LDM2LjU2N0gtMTk4LjI2M3oiLz4NCgkJCTwvZz4NCgkJCTxwYXRoIGlkPSJ0ZXh0OTQwNyIgc3R5bGU9ImZpbGw6I0ZGRkZGRjsiIGQ9Ik0yODkuMTA1LDEwNy45NzVjMC40NzksMCwwLjk1MSwwLjEyMywxLjQwNiwwLjM3Mw0KCQkJCWMwLjQ1OSwwLjI0MiwwLjgxNiwwLjU5OCwxLjA3MiwxLjA1OWMwLjI1NywwLjQ1OCwwLjM4MywwLjkzNSwwLjM4MywxLjQzNGMwLDAuNDkzLTAuMTI2LDAuOTY5LTAuMzc5LDEuNDI0DQoJCQkJYy0wLjI1MSwwLjQ1NS0wLjYwNCwwLjgxMi0xLjA1OSwxLjA2M2MtMC40NTQsMC4yNS0wLjkzLDAuMzc2LTEuNDI0LDAuMzc2Yy0wLjQ5OCwwLTAuOTc0LTAuMTI2LTEuNDI5LTAuMzc2DQoJCQkJYy0wLjQ1NC0wLjI1My0wLjgwNi0wLjYwOC0xLjA1OC0xLjA2M2MtMC4yNTYtMC40NTUtMC4zODEtMC45MzEtMC4zODEtMS40MjRjMC0wLjQ5OSwwLjEyNy0wLjk3NiwwLjM4NC0xLjQzNA0KCQkJCWMwLjI1OC0wLjQ2MSwwLjYxNi0wLjgxNSwxLjA3My0xLjA1OUMyODguMTU0LDEwOC4wOTgsMjg4LjYyNiwxMDcuOTc1LDI4OS4xMDUsMTA3Ljk3NSBNMjg5LjEwNSwxMDguNDQ3DQoJCQkJYy0wLjQwMSwwLTAuNzkzLDAuMTA0LTEuMTc2LDAuMzEzYy0wLjM4MiwwLjIwNC0wLjY3OSwwLjQ5OS0wLjg5NCwwLjg4NWMtMC4yMTQsMC4zODEtMC4zMjIsMC43OC0wLjMyMiwxLjE5NA0KCQkJCXMwLjEwNCwwLjgxLDAuMzEzLDEuMTg4YzAuMjEzLDAuMzc3LDAuNTA5LDAuNjczLDAuODkxLDAuODg2YzAuMzc4LDAuMjA4LDAuNzczLDAuMzEzLDEuMTg4LDAuMzEzDQoJCQkJYzAuNDEyLDAsMC44MS0wLjEwNSwxLjE4OC0wLjMxM2MwLjM3OC0wLjIxMywwLjY3NC0wLjUwOSwwLjg4NC0wLjg4NmMwLjIxMS0wLjM4MSwwLjMxNC0wLjc3NCwwLjMxNC0xLjE4OA0KCQkJCXMtMC4xMDctMC44MTMtMC4zMjEtMS4xOTRjLTAuMjEzLTAuMzg2LTAuNTEtMC42ODEtMC44OTQtMC44ODVDMjg5Ljg5NiwxMDguNTUyLDI4OS41MDcsMTA4LjQ0NywyODkuMTA1LDEwOC40NDcNCgkJCQkgTTI4Ny44NSwxMTIuNDIzdi0zLjA4M2gxLjA2MWMwLjM2MSwwLDAuNjI1LDAuMDI5LDAuNzg1LDAuMDg4YzAuMTYyLDAuMDU1LDAuMjg5LDAuMTU0LDAuMzg4LDAuMjk3DQoJCQkJYzAuMDk3LDAuMTQyLDAuMTQ2LDAuMjkxLDAuMTQ2LDAuNDUxYzAsMC4yMjUtMC4wODIsMC40MjItMC4yNDQsMC41ODhjLTAuMTU4LDAuMTY2LTAuMzcxLDAuMjYyLTAuNjM3LDAuMjgNCgkJCQljMC4xMDYsMC4wNDYsMC4xOTQsMC4xMDEsMC4yNjIsMC4xNjNjMC4xMjMsMC4xMjIsMC4yNzUsMC4zMjYsMC40NTUsMC42MTFsMC4zNzcsMC42MDRoLTAuNjA5bC0wLjI3MS0wLjQ4NQ0KCQkJCWMtMC4yMTYtMC4zODMtMC4zODktMC42MjEtMC41MjEtMC43MThjLTAuMDkxLTAuMDcxLTAuMjI0LTAuMTA2LTAuMzk5LTAuMTA2aC0wLjI5MXYxLjMxMUwyODcuODUsMTEyLjQyMyBNMjg4LjM0OCwxMTAuNjg4DQoJCQkJaDAuNjA0YzAuMjg5LDAsMC40ODQtMC4wNDMsMC41ODgtMC4xMjljMC4xMDUtMC4wODQsMC4xNi0wLjE5OSwwLjE2LTAuMzQyYzAtMC4wOTEtMC4wMjUtMC4xNzMtMC4wNzUtMC4yNDINCgkJCQljLTAuMDUxLTAuMDc0LTAuMTIyLTAuMTI3LTAuMjEzLTAuMTY0Yy0wLjA5MS0wLjAzNS0wLjI1NC0wLjA1My0wLjQ5OC0wLjA1M2gtMC41NjVWMTEwLjY4OCIvPg0KCQk8L2c+DQoJPC9nPg0KPC9nPg0KPC9zdmc+DQo='); 53 | background-size: auto 80%; 54 | background-repeat: no-repeat; 55 | background-position-x: 98%; 56 | background-position-y: 50%; 57 | } 58 | .discover { 59 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIG5vIGtpZGRpbmcgYXJvdW5kIG15IGZpbGVzLi4uIChodHRwOi8vd3d3LmRvZGVyby5ldSkgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgMTQzMCA4ODAiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgdmVyc2lvbj0iMS4xIg0JeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSINCXg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTQzMHB4IiBoZWlnaHQ9Ijg4MHB4Ij4NCTxkZWZzPg0JCTxyYWRpYWxHcmFkaWVudCBpZD0iZ3JhZGllbnQxIiBjeD0iNTAuNjk3NyUiIGN5PSI1MCUiIHI9IjUwJSI+DQkJCTxzdG9wIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMSIgb2Zmc2V0PSIwJSIvPg0JCQk8c3RvcCBzdG9wLWNvbG9yPSIjZmY4MDAwIiBzdG9wLW9wYWNpdHk9IjEiIG9mZnNldD0iMTAwJSIvPg0JCTwvcmFkaWFsR3JhZGllbnQ+DQk8L2RlZnM+DQk8Zz4NCQk8cmVjdCB4PSIwIiB5PSItMSIgd2lkdGg9IjE0MzAiIGhlaWdodD0iODgwIiBmaWxsPSIjZmZmZmZmIi8+DQkJPHBhdGggZD0iTSAxNDI5Ljk4IDg3OS4wMDU4IEwgMzU3LjM4MzggODc4Ljk4MTggQyA1MDcuMzMzNSA4NTMuNjY2NyA3MzguNjY2NSA4MDQuMzMzNCAxMDE0LjY2NjUgNzExLjY2NjcgQyAxMjkwLjY2NjUgNjE5IDE0MTUuMzMzNSA1MjUuODMzMyAxNDI5Ljk4IDUxNy45MDg1IEwgMTQyOS45OCA4NzkuMDA1OCBaIiBmaWxsPSIjZmY4MDAwIi8+DQkJPGc+DQkJCTxwYXRoIGQ9Ik0gMTUwLjAyODggMzk5LjY5MzEgQyAxNzguMzMzIDM5OS42OTMxIDIwMC4zNDU3IDM5MC43Nzg3IDIxNi4wODI1IDM3Mi45MzQzIEMgMjMxLjgxOTMgMzU1LjEwNTYgMjM5LjY4NzUgMzMwLjA2MzUgMjM5LjY4NzUgMjk3LjgyMzggQyAyMzkuNjg3NSAyNjcuNTIxMyAyMzIuMjU2MyAyNDQuMzM3NiAyMTcuNDI1MyAyMjguMjU3MiBDIDIwMi41NzgxIDIxMi4xOTI0IDE4MS4yMDU2IDIwNC4xNDQzIDE1My4zMjMyIDIwNC4xNDQzIEwgNzUuODI2MiAyMDQuMTQ0MyBMIDc1LjgyNjIgMzk5LjY5MzEgTCAxNTAuMDI4OCAzOTkuNjkzMSBMIDE1MC4wMjg4IDM5OS42OTMxIFpNIDExMy43OTM5IDIzMS4zNTk4IEwgMTM2LjI0MzcgMjMxLjM1OTggQyAxNTAuNTYwMSAyMzEuMzU5OCAxNjEuNDU3IDIzMi45OTc4IDE2OC45NTA3IDIzNi4yNTggQyAxNzYuNDI4NyAyMzkuNTE4MiAxODIuODI5NiAyNDUuNDI0NCAxODguMTM3MiAyNTMuOTc2NSBDIDE5NS44NDk2IDI2Ni40MTg4IDE5OS43MjEyIDI4MS45Nzk1IDE5OS43MjEyIDMwMC42NTg3IEMgMTk5LjcyMTIgMzI0LjgxODggMTk0LjkxMzEgMzQyLjgzNjUgMTg1LjI5NTkgMzU0LjY5NjEgQyAxNzUuNjc5MiAzNjYuNTU1NiAxNjEuMDk3NyAzNzIuNDc3NSAxNDEuNTUxOCAzNzIuNDc3NSBMIDExMy43OTM5IDM3Mi40Nzc1IEwgMTEzLjc5MzkgMjMxLjM1OTggTCAxMTMuNzkzOSAyMzEuMzU5OCBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGQ9Ik0gMzExLjYyNyAzOTkuNjkzMSBMIDMxMS42MjcgMjA0LjE0NDMgTCAyNzMuNjU4NyAyMDQuMTQ0MyBMIDI3My42NTg3IDM5OS42OTMxIEwgMzExLjYyNyAzOTkuNjkzMSBMIDMxMS42MjcgMzk5LjY5MzEgWiIgZmlsbD0iIzAwMDAwMCIvPg0JCQk8cGF0aCBkPSJNIDM5MS4yMTE0IDQwNC43MzMgQyA0MTMuMTMwNCA0MDQuNzMzIDQzMC4zMTg4IDM5OS41ODI5IDQ0Mi43OTMgMzg5LjI1MSBDIDQ1NS4yNTEgMzc4LjkzNDkgNDYxLjQ5NTYgMzY0LjY4MTQgNDYxLjQ5NTYgMzQ2LjUwNjIgQyA0NjEuNDk1NiAzMzMuNzE3NCA0NTguMjAxNyAzMjIuODgxNiA0NTEuNjEzOCAzMTMuOTY3MyBDIDQ0NS4wMjU0IDMwNS4wNTI5IDQzMy4wNTEzIDI5NS4zMTk1IDQxNS42NTk3IDI4NC43NjcyIEwgNDAyLjc0ODUgMjc2Ljk4NjggQyAzOTMuMDY5MyAyNzEuMDk2NSAzODYuNjIxNiAyNjYuMTM1MyAzODMuNDA1OCAyNjIuMTAzNCBDIDM4MC4xNzM4IDI1OC4wNzE0IDM3OC41NjU5IDI1My4zNzggMzc4LjU2NTkgMjQ4LjAyMzEgQyAzNzguNTY1OSAyNDEuNTM0MiAzODEuMDE3MSAyMzYuMzA1MyAzODUuOTM0NiAyMzIuMzA0OCBDIDM5MC44MzY5IDIyOC4zMjAyIDM5Ny4zNjIzIDIyNi4zMTk5IDQwNS41MTE3IDIyNi4zMTk5IEMgNDE2LjA0OTggMjI2LjMxOTkgNDMwLjM4MTMgMjMwLjAyMTEgNDQ4LjUwNjggMjM3LjQwNzggTCA0NDguNTA2OCAyMDYuMTYwMyBDIDQzMC41Mzc2IDIwMS40NjY4IDQxNC4zOTUgMTk5LjEwNDQgNDAwLjA3OTEgMTk5LjEwNDQgQyAzODIuMTg4IDE5OS4xMDQ0IDM2Ny43OTM5IDIwNC4wMDI1IDM1Ni45MTI2IDIxMy43OTg5IEMgMzQ2LjAzMDggMjIzLjU5NTIgMzQwLjU5ODEgMjM2LjU1NzMgMzQwLjU5ODEgMjUyLjcwMDcgQyAzNDAuNTk4MSAyNjQuNzk2NiAzNDMuOTIzMyAyNzUuMzQ4OSAzNTAuNTg5NCAyODQuMzg5MyBDIDM1Ny4yNDAyIDI5My40Mjk2IDM2OC42NTIzIDMwMi44NjM3IDM4NC44MjYyIDMxMi42NzU4IEwgMzk2Ljg5NCAzMTkuOTA0OSBDIDQwNi42MzU3IDMyNS44NTgzIDQxMy4xNzcyIDMzMS4wMjQyIDQxNi41MTgxIDMzNS4zODY5IEMgNDE5Ljg1OTQgMzM5Ljc2NTMgNDIxLjUyOTggMzQ1LjEyMDIgNDIxLjUyOTggMzUxLjQ1MTYgQyA0MjEuNTI5OCAzNTkuNDg0IDQxOC43NTA1IDM2NS44NDY5IDQxMy4xOTI5IDM3MC41MDg4IEMgNDA3LjYzNTMgMzc1LjE4NjUgNDAwLjAxNjYgMzc3LjUxNzUgMzkwLjM2ODcgMzc3LjUxNzUgQyAzNzYuNTY3OSAzNzcuNTE3NSAzNTkuOTg3OCAzNzMuMTU0OCAzNDAuNTk4MSAzNjQuNDEzNyBMIDM0MC41OTgxIDM5Ny42NzcxIEMgMzU5LjgzMTUgNDAyLjM3MDYgMzc2LjY5MjQgNDA0LjczMyAzOTEuMjExNCA0MDQuNzMzIEwgMzkxLjIxMTQgNDA0LjczMyBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGQ9Ik0gNjI4LjUgMzYwLjU4MzggQyA2MDguMzE2NCAzNzAuMDE5MyA2MDYuMTc0MyAzNzYuNzI1IDU4Ni4zNzM1IDM3Ni43MjUgQyA1NjQuMjc1NCAzNzYuNzI1IDU0Ny4wMzIyIDM3MC4xMTM4IDUzNC42NDM2IDM1Ni44OTE0IEMgNTIyLjIzNzggMzQzLjY2OTEgNTE2LjA0MzUgMzI1LjI1NTYgNTE2LjA0MzUgMzAxLjYxOTUgQyA1MTYuMDQzNSAyNzcuNTczMSA1MjEuNzg1MiAyNTkuMDAxOCA1MzMuMzAzNyAyNDUuOTA1NyBDIDU0NC44MjIzIDIzMi44MDk2IDU2MS4xNzgyIDIzMS4yNzA2IDU4Mi4zODg3IDIzMS4yNzA2IEMgNTk4Ljk3MDcgMjMxLjI3MDYgNjAxLjcwNDYgMjM1LjMwOTkgNjI2LjI3MjkgMjQzLjM4ODUgTCA2MjYuMjcyOSAyMTEuMDc0MiBDIDYwNC4xODggMjA0LjU3OSA2MDAuNjIzIDIwMSA1NzguNjgyNiAyMDEgQyA1NDQuMzAwOCAyMDEgNTE3Ljg1MyAyMDcuOTExMiA0OTkuMzA0NyAyMjUuNzA5MyBDIDQ4MC43NTY4IDI0My41MjMyIDQ3MS41IDI2OC45NTgxIDQ3MS41IDMwMS45OTgyIEMgNDcxLjUgMzM0LjQzODcgNDgwLjcyMjIgMzU5LjcxNTggNDk5LjE2NTUgMzc3LjgyOTUgQyA1MTcuNjA4OSAzOTUuOTQzMSA1NDMuMzYwOCA0MDUgNTc2LjQyMDQgNDA1IEMgNjAzLjQ5NDYgNDA1IDYwOC45NjA0IDQwMC45NjA3IDYyOC41IDM5Mi44ODIxIEwgNjI4LjUgMzYwLjU4MzggWiIgZmlsbD0iIzAwMDAwMCIvPg0JCQk8cGF0aCBkPSJNIDk3MS4xMDM1IDM5OS42OTMxIEwgMTAzNi4wMTc2IDIwNC4xNDQzIEwgMTAwNC44Mzc0IDIwNC4xNDQzIEwgOTU0LjU4MyAzNTUuNDk5MyBMIDkwMy4yNTE1IDIwNC4xNDQzIEwgODY1LjE2MDIgMjA0LjE0NDMgTCA5MzEuNDc5NSAzOTkuNjkzMSBMIDk3MS4xMDM1IDM5OS42OTMxIFoiIGZpbGw9IiMwMDAwMDAiLz4NCQkJPHBhdGggZD0iTSAxMTc3Ljg5NiAzOTkuNjkzMSBMIDExNzcuODk2IDM3Mi40Nzc1IEwgMTA5Ny45NjM0IDM3Mi40Nzc1IEwgMTA5Ny45NjM0IDMxMy4wMDY1IEwgMTE1Ny45MTMxIDMxMy4wMDY1IEwgMTE1Ny45MTMxIDI4NS43OTEgTCAxMDk3Ljk2MzQgMjg1Ljc5MSBMIDEwOTcuOTYzNCAyMzEuMzU5OCBMIDExNzEuOTAwOSAyMzEuMzU5OCBMIDExNzEuOTAwOSAyMDQuMTQ0MyBMIDEwNTkuOTk1NiAyMDQuMTQ0MyBMIDEwNTkuOTk1NiAzOTkuNjkzMSBMIDExNzcuODk2IDM5OS42OTMxIEwgMTE3Ny44OTYgMzk5LjY5MzEgWiIgZmlsbD0iIzAwMDAwMCIvPg0JCQk8cGF0aCBkPSJNIDEyNDIuODM5NCAzOTkuNjkzMSBMIDEyNDIuODM5NCAzMjAuMDYyNCBMIDEyNjMuMDA5OCAzMjAuMDYyNCBMIDEzMDcuOTA5MiAzOTkuNjkzMSBMIDEzNTMuNzQ1NiAzOTkuNjkzMSBMIDEyOTQuMzc0IDMwOC4yODE2IEMgMTMwNS4zODA0IDMwMy4wMDU0IDEzMTQuMDI5MyAyOTUuNDE0MSAxMzIwLjMyMDggMjg1LjUyMzIgQyAxMzI2LjYxMjMgMjc1LjYzMjQgMTMyOS43NjU2IDI2NC42NTQ4IDEzMjkuNzY1NiAyNTIuNTkwNSBDIDEzMjkuNzY1NiAyMjAuMzAzNSAxMzExLjUzMTMgMjA0LjE0NDMgMTI3NS4wNjIgMjA0LjE0NDMgTCAxMjA3Ljg2OTEgMjA0LjE0NDMgTCAxMjA3Ljg2OTEgMzk5LjY5MzEgTCAxMjQyLjgzOTQgMzk5LjY5MzEgTCAxMjQyLjgzOTQgMzk5LjY5MzEgWk0gMTI0Mi44Mzk0IDIzMS4zNTk4IEwgMTI1NS43MzQ5IDIzMS4zNTk4IEMgMTI3OS43NzY5IDIzMS4zNTk4IDEyOTEuNzk3OSAyNDAuMDIyMiAxMjkxLjc5NzkgMjU3LjMxNTQgQyAxMjkxLjc5NzkgMjgxLjAwMzEgMTI3OC4zMjUyIDI5Mi44NDY5IDEyNTEuMzk0NSAyOTIuODQ2OSBMIDEyNDIuODM5NCAyOTIuODQ2OSBMIDEyNDIuODM5NCAyMzEuMzU5OCBMIDEyNDIuODM5NCAyMzEuMzU5OCBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGlkPSJFbGxpcHNlIiBkPSJNIDY0NS41IDMwMi41IEMgNjQ1LjUgMjQzLjEyODYgNjkzLjYyODQgMTk1IDc1MyAxOTUgQyA4MTIuMzcxNiAxOTUgODYwLjUgMjQzLjEyODYgODYwLjUgMzAyLjUgQyA4NjAuNSAzNjEuODcxNCA4MTIuMzcxNiA0MTAgNzUzIDQxMCBDIDY5My42Mjg0IDQxMCA2NDUuNSAzNjEuODcxNCA2NDUuNSAzMDIuNSBaIiBmaWxsPSJ1cmwoI2dyYWRpZW50MSkiLz4NCQk8L2c+DQkJPGc+DQkJCTxwYXRoIGQ9Ik0gNDM3IDUyNCBMIDQzNyA0NzkuMDYyNSBMIDQ2OS4zNDM4IDUyNCBMIDQ4MSA1MjQgTCA0ODEgNDU4IEwgNDcwIDQ1OCBMIDQ3MCA1MDIuOTM3NSBMIDQzNy42NTYzIDQ1OCBMIDQyNiA0NTggTCA0MjYgNTI0IEwgNDM3IDUyNCBMIDQzNyA1MjQgWiIgZmlsbD0iIzAwMDAwMCIvPg0JCQk8cGF0aCBkPSJNIDU1OS4zOTk5IDUyNCBMIDU1OS4zOTk5IDUxNSBMIDUyOS4zOTk5IDUxNSBMIDUyOS4zOTk5IDQ5NCBMIDU1Mi4zOTk5IDQ5NCBMIDU1Mi4zOTk5IDQ4NSBMIDUyOS4zOTk5IDQ4NSBMIDUyOS4zOTk5IDQ2NyBMIDU1Ny4zOTk5IDQ2NyBMIDU1Ny4zOTk5IDQ1OCBMIDUxNS4zOTk5IDQ1OCBMIDUxNS4zOTk5IDUyNCBMIDU1OS4zOTk5IDUyNCBMIDU1OS4zOTk5IDUyNCBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGQ9Ik0gNjE5Ljc5OTggNTI0IEwgNjE5Ljc5OTggNDY3IEwgNjQzLjc5OTggNDY3IEwgNjQzLjc5OTggNDU4IEwgNTgxLjc5OTggNDU4IEwgNTgxLjc5OTggNDY3IEwgNjA1Ljc5OTggNDY3IEwgNjA1Ljc5OTggNTI0IEwgNjE5Ljc5OTggNTI0IEwgNjE5Ljc5OTggNTI0IFoiIGZpbGw9IiMwMDAwMDAiLz4NCQkJPHBhdGggZD0iTSA2OTMuMzQwOCA1MjQgTCA3MDMuNzAwMiA0NzguNDA2MyBMIDcxMy4yMTU4IDUyNCBMIDcyNi40OTcxIDUyNCBMIDc0NC4yMDAyIDQ1OCBMIDczNC41NDM5IDQ1OCBMIDcyMS43MDAyIDUwNi4zNzUgTCA3MTEuNzE1OCA0NTggTCA2OTkuNjUzMyA0NTggTCA2ODguNzAwMiA1MDYuNjU2MyBMIDY3Ni4yNzgzIDQ1OCBMIDY2My4yMDAyIDQ1OCBMIDY4MC4yMTU4IDUyNCBMIDY5My4zNDA4IDUyNCBMIDY5My4zNDA4IDUyNCBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGQ9Ik0gODI2LjM4MTMgNTE0Ljg1OTQgQyA4MzIuNTIyIDUwOC43NjU2IDgzNS42MDAxIDUwMC40Mzc1IDgzNS42MDAxIDQ4OS44NzUgQyA4MzUuNjAwMSA0NzkuNTQ2OSA4MzIuNTIyIDQ3MS4zMTI1IDgyNi4zODEzIDQ2NS4xODc1IEMgODIwLjIyNTEgNDU5LjA2MjUgODExLjk3NTEgNDU2IDgwMS42MTU3IDQ1NiBDIDc5MS4xOTM4IDQ1NiA3ODIuOTEyNiA0NTkuMDYyNSA3NzYuNzg3NiA0NjUuMTg3NSBDIDc3MC42NjI2IDQ3MS4zMTI1IDc2Ny42MDAxIDQ3OS41OTM4IDc2Ny42MDAxIDQ5MCBDIDc2Ny42MDAxIDUwMC4zMTI1IDc3MC42NDcgNTA4LjU0NjkgNzc2Ljc0MDcgNTE0LjczNDQgQyA3ODIuODM0NSA1MjAuOTIxOSA3OTAuOTc1MSA1MjQgODAxLjE2MjYgNTI0IEMgODExLjgxODggNTI0IDgyMC4yMjUxIDUyMC45NTMxIDgyNi4zODEzIDUxNC44NTk0IEwgODI2LjM4MTMgNTE0Ljg1OTQgWk0gNzg3LjAyMiA1MDguMTQwNiBDIDc4My4zOTcgNTAzLjU2MjUgNzgxLjYwMDEgNDk3LjUxNTYgNzgxLjYwMDEgNDg5Ljk4NDQgQyA3ODEuNjAwMSA0ODIuMzkwNiA3ODMuNDEyNiA0NzYuMzI4MSA3ODcuMDUzMiA0NzEuNzk2OSBDIDc5MC42NzgyIDQ2Ny4yNjU2IDc5NS41Mzc2IDQ2NSA4MDEuNjMxMyA0NjUgQyA4MDcuNjMxMyA0NjUgODEyLjQ1OTUgNDY3LjI2NTYgODE2LjExNTcgNDcxLjc5NjkgQyA4MTkuNzcyIDQ3Ni4zMjgxIDgyMS42MDAxIDQ4Mi4zNDM4IDgyMS42MDAxIDQ4OS44NDM4IEMgODIxLjYwMDEgNDk3LjU3ODEgODE5Ljc3MiA1MDMuNzAzMSA4MTYuMTQ3IDUwOC4yMTg4IEMgODEyLjUwNjMgNTEyLjc1IDgwNy41Njg4IDUxNSA4MDEuMzM0NSA1MTUgQyA3OTUuNDEyNiA1MTUgNzkwLjY0NyA1MTIuNzE4OCA3ODcuMDIyIDUwOC4xNDA2IEwgNzg3LjAyMiA1MDguMTQwNiBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJCTxwYXRoIGQ9Ik0gODgwIDUyNCBMIDg4MCA0OTcgTCA4ODYuMzkwNiA0OTcgTCA5MDMuMDkzOCA1MjQgTCA5MjAgNTI0IEwgODk4LjIzNDQgNDkzLjI1IEMgOTAyLjIwMzEgNDkxLjQ2ODggOTA1LjMxMjUgNDg4Ljg5MDYgOTA3LjU5MzggNDg1LjU0NjkgQyA5MDkuODU5NCA0ODIuMjAzMSA5MTEgNDc4LjQ4NDQgOTExIDQ3NC4zOTA2IEMgOTExIDQ2My40Njg4IDkwNC4yNjU2IDQ1OCA4OTAuODEyNSA0NTggTCA4NjYgNDU4IEwgODY2IDUyNCBMIDg4MCA1MjQgTCA4ODAgNTI0IFpNIDg4MCA0NjcgTCA4ODQuNDg0NCA0NjcgQyA4OTIuODI4MSA0NjcgODk3IDQ2OS45NTMxIDg5NyA0NzUuODU5NCBDIDg5NyA0ODMuOTUzMSA4OTIuMzEyNSA0ODggODgyLjk2ODggNDg4IEwgODgwIDQ4OCBMIDg4MCA0NjcgTCA4ODAgNDY3IFoiIGZpbGw9IiMwMDAwMDAiLz4NCQkJPHBhdGggZD0iTSA5NjEuMzk5OSA1MjQgTCA5NjEuMzk5OSA0OTEuNTMxMyBMIDk4Ni42NjU1IDUyNCBMIDEwMDMuNjQ5OSA1MjQgTCA5NzUuMjU5MyA0ODcuNTE1NiBMIDk5Ny42NDk5IDQ1OCBMIDk4NS42ODEyIDQ1OCBMIDk2MS4zOTk5IDQ5MCBMIDk2MS4zOTk5IDQ1OCBMIDk0Ny4zOTk5IDQ1OCBMIDk0Ny4zOTk5IDUyNCBMIDk2MS4zOTk5IDUyNCBMIDk2MS4zOTk5IDUyNCBaIiBmaWxsPSIjMDAwMDAwIi8+DQkJPC9nPg0JPC9nPg08L3N2Zz4='); 60 | background-size: auto 80%; 61 | background-repeat: no-repeat; 62 | background-position-x: 98%; 63 | background-position-y: 50%; 64 | } 65 | --------------------------------------------------------------------------------