diff --git a/.travis.yml b/.travis.yml index 33fed981d380..91a6651bf13f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -114,6 +114,8 @@ after_script: - mysql -u root -e 'select * from credits;' ninja - mysql -u root -e 'select * from expenses;' ninja - mysql -u root -e 'select * from accounts;' ninja + - mysql -u root -e 'select * from fonts;' ninja + - mysql -u root -e 'select * from banks;' ninja - cat storage/logs/laravel-error.log - cat storage/logs/laravel-info.log - FILES=$(find tests/_output -type f -name '*.png' | sort -nr) diff --git a/app/Console/Commands/InitLookup.php b/app/Console/Commands/InitLookup.php index aa52ec4f4a35..f37de078be2f 100644 --- a/app/Console/Commands/InitLookup.php +++ b/app/Console/Commands/InitLookup.php @@ -21,7 +21,7 @@ class InitLookup extends Command * * @var string */ - protected $signature = 'ninja:init-lookup {--truncate=} {--validate=} {--update=} {--company_id=} {--page_size=100} {--database=db-ninja-1}'; + protected $signature = 'ninja:init-lookup {--truncate=} {--subdomain} {--validate=} {--update=} {--company_id=} {--page_size=100} {--database=db-ninja-1}'; /** * The console command description. @@ -57,9 +57,12 @@ class InitLookup extends Command $database = $this->option('database'); $dbServer = DbServer::whereName($database)->first(); - if ($this->option('truncate')) { + if ($this->option('subdomain')) { + $this->logMessage('Updating subdomains...'); + $this->popuplateSubdomains(); + } else if ($this->option('truncate')) { + $this->logMessage('Truncating data...'); $this->truncateTables(); - $this->logMessage('Truncated'); } else { config(['database.default' => $this->option('database')]); @@ -87,6 +90,30 @@ class InitLookup extends Command } } + private function popuplateSubdomains() + { + $data = []; + + config(['database.default' => $this->option('database')]); + + $accounts = DB::table('accounts') + ->orderBy('id') + ->where('subdomain', '!=', '') + ->get(['account_key', 'subdomain']); + foreach ($accounts as $account) { + $data[$account->account_key] = $account->subdomain; + } + + config(['database.default' => DB_NINJA_LOOKUP]); + + $validate = $this->option('validate'); + $update = $this->option('update'); + + foreach ($data as $accountKey => $subdomain) { + LookupAccount::whereAccountKey($accountKey)->update(['subdomain' => $subdomain]); + } + } + private function initCompanies($dbServerId, $offset = 0) { $data = []; @@ -340,6 +367,7 @@ class InitLookup extends Command protected function getOptions() { return [ + ['subdomain', null, InputOption::VALUE_OPTIONAL, 'Subdomain', null], ['truncate', null, InputOption::VALUE_OPTIONAL, 'Truncate', null], ['company_id', null, InputOption::VALUE_OPTIONAL, 'Company Id', null], ['page_size', null, InputOption::VALUE_OPTIONAL, 'Page Size', null], diff --git a/app/Console/Commands/SendRecurringInvoices.php b/app/Console/Commands/SendRecurringInvoices.php index c7d32473ee4c..b608a092055d 100644 --- a/app/Console/Commands/SendRecurringInvoices.php +++ b/app/Console/Commands/SendRecurringInvoices.php @@ -116,8 +116,10 @@ class SendRecurringInvoices extends Command try { $invoice = $this->invoiceRepo->createRecurringInvoice($recurInvoice); if ($invoice && ! $invoice->isPaid()) { - $this->info('Sending Invoice'); + $this->info('Not billed - Sending Invoice'); $this->mailer->sendInvoice($invoice); + } elseif ($invoice) { + $this->info('Successfully billed invoice'); } } catch (Exception $exception) { $this->info('Error: ' . $exception->getMessage()); diff --git a/app/Console/Commands/SendReminders.php b/app/Console/Commands/SendReminders.php index 9347b69f525d..cd691a768243 100644 --- a/app/Console/Commands/SendReminders.php +++ b/app/Console/Commands/SendReminders.php @@ -2,12 +2,18 @@ namespace App\Console\Commands; +use Carbon; +use Str; use App\Models\Invoice; use App\Ninja\Mailers\ContactMailer as Mailer; +use App\Ninja\Mailers\UserMailer; use App\Ninja\Repositories\AccountRepository; use App\Ninja\Repositories\InvoiceRepository; +use App\Models\ScheduledReport; use Illuminate\Console\Command; use Symfony\Component\Console\Input\InputOption; +use App\Jobs\ExportReportResults; +use App\Jobs\RunReport; /** * Class SendReminders. @@ -46,13 +52,14 @@ class SendReminders extends Command * @param InvoiceRepository $invoiceRepo * @param accountRepository $accountRepo */ - public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo) + public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, UserMailer $userMailer) { parent::__construct(); $this->mailer = $mailer; $this->invoiceRepo = $invoiceRepo; $this->accountRepo = $accountRepo; + $this->userMailer = $userMailer; } public function fire() @@ -63,6 +70,23 @@ class SendReminders extends Command config(['database.default' => $database]); } + $this->chargeLateFees(); + $this->setReminderEmails(); + $this->sendScheduledReports(); + + $this->info('Done'); + + if ($errorEmail = env('ERROR_EMAIL')) { + \Mail::raw('EOM', function ($message) use ($errorEmail, $database) { + $message->to($errorEmail) + ->from(CONTACT_EMAIL) + ->subject("SendReminders [{$database}]: Finished successfully"); + }); + } + } + + private function chargeLateFees() + { $accounts = $this->accountRepo->findWithFees(); $this->info(count($accounts) . ' accounts found with fees'); @@ -79,17 +103,20 @@ class SendReminders extends Command $this->info('Charge fee: ' . $invoice->id); $account->loadLocalizationSettings($invoice->client); // support trans to add fee line item $number = preg_replace('/[^0-9]/', '', $reminder); + $amount = $account->account_email_settings->{"late_fee{$number}_amount"}; $percent = $account->account_email_settings->{"late_fee{$number}_percent"}; $this->invoiceRepo->setLateFee($invoice, $amount, $percent); } } } + } + private function setReminderEmails() + { $accounts = $this->accountRepo->findWithReminders(); $this->info(count($accounts) . ' accounts found with reminders'); - /** @var \App\Models\Account $account */ foreach ($accounts as $account) { if (! $account->hasFeature(FEATURE_EMAIL_TEMPLATES_REMINDERS)) { continue; @@ -98,7 +125,6 @@ class SendReminders extends Command $invoices = $this->invoiceRepo->findNeedingReminding($account); $this->info($account->name . ': ' . count($invoices) . ' invoices found'); - /** @var Invoice $invoice */ foreach ($invoices as $invoice) { if ($reminder = $account->getInvoiceReminder($invoice)) { $this->info('Send email: ' . $invoice->id); @@ -106,15 +132,34 @@ class SendReminders extends Command } } } + } - $this->info('Done'); + private function sendScheduledReports() + { + $scheduledReports = ScheduledReport::where('send_date', '<=', date('Y-m-d')) + ->with('user', 'account.company') + ->get(); + $this->info(count($scheduledReports) . ' scheduled reports'); - if ($errorEmail = env('ERROR_EMAIL')) { - \Mail::raw('EOM', function ($message) use ($errorEmail, $database) { - $message->to($errorEmail) - ->from(CONTACT_EMAIL) - ->subject("SendReminders [{$database}]: Finished successfully"); - }); + foreach ($scheduledReports as $scheduledReport) { + $user = $scheduledReport->user; + $account = $scheduledReport->account; + + if (! $account->hasFeature(FEATURE_REPORTS)) { + continue; + } + + $config = (array) json_decode($scheduledReport->config); + $reportType = $config['report_type']; + + $report = dispatch(new RunReport($scheduledReport->user, $reportType, $config, true)); + $file = dispatch(new ExportReportResults($scheduledReport->user, $config['export_format'], $reportType, $report->exportParams)); + + if ($file) { + $this->userMailer->sendScheduledReport($scheduledReport, $file); + } + + $scheduledReport->updateSendDate(); } } diff --git a/app/Console/Commands/UpdateKey.php b/app/Console/Commands/UpdateKey.php index 5625822488a9..4bf51c28ef2e 100644 --- a/app/Console/Commands/UpdateKey.php +++ b/app/Console/Commands/UpdateKey.php @@ -7,11 +7,11 @@ use Symfony\Component\Console\Input\InputOption; use App\Models\AccountGateway; use App\Models\BankAccount; use Artisan; -use Crypt; use Illuminate\Encryption\Encrypter; +use Laravel\LegacyEncrypter\McryptEncrypter; /** - * Class PruneData. + * Class UpdateKey */ class UpdateKey extends Command { @@ -34,16 +34,29 @@ class UpdateKey extends Command exit; } + $legacy = false; + if ($this->option('legacy') == 'true') { + $legacy = new McryptEncrypter(env('APP_KEY')); + } + // load the current values $gatewayConfigs = []; $bankUsernames = []; foreach (AccountGateway::all() as $gateway) { - $gatewayConfigs[$gateway->id] = $gateway->getConfig(); + if ($legacy) { + $gatewayConfigs[$gateway->id] = json_decode($legacy->decrypt($gateway->config)); + } else { + $gatewayConfigs[$gateway->id] = $gateway->getConfig(); + } } foreach (BankAccount::all() as $bank) { - $bankUsernames[$bank->id] = $bank->getUsername(); + if ($legacy) { + $bankUsernames[$bank->id] = $legacy->decrypt($bank->username); + } else { + $bankUsernames[$bank->id] = $bank->getUsername(); + } } // check if we can write to the .env file @@ -57,7 +70,8 @@ class UpdateKey extends Command $key = str_random(32); } - $crypt = new Encrypter($key, config('app.cipher')); + $cipher = $legacy ? 'AES-256-CBC' : config('app.cipher'); + $crypt = new Encrypter($key, $cipher); // update values using the new key/encrypter foreach (AccountGateway::all() as $gateway) { @@ -72,11 +86,21 @@ class UpdateKey extends Command $bank->save(); } + $message = date('r') . ' Successfully updated '; if ($envWriteable) { - $this->info(date('r') . ' Successfully update the key'); + if ($legacy) { + $message .= 'the key, set the cipher in the .env file to AES-256-CBC'; + } else { + $message .= 'the key'; + } } else { - $this->info(date('r') . ' Successfully update data, make sure to set the new app key: ' . $key); + if ($legacy) { + $message .= 'the data, make sure to set the new cipher/key: AES-256-CBC/' . $key; + } else { + $message .= 'the data, make sure to set the new key: ' . $key; + } } + $this->info($message); } /** @@ -92,6 +116,8 @@ class UpdateKey extends Command */ protected function getOptions() { - return []; + return [ + ['legacy', null, InputOption::VALUE_OPTIONAL, 'Legacy', null], + ]; } } diff --git a/app/Constants.php b/app/Constants.php index bfacde203d42..e55e00c3185b 100644 --- a/app/Constants.php +++ b/app/Constants.php @@ -2,6 +2,7 @@ if (! defined('APP_NAME')) { define('APP_NAME', env('APP_NAME', 'Invoice Ninja')); + define('APP_DOMAIN', env('APP_DOMAIN', 'invoiceninja.com')); define('CONTACT_EMAIL', env('MAIL_FROM_ADDRESS', env('MAIL_USERNAME'))); define('CONTACT_NAME', env('MAIL_FROM_NAME')); define('SITE_URL', env('APP_URL')); @@ -39,6 +40,7 @@ if (! defined('APP_NAME')) { define('ENTITY_PROJECT', 'project'); define('ENTITY_RECURRING_EXPENSE', 'recurring_expense'); define('ENTITY_CUSTOMER', 'customer'); + define('ENTITY_SUBSCRIPTION', 'subscription'); define('INVOICE_TYPE_STANDARD', 1); define('INVOICE_TYPE_QUOTE', 2); @@ -228,6 +230,11 @@ if (! defined('APP_NAME')) { define('FREQUENCY_SIX_MONTHS', 8); define('FREQUENCY_ANNUALLY', 9); + define('REPORT_FREQUENCY_DAILY', 'daily'); + define('REPORT_FREQUENCY_WEEKLY', 'weekly'); + define('REPORT_FREQUENCY_BIWEEKLY', 'biweekly'); + define('REPORT_FREQUENCY_MONTHLY', 'monthly'); + define('SESSION_TIMEZONE', 'timezone'); define('SESSION_CURRENCY', 'currency'); define('SESSION_CURRENCY_DECORATOR', 'currency_decorator'); @@ -310,7 +317,7 @@ if (! defined('APP_NAME')) { define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com')); define('NINJA_DOCS_URL', env('NINJA_DOCS_URL', 'http://docs.invoiceninja.com/en/latest')); define('NINJA_DATE', '2000-01-01'); - define('NINJA_VERSION', '3.9.2' . env('NINJA_VERSION_SUFFIX')); + define('NINJA_VERSION', '4.0.0' . env('NINJA_VERSION_SUFFIX')); define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja')); define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja')); @@ -426,6 +433,7 @@ if (! defined('APP_NAME')) { define('GATEWAY_TYPE_SOFORT', 8); define('GATEWAY_TYPE_SEPA', 9); define('GATEWAY_TYPE_GOCARDLESS', 10); + define('GATEWAY_TYPE_APPLE_PAY', 11); define('GATEWAY_TYPE_TOKEN', 'token'); define('TEMPLATE_INVOICE', 'invoice'); @@ -451,6 +459,9 @@ if (! defined('APP_NAME')) { define('FILTER_INVOICE_DATE', 'invoice_date'); define('FILTER_PAYMENT_DATE', 'payment_date'); + define('ADDRESS_BILLING', 'billing_address'); + define('ADDRESS_SHIPPING', 'shipping_address'); + define('SOCIAL_GOOGLE', 'Google'); define('SOCIAL_FACEBOOK', 'Facebook'); define('SOCIAL_GITHUB', 'GitHub'); diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 6aa8054d38f0..8922c26ba5ab 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -4,6 +4,7 @@ namespace App\Exceptions; use Crawler; use Exception; +use Illuminate\Auth\AuthenticationException; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; @@ -28,7 +29,7 @@ class Handler extends ExceptionHandler */ protected $dontReport = [ TokenMismatchException::class, - //ModelNotFoundException::class, + ModelNotFoundException::class, //AuthorizationException::class, //HttpException::class, //ValidationException::class, @@ -150,4 +151,31 @@ class Handler extends ExceptionHandler return parent::render($request, $e); } } + + /** + * Convert an authentication exception into an unauthenticated response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Auth\AuthenticationException $exception + * @return \Illuminate\Http\Response + */ + protected function unauthenticated($request, AuthenticationException $exception) + { + if ($request->expectsJson()) { + return response()->json(['error' => 'Unauthenticated.'], 401); + } + + $guard = array_get($exception->guards(), 0); + + switch ($guard) { + case 'client': + $url = '/client/login'; + break; + default: + $url = '/login'; + break; + } + + return redirect()->guest($url); + } } diff --git a/app/Http/Controllers/AccountApiController.php b/app/Http/Controllers/AccountApiController.php index cf6b3647559e..dc6c335cc887 100644 --- a/app/Http/Controllers/AccountApiController.php +++ b/app/Http/Controllers/AccountApiController.php @@ -16,6 +16,7 @@ use Auth; use Cache; use Exception; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; use Response; use Socialite; use Utils; @@ -91,7 +92,7 @@ class AccountApiController extends BaseAPIController return $this->response($data); } - + public function show(Request $request) { $account = Auth::user()->account; @@ -118,7 +119,13 @@ class AccountApiController extends BaseAPIController public function getUserAccounts(Request $request) { - return $this->processLogin($request); + $user = Auth::user(); + + $users = $this->accountRepo->findUsers($user, 'account.account_tokens'); + $transformer = new UserAccountTransformer($user->account, $request->serializer, $request->token_name); + $data = $this->createCollection($users, $transformer, 'user_account'); + + return $this->response($data); } public function update(UpdateAccountRequest $request) @@ -140,7 +147,7 @@ class AccountApiController extends BaseAPIController $devices = json_decode($account->devices, true); for ($x = 0; $x < count($devices); $x++) { - if ($devices[$x]['email'] == Auth::user()->username) { + if ($devices[$x]['email'] == $request->email) { $devices[$x]['token'] = $request->token; //update $devices[$x]['device'] = $request->device; $account->devices = json_encode($devices); @@ -171,6 +178,26 @@ class AccountApiController extends BaseAPIController return $this->response($newDevice); } + public function removeDeviceToken(Request $request) { + + $account = Auth::user()->account; + + $devices = json_decode($account->devices, true); + + foreach($devices as $key => $value) + { + + if($request->token == $value['token']) + unset($devices[$key]); + + } + + $account->devices = json_encode(array_values($devices)); + $account->save(); + + return $this->response(['success']); + } + public function updatePushNotifications(Request $request) { $account = Auth::user()->account; @@ -220,4 +247,11 @@ class AccountApiController extends BaseAPIController return $this->errorResponse(['message' => 'Invalid credentials'], 401); } + + public function iosSubscriptionStatus() { + + //stubbed for iOS callbacks + + } + } diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 97e35c140149..ffdb3094af77 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -494,6 +494,8 @@ class AccountController extends BaseController 'account' => Auth::user()->account, 'title' => trans('texts.tax_rates'), 'taxRates' => TaxRate::scope()->whereIsInclusive(false)->get(), + 'countInvoices' => Invoice::scope()->withTrashed()->count(), + 'hasInclusiveTaxRates' => TaxRate::scope()->whereIsInclusive(true)->count() ? true : false, ]; return View::make('accounts.tax_rates', $data); @@ -769,11 +771,20 @@ class AccountController extends BaseController */ public function saveClientPortalSettings(SaveClientPortalSettings $request) { - $account = $request->user()->account; - if($account->subdomain !== $request->subdomain) + // check subdomain is unique in the lookup tables + if (request()->subdomain) { + if (! \App\Models\LookupAccount::validateField('subdomain', request()->subdomain, $account)) { + return Redirect::to('settings/' . ACCOUNT_CLIENT_PORTAL) + ->withError(trans('texts.subdomain_taken')) + ->withInput(); + } + } + + if ($account->subdomain !== $request->subdomain) { event(new SubdomainWasUpdated($account)); + } $account->fill($request->all()); $account->client_view_css = $request->client_view_css; diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index 09a17ede065e..559840caaa2b 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -17,6 +17,7 @@ use Utils; use Validator; use View; use WePay; +use File; class AccountGatewayController extends BaseController { @@ -119,9 +120,9 @@ class AccountGatewayController extends BaseController $creditCards = []; foreach ($creditCardsArray as $card => $name) { if ($selectedCards > 0 && ($selectedCards & $card) == $card) { - $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card']), 'checked' => 'checked']; + $creditCards['
' . $name['text'] . '
'] = ['value' => $card, 'data-imageUrl' => asset($name['card']), 'checked' => 'checked']; } else { - $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card'])]; + $creditCards['
' . $name['text'] . '
'] = ['value' => $card, 'data-imageUrl' => asset($name['card'])]; } } @@ -297,6 +298,13 @@ class AccountGatewayController extends BaseController $config->enableSofort = boolval(Input::get('enable_sofort')); $config->enableSepa = boolval(Input::get('enable_sepa')); $config->enableBitcoin = boolval(Input::get('enable_bitcoin')); + $config->enableApplePay = boolval(Input::get('enable_apple_pay')); + + if ($config->enableApplePay && $uploadedFile = request()->file('apple_merchant_id')) { + $config->appleMerchantId = File::get($uploadedFile); + } elseif ($oldConfig && ! empty($oldConfig->appleMerchantId)) { + $config->appleMerchantId = $oldConfig->appleMerchantId; + } } if ($gatewayId == GATEWAY_STRIPE || $gatewayId == GATEWAY_WEPAY) { @@ -316,6 +324,7 @@ class AccountGatewayController extends BaseController $accountGateway->accepted_credit_cards = $cardCount; $accountGateway->show_address = Input::get('show_address') ? true : false; + $accountGateway->show_shipping_address = Input::get('show_shipping_address') ? true : false; $accountGateway->update_address = Input::get('update_address') ? true : false; $accountGateway->setConfig($config); diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index ba0dc4cea421..7d92ba73a9eb 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -269,9 +269,21 @@ class AppController extends BaseController public function update() { if (! Utils::isNinjaProd()) { + if ($password = env('UPDATE_SECRET')) { + if (! hash_equals($password, request('secret') ?: '')) { + abort(400, 'Invalid secret: /update?secret='); + } + } + try { set_time_limit(60 * 5); $this->checkInnoDB(); + + $cacheCompiled = base_path('bootstrap/cache/compiled.php'); + if (file_exists($cacheCompiled)) { unlink ($cacheCompiled); } + $cacheServices = base_path('bootstrap/cache/services.json'); + if (file_exists($cacheServices)) { unlink ($cacheServices); } + Artisan::call('clear-compiled'); Artisan::call('cache:clear'); Artisan::call('debugbar:clear'); diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 7403ce9b2960..016cb29d264b 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -2,42 +2,13 @@ namespace App\Http\Controllers\Auth; -use App\Events\UserLoggedIn; -use App\Http\Controllers\Controller; -use App\Models\User; +use Illuminate\Http\Request; use App\Ninja\Repositories\AccountRepository; use App\Services\AuthService; -use Auth; -use Event; -use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; -use Illuminate\Http\Request; -use Lang; -use Session; -use Utils; -use Cache; -use Illuminate\Contracts\Auth\Authenticatable; -use App\Http\Requests\ValidateTwoFactorRequest; +use App\Http\Controllers\Controller; class AuthController extends Controller { - /* - |-------------------------------------------------------------------------- - | Registration & Login Controller - |-------------------------------------------------------------------------- - | - | This controller handles the registration of new users, as well as the - | authentication of existing users. By default, this controller uses - | a simple trait to add these behaviors. Why don't you explore it? - | - */ - - use AuthenticatesAndRegistersUsers; - - /** - * @var string - */ - protected $redirectTo = '/dashboard'; - /** * @var AuthService */ @@ -63,43 +34,13 @@ class AuthController extends Controller $this->authService = $authService; } - /** - * @param array $data - * - * @return mixed - */ - public function validator(array $data) - { - return Validator::make($data, [ - 'name' => 'required|max:255', - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:6', - ]); - } - - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * - * @return User - */ - public function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); - } - /** * @param $provider * @param Request $request * * @return \Illuminate\Http\RedirectResponse */ - public function authLogin($provider, Request $request) + public function oauthLogin($provider, Request $request) { return $this->authService->execute($provider, $request->has('code')); } @@ -107,161 +48,12 @@ class AuthController extends Controller /** * @return \Illuminate\Http\RedirectResponse */ - public function authUnlink() + public function oauthUnlink() { - $this->accountRepo->unlinkUserFromOauth(Auth::user()); + $this->accountRepo->unlinkUserFromOauth(auth()->user()); - Session::flash('message', trans('texts.updated_settings')); + session()->flash('message', trans('texts.updated_settings')); return redirect()->to('/settings/' . ACCOUNT_USER_DETAILS); } - - /** - * @return \Illuminate\Http\Response - */ - public function getLoginWrapper() - { - if (auth()->check()) { - return redirect('/'); - } - - if (! Utils::isNinja() && ! User::count()) { - return redirect()->to('/setup'); - } - - if (Utils::isNinja() && ! Utils::isTravis()) { - // make sure the user is on SITE_URL/login to ensure OAuth works - $requestURL = request()->url(); - $loginURL = SITE_URL . '/login'; - $subdomain = Utils::getSubdomain(request()->url()); - if ($requestURL != $loginURL && ! strstr($subdomain, 'webapp-')) { - return redirect()->to($loginURL); - } - } - - return self::getLogin(); - } - - /** - * @param Request $request - * - * @return \Illuminate\Http\Response - */ - public function postLoginWrapper(Request $request) - { - $userId = Auth::check() ? Auth::user()->id : null; - $user = User::where('email', '=', $request->input('email'))->first(); - - if ($user && $user->failed_logins >= MAX_FAILED_LOGINS) { - Session::flash('error', trans('texts.invalid_credentials')); - return redirect()->to('login'); - } - - $response = self::postLogin($request); - - if (Auth::check()) { - /* - $users = false; - // we're linking a new account - if ($request->link_accounts && $userId && Auth::user()->id != $userId) { - $users = $this->accountRepo->associateAccounts($userId, Auth::user()->id); - Session::flash('message', trans('texts.associated_accounts')); - // check if other accounts are linked - } else { - $users = $this->accountRepo->loadAccounts(Auth::user()->id); - } - */ - } elseif ($user) { - error_log('login failed'); - $user->failed_logins = $user->failed_logins + 1; - $user->save(); - } - - return $response; - } - - /** - * Send the post-authentication response. - * - * @param \Illuminate\Http\Request $request - * @param \Illuminate\Contracts\Auth\Authenticatable $user - * @return \Illuminate\Http\Response - */ - private function authenticated(Request $request, Authenticatable $user) - { - if ($user->google_2fa_secret) { - Auth::logout(); - $request->session()->put('2fa:user:id', $user->id); - return redirect('/validate_two_factor/' . $user->account->account_key); - } - - Event::fire(new UserLoggedIn()); - - return redirect()->intended($this->redirectTo); - } - - /** - * - * @return \Illuminate\Http\Response - */ - public function getValidateToken() - { - if (session('2fa:user:id')) { - return view('auth.two_factor'); - } - - return redirect('login'); - } - - /** - * - * @param App\Http\Requests\ValidateSecretRequest $request - * @return \Illuminate\Http\Response - */ - public function postValidateToken(ValidateTwoFactorRequest $request) - { - //get user id and create cache key - $userId = $request->session()->pull('2fa:user:id'); - $key = $userId . ':' . $request->totp; - - //use cache to store token to blacklist - Cache::add($key, true, 4); - - //login and redirect user - Auth::loginUsingId($userId); - Event::fire(new UserLoggedIn()); - - return redirect()->intended($this->redirectTo); - } - - /** - * @return \Illuminate\Http\Response - */ - public function getLogoutWrapper() - { - if (Auth::check() && ! Auth::user()->registered) { - if (request()->force_logout) { - $account = Auth::user()->account; - $this->accountRepo->unlinkAccount($account); - - if (! $account->hasMultipleAccounts()) { - $account->company->forceDelete(); - } - $account->forceDelete(); - } else { - return redirect('/'); - } - } - - $response = self::getLogout(); - - Session::flush(); - - $reason = htmlentities(request()->reason); - if (!empty($reason) && Lang::has("texts.{$reason}_logout")) { - Session::flash('warning', trans("texts.{$reason}_logout")); - } - - return $response; - } } diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php new file mode 100644 index 000000000000..6a247fefd088 --- /dev/null +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -0,0 +1,32 @@ +middleware('guest'); + } +} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php new file mode 100644 index 000000000000..296e65c0acb2 --- /dev/null +++ b/app/Http/Controllers/Auth/LoginController.php @@ -0,0 +1,214 @@ +middleware('guest', ['except' => 'getLogoutWrapper']); + } + + /** + * @return \Illuminate\Http\Response + */ + public function getLoginWrapper(Request $request) + { + if (auth()->check()) { + return redirect('/'); + } + + if (! Utils::isNinja() && ! User::count()) { + return redirect()->to('/setup'); + } + + if (Utils::isNinja() && ! Utils::isTravis()) { + // make sure the user is on SITE_URL/login to ensure OAuth works + $requestURL = request()->url(); + $loginURL = SITE_URL . '/login'; + $subdomain = Utils::getSubdomain(request()->url()); + if ($requestURL != $loginURL && ! strstr($subdomain, 'webapp-')) { + return redirect()->to($loginURL); + } + } + + return self::showLoginForm($request); + } + + /** + * @param Request $request + * + * @return \Illuminate\Http\Response + */ + public function postLoginWrapper(Request $request) + { + $userId = auth()->check() ? auth()->user()->id : null; + $user = User::where('email', '=', $request->input('email'))->first(); + + if ($user && $user->failed_logins >= MAX_FAILED_LOGINS) { + session()->flash('error', trans('texts.invalid_credentials')); + return redirect()->to('login'); + } + + $response = self::login($request); + + if (auth()->check()) { + /* + $users = false; + // we're linking a new account + if ($request->link_accounts && $userId && Auth::user()->id != $userId) { + $users = $this->accountRepo->associateAccounts($userId, Auth::user()->id); + Session::flash('message', trans('texts.associated_accounts')); + // check if other accounts are linked + } else { + $users = $this->accountRepo->loadAccounts(Auth::user()->id); + } + */ + } else { + $stacktrace = sprintf("%s %s %s %s\n", date('Y-m-d h:i:s'), $request->input('email'), \Request::getClientIp(), array_get($_SERVER, 'HTTP_USER_AGENT')); + file_put_contents(storage_path('logs/failed-logins.log'), $stacktrace, FILE_APPEND); + error_log('login failed'); + if ($user) { + $user->failed_logins = $user->failed_logins + 1; + $user->save(); + } + } + + return $response; + } + + /** + * Get the failed login response instance. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse + */ + protected function sendFailedLoginResponse(Request $request) + { + return redirect()->back() + ->withInput($request->only($this->username(), 'remember')) + ->withErrors([ + $this->username() => trans('texts.invalid_credentials'), + ]); + } + + /** + * Send the post-authentication response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return \Illuminate\Http\Response + */ + private function authenticated(Request $request, Authenticatable $user) + { + if ($user->google_2fa_secret) { + auth()->logout(); + session()->put('2fa:user:id', $user->id); + return redirect('/validate_two_factor/' . $user->account->account_key); + } + + Event::fire(new UserLoggedIn()); + + return redirect()->intended($this->redirectTo); + } + + /** + * + * @return \Illuminate\Http\Response + */ + public function getValidateToken() + { + if (session('2fa:user:id')) { + return view('auth.two_factor'); + } + + return redirect('login'); + } + + /** + * + * @param App\Http\Requests\ValidateSecretRequest $request + * @return \Illuminate\Http\Response + */ + public function postValidateToken(ValidateTwoFactorRequest $request) + { + //get user id and create cache key + $userId = session()->pull('2fa:user:id'); + $key = $userId . ':' . $request->totp; + + //use cache to store token to blacklist + Cache::add($key, true, 4); + + //login and redirect user + auth()->loginUsingId($userId); + Event::fire(new UserLoggedIn()); + + return redirect()->intended($this->redirectTo); + } + + /** + * @return \Illuminate\Http\Response + */ + public function getLogoutWrapper(Request $request) + { + if (auth()->check() && ! auth()->user()->registered) { + if (request()->force_logout) { + $account = auth()->user()->account; + app('App\Ninja\Repositories\AccountRepository')->unlinkAccount($account); + + if (! $account->hasMultipleAccounts()) { + $account->company->forceDelete(); + } + $account->forceDelete(); + } else { + return redirect('/'); + } + } + + $response = self::logout($request); + + $reason = htmlentities(request()->reason); + if (!empty($reason) && Lang::has("texts.{$reason}_logout")) { + session()->flash('warning', trans("texts.{$reason}_logout")); + } + + return $response; + } +} diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php similarity index 60% rename from app/Http/Controllers/Auth/PasswordController.php rename to app/Http/Controllers/Auth/ResetPasswordController.php index 189f736fcfd8..b19a40cde50f 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -3,11 +3,13 @@ namespace App\Http\Controllers\Auth; use Event; +use Illuminate\Http\Request; +use App\Models\PasswordReset; use App\Events\UserLoggedIn; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; -class PasswordController extends Controller +class ResetPasswordController extends Controller { /* |-------------------------------------------------------------------------- @@ -21,40 +23,27 @@ class PasswordController extends Controller */ use ResetsPasswords { - getResetSuccessResponse as protected traitGetResetSuccessResponse; + sendResetResponse as protected traitSendResetResponse; } /** + * Where to redirect users after resetting their password. + * * @var string */ protected $redirectTo = '/dashboard'; /** - * Create a new password controller instance. + * Create a new controller instance. * - * @internal param \Illuminate\Contracts\Auth\Guard $auth - * @internal param \Illuminate\Contracts\Auth\PasswordBroker $passwords + * @return void */ public function __construct() { $this->middleware('guest'); } - /** - * Display the form to request a password reset link. - * - * @return \Illuminate\Http\Response - */ - public function getEmailWrapper() - { - if (auth()->check()) { - return redirect('/'); - } - - return $this->getEmail(); - } - - protected function getResetSuccessResponse($response) + protected function sendResetResponse($response) { $user = auth()->user(); @@ -64,7 +53,20 @@ class PasswordController extends Controller return redirect('/validate_two_factor/' . $user->account->account_key); } else { Event::fire(new UserLoggedIn()); - return $this->traitGetResetSuccessResponse($response); + return $this->traitSendResetResponse($response); } } + + public function showResetForm(Request $request, $token = null) + { + $passwordReset = PasswordReset::whereToken($token)->first(); + + if (! $passwordReset) { + return redirect('login')->withMessage(trans('texts.invalid_code')); + } + + return view('auth.passwords.reset')->with( + ['token' => $token, 'email' => $passwordReset->email] + ); + } } diff --git a/app/Http/Controllers/ClientAuth/AuthController.php b/app/Http/Controllers/ClientAuth/AuthController.php deleted file mode 100644 index f48934b06826..000000000000 --- a/app/Http/Controllers/ClientAuth/AuthController.php +++ /dev/null @@ -1,82 +0,0 @@ - true, - ]; - - return view('clientauth.login')->with($data); - } - - /** - * Get the needed authorization credentials from the request. - * - * @param \Illuminate\Http\Request $request - * - * @return array - */ - protected function getCredentials(Request $request) - { - $credentials = $request->only('password'); - $credentials['id'] = null; - - $contactKey = session('contact_key'); - if ($contactKey) { - $contact = Contact::where('contact_key', '=', $contactKey)->first(); - if ($contact && ! $contact->is_deleted) { - $credentials['id'] = $contact->id; - } - } - - return $credentials; - } - - /** - * Validate the user login request. - * - * @param \Illuminate\Http\Request $request - * - * @return void - */ - protected function validateLogin(Request $request) - { - $this->validate($request, [ - 'password' => 'required', - ]); - } - - /** - * @return mixed - */ - public function getSessionExpired() - { - return view('clientauth.sessionexpired')->with(['clientauth' => true]); - } -} diff --git a/app/Http/Controllers/ClientAuth/ForgotPasswordController.php b/app/Http/Controllers/ClientAuth/ForgotPasswordController.php new file mode 100644 index 000000000000..6af3c1d143b2 --- /dev/null +++ b/app/Http/Controllers/ClientAuth/ForgotPasswordController.php @@ -0,0 +1,86 @@ +middleware('guest:client'); + + //Config::set('auth.defaults.passwords', 'client'); + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function showLinkRequestForm() + { + $data = [ + 'clientauth' => true, + ]; + + if (! session('contact_key')) { + return \Redirect::to('/client/session_expired'); + } + + return view('clientauth.passwords.email')->with($data); + } + + /** + * Send a reset link to the given user. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\Response + */ + public function sendResetLinkEmail(Request $request) + { + $contactId = null; + $contactKey = session('contact_key'); + if ($contactKey) { + $contact = Contact::where('contact_key', '=', $contactKey)->first(); + if ($contact && ! $contact->is_deleted && $contact->email) { + $contactId = $contact->id; + } + } + + $response = $this->broker()->sendResetLink(['id' => $contactId], function (Message $message) { + $message->subject($this->getEmailSubject()); + }); + + return $response == Password::RESET_LINK_SENT + ? $this->sendResetLinkResponse($response) + : $this->sendResetLinkFailedResponse($request, $response); + } + + protected function broker() + { + return Password::broker('clients'); + } +} diff --git a/app/Http/Controllers/ClientAuth/LoginController.php b/app/Http/Controllers/ClientAuth/LoginController.php new file mode 100644 index 000000000000..a6a779b43936 --- /dev/null +++ b/app/Http/Controllers/ClientAuth/LoginController.php @@ -0,0 +1,171 @@ +middleware('guest:client', ['except' => 'logout']); + } + + /** + * Get the guard to be used during authentication. + * + * @return \Illuminate\Contracts\Auth\StatefulGuard + */ + protected function guard() + { + return auth()->guard('client'); + } + + /** + * @return mixed + */ + public function showLoginForm() + { + $subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST')); + $hasAccountIndentifier = request()->account_key || ($subdomain && $subdomain != 'app'); + + if (! session('contact_key')) { + if (Utils::isNinja()) { + if (! $hasAccountIndentifier) { + return redirect('/client/session_expired'); + } + } else { + if (! $hasAccountIndentifier && Account::count() > 1) { + return redirect('/client/session_expired'); + } + } + } + + return view('clientauth.login')->with(['clientauth' => true]); + } + + /** + * Get the needed authorization credentials from the request. + * + * @param \Illuminate\Http\Request $request + * + * @return array + */ + protected function credentials(Request $request) + { + if ($contactKey = session('contact_key')) { + $credentials = $request->only('password'); + $credentials['contact_key'] = $contactKey; + } else { + $credentials = $request->only('email', 'password'); + $account = false; + + // resovle the email to a contact/account + if ($accountKey = request()->account_key) { + $account = Account::whereAccountKey($accountKey)->first(); + } else { + $subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST')); + if ($subdomain != 'app') { + $account = Account::whereSubdomain($subdomain)->first(); + } + } + + if ($account) { + $credentials['account_id'] = $account->id; + } else { + abort(500, 'Account not resolved in client login'); + } + } + + return $credentials; + } + + /** + * Send the post-authentication response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return \Illuminate\Http\Response + */ + private function authenticated(Request $request, Authenticatable $contact) + { + session(['contact_key' => $contact->contact_key]); + + return redirect()->intended($this->redirectPath()); + } + + /** + * Get the failed login response instance. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse + */ + protected function sendFailedLoginResponse(Request $request) + { + return redirect()->back() + ->withInput($request->only($this->username(), 'remember')) + ->withErrors([ + $this->username() => trans('texts.invalid_credentials'), + ]); + } + + /** + * Validate the user login request - don't require the email + * + * @param \Illuminate\Http\Request $request + * + * @return void + */ + protected function validateLogin(Request $request) + { + $rules = [ + 'password' => 'required', + ]; + + if (! session('contact_key')) { + $rules['email'] = 'required|email'; + } + + $this->validate($request, $rules); + } + + /** + * @return mixed + */ + public function getSessionExpired() + { + return view('clientauth.sessionexpired')->with(['clientauth' => true]); + } + +} diff --git a/app/Http/Controllers/ClientAuth/PasswordController.php b/app/Http/Controllers/ClientAuth/PasswordController.php index b13f0dffb16e..a9996227a416 100644 --- a/app/Http/Controllers/ClientAuth/PasswordController.php +++ b/app/Http/Controllers/ClientAuth/PasswordController.php @@ -13,86 +13,6 @@ use Illuminate\Support\Facades\Password; class PasswordController extends Controller { - /* - |-------------------------------------------------------------------------- - | Password Reset Controller - |-------------------------------------------------------------------------- - | - | This controller is responsible for handling password reset requests - | and uses a simple trait to include this behavior. You're free to - | explore this trait and override any methods you wish to tweak. - | - */ - - use ResetsPasswords; - - /** - * @var string - */ - protected $redirectTo = '/client/dashboard'; - - /** - * Create a new password controller instance. - * - * @internal param \Illuminate\Contracts\Auth\Guard $auth - * @internal param \Illuminate\Contracts\Auth\PasswordBroker $passwords - */ - public function __construct() - { - $this->middleware('guest'); - Config::set('auth.defaults.passwords', 'client'); - } - - /** - * @return \Illuminate\Http\RedirectResponse - */ - public function showLinkRequestForm() - { - $data = [ - 'clientauth' => true, - ]; - - if (! session('contact_key')) { - return \Redirect::to('/client/sessionexpired'); - } - - return view('clientauth.password')->with($data); - } - - /** - * Send a reset link to the given user. - * - * @param \Illuminate\Http\Request $request - * - * @return \Illuminate\Http\Response - */ - public function sendResetLinkEmail(Request $request) - { - $broker = $this->getBroker(); - - $contactId = null; - $contactKey = session('contact_key'); - if ($contactKey) { - $contact = Contact::where('contact_key', '=', $contactKey)->first(); - if ($contact && ! $contact->is_deleted && $contact->email) { - $contactId = $contact->id; - } - } - - $response = Password::broker($broker)->sendResetLink(['id' => $contactId], function (Message $message) { - $message->subject($this->getEmailSubject()); - }); - - switch ($response) { - case Password::RESET_LINK_SENT: - return $this->getSendResetLinkEmailSuccessResponse($response); - - case Password::INVALID_USER: - default: - return $this->getSendResetLinkEmailFailureResponse($response); - } - } - /** * Display the password reset view for the given token. * @@ -116,7 +36,7 @@ class PasswordController extends Controller ); if (! session('contact_key')) { - return \Redirect::to('/client/sessionexpired'); + return \Redirect::to('/client/session_expired'); } return view('clientauth.reset')->with($data); diff --git a/app/Http/Controllers/ClientAuth/ResetPasswordController.php b/app/Http/Controllers/ClientAuth/ResetPasswordController.php new file mode 100644 index 000000000000..33b8f85e38ba --- /dev/null +++ b/app/Http/Controllers/ClientAuth/ResetPasswordController.php @@ -0,0 +1,70 @@ +middleware('guest:client'); + + //Config::set('auth.defaults.passwords', 'client'); + } + + protected function broker() + { + return Password::broker('clients'); + } + + protected function guard() + { + return auth()->guard('client'); + } + + public function showResetForm(Request $request, $token = null) + { + $passwordReset = PasswordReset::whereToken($token)->first(); + + if (! $passwordReset) { + return redirect('login')->withMessage(trans('texts.invalid_code')); + } + + return view('clientauth.passwords.reset')->with( + ['token' => $token, 'email' => $passwordReset->email] + ); + } + +} diff --git a/app/Http/Controllers/ClientPortalController.php b/app/Http/Controllers/ClientPortalController.php index 6d0d5b1ad0cd..e276867b0a6a 100644 --- a/app/Http/Controllers/ClientPortalController.php +++ b/app/Http/Controllers/ClientPortalController.php @@ -14,6 +14,7 @@ use App\Ninja\Repositories\CreditRepository; use App\Ninja\Repositories\DocumentRepository; use App\Ninja\Repositories\InvoiceRepository; use App\Ninja\Repositories\PaymentRepository; +use App\Ninja\Repositories\TaskRepository; use App\Services\PaymentService; use Auth; use Barracuda\ArchiveStream\ZipArchive; @@ -36,7 +37,14 @@ class ClientPortalController extends BaseController private $paymentRepo; private $documentRepo; - public function __construct(InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo, ActivityRepository $activityRepo, DocumentRepository $documentRepo, PaymentService $paymentService, CreditRepository $creditRepo) + public function __construct( + InvoiceRepository $invoiceRepo, + PaymentRepository $paymentRepo, + ActivityRepository $activityRepo, + DocumentRepository $documentRepo, + PaymentService $paymentService, + CreditRepository $creditRepo, + TaskRepository $taskRepo) { $this->invoiceRepo = $invoiceRepo; $this->paymentRepo = $paymentRepo; @@ -44,6 +52,7 @@ class ClientPortalController extends BaseController $this->documentRepo = $documentRepo; $this->paymentService = $paymentService; $this->creditRepo = $creditRepo; + $this->taskRepo = $taskRepo; } public function view($invitationKey) @@ -133,9 +142,6 @@ class ClientPortalController extends BaseController } $showApprove = $invoice->quote_invoice_id ? false : true; - if ($invoice->due_date) { - $showApprove = time() < strtotime($invoice->getOriginal('due_date')); - } if ($invoice->invoice_status_id >= INVOICE_STATUS_APPROVED) { $showApprove = false; } @@ -556,6 +562,46 @@ class ClientPortalController extends BaseController return $this->creditRepo->getClientDatatable($contact->client_id); } + public function taskIndex() + { + if (! $contact = $this->getContact()) { + return $this->returnError(); + } + + $account = $contact->account; + $account->loadLocalizationSettings($contact->client); + + if (! $contact->client->show_tasks_in_portal) { + return redirect()->to($account->enable_client_portal_dashboard ? '/client/dashboard' : '/client/payment_methods/'); + } + + if (! $account->enable_client_portal) { + return $this->returnError(); + } + + $color = $account->primary_color ? $account->primary_color : '#0b4d78'; + + $data = [ + 'color' => $color, + 'account' => $account, + 'title' => trans('texts.tasks'), + 'entityType' => ENTITY_TASK, + 'columns' => Utils::trans(['project', 'date', 'duration', 'description']), + 'sortColumn' => 1, + ]; + + return response()->view('public_list', $data); + } + + public function taskDatatable() + { + if (! $contact = $this->getContact()) { + return false; + } + + return $this->taskRepo->getClientDatatable($contact->client_id); + } + public function documentIndex() { if (! $contact = $this->getContact()) { @@ -601,7 +647,7 @@ class ClientPortalController extends BaseController return response()->view('error', [ 'error' => $error ?: trans('texts.invoice_not_found'), 'hideHeader' => true, - 'account' => $this->getContact()->account, + 'account' => $this->getContact() ? $this->getContact()->account : false, ]); } diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 7837c0980710..1d6f931099f9 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -83,6 +83,7 @@ class DashboardController extends BaseController 'tasks' => $tasks, 'showBlueVinePromo' => $showBlueVinePromo, 'showWhiteLabelExpired' => $showWhiteLabelExpired, + 'showExpenses' => count($expenses) && $account->isModuleEnabled(ENTITY_EXPENSE), 'headerClass' => in_array(\App::getLocale(), ['lt', 'pl', 'cs', 'sl', 'tr_TR']) ? 'in-large' : 'in-thin', 'footerClass' => in_array(\App::getLocale(), ['lt', 'pl', 'cs', 'sl', 'tr_TR']) ? '' : 'in-thin', ]; diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index 65cccabfcfc6..4ca491d7bab5 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -170,7 +170,7 @@ class ExportController extends BaseController if ($request->input('include') === 'all' || $request->input('clients')) { $data['clients'] = Client::scope() - ->with('user', 'contacts', 'country', 'currency') + ->with('user', 'contacts', 'country', 'currency', 'shipping_country') ->withArchived() ->get(); } diff --git a/app/Http/Controllers/IntegrationController.php b/app/Http/Controllers/IntegrationController.php index 1437a215e8a6..07728dd54eea 100644 --- a/app/Http/Controllers/IntegrationController.php +++ b/app/Http/Controllers/IntegrationController.php @@ -24,15 +24,8 @@ class IntegrationController extends Controller return Response::json('Event is invalid', 500); } - $subscription = Subscription::where('account_id', '=', Auth::user()->account_id) - ->where('event_id', '=', $eventId)->first(); - - if (! $subscription) { - $subscription = new Subscription(); - $subscription->account_id = Auth::user()->account_id; - $subscription->event_id = $eventId; - } - + $subscription = Subscription::createNew(); + $subscription->event_id = $eventId; $subscription->target_url = trim(Input::get('target_url')); $subscription->save(); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index c9fc36f466d6..c380430fd9dc 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -93,7 +93,7 @@ class InvoiceController extends BaseController ->where('invitations.invoice_id', '=', $invoice->id) ->where('invitations.account_id', '=', Auth::user()->account_id) ->where('invitations.deleted_at', '=', null) - ->select('contacts.public_id')->lists('public_id'); + ->select('contacts.public_id')->pluck('public_id'); $clients = Client::scope()->withTrashed()->with('contacts', 'country'); @@ -590,6 +590,28 @@ class InvoiceController extends BaseController return View::make('invoices.history', $data); } + public function deliveryNote(InvoiceRequest $request) + { + $invoice = $request->entity(); + $invoice->load('user', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'account.country', 'client.contacts', 'client.country', 'client.shipping_country'); + $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); + $invoice->due_date = Utils::fromSqlDate($invoice->due_date); + $invoice->features = [ + 'customize_invoice_design' => Auth::user()->hasFeature(FEATURE_CUSTOMIZE_INVOICE_DESIGN), + 'remove_created_by' => Auth::user()->hasFeature(FEATURE_REMOVE_CREATED_BY), + 'invoice_settings' => Auth::user()->hasFeature(FEATURE_INVOICE_SETTINGS), + ]; + $invoice->invoice_type_id = intval($invoice->invoice_type_id); + + $data = [ + 'invoice' => $invoice, + 'invoiceDesigns' => InvoiceDesign::getDesigns(), + 'invoiceFonts' => Cache::get('fonts'), + ]; + + return View::make('invoices.delivery_note', $data); + } + public function checkInvoiceNumber($invoicePublicId = false) { $invoiceNumber = request()->invoice_number; diff --git a/app/Http/Controllers/OnlinePaymentController.php b/app/Http/Controllers/OnlinePaymentController.php index 4a490add165e..852f0f7bc1e6 100644 --- a/app/Http/Controllers/OnlinePaymentController.php +++ b/app/Http/Controllers/OnlinePaymentController.php @@ -114,10 +114,16 @@ class OnlinePaymentController extends BaseController * * @return \Illuminate\Http\RedirectResponse */ - public function doPayment(CreateOnlinePaymentRequest $request) + public function doPayment(CreateOnlinePaymentRequest $request, $invitationKey, $gatewayTypeAlias = false) { $invitation = $request->invitation; - $gatewayTypeId = Session::get($invitation->id . 'gateway_type'); + + if ($gatewayTypeAlias) { + $gatewayTypeId = GatewayType::getIdFromAlias($gatewayTypeAlias); + } else { + $gatewayTypeId = Session::get($invitation->id . 'gateway_type'); + } + $paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId); if (! $invitation->invoice->canBePaid() && ! request()->update) { @@ -184,7 +190,9 @@ class OnlinePaymentController extends BaseController private function completePurchase($invitation, $isOffsite = false) { - if ($redirectUrl = session('redirect_url:' . $invitation->invitation_key)) { + if (request()->wantsJson()) { + return response()->json(RESULT_SUCCESS); + } elseif ($redirectUrl = session('redirect_url:' . $invitation->invitation_key)) { $separator = strpos($redirectUrl, '?') === false ? '?' : '&'; return redirect()->to($redirectUrl . $separator . 'invoice_id=' . $invitation->invoice->public_id); @@ -412,4 +420,28 @@ class OnlinePaymentController extends BaseController return redirect()->to($link); } } + + public function showAppleMerchantId() + { + if (Utils::isNinja()) { + $subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST')); + $account = Account::whereSubdomain($subdomain)->first(); + } else { + $account = Account::first(); + } + + if (! $account) { + exit("Account not found"); + } + + $accountGateway = $account->account_gateways() + ->whereGatewayId(GATEWAY_STRIPE)->first(); + + if (! $account) { + exit("Apple merchant id not set"); + } + + echo $accountGateway->getConfigField('appleMerchantId'); + exit; + } } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index dbe2d7dd58ba..a8a9ecee41e9 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -6,6 +6,7 @@ use App\Http\Requests\CreateProjectRequest; use App\Http\Requests\ProjectRequest; use App\Http\Requests\UpdateProjectRequest; use App\Models\Client; +use App\Models\Project; use App\Ninja\Datatables\ProjectDatatable; use App\Ninja\Repositories\ProjectRepository; use App\Services\ProjectService; @@ -95,6 +96,11 @@ class ProjectController extends BaseController Session::flash('message', trans('texts.updated_project')); + $action = Input::get('action'); + if (in_array($action, ['archive', 'delete', 'restore', 'invoice'])) { + return self::bulk(); + } + return redirect()->to($project->getRoute()); } @@ -102,14 +108,51 @@ class ProjectController extends BaseController { $action = Input::get('action'); $ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids'); - $count = $this->projectService->bulk($ids, $action); - if ($count > 0) { - $field = $count == 1 ? "{$action}d_project" : "{$action}d_projects"; - $message = trans("texts.$field", ['count' => $count]); - Session::flash('message', $message); + if ($action == 'invoice') { + $data = []; + $clientPublicId = false; + $lastClientId = false; + $lastProjectId = false; + $projects = Project::scope($ids) + ->with(['client', 'tasks' => function ($query) { + $query->whereNull('invoice_id'); + }]) + ->get(); + foreach ($projects as $project) { + if (! $clientPublicId) { + $clientPublicId = $project->client->public_id; + } + if ($lastClientId && $lastClientId != $project->client_id) { + return redirect('projects')->withError(trans('texts.project_error_multiple_clients')); + } + $lastClientId = $project->client_id; + + foreach ($project->tasks as $task) { + if ($task->is_running) { + return redirect('projects')->withError(trans('texts.task_error_running')); + } + $showProject = $lastProjectId != $task->project_id; + $data[] = [ + 'publicId' => $task->public_id, + 'description' => $task->present()->invoiceDescription(auth()->user()->account, $showProject), + 'duration' => $task->getHours(), + 'cost' => $task->getRate(), + ]; + $lastProjectId = $task->project_id; + } + } + return redirect("invoices/create/{$clientPublicId}")->with('tasks', $data); + } else { + $count = $this->projectService->bulk($ids, $action); + + if ($count > 0) { + $field = $count == 1 ? "{$action}d_project" : "{$action}d_projects"; + $message = trans("texts.$field", ['count' => $count]); + Session::flash('message', $message); + } + + return redirect()->to('/projects'); } - - return redirect()->to('/projects'); } } diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 630c4b8f18a0..93ee5f599b06 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -149,6 +149,13 @@ class QuoteController extends BaseController $invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail(); $invoice = $invitation->invoice; + if ($invoice->due_date) { + $carbonDueDate = \Carbon::parse($invoice->due_date); + if (! $carbonDueDate->isToday() && ! $carbonDueDate->isFuture()) { + return redirect("view/{$invitationKey}")->withError(trans('texts.quote_has_expired')); + } + } + $invitationKey = $this->invoiceService->approveQuote($invoice, $invitation); Session::flash('message', trans('texts.quote_is_approved')); diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 5e6112aed181..21a83f08186a 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -2,13 +2,16 @@ namespace App\Http\Controllers; +use App\Jobs\ExportReportResults; +use App\Jobs\RunReport; use App\Models\Account; +use App\Models\ScheduledReport; use Auth; use Input; -use Str; use Utils; use View; -use Excel; +use Carbon; +use Validator; /** * Class ReportController. @@ -94,22 +97,30 @@ class ReportController extends BaseController if (Auth::user()->account->hasFeature(FEATURE_REPORTS)) { $isExport = $action == 'export'; - $reportClass = '\\App\\Ninja\\Reports\\' . Str::studly($reportType) . 'Report'; - $options = [ + $config = [ 'date_field' => $dateField, - 'invoice_status' => request()->invoice_status, + 'status_ids' => request()->status_ids, 'group_dates_by' => request()->group_dates_by, 'document_filter' => request()->document_filter, + 'currency_type' => request()->currency_type, 'export_format' => $format, + 'start_date' => $params['startDate'], + 'end_date' => $params['endDate'], ]; - $report = new $reportClass($startDate, $endDate, $isExport, $options); - if (Input::get('report_type')) { - $report->run(); - } - $params['report'] = $report; - $params = array_merge($params, $report->results()); - if ($isExport) { - return self::export($format, $reportType, $params); + $report = dispatch(new RunReport(auth()->user(), $reportType, $config, $isExport)); + $params = array_merge($params, $report->exportParams); + switch ($action) { + case 'export': + return dispatch(new ExportReportResults(auth()->user(), $format, $reportType, $params))->export($format); + break; + case 'schedule': + self::schedule($params, $config); + return redirect('/reports'); + break; + case 'cancel_schedule': + self::cancelSchdule(); + return redirect('/reports'); + break; } } else { $params['columns'] = []; @@ -118,112 +129,47 @@ class ReportController extends BaseController $params['report'] = false; } - return View::make('reports.chart_builder', $params); + $params['scheduledReports'] = ScheduledReport::scope()->whereUserId(auth()->user()->id)->get(); + + return View::make('reports.report_builder', $params); } - /** - * @param $format - * @param $reportType - * @param $params - * @todo: Add summary to export - */ - private function export($format, $reportType, $params) + private function schedule($params, $options) { - if (! Auth::user()->hasPermission('view_all')) { - exit; + $validator = Validator::make(request()->all(), [ + 'frequency' => 'required|in:daily,weekly,biweekly,monthly', + 'send_date' => 'required', + ]); + + if ($validator->fails()) { + session()->now('message', trans('texts.scheduled_report_error')); + } else { + $options['report_type'] = $params['reportType']; + $options['range'] = request('range'); + $options['start_date_offset'] = $options['range'] ? '' : Carbon::parse($params['startDate'])->diffInDays(null, false); // null,false to get the relative/non-absolute diff + $options['end_date_offset'] = $options['range'] ? '' : Carbon::parse($params['endDate'])->diffInDays(null, false); + + unset($options['start_date']); + unset($options['end_date']); + unset($options['group_dates_by']); + + $schedule = ScheduledReport::createNew(); + $schedule->config = json_encode($options); + $schedule->frequency = request('frequency'); + $schedule->send_date = Utils::toSqlDate(request('send_date')); + $schedule->save(); + + session()->flash('message', trans('texts.created_scheduled_report')); } + } - $format = strtolower($format); - $data = $params['displayData']; - $columns = $params['columns']; - $totals = $params['reportTotals']; - $report = $params['report']; + private function cancelSchdule() + { + ScheduledReport::scope() + ->whereUserId(auth()->user()->id) + ->wherePublicId(request('scheduled_report_id')) + ->delete(); - $filename = "{$params['startDate']}-{$params['endDate']}_invoiceninja-".strtolower(Utils::normalizeChars(trans("texts.$reportType")))."-report"; - - $formats = ['csv', 'pdf', 'xlsx', 'zip']; - if (! in_array($format, $formats)) { - throw new \Exception("Invalid format request to export report"); - } - - //Get labeled header - $data = array_merge( - [ - array_map(function($col) { - return $col['label']; - }, $report->tableHeaderArray()) - ], - $data - ); - - $summary = []; - if (count(array_values($totals))) { - $summary[] = array_merge([ - trans("texts.totals") - ], array_map(function ($key) { - return trans("texts.{$key}"); - }, array_keys(array_values(array_values($totals)[0])[0]))); - } - - foreach ($totals as $currencyId => $each) { - foreach ($each as $dimension => $val) { - $tmp = []; - $tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : ''); - foreach ($val as $id => $field) { - $tmp[] = Utils::formatMoney($field, $currencyId); - } - $summary[] = $tmp; - } - } - - return Excel::create($filename, function($excel) use($report, $data, $reportType, $format, $summary) { - - $excel->sheet(trans("texts.$reportType"), function($sheet) use($report, $data, $format, $summary) { - $sheet->setOrientation('landscape'); - $sheet->freezeFirstRow(); - if ($format == 'pdf') { - $sheet->setAllBorders('thin'); - } - - if ($format == 'csv') { - $sheet->rows(array_merge($data, [[]], $summary)); - } else { - $sheet->rows($data); - } - - // Styling header - $sheet->cells('A1:'.Utils::num2alpha(count($data[0])-1).'1', function($cells) { - $cells->setBackground('#777777'); - $cells->setFontColor('#FFFFFF'); - $cells->setFontSize(13); - $cells->setFontFamily('Calibri'); - $cells->setFontWeight('bold'); - }); - $sheet->setAutoSize(true); - }); - - if (count($summary)) { - $excel->sheet(trans("texts.totals"), function($sheet) use($report, $summary, $format) { - $sheet->setOrientation('landscape'); - $sheet->freezeFirstRow(); - - if ($format == 'pdf') { - $sheet->setAllBorders('thin'); - } - $sheet->rows($summary); - - // Styling header - $sheet->cells('A1:'.Utils::num2alpha(count($summary[0])-1).'1', function($cells) { - $cells->setBackground('#777777'); - $cells->setFontColor('#FFFFFF'); - $cells->setFontSize(13); - $cells->setFontFamily('Calibri'); - $cells->setFontWeight('bold'); - }); - $sheet->setAutoSize(true); - }); - } - - })->export($format); + session()->flash('message', trans('texts.deleted_scheduled_report')); } } diff --git a/app/Http/Controllers/SubscriptionController.php b/app/Http/Controllers/SubscriptionController.php new file mode 100644 index 000000000000..82d4d2fcbc9b --- /dev/null +++ b/app/Http/Controllers/SubscriptionController.php @@ -0,0 +1,159 @@ +subscriptionService = $subscriptionService; + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function index() + { + return Redirect::to('settings/' . ACCOUNT_API_TOKENS); + } + + /** + * @return \Illuminate\Http\JsonResponse + */ + public function getDatatable() + { + return $this->subscriptionService->getDatatable(Auth::user()->account_id); + } + + /** + * @param $publicId + * + * @return \Illuminate\Contracts\View\View + */ + public function edit($publicId) + { + $subscription = Subscription::scope($publicId)->firstOrFail(); + + $data = [ + 'subscription' => $subscription, + 'method' => 'PUT', + 'url' => 'subscriptions/' . $publicId, + 'title' => trans('texts.edit_subscription'), + ]; + + return View::make('accounts.subscription', $data); + } + + /** + * @param $publicId + * + * @return \Illuminate\Http\RedirectResponse + */ + public function update($publicId) + { + return $this->save($publicId); + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function store() + { + return $this->save(); + } + + /** + * @return \Illuminate\Contracts\View\View + */ + public function create() + { + $data = [ + 'subscription' => null, + 'method' => 'POST', + 'url' => 'subscriptions', + 'title' => trans('texts.add_subscription'), + ]; + + return View::make('accounts.subscription', $data); + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function bulk() + { + $action = Input::get('bulk_action'); + $ids = Input::get('bulk_public_id'); + + $count = $this->subscriptionService->bulk($ids, $action); + + Session::flash('message', trans('texts.archived_subscription')); + + return Redirect::to('settings/' . ACCOUNT_API_TOKENS); + } + + /** + * @param bool $subscriptionPublicId + * + * @return $this|\Illuminate\Http\RedirectResponse + */ + public function save($subscriptionPublicId = false) + { + if (Auth::user()->account->hasFeature(FEATURE_API)) { + $rules = [ + 'event_id' => 'required', + 'target_url' => 'required|url', + ]; + + if ($subscriptionPublicId) { + $subscription = Subscription::scope($subscriptionPublicId)->firstOrFail(); + } else { + $subscription = Subscription::createNew(); + } + + $validator = Validator::make(Input::all(), $rules); + + if ($validator->fails()) { + return Redirect::to($subscriptionPublicId ? 'subscriptions/edit' : 'subscriptions/create')->withInput()->withErrors($validator); + } + + $subscription->fill(request()->all()); + $subscription->save(); + + if ($subscriptionPublicId) { + $message = trans('texts.updated_subscription'); + } else { + $message = trans('texts.created_subscription'); + } + + Session::flash('message', $message); + } + + return Redirect::to('settings/' . ACCOUNT_API_TOKENS); + } +} diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index 4091667352e4..2ca566196da6 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -308,7 +308,6 @@ class TaskController extends BaseController } } else { $count = $this->taskService->bulk($ids, $action); - if (request()->wantsJson()) { return response()->json($count); } else { diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index c19fce2245e5..e5053551dcd6 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -9,33 +9,57 @@ class Kernel extends HttpKernel /** * The application's global HTTP middleware stack. * + * These middleware are run during every request to your application. + * * @var array */ protected $middleware = [ - 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode', - 'Illuminate\Cookie\Middleware\EncryptCookies', - 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', - 'Illuminate\Session\Middleware\StartSession', - 'Illuminate\View\Middleware\ShareErrorsFromSession', - 'App\Http\Middleware\VerifyCsrfToken', - 'App\Http\Middleware\DuplicateSubmissionCheck', - 'App\Http\Middleware\QueryLogging', - 'App\Http\Middleware\StartupCheck', + \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array + */ + protected $middlewareGroups = [ + 'web' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + //\Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\DuplicateSubmissionCheck::class, + \App\Http\Middleware\QueryLogging::class, + \App\Http\Middleware\StartupCheck::class, + ], + 'api' => [ + \App\Http\Middleware\ApiCheck::class, + ], + /* + 'api' => [ + 'throttle:60,1', + 'bindings', + ], + */ ]; /** * The application's route middleware. * + * These middleware may be assigned to groups or used individually. + * * @var array */ protected $routeMiddleware = [ - 'lookup' => 'App\Http\Middleware\DatabaseLookup', - 'auth' => 'App\Http\Middleware\Authenticate', - 'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', - 'permissions.required' => 'App\Http\Middleware\PermissionsRequired', - 'guest' => 'App\Http\Middleware\RedirectIfAuthenticated', - 'api' => 'App\Http\Middleware\ApiCheck', - 'cors' => '\Barryvdh\Cors\HandleCors', - 'throttle' => 'Illuminate\Routing\Middleware\ThrottleRequests', + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'lookup' => \App\Http\Middleware\DatabaseLookup::class, + 'permissions.required' => \App\Http\Middleware\PermissionsRequired::class, ]; } diff --git a/app/Http/Middleware/ApiCheck.php b/app/Http/Middleware/ApiCheck.php index 2638323ee5e9..310ebaaf60aa 100644 --- a/app/Http/Middleware/ApiCheck.php +++ b/app/Http/Middleware/ApiCheck.php @@ -28,7 +28,8 @@ class ApiCheck { $loggingIn = $request->is('api/v1/login') || $request->is('api/v1/register') - || $request->is('api/v1/oauth_login'); + || $request->is('api/v1/oauth_login') + || $request->is('api/v1/ios_subscription_status'); $headers = Utils::getApiHeaders(); $hasApiSecret = false; diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index ccd3a90c4a08..c233ac7e770d 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -64,8 +64,9 @@ class Authenticate Session::put('contact_key', $contact->contact_key); } if (! $contact) { - return \Redirect::to('client/sessionexpired'); + return \Redirect::to('client/session_expired'); } + $account = $contact->account; if (Auth::guard('user')->check() && Auth::user('user')->account_id == $account->id) { @@ -86,8 +87,8 @@ class Authenticate $authenticated = true; } - if (env('PHANTOMJS_SECRET') && $request->phantomjs_secret && hash_equals(env('PHANTOMJS_SECRET'), $request->phantomjs_secret)) { - $authenticated = true; + if ($authenticated) { + $request->merge(['contact' => $contact]); } } diff --git a/app/Http/Middleware/DatabaseLookup.php b/app/Http/Middleware/DatabaseLookup.php index 27f2d648300a..345a063805a2 100644 --- a/app/Http/Middleware/DatabaseLookup.php +++ b/app/Http/Middleware/DatabaseLookup.php @@ -10,6 +10,7 @@ use App\Models\LookupInvitation; use App\Models\LookupAccountToken; use App\Models\LookupUser; use Auth; +use Utils; class DatabaseLookup { @@ -44,6 +45,13 @@ class DatabaseLookup LookupInvitation::setServerByField('invitation_key', $key); } elseif ($key = request()->contact_key ?: session('contact_key')) { LookupContact::setServerByField('contact_key', $key); + } elseif ($key = request()->account_key) { + LookupAccount::setServerByField('account_key', $key); + } else { + $subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST')); + if ($subdomain != 'app') { + LookupAccount::setServerByField('subdomain', $subdomain); + } } } elseif ($guard == 'postmark') { LookupInvitation::setServerByField('message_id', request()->MessageID); diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 000000000000..3aa15f8dd91d --- /dev/null +++ b/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ +auth->check() && Client::scope()->count() > 0) { + if (auth()->guard($guard)->check()) { Session::reflash(); - return new RedirectResponse(url('/dashboard')); + switch ($guard) { + case 'client': + if (session('contact_key')) { + return redirect('/client/dashboard'); + } + break; + default: + return redirect('/dashboard'); + break; + } } return $next($request); diff --git a/app/Http/Middleware/StartupCheck.php b/app/Http/Middleware/StartupCheck.php index 5db83b89b0c0..9c82abad036c 100644 --- a/app/Http/Middleware/StartupCheck.php +++ b/app/Http/Middleware/StartupCheck.php @@ -55,8 +55,8 @@ class StartupCheck $file = storage_path() . '/version.txt'; $version = @file_get_contents($file); if ($version != NINJA_VERSION) { - if (version_compare(phpversion(), '5.5.9', '<')) { - dd('Please update PHP to >= 5.5.9'); + if (version_compare(phpversion(), '7.0.0', '<')) { + dd('Please update PHP to >= 7.0.0'); } $handle = fopen($file, 'w'); fwrite($handle, NINJA_VERSION); diff --git a/app/Http/Requests/CreateOnlinePaymentRequest.php b/app/Http/Requests/CreateOnlinePaymentRequest.php index 1e9910082b9d..387f25c0f84c 100644 --- a/app/Http/Requests/CreateOnlinePaymentRequest.php +++ b/app/Http/Requests/CreateOnlinePaymentRequest.php @@ -3,6 +3,7 @@ namespace App\Http\Requests; use App\Models\Invitation; +use App\Models\GatewayType; class CreateOnlinePaymentRequest extends Request { @@ -26,7 +27,7 @@ class CreateOnlinePaymentRequest extends Request $account = $this->invitation->account; $paymentDriver = $account->paymentDriver($this->invitation, $this->gateway_type); - + return $paymentDriver->rules(); } @@ -39,7 +40,12 @@ class CreateOnlinePaymentRequest extends Request ->firstOrFail(); $input['invitation'] = $invitation; - $input['gateway_type'] = session($invitation->id . 'gateway_type'); + + if ($gatewayTypeAlias = request()->gateway_type) { + $input['gateway_type'] = GatewayType::getIdFromAlias($gatewayTypeAlias); + } else { + $input['gateway_type'] = session($invitation->id . 'gateway_type'); + } $this->replace($input); diff --git a/app/Http/Requests/CreateProjectRequest.php b/app/Http/Requests/CreateProjectRequest.php index cf6d6da316fc..2d354a100a76 100644 --- a/app/Http/Requests/CreateProjectRequest.php +++ b/app/Http/Requests/CreateProjectRequest.php @@ -22,7 +22,7 @@ class CreateProjectRequest extends ProjectRequest public function rules() { return [ - 'name' => sprintf('required|unique:projects,name,,id,account_id,%s', $this->user()->account_id), + 'name' => 'required', 'client_id' => 'required', ]; } diff --git a/app/Http/Requests/UpdateProjectRequest.php b/app/Http/Requests/UpdateProjectRequest.php index 84639fd18d88..bf6b3117fee6 100644 --- a/app/Http/Requests/UpdateProjectRequest.php +++ b/app/Http/Requests/UpdateProjectRequest.php @@ -26,7 +26,7 @@ class UpdateProjectRequest extends ProjectRequest } return [ - 'name' => sprintf('required|unique:projects,name,%s,id,account_id,%s', $this->entity()->id, $this->user()->account_id), + 'name' => 'required', ]; } } diff --git a/app/Jobs/ExportReportResults.php b/app/Jobs/ExportReportResults.php new file mode 100644 index 000000000000..aed6a34e4a21 --- /dev/null +++ b/app/Jobs/ExportReportResults.php @@ -0,0 +1,126 @@ +user = $user; + $this->format = strtolower($format); + $this->reportType = $reportType; + $this->params = $params; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if (! $this->user->hasPermission('view_all')) { + return false; + } + + $format = $this->format; + $reportType = $this->reportType; + $params = $this->params; + + $data = $params['displayData']; + $columns = $params['columns']; + $totals = $params['reportTotals']; + $report = $params['report']; + + $filename = "{$params['startDate']}-{$params['endDate']}_invoiceninja-".strtolower(Utils::normalizeChars(trans("texts.$reportType")))."-report"; + + $formats = ['csv', 'pdf', 'xlsx', 'zip']; + if (! in_array($format, $formats)) { + throw new \Exception("Invalid format request to export report"); + } + + //Get labeled header + $data = array_merge( + [ + array_map(function($col) { + return $col['label']; + }, $report->tableHeaderArray()) + ], + $data + ); + + $summary = []; + if (count(array_values($totals))) { + $summary[] = array_merge([ + trans("texts.totals") + ], array_map(function ($key) { + return trans("texts.{$key}"); + }, array_keys(array_values(array_values($totals)[0])[0]))); + } + + foreach ($totals as $currencyId => $each) { + foreach ($each as $dimension => $val) { + $tmp = []; + $tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : ''); + foreach ($val as $id => $field) { + $tmp[] = Utils::formatMoney($field, $currencyId); + } + $summary[] = $tmp; + } + } + + return Excel::create($filename, function($excel) use($report, $data, $reportType, $format, $summary) { + + $excel->sheet(trans("texts.$reportType"), function($sheet) use($report, $data, $format, $summary) { + $sheet->setOrientation('landscape'); + $sheet->freezeFirstRow(); + if ($format == 'pdf') { + $sheet->setAllBorders('thin'); + } + + if ($format == 'csv') { + $sheet->rows(array_merge($data, [[]], $summary)); + } else { + $sheet->rows($data); + } + + // Styling header + $sheet->cells('A1:'.Utils::num2alpha(count($data[0])-1).'1', function($cells) { + $cells->setBackground('#777777'); + $cells->setFontColor('#FFFFFF'); + $cells->setFontSize(13); + $cells->setFontFamily('Calibri'); + $cells->setFontWeight('bold'); + }); + $sheet->setAutoSize(true); + }); + + if (count($summary)) { + $excel->sheet(trans("texts.totals"), function($sheet) use($report, $summary, $format) { + $sheet->setOrientation('landscape'); + $sheet->freezeFirstRow(); + + if ($format == 'pdf') { + $sheet->setAllBorders('thin'); + } + $sheet->rows($summary); + + // Styling header + $sheet->cells('A1:'.Utils::num2alpha(count($summary[0])-1).'1', function($cells) { + $cells->setBackground('#777777'); + $cells->setFontColor('#FFFFFF'); + $cells->setFontSize(13); + $cells->setFontFamily('Calibri'); + $cells->setFontWeight('bold'); + }); + $sheet->setAutoSize(true); + }); + } + + }); + } +} diff --git a/app/Jobs/RunReport.php b/app/Jobs/RunReport.php new file mode 100644 index 000000000000..da9967a861c4 --- /dev/null +++ b/app/Jobs/RunReport.php @@ -0,0 +1,86 @@ +user = $user; + $this->reportType = $reportType; + $this->config = $config; + $this->isExport = $isExport; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if (! $this->user->hasPermission('view_all')) { + return false; + } + + $reportType = $this->reportType; + $config = $this->config; + $isExport = $this->isExport; + $reportClass = '\\App\\Ninja\\Reports\\' . Str::studly($reportType) . 'Report'; + + if (! empty($config['range'])) { + switch ($config['range']) { + case 'this_month': + $startDate = Carbon::now()->firstOfMonth()->toDateString(); + $endDate = Carbon::now()->lastOfMonth()->toDateString(); + break; + case 'last_month': + $startDate = Carbon::now()->subMonth()->firstOfMonth()->toDateString(); + $endDate = Carbon::now()->subMonth()->lastOfMonth()->toDateString(); + break; + case 'this_year': + $startDate = Carbon::now()->firstOfYear()->toDateString(); + $endDate = Carbon::now()->lastOfYear()->toDateString(); + break; + case 'last_year': + $startDate = Carbon::now()->subYear()->firstOfYear()->toDateString(); + $endDate = Carbon::now()->subYear()->lastOfYear()->toDateString(); + break; + } + } elseif (! empty($config['start_date_offset'])) { + $startDate = Carbon::now()->subDays($config['start_date_offset'])->toDateString(); + $endDate = Carbon::now()->subDays($config['end_date_offset'])->toDateString(); + } else { + $startDate = $config['start_date']; + $endDate = $config['end_date']; + } + + // send email as user + if (App::runningInConsole() && $this->user) { + auth()->onceUsingId($this->user->id); + } + + $report = new $reportClass($startDate, $endDate, $isExport, $config); + $report->run(); + + if (App::runningInConsole() && $this->user) { + auth()->logout(); + } + + $params = [ + 'startDate' => $startDate, + 'endDate' => $endDate, + 'report' => $report, + ]; + + $report->exportParams = array_merge($params, $report->results()); + + return $report; + } +} diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index b0468d9f836d..afab900eee0c 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -108,6 +108,11 @@ class Utils return self::getResllerType() ? true : false; } + public static function isRootFolder() + { + return strlen(preg_replace('/[^\/]/', '', url('/'))) == 2; + } + public static function clientViewCSS() { $account = false; @@ -459,6 +464,11 @@ class Utils public static function parseFloat($value) { + // check for comma as decimal separator + if (preg_match('/,[\d]{1,2}$/', $value)) { + $value = str_replace(',', '.', $value); + } + $value = preg_replace('/[^0-9\.\-]/', '', $value); return floatval($value); diff --git a/app/Listeners/HandleUserLoggedIn.php b/app/Listeners/HandleUserLoggedIn.php index 9ac0c2f235f4..9eee5232041c 100644 --- a/app/Listeners/HandleUserLoggedIn.php +++ b/app/Listeners/HandleUserLoggedIn.php @@ -101,6 +101,8 @@ class HandleUserLoggedIn // warn if using the default app key if (in_array(config('app.key'), ['SomeRandomString', 'SomeRandomStringSomeRandomString', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'])) { Session::flash('error', trans('texts.error_app_key_set_to_default')); + } elseif (in_array($appCipher, ['MCRYPT_RIJNDAEL_256', 'MCRYPT_RIJNDAEL_128'])) { + Session::flash('error', trans('texts.mcrypt_warning')); } } } diff --git a/app/Listeners/SubscriptionListener.php b/app/Listeners/SubscriptionListener.php index 15fd543d5440..6f6298c3e6d9 100644 --- a/app/Listeners/SubscriptionListener.php +++ b/app/Listeners/SubscriptionListener.php @@ -132,21 +132,25 @@ class SubscriptionListener return; } - $subscription = $entity->account->getSubscription($eventId); + $subscriptions = $entity->account->getSubscriptions($eventId); - if ($subscription) { - $manager = new Manager(); - $manager->setSerializer(new ArraySerializer()); - $manager->parseIncludes($include); + if (! $subscriptions->count()) { + return; + } - $resource = new Item($entity, $transformer, $entity->getEntityType()); - $data = $manager->createData($resource)->toArray(); + $manager = new Manager(); + $manager->setSerializer(new ArraySerializer()); + $manager->parseIncludes($include); - // For legacy Zapier support - if (isset($data['client_id'])) { - $data['client_name'] = $entity->client->getDisplayName(); - } + $resource = new Item($entity, $transformer, $entity->getEntityType()); + $data = $manager->createData($resource)->toArray(); + // For legacy Zapier support + if (isset($data['client_id'])) { + $data['client_name'] = $entity->client->getDisplayName(); + } + + foreach ($subscriptions as $subscription) { Utils::notifyZapier($subscription, $data); } } diff --git a/app/Models/Account.php b/app/Models/Account.php index aff6a20ff0b1..00212bb7306d 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -177,6 +177,7 @@ class Account extends Eloquent 'credit_number_prefix', 'credit_number_pattern', 'task_rate', + 'inclusive_taxes', ]; /** @@ -216,7 +217,6 @@ class Account extends Eloquent ENTITY_QUOTE => 4, ENTITY_TASK => 8, ENTITY_EXPENSE => 16, - ENTITY_VENDOR => 32, ]; public static $dashboardSections = [ @@ -233,6 +233,7 @@ class Account extends Eloquent 'due_date', 'hours', 'id_number', + 'invoice', 'item', 'line_total', 'outstanding', @@ -240,6 +241,7 @@ class Account extends Eloquent 'partial_due', 'po_number', 'quantity', + 'quote', 'rate', 'service', 'subtotal', @@ -1008,6 +1010,15 @@ class Account extends Eloquent $this->company->save(); } + public function hasReminders() + { + if (! $this->hasFeature(FEATURE_EMAIL_TEMPLATES_REMINDERS)) { + return false; + } + + return $this->enable_reminder1 || $this->enable_reminder2 || $this->enable_reminder3; + } + /** * @param $feature * @@ -1293,9 +1304,9 @@ class Account extends Eloquent * * @return \Illuminate\Database\Eloquent\Model|null|static */ - public function getSubscription($eventId) + public function getSubscriptions($eventId) { - return Subscription::where('account_id', '=', $this->id)->where('event_id', '=', $eventId)->first(); + return Subscription::where('account_id', '=', $this->id)->where('event_id', '=', $eventId)->get(); } /** @@ -1625,10 +1636,17 @@ class Account extends Eloquent ENTITY_TASK, ENTITY_EXPENSE, ENTITY_VENDOR, + ENTITY_PROJECT, ])) { return true; } + if ($entityType == ENTITY_VENDOR) { + $entityType = ENTITY_EXPENSE; + } elseif ($entityType == ENTITY_PROJECT) { + $entityType = ENTITY_TASK; + } + // note: single & checks bitmask match return $this->enabled_modules & static::$modules[$entityType]; } @@ -1692,6 +1710,11 @@ class Account extends Eloquent return $this->company->accounts->count() > 1; } + public function getPrimaryAccount() + { + return $this->company->accounts()->orderBy('id')->first(); + } + public function financialYearStart() { if (! $this->financial_year_start) { @@ -1712,6 +1735,29 @@ class Account extends Eloquent { return $this->hasFeature(FEATURE_CLIENT_PORTAL_PASSWORD) && $this->enable_portal_password; } + + public function getBaseUrl() + { + if ($this->hasFeature(FEATURE_CUSTOM_URL)) { + if ($this->iframe_url) { + return $this->iframe_url; + } + + if (Utils::isNinjaProd() && ! Utils::isReseller()) { + $url = $this->present()->clientPortalLink(); + } else { + $url = url('/'); + } + + if ($this->subdomain) { + $url = Utils::replaceSubdomain($url, $this->subdomain); + } + + return $url; + } else { + return url('/'); + } + } } Account::creating(function ($account) @@ -1719,6 +1765,13 @@ Account::creating(function ($account) LookupAccount::createAccount($account->account_key, $account->company_id); }); +Account::updating(function ($account) { + $dirty = $account->getDirty(); + if (array_key_exists('subdomain', $dirty)) { + LookupAccount::updateAccount($account->account_key, $account); + } +}); + Account::updated(function ($account) { // prevent firing event if the invoice/quote counter was changed // TODO: remove once counters are moved to separate table diff --git a/app/Models/AccountGateway.php b/app/Models/AccountGateway.php index 5e78f4aca62c..a5757ad7448e 100644 --- a/app/Models/AccountGateway.php +++ b/app/Models/AccountGateway.php @@ -136,6 +136,15 @@ class AccountGateway extends EntityModel return $this->getConfigField('publishableKey'); } + public function getAppleMerchantId() + { + if (! $this->isGateway(GATEWAY_STRIPE)) { + return false; + } + + return $this->getConfigField('appleMerchantId'); + } + /** * @return bool */ @@ -144,6 +153,14 @@ class AccountGateway extends EntityModel return ! empty($this->getConfigField('enableAch')); } + /** + * @return bool + */ + public function getApplePayEnabled() + { + return ! empty($this->getConfigField('enableApplePay')); + } + /** * @return bool */ diff --git a/app/Models/Client.php b/app/Models/Client.php index 3213e3d17026..7d992d6c90fb 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -53,10 +53,16 @@ class Client extends EntityModel 'quote_number_counter', 'public_notes', 'task_rate', + 'shipping_address1', + 'shipping_address2', + 'shipping_city', + 'shipping_state', + 'shipping_postal_code', + 'shipping_country_id', + 'show_tasks_in_portal', + 'send_reminders', ]; - - /** * @return array */ @@ -179,6 +185,14 @@ class Client extends EntityModel return $this->belongsTo('App\Models\Country'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function shipping_country() + { + return $this->belongsTo('App\Models\Country'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ @@ -375,7 +389,7 @@ class Client extends EntityModel /** * @return bool */ - public function hasAddress() + public function hasAddress($shipping = false) { $fields = [ 'address1', @@ -387,6 +401,9 @@ class Client extends EntityModel ]; foreach ($fields as $field) { + if ($shipping) { + $field = 'shipping_' . $field; + } if ($this->$field) { return true; } @@ -489,6 +506,20 @@ class Client extends EntityModel return $this->account->currency ? $this->account->currency->code : 'USD'; } + public function getCountryCode() + { + if ($country = $this->country) { + return $country->iso_3166_2; + } + + if (! $this->account) { + $this->load('account'); + } + + return $this->account->country ? $this->account->country->iso_3166_2 : 'US'; + } + + /** * @param $isQuote * diff --git a/app/Models/Contact.php b/app/Models/Contact.php index fffc93c6d753..799f8e8e80bc 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -9,13 +9,20 @@ use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Database\Eloquent\SoftDeletes; use App\Models\LookupContact; +use Illuminate\Notifications\Notifiable; /** * Class Contact. */ class Contact extends EntityModel implements AuthenticatableContract, CanResetPasswordContract { - use SoftDeletes, Authenticatable, CanResetPassword; + use SoftDeletes; + use Authenticatable; + use CanResetPassword; + use Notifiable; + + protected $guard = 'client'; + /** * @var array */ @@ -42,6 +49,17 @@ class Contact extends EntityModel implements AuthenticatableContract, CanResetPa 'custom_value2', ]; + /** + * The attributes excluded from the model's JSON form. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + 'confirmation_code', + ]; + /** * @var string */ @@ -165,6 +183,12 @@ class Contact extends EntityModel implements AuthenticatableContract, CanResetPa return "{$url}/client/dashboard/{$this->contact_key}"; } + + public function sendPasswordResetNotification($token) + { + //$this->notify(new ResetPasswordNotification($token)); + app('App\Ninja\Mailers\ContactMailer')->sendPasswordReset($this, $token); + } } Contact::creating(function ($contact) diff --git a/app/Models/Currency.php b/app/Models/Currency.php index 6992a8cd749f..77d99d543a36 100644 --- a/app/Models/Currency.php +++ b/app/Models/Currency.php @@ -3,6 +3,7 @@ namespace App\Models; use Eloquent; +use Str; /** * Class Currency. @@ -28,4 +29,12 @@ class Currency extends Eloquent { return $this->name; } + + /** + * @return mixed + */ + public function getTranslatedName() + { + return trans('texts.currency_' . Str::slug($this->name, '_')); + } } diff --git a/app/Models/EntityModel.php b/app/Models/EntityModel.php index 79175a43d79e..e830e56a0348 100644 --- a/app/Models/EntityModel.php +++ b/app/Models/EntityModel.php @@ -161,6 +161,7 @@ class EntityModel extends Eloquent $query->where($this->getTable() .'.account_id', '=', $accountId); + // If 'false' is passed as the publicId return nothing rather than everything if (func_num_args() > 1 && ! $publicId && ! $accountId) { $query->where('id', '=', 0); return $query; @@ -326,6 +327,7 @@ class EntityModel extends Eloquent 'settings' => 'cog', 'self-update' => 'download', 'reports' => 'th-list', + 'projects' => 'briefcase', ]; return array_get($icons, $entityType); diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 1ea05337b475..66609291b998 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -42,9 +42,8 @@ class Gateway extends Eloquent */ public static $preferred = [ GATEWAY_PAYPAL_EXPRESS, - GATEWAY_BITPAY, - GATEWAY_DWOLLA, GATEWAY_STRIPE, + GATEWAY_WEPAY, GATEWAY_BRAINTREE, GATEWAY_AUTHORIZE_NET, GATEWAY_MOLLIE, @@ -140,7 +139,6 @@ class Gateway extends Eloquent public function scopePrimary($query, $accountGatewaysIds) { $query->where('payment_library_id', '=', 1) - ->where('id', '!=', GATEWAY_WEPAY) ->whereIn('id', static::$preferred) ->whereIn('id', $accountGatewaysIds); } @@ -152,7 +150,6 @@ class Gateway extends Eloquent public function scopeSecondary($query, $accountGatewaysIds) { $query->where('payment_library_id', '=', 1) - ->where('id', '!=', GATEWAY_WEPAY) ->whereNotIn('id', static::$preferred) ->whereIn('id', $accountGatewaysIds); } @@ -178,11 +175,13 @@ class Gateway extends Eloquent $link = 'https://applications.sagepay.com/apply/2C02C252-0F8A-1B84-E10D-CF933EFCAA99'; } elseif ($this->id == GATEWAY_STRIPE) { $link = 'https://dashboard.stripe.com/account/apikeys'; + } elseif ($this->id == GATEWAY_WEPAY) { + $link = url('/gateways/create?wepay=true'); } $key = 'texts.gateway_help_'.$this->id; $str = trans($key, [ - 'link' => "Click here", + 'link' => "Click here", 'complete_link' => url('/complete'), ]); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index eedad8a955de..e14d2cc26275 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -460,6 +460,38 @@ class Invoice extends EntityModel implements BalanceAffecting return $query->where('invoice_type_id', '=', $typeId); } + /** + * @param $query + * @param $typeId + * + * @return mixed + */ + public function scopeStatusIds($query, $statusIds) + { + if (! $statusIds || (is_array($statusIds) && ! count($statusIds))) { + return $query; + } + + return $query->where(function ($query) use ($statusIds) { + foreach ($statusIds as $statusId) { + $query->orWhere('invoice_status_id', '=', $statusId); + } + if (in_array(INVOICE_STATUS_UNPAID, $statusIds)) { + $query->orWhere(function ($query) { + $query->where('balance', '>', 0) + ->where('is_public', '=', true); + }); + } + if (in_array(INVOICE_STATUS_OVERDUE, $statusIds)) { + $query->orWhere(function ($query) { + $query->where('balance', '>', 0) + ->where('due_date', '<', date('Y-m-d')) + ->where('is_public', '=', true); + }); + } + }); + } + /** * @param $typeId * @@ -955,6 +987,7 @@ class Invoice extends EntityModel implements BalanceAffecting 'include_item_taxes_inline', 'invoice_fields', 'show_currency_code', + 'inclusive_taxes', ]); foreach ($this->invoice_items as $invoiceItem) { @@ -1319,17 +1352,26 @@ class Invoice extends EntityModel implements BalanceAffecting public function getTaxes($calculatePaid = false) { $taxes = []; + $account = $this->account; $taxable = $this->getTaxable(); $paidAmount = $this->getAmountPaid($calculatePaid); if ($this->tax_name1) { - $invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2); + if ($account->inclusive_taxes) { + $invoiceTaxAmount = round(($taxable * 100) / (100 + ($this->tax_rate1 * 100)), 2); + } else { + $invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2); + } $invoicePaidAmount = floatval($this->amount) && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; $this->calculateTax($taxes, $this->tax_name1, $this->tax_rate1, $invoiceTaxAmount, $invoicePaidAmount); } if ($this->tax_name2) { - $invoiceTaxAmount = round($taxable * ($this->tax_rate2 / 100), 2); + if ($account->inclusive_taxes) { + $invoiceTaxAmount = round(($taxable * 100) / (100 + ($this->tax_rate2 * 100)), 2); + } else { + $invoiceTaxAmount = round($taxable * ($this->tax_rate2 / 100), 2); + } $invoicePaidAmount = floatval($this->amount) && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; $this->calculateTax($taxes, $this->tax_name2, $this->tax_rate2, $invoiceTaxAmount, $invoicePaidAmount); } @@ -1338,13 +1380,21 @@ class Invoice extends EntityModel implements BalanceAffecting $itemTaxable = $this->getItemTaxable($invoiceItem, $taxable); if ($invoiceItem->tax_name1) { - $itemTaxAmount = round($itemTaxable * ($invoiceItem->tax_rate1 / 100), 2); + if ($account->inclusive_taxes) { + $itemTaxAmount = round(($itemTaxable * 100) / (100 + ($invoiceItem->tax_rate1 * 100)), 2); + } else { + $itemTaxAmount = round($itemTaxable * ($invoiceItem->tax_rate1 / 100), 2); + } $itemPaidAmount = floatval($this->amount) && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; $this->calculateTax($taxes, $invoiceItem->tax_name1, $invoiceItem->tax_rate1, $itemTaxAmount, $itemPaidAmount); } if ($invoiceItem->tax_name2) { - $itemTaxAmount = round($itemTaxable * ($invoiceItem->tax_rate2 / 100), 2); + if ($account->inclusive_taxes) { + $itemTaxAmount = round(($itemTaxable * 100) / (100 + ($invoiceItem->tax_rate2 * 100)), 2); + } else { + $itemTaxAmount = round($itemTaxable * ($invoiceItem->tax_rate2 / 100), 2); + } $itemPaidAmount = floatval($this->amount) && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; $this->calculateTax($taxes, $invoiceItem->tax_name2, $invoiceItem->tax_rate2, $itemTaxAmount, $itemPaidAmount); } diff --git a/app/Models/InvoiceStatus.php b/app/Models/InvoiceStatus.php index 302b79ca9fc3..9b0132ae0899 100644 --- a/app/Models/InvoiceStatus.php +++ b/app/Models/InvoiceStatus.php @@ -3,6 +3,7 @@ namespace App\Models; use Eloquent; +use Str; /** * Class InvoiceStatus. @@ -33,6 +34,14 @@ class InvoiceStatus extends Eloquent return INVOICE_STATUS_UNPAID; default: return false; - } + } + } + + /** + * @return mixed + */ + public function getTranslatedName() + { + return trans('texts.status_' . Str::slug($this->name, '_')); } } diff --git a/app/Models/LookupAccount.php b/app/Models/LookupAccount.php index 7d5cd8e8c12d..ae682bcf56c5 100644 --- a/app/Models/LookupAccount.php +++ b/app/Models/LookupAccount.php @@ -55,4 +55,44 @@ class LookupAccount extends LookupModel return $this->lookupCompany->dbServer->name; } + public static function updateAccount($accountKey, $account) + { + if (! env('MULTI_DB_ENABLED')) { + return; + } + + $current = config('database.default'); + config(['database.default' => DB_NINJA_LOOKUP]); + + $lookupAccount = LookupAccount::whereAccountKey($accountKey) + ->firstOrFail(); + + $lookupAccount->subdomain = $account->subdomain ?: null; + $lookupAccount->save(); + + config(['database.default' => $current]); + } + + public static function validateField($field, $value, $account = false) + { + if (! env('MULTI_DB_ENABLED')) { + return true; + } + + $current = config('database.default'); + + config(['database.default' => DB_NINJA_LOOKUP]); + + $lookupAccount = LookupAccount::where($field, '=', $value)->first(); + + if ($account) { + $isValid = ! $lookupAccount || ($lookupAccount->account_key == $account->account_key); + } else { + $isValid = ! $lookupAccount; + } + + config(['database.default' => $current]); + + return $isValid; + } } diff --git a/app/Models/PasswordReset.php b/app/Models/PasswordReset.php new file mode 100644 index 000000000000..468c9901e72b --- /dev/null +++ b/app/Models/PasswordReset.php @@ -0,0 +1,13 @@ +getCompletedAmount() > 0 && ($this->isCompleted() || $this->isPartiallyRefunded()); } + /** + * @return bool + */ + public function isExchanged() + { + return $this->exchange_currency_id || $this->exchange_rate != 1; + } + /** * @return mixed|null|\stdClass|string */ diff --git a/app/Models/PaymentMethod.php b/app/Models/PaymentMethod.php index 76dce0891bf0..c4efaac6a6ab 100644 --- a/app/Models/PaymentMethod.php +++ b/app/Models/PaymentMethod.php @@ -256,7 +256,7 @@ class PaymentMethod extends EntityModel PaymentMethod::deleting(function ($paymentMethod) { $accountGatewayToken = $paymentMethod->account_gateway_token; if ($accountGatewayToken->default_payment_method_id == $paymentMethod->id) { - $newDefault = $accountGatewayToken->payment_methods->first(function ($i, $paymentMethdod) use ($accountGatewayToken) { + $newDefault = $accountGatewayToken->payment_methods->first(function ($paymentMethdod) use ($accountGatewayToken) { return $paymentMethdod->id != $accountGatewayToken->default_payment_method_id; }); $accountGatewayToken->default_payment_method_id = $newDefault ? $newDefault->id : null; diff --git a/app/Models/Project.php b/app/Models/Project.php index 72bd1d10c1b7..ed5692dd3cd2 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -55,6 +55,14 @@ class Project extends EntityModel { return $this->belongsTo('App\Models\Client')->withTrashed(); } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function tasks() + { + return $this->hasMany('App\Models\Task'); + } } Project::creating(function ($project) { diff --git a/app/Models/ScheduledReport.php b/app/Models/ScheduledReport.php new file mode 100644 index 000000000000..1425457d5e22 --- /dev/null +++ b/app/Models/ScheduledReport.php @@ -0,0 +1,59 @@ +belongsTo('App\Models\Account'); + } + + /** + * @return mixed + */ + public function user() + { + return $this->belongsTo('App\Models\User')->withTrashed(); + } + + public function updateSendDate() + { + switch ($this->frequency) { + case REPORT_FREQUENCY_DAILY; + $this->send_date = Carbon::now()->addDay()->toDateString(); + break; + case REPORT_FREQUENCY_WEEKLY: + $this->send_date = Carbon::now()->addWeek()->toDateString(); + break; + case REPORT_FREQUENCY_BIWEEKLY: + $this->send_date = Carbon::now()->addWeeks(2)->toDateString(); + break; + case REPORT_FREQUENCY_MONTHLY: + $this->send_date = Carbon::now()->addMonth()->toDateString(); + break; + } + + $this->save(); + } +} diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php index 766678a1888a..ad29cd07aa34 100644 --- a/app/Models/Subscription.php +++ b/app/Models/Subscription.php @@ -8,15 +8,42 @@ use Illuminate\Database\Eloquent\SoftDeletes; /** * Class Subscription. */ -class Subscription extends Eloquent +class Subscription extends EntityModel { /** * @var bool */ public $timestamps = true; + use SoftDeletes; + /** * @var array */ protected $dates = ['deleted_at']; + + /** + * @var array + */ + protected $fillable = [ + 'event_id', + 'target_url', + ]; + + /** + * @return mixed + */ + public function getEntityType() + { + return ENTITY_SUBSCRIPTION; + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function account() + { + return $this->belongsTo('App\Models\Account'); + } + } diff --git a/app/Models/Traits/HasRecurrence.php b/app/Models/Traits/HasRecurrence.php index d4e63d552e56..e1d663042b5c 100644 --- a/app/Models/Traits/HasRecurrence.php +++ b/app/Models/Traits/HasRecurrence.php @@ -40,7 +40,7 @@ trait HasRecurrence $monthsSinceLastSent = ($diff->format('%y') * 12) + $diff->format('%m'); // check we don't send a few hours early due to timezone difference - if (Carbon::now()->format('Y-m-d') != Carbon::now($timezone)->format('Y-m-d')) { + if (Utils::isNinja() && Carbon::now()->format('Y-m-d') != Carbon::now($timezone)->format('Y-m-d')) { return false; } diff --git a/app/Models/Traits/PresentsInvoice.php b/app/Models/Traits/PresentsInvoice.php index 334950366de2..082f539bb0e2 100644 --- a/app/Models/Traits/PresentsInvoice.php +++ b/app/Models/Traits/PresentsInvoice.php @@ -331,6 +331,7 @@ trait PresentsInvoice 'unit_cost', 'custom_value1', 'custom_value2', + 'delivery_note', ]; foreach ($fields as $field) { diff --git a/app/Models/User.php b/app/Models/User.php index 830e498ec54f..4b0c8bdbc05f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -11,6 +11,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Laracasts\Presenter\PresentableTrait; use Session; use App\Models\LookupUser; +use Illuminate\Notifications\Notifiable; /** * Class User. @@ -19,6 +20,7 @@ class User extends Authenticatable { use PresentableTrait; use SoftDeletes; + use Notifiable; /** * @var string @@ -176,7 +178,7 @@ class User extends Authenticatable } elseif ($this->email) { return $this->email; } else { - return 'Guest'; + return trans('texts.guest'); } } @@ -427,6 +429,12 @@ class User extends Authenticatable { return $this->account->company->accounts->sortBy('id')->first(); } + + public function sendPasswordResetNotification($token) + { + //$this->notify(new ResetPasswordNotification($token)); + app('App\Ninja\Mailers\UserMailer')->sendPasswordReset($this, $token); + } } User::created(function ($user) diff --git a/app/Ninja/Datatables/InvoiceDatatable.php b/app/Ninja/Datatables/InvoiceDatatable.php index f2765e425d7d..33bc529ab5bb 100644 --- a/app/Ninja/Datatables/InvoiceDatatable.php +++ b/app/Ninja/Datatables/InvoiceDatatable.php @@ -68,7 +68,10 @@ class InvoiceDatatable extends EntityDatatable function ($model) { $str = ''; if ($model->partial_due_date) { - $str = Utils::fromSqlDate($model->partial_due_date) . ', '; + $str = Utils::fromSqlDate($model->partial_due_date); + if ($model->due_date_sql && $model->due_date_sql != '0000-00-00') { + $str .= ', '; + } } return $str . Utils::fromSqlDate($model->due_date_sql); }, @@ -106,11 +109,20 @@ class InvoiceDatatable extends EntityDatatable }, ], [ - trans('texts.view_history'), + trans("texts.{$entityType}_history"), function ($model) use ($entityType) { return URL::to("{$entityType}s/{$entityType}_history/{$model->public_id}"); }, ], + [ + trans('texts.delivery_note'), + function ($model) use ($entityType) { + return url("invoices/delivery_note/{$model->public_id}"); + }, + function ($model) use ($entityType) { + return $entityType == ENTITY_INVOICE; + }, + ], [ '--divider--', function () { return false; diff --git a/app/Ninja/Datatables/PaymentDatatable.php b/app/Ninja/Datatables/PaymentDatatable.php index 435b610f92c7..193207f9d82a 100644 --- a/app/Ninja/Datatables/PaymentDatatable.php +++ b/app/Ninja/Datatables/PaymentDatatable.php @@ -91,7 +91,13 @@ class PaymentDatatable extends EntityDatatable [ 'amount', function ($model) { - return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); + $amount = Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); + + if ($model->exchange_currency_id && $model->exchange_rate != 1) { + $amount .= ' | ' . Utils::formatMoney($model->amount * $model->exchange_rate, $model->exchange_currency_id, $model->country_id); + } + + return $amount; }, ], [ diff --git a/app/Ninja/Datatables/ProjectDatatable.php b/app/Ninja/Datatables/ProjectDatatable.php index 6165028e45aa..20b52c98ccfd 100644 --- a/app/Ninja/Datatables/ProjectDatatable.php +++ b/app/Ninja/Datatables/ProjectDatatable.php @@ -59,6 +59,15 @@ class ProjectDatatable extends EntityDatatable return Auth::user()->can('editByOwner', [ENTITY_PROJECT, $model->user_id]); }, ], + [ + trans('texts.invoice_project'), + function ($model) { + return "javascript:submitForm_project('invoice', {$model->public_id})"; + }, + function ($model) { + return Auth::user()->can('create', ENTITY_INVOICE); + }, + ], ]; } } diff --git a/app/Ninja/Datatables/SubscriptionDatatable.php b/app/Ninja/Datatables/SubscriptionDatatable.php new file mode 100644 index 000000000000..8538b99391e4 --- /dev/null +++ b/app/Ninja/Datatables/SubscriptionDatatable.php @@ -0,0 +1,40 @@ +event); + }, + ], + [ + 'target', + function ($model) { + return $model->target; + }, + ], + ]; + } + + public function actions() + { + return [ + [ + uctrans('texts.edit_subscription'), + function ($model) { + return URL::to("subscriptions/{$model->public_id}/edit"); + }, + ], + ]; + } +} diff --git a/app/Ninja/Datatables/TaxRateDatatable.php b/app/Ninja/Datatables/TaxRateDatatable.php index fb20386e2e71..e42308b0b5de 100644 --- a/app/Ninja/Datatables/TaxRateDatatable.php +++ b/app/Ninja/Datatables/TaxRateDatatable.php @@ -26,7 +26,11 @@ class TaxRateDatatable extends EntityDatatable [ 'type', function ($model) { - return $model->is_inclusive ? trans('texts.inclusive') : trans('texts.exclusive'); + if (auth()->user()->account->inclusive_taxes) { + return trans('texts.inclusive'); + } else { + return $model->is_inclusive ? trans('texts.inclusive') : trans('texts.exclusive'); + } }, ], ]; diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index 5507ef2ccfce..6647f56d5ebc 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -327,4 +327,19 @@ class ContactMailer extends Mailer $this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } + + public function sendPasswordReset($contact, $token) + { + if (! $contact->email) { + return; + } + + $subject = trans('texts.your_password_reset_link'); + $view = 'client_password'; + $data = [ + 'token' => $token, + ]; + + $this->sendTo($contact->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); + } } diff --git a/app/Ninja/Mailers/UserMailer.php b/app/Ninja/Mailers/UserMailer.php index bc464525e438..6b5d130b697a 100644 --- a/app/Ninja/Mailers/UserMailer.php +++ b/app/Ninja/Mailers/UserMailer.php @@ -154,4 +154,42 @@ class UserMailer extends Mailer $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } + + public function sendPasswordReset($user, $token) + { + if (! $user->email) { + return; + } + + $subject = trans('texts.your_password_reset_link'); + $view = 'password'; + $data = [ + 'token' => $token, + ]; + + $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); + } + + public function sendScheduledReport($scheduledReport, $file) + { + $user = $scheduledReport->user; + $config = json_decode($scheduledReport->config); + + if (! $user->email) { + return; + } + + $subject = sprintf('%s - %s %s', APP_NAME, trans('texts.' . $config->report_type), trans('texts.report')); + $view = 'user_message'; + $data = [ + 'userName' => $user->getDisplayName(), + 'primaryMessage' => trans('texts.scheduled_report_attached', ['type' => trans('texts.' . $config->report_type)]), + 'documents' => [[ + 'name' => $file->filename . '.' . $config->export_format, + 'data' => $file->string($config->export_format), + ]] + ]; + + $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); + } } diff --git a/app/Ninja/PaymentDrivers/BasePaymentDriver.php b/app/Ninja/PaymentDrivers/BasePaymentDriver.php index 7d0cad613da4..754c8bd0320b 100644 --- a/app/Ninja/PaymentDrivers/BasePaymentDriver.php +++ b/app/Ninja/PaymentDrivers/BasePaymentDriver.php @@ -173,7 +173,6 @@ class BasePaymentDriver 'accountGateway' => $this->accountGateway, 'acceptedCreditCardTypes' => $this->accountGateway->getCreditcardTypes(), 'gateway' => $gateway, - 'showAddress' => $this->accountGateway->show_address, 'showBreadcrumbs' => false, 'url' => $url, 'amount' => $this->invoice()->getRequestedAmount(), @@ -407,19 +406,30 @@ class BasePaymentDriver $this->contact()->save(); } - if (! $this->accountGateway->show_address || ! $this->accountGateway->update_address) { - return; - } - // update the address info $client = $this->client(); - $client->address1 = trim($this->input['address1']); - $client->address2 = trim($this->input['address2']); - $client->city = trim($this->input['city']); - $client->state = trim($this->input['state']); - $client->postal_code = trim($this->input['postal_code']); - $client->country_id = trim($this->input['country_id']); - $client->save(); + + if ($this->accountGateway->show_address && $this->accountGateway->update_address) { + $client->address1 = trim($this->input['address1']); + $client->address2 = trim($this->input['address2']); + $client->city = trim($this->input['city']); + $client->state = trim($this->input['state']); + $client->postal_code = trim($this->input['postal_code']); + $client->country_id = trim($this->input['country_id']); + } + + if ($this->accountGateway->show_shipping_address) { + $client->shipping_address1 = trim($this->input['shipping_address1']); + $client->shipping_address2 = trim($this->input['shipping_address2']); + $client->shipping_city = trim($this->input['shipping_city']); + $client->shipping_state = trim($this->input['shipping_state']); + $client->shipping_postal_code = trim($this->input['shipping_postal_code']); + $client->shipping_country_id = trim($this->input['shipping_country_id']); + } + + if ($client->isDirty()) { + $client->save(); + } } protected function paymentDetails($paymentMethod = false) @@ -474,22 +484,23 @@ class BasePaymentDriver } if (isset($input['address1'])) { - // TODO use cache instead - $country = Country::find($input['country_id']); + $hasShippingAddress = $this->accountGateway->show_shipping_address; + $country = Utils::getFromCache($input['country_id'], 'countries'); + $shippingCountry = $hasShippingAddress ? Utils::getFromCache($input['shipping_country_id'], 'countries') : $country; $data = array_merge($data, [ - 'billingAddress1' => $input['address1'], - 'billingAddress2' => $input['address2'], - 'billingCity' => $input['city'], - 'billingState' => $input['state'], - 'billingPostcode' => $input['postal_code'], + 'billingAddress1' => trim($input['address1']), + 'billingAddress2' => trim($input['address2']), + 'billingCity' => trim($input['city']), + 'billingState' => trim($input['state']), + 'billingPostcode' => trim($input['postal_code']), 'billingCountry' => $country->iso_3166_2, - 'shippingAddress1' => $input['address1'], - 'shippingAddress2' => $input['address2'], - 'shippingCity' => $input['city'], - 'shippingState' => $input['state'], - 'shippingPostcode' => $input['postal_code'], - 'shippingCountry' => $country->iso_3166_2, + 'shippingAddress1' => $hasShippingAddress ? trim($this->input['shipping_address1']) : trim($input['address1']), + 'shippingAddress2' => $hasShippingAddress ? trim($this->input['shipping_address2']) : trim($input['address2']), + 'shippingCity' => $hasShippingAddress ? trim($this->input['shipping_city']) : trim($input['city']), + 'shippingState' => $hasShippingAddress ? trim($this->input['shipping_state']) : trim($input['state']), + 'shippingPostcode' => $hasShippingAddress ? trim($this->input['shipping_postal_code']) : trim($input['postal_code']), + 'shippingCountry' => $hasShippingAddress ? $shippingCountry->iso_3166_2 : $country->iso_3166_2, ]); } @@ -501,6 +512,7 @@ class BasePaymentDriver $invoice = $this->invoice(); $client = $this->client(); $contact = $this->invitation->contact ?: $client->contacts()->first(); + $hasShippingAddress = $this->accountGateway->show_shipping_address; return [ 'email' => $contact->email, @@ -514,12 +526,12 @@ class BasePaymentDriver 'billingState' => $client->state, 'billingCountry' => $client->country ? $client->country->iso_3166_2 : '', 'billingPhone' => $contact->phone, - 'shippingAddress1' => $client->address1, - 'shippingAddress2' => $client->address2, - 'shippingCity' => $client->city, - 'shippingPostcode' => $client->postal_code, - 'shippingState' => $client->state, - 'shippingCountry' => $client->country ? $client->country->iso_3166_2 : '', + 'shippingAddress1' => $client->shipping_address1 ? $client->shipping_address1 : $client->address1, + 'shippingAddress2' => $client->shipping_address1 ? $client->shipping_address1 : $client->address2, + 'shippingCity' => $client->shipping_address1 ? $client->shipping_address1 : $client->city, + 'shippingPostcode' => $client->shipping_address1 ? $client->shipping_address1 : $client->postal_code, + 'shippingState' => $client->shipping_address1 ? $client->shipping_address1 : $client->state, + 'shippingCountry' => $client->shipping_address1 ? ($client->shipping_country ? $client->shipping_country->iso_3166_2 : '') : ($client->country ? $client->country->iso_3166_2 : ''), 'shippingPhone' => $contact->phone, ]; } @@ -867,23 +879,32 @@ class BasePaymentDriver return $payment; } + protected function updateClientFromOffsite($transRef, $paymentRef) + { + // do nothing + } + public function completeOffsitePurchase($input) { $this->input = $input; - $ref = array_get($this->input, 'token') ?: $this->invitation->transaction_reference; + $transRef = array_get($this->input, 'token') ?: $this->invitation->transaction_reference; if (method_exists($this->gateway(), 'completePurchase')) { $details = $this->paymentDetails(); $response = $this->gateway()->completePurchase($details)->send(); - $ref = $response->getTransactionReference() ?: $ref; + $paymentRef = $response->getTransactionReference() ?: $transRef; if ($response->isCancelled()) { return false; } elseif (! $response->isSuccessful()) { throw new Exception($response->getMessage()); } + } else { + $paymentRef = $transRef; } + $this->updateClientFromOffsite($transRef, $paymentRef); + // check invoice still has balance if (! floatval($this->invoice()->balance)) { throw new Exception(trans('texts.payment_error_code', ['code' => 'NB'])); @@ -891,12 +912,12 @@ class BasePaymentDriver // check this isn't a duplicate transaction reference if (Payment::whereAccountId($this->invitation->account_id) - ->whereTransactionReference($ref) + ->whereTransactionReference($paymentRef) ->first()) { throw new Exception(trans('texts.payment_error_code', ['code' => 'DT'])); } - return $this->createPayment($ref); + return $this->createPayment($paymentRef); } public function tokenLinks() diff --git a/app/Ninja/PaymentDrivers/PayPalExpressPaymentDriver.php b/app/Ninja/PaymentDrivers/PayPalExpressPaymentDriver.php index ffec414c59b7..1c0d304b26ad 100644 --- a/app/Ninja/PaymentDrivers/PayPalExpressPaymentDriver.php +++ b/app/Ninja/PaymentDrivers/PayPalExpressPaymentDriver.php @@ -41,4 +41,33 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver } } + protected function updateClientFromOffsite($transRef, $paymentRef) + { + $response = $this->gateway()->fetchCheckout([ + 'token' => $transRef + ])->send(); + + $data = $response->getData(); + $client = $this->client(); + + if (empty($data['SHIPTOSTREET'])) { + return; + } + + $client->shipping_address1 = trim($data['SHIPTOSTREET']); + $client->shipping_address2 = ''; + $client->shipping_city = trim($data['SHIPTOCITY']); + $client->shipping_state = trim($data['SHIPTOSTATE']); + $client->shipping_postal_code = trim($data['SHIPTOZIP']); + + if ($country = cache('countries')->filter(function ($item) use ($data) { + return strtolower($item->iso_3166_2) == strtolower(trim($data['SHIPTOCOUNTRYCODE'])); + })->first()) { + $client->shipping_country_id = $country->id; + } else { + $client->shipping_country_id = null; + } + + $client->save(); + } } diff --git a/app/Ninja/PaymentDrivers/StripePaymentDriver.php b/app/Ninja/PaymentDrivers/StripePaymentDriver.php index 6024b0d0c72f..ae0622238327 100644 --- a/app/Ninja/PaymentDrivers/StripePaymentDriver.php +++ b/app/Ninja/PaymentDrivers/StripePaymentDriver.php @@ -53,6 +53,9 @@ class StripePaymentDriver extends BasePaymentDriver if ($gateway->getAlipayEnabled()) { $types[] = GATEWAY_TYPE_ALIPAY; } + if ($gateway->getApplePayEnabled()) { + $types[] = GATEWAY_TYPE_APPLE_PAY; + } } return $types; @@ -67,6 +70,10 @@ class StripePaymentDriver extends BasePaymentDriver { $rules = parent::rules(); + if ($this->isGatewayType(GATEWAY_TYPE_APPLE_PAY)) { + return ['sourceToken' => 'required']; + } + if ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER)) { $rules['authorize_ach'] = 'required'; } @@ -224,7 +231,9 @@ class StripePaymentDriver extends BasePaymentDriver // For older users the Stripe account may just have the customer token but not the card version // In that case we'd use GATEWAY_TYPE_TOKEN even though we're creating the credit card - if ($this->isGatewayType(GATEWAY_TYPE_CREDIT_CARD) || $this->isGatewayType(GATEWAY_TYPE_TOKEN)) { + if ($this->isGatewayType(GATEWAY_TYPE_CREDIT_CARD) + || $this->isGatewayType(GATEWAY_TYPE_APPLE_PAY) + || $this->isGatewayType(GATEWAY_TYPE_TOKEN)) { $paymentMethod->expiration = $source['exp_year'] . '-' . $source['exp_month'] . '-01'; $paymentMethod->payment_type_id = PaymentType::parseCardType($source['brand']); } elseif ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER)) { diff --git a/app/Ninja/Presenters/AccountPresenter.php b/app/Ninja/Presenters/AccountPresenter.php index b3f3e07ad2c0..df806c981c79 100644 --- a/app/Ninja/Presenters/AccountPresenter.php +++ b/app/Ninja/Presenters/AccountPresenter.php @@ -236,4 +236,31 @@ class AccountPresenter extends Presenter return $data; } + + public function clientLoginUrl() + { + $account = $this->entity; + + if (Utils::isNinjaProd()) { + $url = 'https://'; + $url .= $account->subdomain ?: 'app'; + $url .= '.' . Domain::getDomainFromId($account->domain_id); + } else { + $url = SITE_URL; + } + + $url .= '/client/login'; + + if (Utils::isNinja()) { + if (! $account->subdomain) { + $url .= '?account_key=' . $account->account_key; + } + } else { + if (Account::count() > 1) { + $url .= '?account_key=' . $account->account_key; + } + } + + return $url; + } } diff --git a/app/Ninja/Presenters/ClientPresenter.php b/app/Ninja/Presenters/ClientPresenter.php index 6bc87ebb46c1..d2f3ba553a6b 100644 --- a/app/Ninja/Presenters/ClientPresenter.php +++ b/app/Ninja/Presenters/ClientPresenter.php @@ -11,6 +11,11 @@ class ClientPresenter extends EntityPresenter return $this->entity->country ? $this->entity->country->name : ''; } + public function shipping_country() + { + return $this->entity->shipping_country ? $this->entity->shipping_country->name : ''; + } + public function balance() { $client = $this->entity; @@ -51,6 +56,53 @@ class ClientPresenter extends EntityPresenter return sprintf('%s: %s %s', trans('texts.payment_terms'), trans('texts.payment_terms_net'), $client->defaultDaysDue()); } + public function address($addressType = ADDRESS_BILLING) + { + $str = ''; + $prefix = $addressType == ADDRESS_BILLING ? '' : 'shipping_'; + $client = $this->entity; + + if ($address1 = $client->{$prefix . 'address1'}) { + $str .= e($address1) . '
'; + } + if ($address2 = $client->{$prefix . 'address2'}) { + $str .= e($address2) . '
'; + } + if ($cityState = $this->getCityState($addressType)) { + $str .= e($cityState) . '
'; + } + if ($country = $client->{$prefix . 'country'}) { + $str .= e($country->name) . '
'; + } + + if ($str) { + $str = '' . trans('texts.' . $addressType) . '
' . $str; + } + + return $str; + } + + /** + * @return string + */ + public function getCityState($addressType = ADDRESS_BILLING) + { + $client = $this->entity; + $prefix = $addressType == ADDRESS_BILLING ? '' : 'shipping_'; + $swap = $client->{$prefix . 'country'} && $client->{$prefix . 'country'}->swap_postal_code; + + $city = e($client->{$prefix . 'city'}); + $state = e($client->{$prefix . 'state'}); + $postalCode = e($client->{$prefix . 'post_code'}); + + if ($city || $state || $postalCode) { + return Utils::cityStateZip($city, $state, $postalCode, $swap); + } else { + return false; + } + } + + /** * @return string */ diff --git a/app/Ninja/Presenters/InvoiceItemPresenter.php b/app/Ninja/Presenters/InvoiceItemPresenter.php index daa898602610..0411df7a5b32 100644 --- a/app/Ninja/Presenters/InvoiceItemPresenter.php +++ b/app/Ninja/Presenters/InvoiceItemPresenter.php @@ -2,6 +2,7 @@ namespace App\Ninja\Presenters; +use Str; use stdClass; class InvoiceItemPresenter extends EntityPresenter @@ -16,4 +17,9 @@ class InvoiceItemPresenter extends EntityPresenter return $data; } + + public function notes() + { + return Str::limit($this->entity->notes); + } } diff --git a/app/Ninja/Presenters/InvoicePresenter.php b/app/Ninja/Presenters/InvoicePresenter.php index ce24bad54fd6..07ffa8789977 100644 --- a/app/Ninja/Presenters/InvoicePresenter.php +++ b/app/Ninja/Presenters/InvoicePresenter.php @@ -242,6 +242,11 @@ class InvoicePresenter extends EntityPresenter } $actions[] = ['url' => url("{$entityType}s/{$entityType}_history/{$invoice->public_id}"), 'label' => trans('texts.view_history')]; + + if ($entityType == ENTITY_INVOICE) { + $actions[] = ['url' => url("invoices/delivery_note/{$invoice->public_id}"), 'label' => trans('texts.delivery_note')]; + } + $actions[] = DropdownButton::DIVIDER; if ($entityType == ENTITY_QUOTE) { diff --git a/app/Ninja/Reports/ActivityReport.php b/app/Ninja/Reports/ActivityReport.php index 3e843b25b3f9..2aaac5188af9 100644 --- a/app/Ninja/Reports/ActivityReport.php +++ b/app/Ninja/Reports/ActivityReport.php @@ -18,8 +18,8 @@ class ActivityReport extends AbstractReport { $account = Auth::user()->account; - $startDate = $this->startDate->format('Y-m-d'); - $endDate = $this->endDate->format('Y-m-d'); + $startDate = $this->startDate;; + $endDate = $this->endDate; $activities = Activity::scope() ->with('client.contacts', 'user', 'invoice', 'payment', 'credit', 'task', 'expense', 'account') @@ -32,7 +32,7 @@ class ActivityReport extends AbstractReport $activity->present()->createdAt, $client ? ($this->isExport ? $client->getDisplayName() : $client->present()->link) : '', $activity->present()->user, - $activity->getMessage(), + $this->isExport ? strip_tags($activity->getMessage()) : $activity->getMessage(), ]; } diff --git a/app/Ninja/Reports/ExpenseReport.php b/app/Ninja/Reports/ExpenseReport.php index 505db8e7f170..8457d7079b06 100644 --- a/app/Ninja/Reports/ExpenseReport.php +++ b/app/Ninja/Reports/ExpenseReport.php @@ -38,7 +38,8 @@ class ExpenseReport extends AbstractReport $zip = Archive::instance_by_useragent(date('Y-m-d') . '_' . str_replace(' ', '_', trans('texts.expense_documents'))); foreach ($expenses->get() as $expense) { foreach ($expense->documents as $document) { - $name = sprintf('%s_%s_%s_%s', date('Y-m-d'), trans('texts.expense'), $expense->public_id, $document->name); + $expenseId = str_pad($expense->public_id, $account->invoice_number_padding, '0', STR_PAD_LEFT); + $name = sprintf('%s_%s_%s_%s', date('Y-m-d'), trans('texts.expense'), $expenseId, $document->name); $name = str_replace(' ', '_', $name); $zip->add_file($name, $document->getRaw()); } diff --git a/app/Ninja/Reports/InvoiceReport.php b/app/Ninja/Reports/InvoiceReport.php index 2341ae6f2de7..f8f5e24ffa4b 100644 --- a/app/Ninja/Reports/InvoiceReport.php +++ b/app/Ninja/Reports/InvoiceReport.php @@ -22,21 +22,17 @@ class InvoiceReport extends AbstractReport public function run() { $account = Auth::user()->account; - $status = $this->options['invoice_status']; + $statusIds = $this->options['status_ids']; $exportFormat = $this->options['export_format']; $clients = Client::scope() ->orderBy('name') ->withArchived() ->with('contacts') - ->with(['invoices' => function ($query) use ($status) { - if ($status == 'draft') { - $query->whereIsPublic(false); - } elseif (in_array($status, ['paid', 'unpaid', 'sent'])) { - $query->whereIsPublic(true); - } + ->with(['invoices' => function ($query) use ($statusIds) { $query->invoices() ->withArchived() + ->statusIds($statusIds) ->where('invoice_date', '>=', $this->startDate) ->where('invoice_date', '<=', $this->endDate) ->with(['payments' => function ($query) { @@ -65,17 +61,12 @@ class InvoiceReport extends AbstractReport foreach ($client->invoices as $invoice) { $payments = count($invoice->payments) ? $invoice->payments : [false]; foreach ($payments as $payment) { - if (! $payment && $status == 'paid') { - continue; - } elseif ($payment && $status == 'unpaid') { - continue; - } $this->data[] = [ $this->isExport ? $client->getDisplayName() : $client->present()->link, $this->isExport ? $invoice->invoice_number : $invoice->present()->link, $invoice->present()->invoice_date, $account->formatMoney($invoice->amount, $client), - $invoice->present()->status(), + $invoice->statusLabel(), $payment ? $payment->present()->payment_date : '', $payment ? $account->formatMoney($payment->getCompletedAmount(), $client) : '', $payment ? $payment->present()->method : '', diff --git a/app/Ninja/Reports/PaymentReport.php b/app/Ninja/Reports/PaymentReport.php index f3589ca00360..53d201f1880f 100644 --- a/app/Ninja/Reports/PaymentReport.php +++ b/app/Ninja/Reports/PaymentReport.php @@ -4,6 +4,7 @@ namespace App\Ninja\Reports; use App\Models\Payment; use Auth; +use Utils; class PaymentReport extends AbstractReport { @@ -20,6 +21,7 @@ class PaymentReport extends AbstractReport public function run() { $account = Auth::user()->account; + $currencyType = $this->options['currency_type']; $invoiceMap = []; $payments = Payment::scope() @@ -39,22 +41,36 @@ class PaymentReport extends AbstractReport foreach ($payments->get() as $payment) { $invoice = $payment->invoice; $client = $payment->client; + $amount = $payment->getCompletedAmount(); + + if ($currencyType == 'converted') { + $amount *= $payment->exchange_rate; + $this->addToTotals($payment->exchange_currency_id, 'paid', $amount); + $amount = Utils::formatMoney($amount, $payment->exchange_currency_id); + } else { + $this->addToTotals($client->currency_id, 'paid', $amount); + $amount = $account->formatMoney($amount, $client); + } + $this->data[] = [ $this->isExport ? $client->getDisplayName() : $client->present()->link, $this->isExport ? $invoice->invoice_number : $invoice->present()->link, $invoice->present()->invoice_date, $account->formatMoney($invoice->amount, $client), $payment->present()->payment_date, - $account->formatMoney($payment->getCompletedAmount(), $client), + $amount, $payment->present()->method, ]; if (! isset($invoiceMap[$invoice->id])) { - $this->addToTotals($client->currency_id, 'amount', $invoice->amount); $invoiceMap[$invoice->id] = true; - } - $this->addToTotals($client->currency_id, 'paid', $payment->getCompletedAmount()); + if ($currencyType == 'converted') { + $this->addToTotals($payment->exchange_currency_id, 'amount', $invoice->amount * $payment->exchange_rate); + } else { + $this->addToTotals($client->currency_id, 'amount', $invoice->amount); + } + } } } } diff --git a/app/Ninja/Reports/ProductReport.php b/app/Ninja/Reports/ProductReport.php index 8f1cf85a134e..d0a9c7c96a7e 100644 --- a/app/Ninja/Reports/ProductReport.php +++ b/app/Ninja/Reports/ProductReport.php @@ -13,6 +13,7 @@ class ProductReport extends AbstractReport 'invoice_number', 'invoice_date', 'product', + 'description', 'qty', 'cost', //'tax_rate1', @@ -22,20 +23,16 @@ class ProductReport extends AbstractReport public function run() { $account = Auth::user()->account; - $status = $this->options['invoice_status']; + $statusIds = $this->options['status_ids']; $clients = Client::scope() ->orderBy('name') ->withArchived() ->with('contacts') - ->with(['invoices' => function ($query) use ($status) { - if ($status == 'draft') { - $query->whereIsPublic(false); - } elseif (in_array($status, ['paid', 'unpaid', 'sent'])) { - $query->whereIsPublic(true); - } + ->with(['invoices' => function ($query) use ($statusIds) { $query->invoices() ->withArchived() + ->statusIds($statusIds) ->where('invoice_date', '>=', $this->startDate) ->where('invoice_date', '<=', $this->endDate) ->with(['invoice_items']); @@ -43,17 +40,13 @@ class ProductReport extends AbstractReport foreach ($clients->get() as $client) { foreach ($client->invoices as $invoice) { - if (! $invoice->isPaid() && $status == 'paid') { - continue; - } elseif ($invoice->isPaid() && $status == 'unpaid') { - continue; - } foreach ($invoice->invoice_items as $item) { $this->data[] = [ $this->isExport ? $client->getDisplayName() : $client->present()->link, $this->isExport ? $invoice->invoice_number : $invoice->present()->link, $invoice->present()->invoice_date, $item->product_key, + $this->isExport ? $item->notes : $item->present()->notes, Utils::roundSignificant($item->qty, 0), Utils::roundSignificant($item->cost, 2), ]; diff --git a/app/Ninja/Reports/ProfitAndLossReport.php b/app/Ninja/Reports/ProfitAndLossReport.php index 9370d91dfbd7..cd16ed49b0c9 100644 --- a/app/Ninja/Reports/ProfitAndLossReport.php +++ b/app/Ninja/Reports/ProfitAndLossReport.php @@ -59,7 +59,7 @@ class ProfitAndLossReport extends AbstractReport $this->data[] = [ trans('texts.expense'), $client ? ($this->isExport ? $client->getDisplayName() : $client->present()->link) : '', - $expense->present()->amount, + '-' . $expense->present()->amount, $expense->present()->expense_date, $expense->present()->category, ]; diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index fe01b476f3a6..4b5de57d4b3f 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -60,6 +60,7 @@ class AccountRepository $account->ip = Request::getClientIp(); $account->account_key = strtolower(str_random(RANDOM_KEY_LENGTH)); $account->company_id = $company->id; + $account->currency_id = DEFAULT_CURRENCY; // Set default language/currency based on IP if (\Cache::get('currencies')) { @@ -151,12 +152,17 @@ class AccountRepository if ($user->hasPermission('view_all')) { $clients = Client::scope() ->with('contacts', 'invoices') - ->get(); + ->withArchived() + ->with(['contacts', 'invoices' => function ($query) use ($user) { + $query->withArchived(); + }])->get(); } else { $clients = Client::scope() ->where('user_id', '=', $user->id) + ->withArchived() ->with(['contacts', 'invoices' => function ($query) use ($user) { - $query->where('user_id', '=', $user->id); + $query->withArchived() + ->where('user_id', '=', $user->id); }])->get(); } diff --git a/app/Ninja/Repositories/DashboardRepository.php b/app/Ninja/Repositories/DashboardRepository.php index 68507de7cd83..1897a269e915 100644 --- a/app/Ninja/Repositories/DashboardRepository.php +++ b/app/Ninja/Repositories/DashboardRepository.php @@ -159,7 +159,7 @@ class DashboardRepository $records->select(DB::raw('sum(expenses.amount + (expenses.amount * expenses.tax_rate1 / 100) + (expenses.amount * expenses.tax_rate2 / 100)) as total, count(expenses.id) as count, '.$timeframe.' as '.$groupBy)); } - return $records->get(); + return $records->get()->all(); } public function totals($accountId, $userId, $viewAll) diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 58d69e99e81a..1504a1f9225e 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -607,10 +607,12 @@ class InvoiceRepository extends BaseRepository $total += $invoice->custom_value2; } - $taxAmount1 = round($total * ($invoice->tax_rate1 ? $invoice->tax_rate1 : 0) / 100, 2); - $taxAmount2 = round($total * ($invoice->tax_rate2 ? $invoice->tax_rate2 : 0) / 100, 2); - $total = round($total + $taxAmount1 + $taxAmount2, 2); - $total += $itemTax; + if (! $account->inclusive_taxes) { + $taxAmount1 = round($total * ($invoice->tax_rate1 ? $invoice->tax_rate1 : 0) / 100, 2); + $taxAmount2 = round($total * ($invoice->tax_rate2 ? $invoice->tax_rate2 : 0) / 100, 2); + $total = round($total + $taxAmount1 + $taxAmount2, 2); + $total += $itemTax; + } // custom fields not charged taxes if ($invoice->custom_value1 && ! $invoice->custom_taxes1) { @@ -1174,7 +1176,10 @@ class InvoiceRepository extends BaseRepository $sql = implode(' OR ', $dates); $invoices = Invoice::invoiceType(INVOICE_TYPE_STANDARD) - ->with('invoice_items') + ->with('client', 'invoice_items') + ->whereHas('client', function ($query) { + $query->whereSendReminders(true); + }) ->whereAccountId($account->id) ->where('balance', '>', 0) ->where('is_recurring', '=', false) diff --git a/app/Ninja/Repositories/PaymentRepository.php b/app/Ninja/Repositories/PaymentRepository.php index 1cb48cb64819..1aa790774947 100644 --- a/app/Ninja/Repositories/PaymentRepository.php +++ b/app/Ninja/Repositories/PaymentRepository.php @@ -64,6 +64,8 @@ class PaymentRepository extends BaseRepository 'payments.routing_number', 'payments.bank_name', 'payments.private_notes', + 'payments.exchange_rate', + 'payments.exchange_currency_id', 'invoices.is_deleted as invoice_is_deleted', 'gateways.name as gateway_name', 'gateways.id as gateway_id', @@ -187,12 +189,7 @@ class PaymentRepository extends BaseRepository $payment->payment_date = date('Y-m-d'); } - if (isset($input['transaction_reference'])) { - $payment->transaction_reference = trim($input['transaction_reference']); - } - if (isset($input['private_notes'])) { - $payment->private_notes = trim($input['private_notes']); - } + $payment->fill($input); if (! $publicId) { $clientId = $input['client_id']; diff --git a/app/Ninja/Repositories/SubscriptionRepository.php b/app/Ninja/Repositories/SubscriptionRepository.php new file mode 100644 index 000000000000..b4687f8b192e --- /dev/null +++ b/app/Ninja/Repositories/SubscriptionRepository.php @@ -0,0 +1,29 @@ +where('subscriptions.account_id', '=', $accountId) + ->whereNull('subscriptions.deleted_at') + ->select( + 'subscriptions.public_id', + 'subscriptions.target_url as target', + 'subscriptions.event_id as event', + 'subscriptions.deleted_at' + ); + + return $query; + } +} diff --git a/app/Ninja/Repositories/TaskRepository.php b/app/Ninja/Repositories/TaskRepository.php index 327164741e30..56da52cc62eb 100644 --- a/app/Ninja/Repositories/TaskRepository.php +++ b/app/Ninja/Repositories/TaskRepository.php @@ -8,6 +8,7 @@ use App\Models\Task; use Auth; use Session; use DB; +use Utils; class TaskRepository extends BaseRepository { @@ -101,6 +102,38 @@ class TaskRepository extends BaseRepository return $query; } + public function getClientDatatable($clientId) + { + $query = DB::table('tasks') + ->leftJoin('projects', 'projects.id', '=', 'tasks.project_id') + ->where('tasks.client_id', '=', $clientId) + ->where('tasks.is_deleted', '=', false) + ->whereNull('tasks.invoice_id') + ->select( + 'tasks.description', + 'tasks.time_log', + 'tasks.time_log as duration', + DB::raw("SUBSTRING(time_log, 3, 10) date"), + 'projects.name as project' + ); + + $table = \Datatable::query($query) + ->addColumn('project', function ($model) { + return $model->project; + }) + ->addColumn('date', function ($model) { + return Task::calcStartTime($model); + }) + ->addColumn('duration', function ($model) { + return Utils::formatTime(Task::calcDuration($model)); + }) + ->addColumn('description', function ($model) { + return $model->description; + }); + + return $table->make(); + } + public function save($publicId, $data, $task = null) { if ($task) { diff --git a/app/Ninja/Transformers/AccountEmailSettingsTransformer.php b/app/Ninja/Transformers/AccountEmailSettingsTransformer.php index 6239c8452939..dd09fb011b86 100644 --- a/app/Ninja/Transformers/AccountEmailSettingsTransformer.php +++ b/app/Ninja/Transformers/AccountEmailSettingsTransformer.php @@ -43,6 +43,12 @@ class AccountEmailSettingsTransformer extends EntityTransformer 'email_template_reminder1' => $settings->email_template_reminder1, 'email_template_reminder2' => $settings->email_template_reminder2, 'email_template_reminder3' => $settings->email_template_reminder3, + 'late_fee1_amount' => $settings->late_fee1_amount, + 'late_fee1_percent' => $settings->late_fee1_percent, + 'late_fee2_amount' => $settings->late_fee2_amount, + 'late_fee2_percent' => $settings->late_fee2_percent, + 'late_fee3_amount' => $settings->late_fee3_amount, + 'late_fee3_percent' => $settings->late_fee3_percent, ]; } } diff --git a/app/Ninja/Transformers/AccountTransformer.php b/app/Ninja/Transformers/AccountTransformer.php index dbf53acf9485..69c084691af0 100644 --- a/app/Ninja/Transformers/AccountTransformer.php +++ b/app/Ninja/Transformers/AccountTransformer.php @@ -275,6 +275,7 @@ class AccountTransformer extends EntityTransformer 'custom_contact_label1' => $account->custom_contact_label1, 'custom_contact_label2' => $account->custom_contact_label2, 'task_rate' => (float) $account->task_rate, + 'inclusive_taxes' => (bool) $account->inclusive_taxes, ]; } } diff --git a/app/Ninja/Transformers/ClientTransformer.php b/app/Ninja/Transformers/ClientTransformer.php index e6814a287f5e..24d6161e2c78 100644 --- a/app/Ninja/Transformers/ClientTransformer.php +++ b/app/Ninja/Transformers/ClientTransformer.php @@ -38,6 +38,15 @@ class ClientTransformer extends EntityTransformer * @SWG\Property(property="id_number", type="string", example="123456") * @SWG\Property(property="language_id", type="integer", example=1) * @SWG\Property(property="task_rate", type="number", format="float", example=10) + * @SWG\Property(property="shipping_address1", type="string", example="10 Main St.") + * @SWG\Property(property="shipping_address2", type="string", example="1st Floor") + * @SWG\Property(property="shipping_city", type="string", example="New York") + * @SWG\Property(property="shipping_state", type="string", example="NY") + * @SWG\Property(property="shipping_postal_code", type="string", example=10010) + * @SWG\Property(property="shipping_country_id", type="integer", example=840) + * @SWG\Property(property="show_tasks_in_portal", type="boolean", example=false) + * @SWG\Property(property="send_reminders", type="boolean", example=false) + * @SWG\Property(property="credit_number_counter", type="integer", example=1) */ protected $defaultIncludes = [ 'contacts', @@ -137,6 +146,15 @@ class ClientTransformer extends EntityTransformer 'invoice_number_counter' => (int) $client->invoice_number_counter, 'quote_number_counter' => (int) $client->quote_number_counter, 'task_rate' => (float) $client->task_rate, + 'shipping_address1' => $client->shipping_address1, + 'shipping_address2' => $client->shipping_address2, + 'shipping_city' => $client->shipping_city, + 'shipping_state' => $client->shipping_state, + 'shipping_postal_code' => $client->shipping_postal_code, + 'shipping_country_id' => (int) $client->shipping_country_id, + 'show_tasks_in_portal' => (bool) $client->show_tasks_in_portal, + 'send_reminders' => (bool) $client->send_reminders, + 'credit_number_counter' => (int) $client->credit_number_counter, ]); } } diff --git a/app/Ninja/Transformers/DocumentTransformer.php b/app/Ninja/Transformers/DocumentTransformer.php index df412106fae2..7ec3b007d779 100644 --- a/app/Ninja/Transformers/DocumentTransformer.php +++ b/app/Ninja/Transformers/DocumentTransformer.php @@ -28,6 +28,7 @@ class DocumentTransformer extends EntityTransformer 'invoice_id' => $document->invoice_id && $document->invoice ? (int) $document->invoice->public_id : null, 'expense_id' => $document->expense_id && $document->expense ? (int) $document->expense->public_id : null, 'updated_at' => $this->getTimestamp($document->updated_at), + 'is_default' => (bool) $document->is_default, ]); } } diff --git a/app/Ninja/Transformers/PaymentTransformer.php b/app/Ninja/Transformers/PaymentTransformer.php index ff78eff829b1..23906c3029ea 100644 --- a/app/Ninja/Transformers/PaymentTransformer.php +++ b/app/Ninja/Transformers/PaymentTransformer.php @@ -60,6 +60,8 @@ class PaymentTransformer extends EntityTransformer 'invoice_id' => (int) ($this->invoice ? $this->invoice->public_id : $payment->invoice->public_id), 'invoice_number' => $this->invoice ? $this->invoice->invoice_number : $payment->invoice->invoice_number, 'private_notes' => $payment->private_notes, + 'exchange_rate' => (float) $payment->exchange_rate, + 'exchange_currency_id' => (int) $payment->exchange_currency_id, ]); } } diff --git a/app/Policies/SubscriptionPolicy.php b/app/Policies/SubscriptionPolicy.php new file mode 100644 index 000000000000..acdc4146d2eb --- /dev/null +++ b/app/Policies/SubscriptionPolicy.php @@ -0,0 +1,18 @@ +hasPermission('admin'); + } + + public static function create(User $user, $item) + { + return $user->hasPermission('admin'); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b7255fd4420c..f723c2c48875 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -10,6 +10,8 @@ use Utils; use Validator; use Queue; use Illuminate\Queue\Events\JobProcessing; +use Illuminate\Support\Facades\Route; + /** * Class AppServiceProvider. @@ -23,7 +25,9 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // support selecting job database + Route::singularResourceParameters(false); + + // support selecting job database Queue::before(function (JobProcessing $event) { $body = $event->job->getRawBody(); preg_match('/db-ninja-[\d+]/', $body, $matches); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 4ed077e8443d..97714c29fa6c 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Gate; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; @@ -28,6 +29,7 @@ class AuthServiceProvider extends ServiceProvider \App\Models\TaxRate::class => \App\Policies\TaxRatePolicy::class, \App\Models\AccountGateway::class => \App\Policies\AccountGatewayPolicy::class, \App\Models\AccountToken::class => \App\Policies\TokenPolicy::class, + \App\Models\Subscription::class => \App\Policies\SubscriptionPolicy::class, \App\Models\BankAccount::class => \App\Policies\BankAccountPolicy::class, \App\Models\PaymentTerm::class => \App\Policies\PaymentTermPolicy::class, \App\Models\Project::class => \App\Policies\ProjectPolicy::class, @@ -41,12 +43,12 @@ class AuthServiceProvider extends ServiceProvider * * @return void */ - public function boot(GateContract $gate) + public function boot() { foreach (get_class_methods(new \App\Policies\GenericEntityPolicy()) as $method) { - $gate->define($method, "App\Policies\GenericEntityPolicy@{$method}"); + Gate::define($method, "App\Policies\GenericEntityPolicy@{$method}"); } - $this->registerPolicies($gate); + $this->registerPolicies(); } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index ecde08cd356a..2b266bbbad06 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,7 +2,6 @@ namespace App\Providers; -use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -222,9 +221,9 @@ class EventServiceProvider extends ServiceProvider * * @return void */ - public function boot(DispatcherContract $events) + public function boot() { - parent::boot($events); + parent::boot(); // } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index ccbd59cd67ee..7331eed87370 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -2,17 +2,13 @@ namespace App\Providers; -use App; +use Illuminate\Support\Facades\Route; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; -use Illuminate\Routing\Router; -/** - * Class RouteServiceProvider. - */ class RouteServiceProvider extends ServiceProvider { /** - * This namespace is applied to the controller routes in your routes file. + * This namespace is applied to your controller routes. * * In addition, it is set as the URL generator's root namespace. * @@ -23,26 +19,61 @@ class RouteServiceProvider extends ServiceProvider /** * Define your route model bindings, pattern filters, etc. * - * @param \Illuminate\Routing\Router $router - * * @return void */ - public function boot(Router $router) + public function boot() { - parent::boot($router); + // + + parent::boot(); } /** * Define the routes for the application. * - * @param \Illuminate\Routing\Router $router + * @return void + */ + public function map() + { + $this->mapApiRoutes(); + + $this->mapWebRoutes(); + + // + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. * * @return void */ - public function map(Router $router) + protected function mapWebRoutes() { - $router->group(['namespace' => $this->namespace], function ($router) { - require app_path('Http/routes.php'); + Route::group([ + 'middleware' => 'web', + 'namespace' => $this->namespace, + ], function ($router) { + require base_path('routes/web.php'); + }); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::group([ + 'middleware' => ['lookup:api', 'api'], + 'namespace' => $this->namespace, + 'prefix' => 'api/v1', + ], function ($router) { + require base_path('routes/api.php'); }); } } diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php index e5a557671658..325f9992174e 100644 --- a/app/Services/AuthService.php +++ b/app/Services/AuthService.php @@ -83,7 +83,6 @@ class AuthService } } else { LookupUser::setServerByField('oauth_user_key', $providerId . '-' . $oauthUserId); - \Log::info("Find user: $providerId, $oauthUserId"); if ($user = $this->accountRepo->findUserByOauth($providerId, $oauthUserId)) { if ($user->google_2fa_secret) { session(['2fa:user:id' => $user->id]); diff --git a/app/Services/SubscriptionService.php b/app/Services/SubscriptionService.php new file mode 100644 index 000000000000..9101fe540d22 --- /dev/null +++ b/app/Services/SubscriptionService.php @@ -0,0 +1,55 @@ +subscriptionRepo = $subscriptionRepo; + $this->datatableService = $datatableService; + } + + /** + * @return SubscriptionRepository + */ + protected function getRepo() + { + return $this->subscriptionRepo; + } + + /** + * @param $userId + * + * @return \Illuminate\Http\JsonResponse + */ + public function getDatatable($accountId) + { + $datatable = new SubscriptionDatatable(false); + $query = $this->subscriptionRepo->find($accountId); + + return $this->datatableService->createDatatable($datatable, $query); + } +} diff --git a/app/Services/TemplateService.php b/app/Services/TemplateService.php index 087d3e122d24..e98cfff390f7 100644 --- a/app/Services/TemplateService.php +++ b/app/Services/TemplateService.php @@ -44,6 +44,8 @@ class TemplateService '$footer' => $account->getEmailFooter(), '$emailSignature' => $account->getEmailFooter(), '$client' => $client->getDisplayName(), + '$idNumber' => $client->id_number, + '$vatNumber' => $client->vat_number, '$account' => $account->getDisplayName(), '$dueDate' => $account->formatDate($invoice->partial_due_date ?: $invoice->due_date), '$invoiceDate' => $account->formatDate($invoice->invoice_date), diff --git a/bower.json b/bower.json index bc99469934a8..9bf2abf3a244 100644 --- a/bower.json +++ b/bower.json @@ -21,7 +21,7 @@ "handsontable": "*", "pdfmake": "0.1.31", "moment": "*", - "jsoneditor": "*", + "jsoneditor": "5.10.1", "moment-timezone": "~0.4.0", "quill": "~0.20.0", "datetimepicker": "~2.4.5", diff --git a/composer.json b/composer.json index f5856c0f31be..f7503246ec56 100644 --- a/composer.json +++ b/composer.json @@ -13,91 +13,63 @@ } ], "require": { - "php": ">=5.5.9", + "php": ">=7.0.0", "ext-gd": "*", "ext-gmp": "*", - "Dwolla/omnipay-dwolla": "dev-master", - "abdala/omnipay-pagseguro": "0.2", - "agmscode/omnipay-agms": "~1.0", - "alfaproject/omnipay-skrill": "dev-master", - "anahkiasen/former": "4.0.*@dev", - "andreas22/omnipay-fasapay": "1.*", + "anahkiasen/former": "4.*", "asgrim/ofxparser": "^1.1", "bacon/bacon-qr-code": "^1.0", "barracudanetworks/archivestream-php": "^1.0", "barryvdh/laravel-cors": "^0.9.1", "barryvdh/laravel-debugbar": "~2.2", "barryvdh/laravel-ide-helper": "~2.2", - "cardgate/omnipay-cardgate": "~2.0", "cerdic/css-tidy": "~v1.5", "chumper/datatable": "dev-develop#04ef2bf", "codedge/laravel-selfupdater": "5.x-dev", "collizo4sky/omnipay-wepay": "dev-address-fix", - "delatbabel/omnipay-fatzebra": "dev-master", - "dercoder/omnipay-ecopayz": "~1.0", - "dercoder/omnipay-paysafecard": "dev-master", - "descubraomundo/omnipay-pagarme": "dev-master", - "digitickets/omnipay-barclays-epdq": "~3.0", - "digitickets/omnipay-datacash": "~3.0", "digitickets/omnipay-gocardlessv2": "dev-payment-fix", - "digitickets/omnipay-realex": "~5.0", - "dioscouri/omnipay-cybersource": "dev-master", "doctrine/dbal": "2.5.x", "ezyang/htmlpurifier": "~v4.7", - "fotografde/omnipay-checkoutcom": "~2.0", - "fruitcakestudio/omnipay-sisow": "~2.0", "fzaninotto/faker": "^1.5", "gatepay/FedACHdir": "dev-master@dev", "google/apiclient": "^2.0", "guzzlehttp/guzzle": "~6.0", - "incube8/omnipay-multicards": "dev-master", "intervention/image": "dev-master", + "invoiceninja/omnipay-collection": "0.4@dev", "jaybizzle/laravel-crawler-detect": "1.*", "jlapp/swaggervel": "master-dev", "jonnyw/php-phantomjs": "4.*", - "justinbusschau/omnipay-secpay": "~2.0", "laracasts/presenter": "dev-master", - "laravel/framework": "5.2.*", + "laravel/framework": "5.3.*", + "laravel/legacy-encrypter": "^1.0", "laravel/socialite": "~2.0", - "laravelcollective/bus": "5.2.*", - "laravelcollective/html": "5.2.*", + "laravelcollective/bus": "5.3.*", + "laravelcollective/html": "5.3.*", "league/flysystem-aws-s3-v3": "~1.0", "league/flysystem-rackspace": "~1.0", "league/fractal": "0.13.*", - "lokielse/omnipay-alipay": "~1.4", "maatwebsite/excel": "~2.0", - "meebio/omnipay-creditcall": "dev-master", - "meebio/omnipay-secure-trading": "dev-master", - "mfauveau/omnipay-pacnet": "~2.0", "mpdf/mpdf": "6.1.3", "nwidart/laravel-modules": "^1.14", - "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/authorizenet": "dev-solution-id as 2.5.0", - "omnipay/bitpay": "dev-master", - "omnipay/braintree": "~2.0@dev", - "omnipay/gocardless": "dev-master", - "omnipay/mollie": "3.*", - "omnipay/omnipay": "~2.3", - "omnipay/stripe": "dev-master", "patricktalmadge/bootstrapper": "5.5.x", "pragmarx/google2fa-laravel": "^0.1.2", "predis/predis": "^1.1", + "roave/security-advisories": "dev-master", "simshaun/recurr": "dev-master", - "softcommerce/omnipay-paytrace": "~1.0", - "symfony/css-selector": "~3.0", + "symfony/css-selector": "~3.1", "turbo124/laravel-push-notification": "2.*", - "vink/omnipay-komoju": "~1.0", "webpatser/laravel-countries": "dev-master", "websight/l5-google-cloud-storage": "dev-master", "wepay/php-sdk": "^0.2", - "wildbit/laravel-postmark-provider": "3.0" + "wildbit/laravel-postmark-provider": "dev-master#134f359" }, "require-dev": { + "symfony/dom-crawler": "~3.1", "codeception/c3": "~2.0", "codeception/codeception": "2.3.3", "phpspec/phpspec": "~2.1", - "phpunit/phpunit": "~4.0", - "symfony/dom-crawler": "~3.0" + "phpunit/phpunit": "~4.0" }, "autoload": { "classmap": [ @@ -137,6 +109,8 @@ "php artisan key:generate" ] }, + "minimum-stability": "dev", + "prefer-stable": true, "config": { "preferred-install": "dist", "sort-packages": true, @@ -161,11 +135,11 @@ }, { "type": "vcs", - "url": "https://github.com/hillelcoren/omnipay-wepay" + "url": "https://github.com/hillelcoren/l5-google-cloud-storage" }, { "type": "vcs", - "url": "https://github.com/hillelcoren/l5-google-cloud-storage" + "url": "https://github.com/hillelcoren/omnipay-wepay" }, { "type": "vcs", diff --git a/composer.lock b/composer.lock index bfef2b142e7e..4758f1cd79aa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "80f6d3f1c26c0eb84d0d9ee5aa88aaa1", - "content-hash": "0891783210a35e9c83addbcdbb691993", + "hash": "aab53e0382a9fe290684134644ba09d2", + "content-hash": "9ca34996a5b715781c82467710f6775a", "packages": [ { "name": "abdala/omnipay-pagseguro", @@ -169,16 +169,16 @@ }, { "name": "anahkiasen/former", - "version": "4.0.x-dev", + "version": "4.1.5", "source": { "type": "git", "url": "https://github.com/formers/former.git", - "reference": "96363d8a0e7a58b80117a68e564104a431cdb49e" + "reference": "657151b3cbe5eb13d59f93d0ca413c7778d15a6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/formers/former/zipball/96363d8a0e7a58b80117a68e564104a431cdb49e", - "reference": "96363d8a0e7a58b80117a68e564104a431cdb49e", + "url": "https://api.github.com/repos/formers/former/zipball/657151b3cbe5eb13d59f93d0ca413c7778d15a6f", + "reference": "657151b3cbe5eb13d59f93d0ca413c7778d15a6f", "shasum": "" }, "require": { @@ -197,6 +197,19 @@ "phpunit/phpunit": "~4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + }, + "laravel": { + "providers": [ + "Former\\FormerServiceProvider" + ], + "aliases": { + "Former": "Former\\Facades\\Former" + } + } + }, "autoload": { "psr-4": { "Former\\": [ @@ -217,14 +230,14 @@ } ], "description": "A powerful form builder", - "homepage": "http://anahkiasen.github.com/former/", + "homepage": "http://formers.github.io/former/", "keywords": [ "bootstrap", "form", "foundation", "laravel" ], - "time": "2017-02-09 23:05:49" + "time": "2017-11-27 14:58:10" }, { "name": "anahkiasen/html-object", @@ -380,16 +393,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.36.28", + "version": "3.44.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "65ca98c303ea1489b2719b6d892d800dd604d4b2" + "reference": "3f88cb0b9eb6ca34b2823c1cb42e10ac4d52fa6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/65ca98c303ea1489b2719b6d892d800dd604d4b2", - "reference": "65ca98c303ea1489b2719b6d892d800dd604d4b2", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3f88cb0b9eb6ca34b2823c1cb42e10ac4d52fa6d", + "reference": "3f88cb0b9eb6ca34b2823c1cb42e10ac4d52fa6d", "shasum": "" }, "require": { @@ -456,7 +469,7 @@ "s3", "sdk" ], - "time": "2017-10-17 19:51:40" + "time": "2017-12-01 20:57:47" }, { "name": "bacon/bacon-qr-code", @@ -546,33 +559,38 @@ }, { "name": "barryvdh/laravel-cors", - "version": "v0.9.2", + "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-cors.git", - "reference": "0b758188dadda20f4a17f1f4fe03c22ea92ce8e4" + "reference": "2551489de60486471434b0c7050f7fc65f9c9119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-cors/zipball/0b758188dadda20f4a17f1f4fe03c22ea92ce8e4", - "reference": "0b758188dadda20f4a17f1f4fe03c22ea92ce8e4", + "url": "https://api.github.com/repos/barryvdh/laravel-cors/zipball/2551489de60486471434b0c7050f7fc65f9c9119", + "reference": "2551489de60486471434b0c7050f7fc65f9c9119", "shasum": "" }, "require": { - "illuminate/support": "5.1.x|5.2.x|5.3.x|5.4.x", + "illuminate/support": "5.3.x|5.4.x|5.5.x", "php": ">=5.5.9", - "symfony/http-foundation": "~2.7|~3.0", - "symfony/http-kernel": "~2.7|~3.0" + "symfony/http-foundation": "~3.1", + "symfony/http-kernel": "~3.1" }, "require-dev": { "orchestra/testbench": "3.x", - "phpunit/phpunit": "^4.8|^5.2" + "phpunit/phpunit": "^4.8|^5.2", + "squizlabs/php_codesniffer": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9-dev", - "dev-develop": "1.0-dev" + "dev-master": "0.9-dev" + }, + "laravel": { + "providers": [ + "Barryvdh\\Cors\\ServiceProvider" + ] } }, "autoload": { @@ -600,7 +618,7 @@ "crossdomain", "laravel" ], - "time": "2017-03-22 08:40:10" + "time": "2017-08-28 11:42:05" }, { "name": "barryvdh/laravel-debugbar", @@ -775,16 +793,16 @@ }, { "name": "braintree/braintree_php", - "version": "3.25.0", + "version": "3.26.0", "source": { "type": "git", "url": "https://github.com/braintree/braintree_php.git", - "reference": "8c8785b8876d5b2f4b4f78c5768ad245a7c43feb" + "reference": "184bbdd65951a3ad766992ef73bb6e93aeba82b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/braintree/braintree_php/zipball/8c8785b8876d5b2f4b4f78c5768ad245a7c43feb", - "reference": "8c8785b8876d5b2f4b4f78c5768ad245a7c43feb", + "url": "https://api.github.com/repos/braintree/braintree_php/zipball/184bbdd65951a3ad766992ef73bb6e93aeba82b7", + "reference": "184bbdd65951a3ad766992ef73bb6e93aeba82b7", "shasum": "" }, "require": { @@ -818,7 +836,7 @@ } ], "description": "Braintree PHP Client Library", - "time": "2017-08-25 19:38:09" + "time": "2017-11-17 21:47:27" }, { "name": "cardgate/omnipay-cardgate", @@ -857,7 +875,7 @@ ], "authors": [ { - "name": "Cardgate", + "name": "CardGate", "email": "tech@cardgate.com" }, { @@ -1009,7 +1027,7 @@ "laravel" ], "abandoned": "OpenSkill/Datatable", - "time": "2015-04-29 07:00:36" + "time": "2017-01-26 10:04:06" }, { "name": "classpreloader/classpreloader", @@ -2533,21 +2551,20 @@ "reference": "origin/master", "shasum": null }, - "type": "library", - "time": "2016-10-12 12:00:38" + "type": "library" }, { "name": "gocardless/gocardless-pro", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/gocardless/gocardless-pro-php.git", - "reference": "d2d4adb7cde53722858f1e7e5508697fefdb5390" + "reference": "16ac38c2531e08c15e54b4a82d44854349cbfcf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/gocardless/gocardless-pro-php/zipball/d2d4adb7cde53722858f1e7e5508697fefdb5390", - "reference": "d2d4adb7cde53722858f1e7e5508697fefdb5390", + "url": "https://api.github.com/repos/gocardless/gocardless-pro-php/zipball/16ac38c2531e08c15e54b4a82d44854349cbfcf6", + "reference": "16ac38c2531e08c15e54b4a82d44854349cbfcf6", "shasum": "" }, "require": { @@ -2586,20 +2603,20 @@ "direct debit", "gocardless" ], - "time": "2017-09-18 15:08:13" + "time": "2017-11-14 15:46:50" }, { "name": "google/apiclient", - "version": "v2.2.0", + "version": "v2.2.1", "source": { "type": "git", "url": "https://github.com/google/google-api-php-client.git", - "reference": "f3fadd538315d62ebd1191d89ac791468c617260" + "reference": "b69b8ac4bf6501793c389d4e013a79d09c85c5f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/google/google-api-php-client/zipball/f3fadd538315d62ebd1191d89ac791468c617260", - "reference": "f3fadd538315d62ebd1191d89ac791468c617260", + "url": "https://api.github.com/repos/google/google-api-php-client/zipball/b69b8ac4bf6501793c389d4e013a79d09c85c5f2", + "reference": "b69b8ac4bf6501793c389d4e013a79d09c85c5f2", "shasum": "" }, "require": { @@ -2645,20 +2662,20 @@ "keywords": [ "google" ], - "time": "2017-07-10 15:34:54" + "time": "2017-11-03 01:19:53" }, { "name": "google/apiclient-services", - "version": "v0.30", + "version": "v0.36", "source": { "type": "git", "url": "https://github.com/google/google-api-php-client-services.git", - "reference": "a7d43aa8748d74e7a8fd1617e4ec9e7af4974bec" + "reference": "2fd7d2876fbc0174faddba3241956a1393536159" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/a7d43aa8748d74e7a8fd1617e4ec9e7af4974bec", - "reference": "a7d43aa8748d74e7a8fd1617e4ec9e7af4974bec", + "url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/2fd7d2876fbc0174faddba3241956a1393536159", + "reference": "2fd7d2876fbc0174faddba3241956a1393536159", "shasum": "" }, "require": { @@ -2682,7 +2699,7 @@ "keywords": [ "google" ], - "time": "2017-10-14 00:23:32" + "time": "2017-11-25 00:23:12" }, { "name": "google/auth", @@ -2731,22 +2748,22 @@ }, { "name": "google/cloud", - "version": "v0.40.0", + "version": "v0.46.0", "source": { "type": "git", "url": "https://github.com/GoogleCloudPlatform/google-cloud-php.git", - "reference": "eb00fd13f31d9540c4e6584b120333f169038be9" + "reference": "288c3daf85300233dd93f1dfd4f1d040a0cdb536" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GoogleCloudPlatform/google-cloud-php/zipball/eb00fd13f31d9540c4e6584b120333f169038be9", - "reference": "eb00fd13f31d9540c4e6584b120333f169038be9", + "url": "https://api.github.com/repos/GoogleCloudPlatform/google-cloud-php/zipball/288c3daf85300233dd93f1dfd4f1d040a0cdb536", + "reference": "288c3daf85300233dd93f1dfd4f1d040a0cdb536", "shasum": "" }, "require": { "google/auth": "~0.9|^1.0", - "google/gax": "^0.24", - "google/proto-client": "^0.24", + "google/gax": "0.27.0", + "google/proto-client": "0.27.0", "guzzlehttp/guzzle": "^5.3|^6.0", "guzzlehttp/psr7": "^1.2", "monolog/monolog": "~1", @@ -2756,29 +2773,31 @@ "rize/uri-template": "~0.3" }, "replace": { - "google/cloud-bigquery": "0.3.0", - "google/cloud-core": "1.10.0", - "google/cloud-datastore": "1.0.1", - "google/cloud-dlp": "0.2.0", - "google/cloud-error-reporting": "0.5.0", - "google/cloud-language": "0.6.0", - "google/cloud-logging": "1.5.0", - "google/cloud-monitoring": "0.5.0", - "google/cloud-pubsub": "0.8.0", - "google/cloud-spanner": "0.7.0", - "google/cloud-speech": "0.8.0", - "google/cloud-storage": "1.2.0", - "google/cloud-trace": "0.3.2", - "google/cloud-translate": "1.0.1", - "google/cloud-videointelligence": "0.5.0", - "google/cloud-vision": "0.5.0" + "google/cloud-bigquery": "0.3.1", + "google/cloud-bigtable": "0.1.0", + "google/cloud-core": "1.14.0", + "google/cloud-datastore": "1.1.0", + "google/cloud-dlp": "0.4.0", + "google/cloud-error-reporting": "0.7.0", + "google/cloud-firestore": "0.2.0", + "google/cloud-language": "0.10.0", + "google/cloud-logging": "1.7.0", + "google/cloud-monitoring": "0.7.0", + "google/cloud-pubsub": "0.10.0", + "google/cloud-spanner": "0.10.0", + "google/cloud-speech": "0.9.0", + "google/cloud-storage": "1.2.1", + "google/cloud-trace": "0.3.3", + "google/cloud-translate": "1.0.2", + "google/cloud-videointelligence": "0.8.0", + "google/cloud-vision": "0.7.0" }, "require-dev": { "erusev/parsedown": "^1.6", "league/json-guard": "^0.3", "phpdocumentor/reflection": "^3.0", "phpseclib/phpseclib": "^2", - "phpunit/phpunit": "4.8.*", + "phpunit/phpunit": "^4.8|^5.0", "squizlabs/php_codesniffer": "2.*", "symfony/console": "^3.0", "symfony/lock": "3.3.x-dev#1ba6ac9", @@ -2826,6 +2845,7 @@ "keywords": [ "big query", "bigquery", + "bigtable", "cloud", "datastore", "gcs", @@ -2848,73 +2868,71 @@ "translation", "vision" ], - "time": "2017-10-17 17:11:46" + "time": "2017-12-02 00:32:15" }, { "name": "google/gax", - "version": "0.24.0", + "version": "0.27.0", "source": { "type": "git", "url": "https://github.com/googleapis/gax-php.git", - "reference": "94c4cf52f55115b7ee528474d72c7ed7829e1365" + "reference": "28d91f30966b91004d1ef66ca09df04fa730c8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/gax-php/zipball/94c4cf52f55115b7ee528474d72c7ed7829e1365", - "reference": "94c4cf52f55115b7ee528474d72c7ed7829e1365", + "url": "https://api.github.com/repos/googleapis/gax-php/zipball/28d91f30966b91004d1ef66ca09df04fa730c8d9", + "reference": "28d91f30966b91004d1ef66ca09df04fa730c8d9", "shasum": "" }, "require": { "google/auth": "~0.9|^1.0", - "google/protobuf": "^3.4", + "google/protobuf": "3.4.*", "grpc/grpc": "^1.4", "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "4.8.*", + "phpunit/phpunit": "^4.8.36", "squizlabs/php_codesniffer": "2.*" }, "type": "library", "autoload": { "psr-4": { - "Google\\GAX\\": "src/", - "Google\\GAX\\UnitTests\\": "tests/", - "Google\\": "src/generated/Google/", - "GPBMetadata\\": "src/generated/GPBMetadata/" + "Google\\": "src", + "GPBMetadata\\Google\\": "metadata" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], - "description": "Google API Extensions for PHP", + "description": "Google API Core for PHP", "homepage": "https://github.com/googleapis/gax-php", "keywords": [ "google" ], - "time": "2017-09-19 20:06:14" + "time": "2017-11-21 23:04:00" }, { "name": "google/proto-client", - "version": "0.24.0", + "version": "0.27.0", "source": { "type": "git", "url": "https://github.com/googleapis/proto-client-php.git", - "reference": "2f36eaa4a2fa1ee6f66525c8f40741acb27cec52" + "reference": "39a6917748da381945e23876e8a9bf6a8e917937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/proto-client-php/zipball/2f36eaa4a2fa1ee6f66525c8f40741acb27cec52", - "reference": "2f36eaa4a2fa1ee6f66525c8f40741acb27cec52", + "url": "https://api.github.com/repos/googleapis/proto-client-php/zipball/39a6917748da381945e23876e8a9bf6a8e917937", + "reference": "39a6917748da381945e23876e8a9bf6a8e917937", "shasum": "" }, "require": { - "google/protobuf": "^3.3.2", + "google/protobuf": "^3.4", "php": ">=5.5" }, "require-dev": { - "google/gax": ">=0.20.0", - "phpunit/phpunit": "4.8.*" + "google/gax": ">=0.25.0", + "phpunit/phpunit": "^4.8.36" }, "type": "library", "autoload": { @@ -2932,7 +2950,7 @@ "keywords": [ "google" ], - "time": "2017-09-18 19:35:44" + "time": "2017-11-22 22:05:44" }, { "name": "google/protobuf", @@ -3466,46 +3484,65 @@ "time": "2017-09-21 16:33:42" }, { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", + "name": "invoiceninja/omnipay-collection", + "version": "v0.4", "source": { "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + "url": "https://github.com/invoiceninja/omnipay-collection.git", + "reference": "eb2d739440efdea418152a68c80fd7d9ca00140d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "url": "https://api.github.com/repos/invoiceninja/omnipay-collection/zipball/eb2d739440efdea418152a68c80fd7d9ca00140d", + "reference": "eb2d739440efdea418152a68c80fd7d9ca00140d", "shasum": "" }, - "require-dev": { - "phpunit/phpunit": "4.*" + "require": { + "abdala/omnipay-pagseguro": "0.2", + "agmscode/omnipay-agms": "~1.0", + "alfaproject/omnipay-skrill": "dev-master", + "andreas22/omnipay-fasapay": "1.*", + "cardgate/omnipay-cardgate": "~2.0", + "delatbabel/omnipay-fatzebra": "dev-master", + "dercoder/omnipay-ecopayz": "~1.0", + "dercoder/omnipay-paysafecard": "dev-master", + "descubraomundo/omnipay-pagarme": "dev-master", + "digitickets/omnipay-barclays-epdq": "~3.0", + "digitickets/omnipay-datacash": "~3.0", + "digitickets/omnipay-realex": "~5.0", + "dioscouri/omnipay-cybersource": "dev-master", + "dwolla/omnipay-dwolla": "dev-master", + "fotografde/omnipay-checkoutcom": "~2.0", + "fruitcakestudio/omnipay-sisow": "~2.0", + "incube8/omnipay-multicards": "dev-master", + "justinbusschau/omnipay-secpay": "~2.0", + "lokielse/omnipay-alipay": "~1.4", + "meebio/omnipay-creditcall": "dev-master", + "meebio/omnipay-secure-trading": "dev-master", + "mfauveau/omnipay-pacnet": "~2.0", + "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", + "omnipay/bitpay": "dev-master", + "omnipay/braintree": "~2.0@dev", + "omnipay/gocardless": "dev-master", + "omnipay/mollie": "3.*", + "omnipay/omnipay": "~2.3", + "omnipay/stripe": "dev-master", + "softcommerce/omnipay-paytrace": "~1.0", + "vink/omnipay-komoju": "~1.0" }, "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" + "name": "Hillel Coren", + "email": "hillelcoren@gmail.com" } ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20 16:49:30" + "description": "Collection of Omnipay drivers", + "time": "2017-11-11 19:43:09" }, { "name": "jakoch/phantomjs-installer", @@ -3637,16 +3674,16 @@ }, { "name": "jaybizzle/crawler-detect", - "version": "v1.2.53", + "version": "v1.2.54", "source": { "type": "git", "url": "https://github.com/JayBizzle/Crawler-Detect.git", - "reference": "a6ce29ecaeb411a9963ea48f4b221c70d242c27f" + "reference": "9af25770d9382917b680009a88497162405bbe48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/a6ce29ecaeb411a9963ea48f4b221c70d242c27f", - "reference": "a6ce29ecaeb411a9963ea48f4b221c70d242c27f", + "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/9af25770d9382917b680009a88497162405bbe48", + "reference": "9af25770d9382917b680009a88497162405bbe48", "shasum": "" }, "require": { @@ -3682,7 +3719,7 @@ "crawlerdetect", "php crawler detect" ], - "time": "2017-10-17 20:08:27" + "time": "2017-10-28 13:05:55" }, { "name": "jaybizzle/laravel-crawler-detect", @@ -4010,16 +4047,16 @@ }, { "name": "laravel/framework", - "version": "v5.2.45", + "version": "v5.3.31", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "2a79f920d5584ec6df7cf996d922a742d11095d1" + "reference": "e641e75fc5b26ad0ba8c19b7e83b08cad1d03b89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/2a79f920d5584ec6df7cf996d922a742d11095d1", - "reference": "2a79f920d5584ec6df7cf996d922a742d11095d1", + "url": "https://api.github.com/repos/laravel/framework/zipball/e641e75fc5b26ad0ba8c19b7e83b08cad1d03b89", + "reference": "e641e75fc5b26ad0ba8c19b7e83b08cad1d03b89", "shasum": "" }, "require": { @@ -4032,20 +4069,20 @@ "monolog/monolog": "~1.11", "mtdowling/cron-expression": "~1.0", "nesbot/carbon": "~1.20", - "paragonie/random_compat": "~1.4", - "php": ">=5.5.9", - "psy/psysh": "0.7.*", - "swiftmailer/swiftmailer": "~5.1", - "symfony/console": "2.8.*|3.0.*", - "symfony/debug": "2.8.*|3.0.*", - "symfony/finder": "2.8.*|3.0.*", - "symfony/http-foundation": "2.8.*|3.0.*", - "symfony/http-kernel": "2.8.*|3.0.*", - "symfony/polyfill-php56": "~1.0", - "symfony/process": "2.8.*|3.0.*", - "symfony/routing": "2.8.*|3.0.*", - "symfony/translation": "2.8.*|3.0.*", - "symfony/var-dumper": "2.8.*|3.0.*", + "paragonie/random_compat": "~1.4|~2.0", + "php": ">=5.6.4", + "psy/psysh": "0.7.*|0.8.*", + "ramsey/uuid": "~3.0", + "swiftmailer/swiftmailer": "~5.4", + "symfony/console": "3.1.*", + "symfony/debug": "3.1.*", + "symfony/finder": "3.1.*", + "symfony/http-foundation": "3.1.*", + "symfony/http-kernel": "3.1.*", + "symfony/process": "3.1.*", + "symfony/routing": "3.1.*", + "symfony/translation": "3.1.*", + "symfony/var-dumper": "3.1.*", "vlucas/phpdotenv": "~2.2" }, "replace": { @@ -4067,6 +4104,7 @@ "illuminate/http": "self.version", "illuminate/log": "self.version", "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", "illuminate/pagination": "self.version", "illuminate/pipeline": "self.version", "illuminate/queue": "self.version", @@ -4083,10 +4121,10 @@ "aws/aws-sdk-php": "~3.0", "mockery/mockery": "~0.9.4", "pda/pheanstalk": "~3.0", - "phpunit/phpunit": "~4.1", + "phpunit/phpunit": "~5.4", "predis/predis": "~1.0", - "symfony/css-selector": "2.8.*|3.0.*", - "symfony/dom-crawler": "2.8.*|3.0.*" + "symfony/css-selector": "3.1.*", + "symfony/dom-crawler": "3.1.*" }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", @@ -4098,20 +4136,17 @@ "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).", - "symfony/css-selector": "Required to use some of the crawler integration testing tools (2.8.*|3.0.*).", - "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (2.8.*|3.0.*).", + "symfony/css-selector": "Required to use some of the crawler integration testing tools (3.1.*).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (3.1.*).", "symfony/psr-http-message-bridge": "Required to use psr7 bridging features (0.2.*)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2-dev" + "dev-master": "5.3-dev" } }, "autoload": { - "classmap": [ - "src/Illuminate/Queue/IlluminateQueueClosure.php" - ], "files": [ "src/Illuminate/Foundation/helpers.php", "src/Illuminate/Support/helpers.php" @@ -4127,16 +4162,63 @@ "authors": [ { "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" + "email": "taylor@laravel.com" } ], "description": "The Laravel Framework.", - "homepage": "http://laravel.com", + "homepage": "https://laravel.com", "keywords": [ "framework", "laravel" ], - "time": "2016-08-26 11:44:52" + "time": "2017-03-24 16:31:06" + }, + { + "name": "laravel/legacy-encrypter", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/legacy-encrypter.git", + "reference": "4047fc1e6a9346501ba48ba3f79509534875dea3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/legacy-encrypter/zipball/4047fc1e6a9346501ba48ba3f79509534875dea3", + "reference": "4047fc1e6a9346501ba48ba3f79509534875dea3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-openssl": "*", + "illuminate/contracts": "5.3.*", + "illuminate/support": "5.3.*", + "paragonie/random_compat": "~1.4|~2.0", + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\LegacyEncrypter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The legacy version of the Laravel mcrypt encrypter.", + "homepage": "http://laravel.com", + "time": "2016-08-03 21:22:03" }, { "name": "laravel/socialite", @@ -4194,28 +4276,28 @@ }, { "name": "laravelcollective/bus", - "version": "v5.2", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/LaravelCollective/bus.git", - "reference": "e48b4d44d49f820e1b85ff16b9402e01c770c83a" + "reference": "720298af5ddaa09e1ddb846d02c2a911e92c3574" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/LaravelCollective/bus/zipball/e48b4d44d49f820e1b85ff16b9402e01c770c83a", - "reference": "e48b4d44d49f820e1b85ff16b9402e01c770c83a", + "url": "https://api.github.com/repos/LaravelCollective/bus/zipball/720298af5ddaa09e1ddb846d02c2a911e92c3574", + "reference": "720298af5ddaa09e1ddb846d02c2a911e92c3574", "shasum": "" }, "require": { - "illuminate/container": "5.2.*", - "illuminate/contracts": "5.2.*", - "illuminate/pipeline": "5.2.*", - "illuminate/support": "5.2.*", - "php": ">=5.5.9" + "illuminate/container": "5.3.*", + "illuminate/contracts": "5.3.*", + "illuminate/pipeline": "5.3.*", + "illuminate/support": "5.3.*", + "php": ">=5.6.4" }, "require-dev": { - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0" + "mockery/mockery": "~0.9.4", + "phpunit/phpunit": "~5.4" }, "type": "library", "autoload": { @@ -4231,38 +4313,42 @@ { "name": "Taylor Otwell", "email": "taylorotwell@gmail.com" + }, + { + "name": "Adam Engebretson", + "email": "adam@laravelcollective.com" } ], - "description": "The Laravel Bus (5.1) package for use in Laravel 5.2.", + "description": "The Laravel Bus (5.1) package for use in Laravel 5.3.", "homepage": "http://laravelcollective.com", - "time": "2015-12-23 07:43:33" + "time": "2016-08-28 00:02:50" }, { "name": "laravelcollective/html", - "version": "v5.2.6", + "version": "v5.3.2", "source": { "type": "git", "url": "https://github.com/LaravelCollective/html.git", - "reference": "4f6701c7c3f6ff2aee1f4ed205ed6820e1e3048e" + "reference": "299f3dccd61c3f6d89ebb9b10f36fb2a9aee5206" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/LaravelCollective/html/zipball/4f6701c7c3f6ff2aee1f4ed205ed6820e1e3048e", - "reference": "4f6701c7c3f6ff2aee1f4ed205ed6820e1e3048e", + "url": "https://api.github.com/repos/LaravelCollective/html/zipball/299f3dccd61c3f6d89ebb9b10f36fb2a9aee5206", + "reference": "299f3dccd61c3f6d89ebb9b10f36fb2a9aee5206", "shasum": "" }, "require": { - "illuminate/http": "5.2.*", - "illuminate/routing": "5.2.*", - "illuminate/session": "5.2.*", - "illuminate/support": "5.2.*", - "illuminate/view": "5.2.*", - "php": ">=5.5.9" + "illuminate/http": "5.3.*", + "illuminate/routing": "5.3.*", + "illuminate/session": "5.3.*", + "illuminate/support": "5.3.*", + "illuminate/view": "5.3.*", + "php": ">=5.6.4" }, "require-dev": { - "illuminate/database": "5.2.*", - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0" + "illuminate/database": "5.3.*", + "mockery/mockery": "~0.9.4", + "phpunit/phpunit": "~5.4" }, "type": "library", "autoload": { @@ -4289,7 +4375,7 @@ ], "description": "HTML and Form Builders for the Laravel Framework", "homepage": "http://laravelcollective.com", - "time": "2017-05-21 18:02:21" + "time": "2017-05-21 22:00:10" }, { "name": "league/flysystem", @@ -5166,7 +5252,7 @@ }, { "name": "mtdowling/cron-expression", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/mtdowling/cron-expression.git", @@ -5318,24 +5404,24 @@ }, { "name": "nikic/php-parser", - "version": "v2.1.1", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0" + "reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4dd659edadffdc2143e4753df655d866dbfeedf0", - "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08131e7ff29de6bb9f12275c7d35df71f25f4d89", + "reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.4" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.0|~5.0" }, "bin": [ "bin/php-parse" @@ -5343,7 +5429,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -5365,7 +5451,7 @@ "parser", "php" ], - "time": "2016-09-16 12:04:44" + "time": "2017-11-04 11:48:34" }, { "name": "nwidart/laravel-modules", @@ -5439,12 +5525,12 @@ "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-2checkout.git", - "reference": "e9c079c2dde0d7ba461903b3b7bd5caf6dee1248" + "reference": "b27d2823d052f5c227eeb29324bb564cfdb8f9af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-2checkout/zipball/e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", - "reference": "e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", + "url": "https://api.github.com/repos/thephpleague/omnipay-2checkout/zipball/b27d2823d052f5c227eeb29324bb564cfdb8f9af", + "reference": "b27d2823d052f5c227eeb29324bb564cfdb8f9af", "shasum": "" }, "require": { @@ -5490,7 +5576,7 @@ "payment", "twocheckout" ], - "time": "2014-09-17 00:35:37" + "time": "2016-03-25 10:39:58" }, { "name": "omnipay/authorizenet", @@ -5848,35 +5934,36 @@ }, { "name": "omnipay/common", - "version": "v2.3.4", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-common.git", - "reference": "fcd5a606713d11536c89315a5ae02d965a737c21" + "reference": "54910f2ece6b1be64f5e53e2111dd1254d50ee49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/fcd5a606713d11536c89315a5ae02d965a737c21", - "reference": "fcd5a606713d11536c89315a5ae02d965a737c21", + "url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/54910f2ece6b1be64f5e53e2111dd1254d50ee49", + "reference": "54910f2ece6b1be64f5e53e2111dd1254d50ee49", "shasum": "" }, "require": { "guzzle/guzzle": "~3.9", "php": ">=5.3.2", - "symfony/http-foundation": "~2.1" + "symfony/http-foundation": "~2.1|~3.0" }, "require-dev": { - "omnipay/tests": "~2.0" + "omnipay/tests": "~2.0", + "squizlabs/php_codesniffer": "~1.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.5.x-dev" }, "gateways": [ "AuthorizeNet_AIM", "AuthorizeNet_SIM", - "Buckaroo", + "Buckaroo_CreditCard", "Buckaroo_Ideal", "Buckaroo_PayPal", "CardSave", @@ -5906,26 +5993,7 @@ "TargetPay_Directebanking", "TargetPay_Ideal", "TargetPay_Mrcash", - "TwoCheckout", - "WorldPay", - "Alipay Bank", - "AliPay Dual Func", - "Alipay Express", - "Alipay Mobile Express", - "Alipay Secured", - "Alipay Wap Express", - "Cybersource", - "DataCash", - "Ecopayz", - "Neteller", - "Pacnet", - "PaymentSense", - "Realex Remote", - "SecPay (PayPoint.net)", - "Sisow", - "Skrill", - "YandexMoney", - "YandexMoneyIndividual" + "WorldPay" ] }, "autoload": { @@ -5960,7 +6028,7 @@ "payment", "purchase" ], - "time": "2015-03-30 14:34:46" + "time": "2016-11-07 06:10:23" }, { "name": "omnipay/dummy", @@ -6078,16 +6146,16 @@ }, { "name": "omnipay/firstdata", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-firstdata.git", - "reference": "e33826821db88d90886cad6c81a29452d3cf91a2" + "reference": "c0123a03bec861e0c00fa19772582dc3639fbb6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/e33826821db88d90886cad6c81a29452d3cf91a2", - "reference": "e33826821db88d90886cad6c81a29452d3cf91a2", + "url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/c0123a03bec861e0c00fa19772582dc3639fbb6e", + "reference": "c0123a03bec861e0c00fa19772582dc3639fbb6e", "shasum": "" }, "require": { @@ -6132,7 +6200,7 @@ "pay", "payment" ], - "time": "2016-01-14 06:24:28" + "time": "2017-07-14 09:26:59" }, { "name": "omnipay/gocardless", @@ -6538,16 +6606,16 @@ }, { "name": "omnipay/omnipay", - "version": "2.3.2", + "version": "2.3.x-dev", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay.git", - "reference": "e9e6d95a2e7c3641ba31c985334d82e39dbd6078" + "reference": "cc04bd22b4149c94c52b002181d4993e4f8fe812" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay/zipball/e9e6d95a2e7c3641ba31c985334d82e39dbd6078", - "reference": "e9e6d95a2e7c3641ba31c985334d82e39dbd6078", + "url": "https://api.github.com/repos/thephpleague/omnipay/zipball/cc04bd22b4149c94c52b002181d4993e4f8fe812", + "reference": "cc04bd22b4149c94c52b002181d4993e4f8fe812", "shasum": "" }, "require": { @@ -6556,7 +6624,7 @@ "omnipay/buckaroo": "~2.0", "omnipay/cardsave": "~2.0", "omnipay/coinbase": "~2.0", - "omnipay/common": "~2.3.0", + "omnipay/common": "~2.3", "omnipay/dummy": "~2.0", "omnipay/eway": "~2.0", "omnipay/firstdata": "~2.0", @@ -6581,6 +6649,38 @@ "require-dev": { "omnipay/tests": "~2.0" }, + "suggest": { + "academe/omnipay-helcim": "Helcim", + "agmscode/omnipay-agms": "Agms", + "alfaproject/omnipay-neteller": "Neteller", + "alfaproject/omnipay-skrill": "Skrill", + "andreas22/omnipay-fasapay": "Fasapay", + "andylibrian/omnipay-veritrans": "Veritrans", + "cardgate/omnipay-cardgate": "CardGate", + "coatesap/omnipay-datacash": "DataCash", + "coatesap/omnipay-paymentsense": "PaymentSense", + "coatesap/omnipay-realex": "Realex", + "dabsquared/omnipay-cybersource-soap": "Cybersource SOAP", + "delatbabel/omnipay-fatzebra": "Fat Zebra", + "dercoder/omnipay-ecopayz": "ecoPayz", + "dercoder/omnipay-globalcloudpay": "Globalcloudpay", + "descubraomundo/omnipay-pagarme": "Pagar.me", + "dioscouri/omnipay-cybersource": "Cybersource", + "fotografde/omnipay-checkoutcom": "Checkout.com", + "fruitcakestudio/omnipay-sisow": "Sisow", + "igaponov/omnipay-wirecard": "Wirecard", + "justinbusschau/omnipay-secpay": "SecPay", + "lokielse/omnipay-alipay": "Alipay", + "lokielse/omnipay-global-alipay": "Global Alipay", + "lokielse/omnipay-unionpay": "UnionPay", + "lokielse/omnipay-wechatpay": "WechatPay", + "mfauveau/omnipay-nmi": "Network Merchants Inc. (NMI)", + "mfauveau/omnipay-pacnet": "Pacnet", + "omnipay/payu": "PayU", + "paypronl/omnipay-paypro": "PayPro", + "samvaughton/omnipay-barclays-epdq": "Barclays ePDQ", + "teaandcode/omnipay-worldpay-xml": "WorldPay XML Direct" + }, "type": "metapackage", "extra": { "branch-alias": { @@ -6596,6 +6696,10 @@ "name": "Adrian Macneil", "email": "adrian@adrianmacneil.com" }, + { + "name": "Kayla Daniels", + "email": "kayladnls@gmail.com" + }, { "name": "Omnipay Community", "homepage": "https://github.com/thephpleague/omnipay/graphs/contributors" @@ -6611,8 +6715,10 @@ "authorize.net", "buckaroo", "cardsave", + "checkoutcom", "coinbase", "commweb", + "cybersource", "dps", "egate", "eway", @@ -6628,12 +6734,15 @@ "multisafepay", "netaxept", "netbanx", + "pagarme", "pay", "payfast", "payflow", "payment", "paymentexpress", + "payone", "paypal", + "payu", "pin", "purchase", "rapid", @@ -6646,7 +6755,7 @@ "twocheckout", "worldpay" ], - "time": "2014-12-10 13:55:00" + "time": "2017-03-21 09:24:49" }, { "name": "omnipay/payfast", @@ -6707,16 +6816,16 @@ }, { "name": "omnipay/payflow", - "version": "v2.2.2", + "version": "v2.3", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-payflow.git", - "reference": "8dbfaf9accc1c2b388c9ab89c4b30176396c973a" + "reference": "2348f82f7eda1e9fb991767d61a3534e4935e9ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-payflow/zipball/8dbfaf9accc1c2b388c9ab89c4b30176396c973a", - "reference": "8dbfaf9accc1c2b388c9ab89c4b30176396c973a", + "url": "https://api.github.com/repos/thephpleague/omnipay-payflow/zipball/2348f82f7eda1e9fb991767d61a3534e4935e9ba", + "reference": "2348f82f7eda1e9fb991767d61a3534e4935e9ba", "shasum": "" }, "require": { @@ -6760,7 +6869,7 @@ "payflow", "payment" ], - "time": "2017-05-12 08:10:23" + "time": "2017-11-10 08:14:36" }, { "name": "omnipay/paymentexpress", @@ -6827,16 +6936,16 @@ }, { "name": "omnipay/paypal", - "version": "v2.6.3", + "version": "v2.6.4", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-paypal.git", - "reference": "e06c8814deacc793715bb9fd3fcae5995b5d8d6b" + "reference": "9e44c31a7038d4a23232b3739b602e8842106c4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/e06c8814deacc793715bb9fd3fcae5995b5d8d6b", - "reference": "e06c8814deacc793715bb9fd3fcae5995b5d8d6b", + "url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/9e44c31a7038d4a23232b3739b602e8842106c4e", + "reference": "9e44c31a7038d4a23232b3739b602e8842106c4e", "shasum": "" }, "require": { @@ -6881,7 +6990,7 @@ "paypal", "purchase" ], - "time": "2016-12-22 12:35:25" + "time": "2017-11-10 08:10:43" }, { "name": "omnipay/pin", @@ -6942,20 +7051,21 @@ }, { "name": "omnipay/sagepay", - "version": "2.4.1", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-sagepay.git", - "reference": "8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0" + "reference": "0165d62d27bd84ce2389ec7fcd224f3a21835b14" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0", - "reference": "8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0", + "url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/0165d62d27bd84ce2389ec7fcd224f3a21835b14", + "reference": "0165d62d27bd84ce2389ec7fcd224f3a21835b14", "shasum": "" }, "require": { - "omnipay/common": "~2.0" + "omnipay/common": "~2.4", + "php": ">=5.4" }, "require-dev": { "omnipay/tests": "~2.0" @@ -6997,7 +7107,7 @@ "sage pay", "sagepay" ], - "time": "2017-09-05 15:31:15" + "time": "2017-09-29 17:16:46" }, { "name": "omnipay/securepay", @@ -7172,16 +7282,16 @@ }, { "name": "omnipay/worldpay", - "version": "v2.2.1", + "version": "v2.2.2", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-worldpay.git", - "reference": "be0b5c31f5a0457b913281aa2d6072b62fd9e65c" + "reference": "522fbac76b1baa65cb62192fedff227fe37a8cf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-worldpay/zipball/be0b5c31f5a0457b913281aa2d6072b62fd9e65c", - "reference": "be0b5c31f5a0457b913281aa2d6072b62fd9e65c", + "url": "https://api.github.com/repos/thephpleague/omnipay-worldpay/zipball/522fbac76b1baa65cb62192fedff227fe37a8cf0", + "reference": "522fbac76b1baa65cb62192fedff227fe37a8cf0", "shasum": "" }, "require": { @@ -7225,7 +7335,7 @@ "payment", "worldpay" ], - "time": "2017-06-15 07:04:25" + "time": "2017-10-23 08:31:50" }, { "name": "paragonie/constant_time_encoding", @@ -7291,16 +7401,16 @@ }, { "name": "paragonie/random_compat", - "version": "v1.4.2", + "version": "v2.0.11", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66" + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/965cdeb01fdcab7653253aa81d40441d261f1e66", - "reference": "965cdeb01fdcab7653253aa81d40441d261f1e66", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", "shasum": "" }, "require": { @@ -7335,7 +7445,7 @@ "pseudorandom", "random" ], - "time": "2017-03-13 16:22:52" + "time": "2017-09-27 21:40:39" }, { "name": "patricktalmadge/bootstrapper", @@ -7455,16 +7565,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.6", + "version": "2.0.9", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa" + "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34a7699e6f31b1ef4035ee36444407cecf9f56aa", - "reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", + "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558", "shasum": "" }, "require": { @@ -7543,7 +7653,7 @@ "x.509", "x509" ], - "time": "2017-06-05 06:31:10" + "time": "2017-11-29 06:38:08" }, { "name": "pragmarx/google2fa", @@ -7920,37 +8030,38 @@ }, { "name": "psy/psysh", - "version": "v0.7.2", + "version": "v0.8.15", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280" + "reference": "b1d289c2cb03a2f8249912c53e96ced38f879926" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280", - "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/b1d289c2cb03a2f8249912c53e96ced38f879926", + "reference": "b1d289c2cb03a2f8249912c53e96ced38f879926", "shasum": "" }, "require": { "dnoegel/php-xdg-base-dir": "0.1", "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "^1.2.1|~2.0", + "nikic/php-parser": "~1.3|~2.0|~3.0", "php": ">=5.3.9", "symfony/console": "~2.3.10|^2.4.2|~3.0", "symfony/var-dumper": "~2.7|~3.0" }, "require-dev": { - "fabpot/php-cs-fixer": "~1.5", - "phpunit/phpunit": "~3.7|~4.0|~5.0", - "squizlabs/php_codesniffer": "~2.0", + "friendsofphp/php-cs-fixer": "~1.11", + "hoa/console": "~3.16|~1.14", + "phpunit/phpunit": "^4.8.35|^5.4.3", "symfony/finder": "~2.1|~3.0" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", "ext-pdo-sqlite": "The doc command requires SQLite to work.", "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", + "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." }, "bin": [ "bin/psysh" @@ -7988,7 +8099,7 @@ "interactive", "shell" ], - "time": "2016-03-09 05:03:14" + "time": "2017-11-16 14:29:51" }, { "name": "rackspace/php-opencloud", @@ -8173,6 +8284,150 @@ ], "time": "2017-06-14 03:57:53" }, + { + "name": "roave/security-advisories", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Roave/SecurityAdvisories.git", + "reference": "f793fe6ff54acabd9bc9f76f4a9ad3c89a68c789" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f793fe6ff54acabd9bc9f76f4a9ad3c89a68c789", + "reference": "f793fe6ff54acabd9bc9f76f4a9ad3c89a68c789", + "shasum": "" + }, + "conflict": { + "adodb/adodb-php": "<5.20.6", + "amphp/artax": "<1.0.6|>=2,<2.0.6", + "aws/aws-sdk-php": ">=3,<3.2.1", + "bugsnag/bugsnag-laravel": ">=2,<2.0.2", + "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4", + "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cartalyst/sentry": "<=2.1.6", + "codeigniter/framework": "<=3.0.6", + "composer/composer": "<=1.0.0-alpha11", + "contao-components/mediaelement": ">=2.14.2,<2.21.1", + "contao/core": ">=2,<3.5.31", + "contao/core-bundle": ">=4,<4.4.8", + "contao/listing-bundle": ">=4,<4.4.8", + "doctrine/annotations": ">=1,<1.2.7", + "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", + "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", + "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2", + "doctrine/doctrine-bundle": "<1.5.2", + "doctrine/doctrine-module": "<=0.7.1", + "doctrine/mongodb-odm": ">=1,<1.0.2", + "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", + "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", + "dompdf/dompdf": ">=0.6,<0.6.2", + "drupal/core": ">=8,<8.3.7", + "drupal/drupal": ">=8,<8.3.7", + "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.2|>=5.4,<5.4.10.1|>=2017.8,<2017.8.1.1", + "firebase/php-jwt": "<2", + "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", + "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "gregwar/rst": "<1.0.3", + "guzzlehttp/guzzle": ">=6,<6.2.1|>=4.0.0-rc2,<4.2.4|>=5,<5.3.1", + "illuminate/auth": ">=4,<4.0.99|>=4.1,<4.1.26", + "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29", + "joomla/session": "<1.3.1", + "laravel/framework": ">=4,<4.0.99|>=4.1,<4.1.29", + "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "magento/magento1ce": ">=1.5.0.1,<1.9.3.2", + "magento/magento1ee": ">=1.9,<1.14.3.2", + "magento/magento2ce": ">=2,<2.2", + "monolog/monolog": ">=1.8,<1.12", + "namshi/jose": "<2.2", + "onelogin/php-saml": "<2.10.4", + "oro/crm": ">=1.7,<1.7.4", + "oro/platform": ">=1.7,<1.7.4", + "phpmailer/phpmailer": ">=5,<5.2.24", + "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpxmlrpc/extras": "<6.0.1", + "pusher/pusher-php-server": "<2.2.1", + "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", + "shopware/shopware": "<5.2.25", + "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11", + "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", + "silverstripe/framework": ">=3,<3.3", + "silverstripe/userforms": "<3", + "simplesamlphp/saml2": "<1.8.1|>=1.9,<1.9.1|>=1.10,<1.10.3|>=2,<2.3.3", + "simplesamlphp/simplesamlphp": "<1.14.16", + "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "socalnick/scn-social-auth": "<1.15.2", + "squizlabs/php_codesniffer": ">=1,<2.8.1", + "swiftmailer/swiftmailer": ">=4,<5.4.5", + "symfony/dependency-injection": ">=2,<2.0.17", + "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2", + "symfony/http-foundation": ">=2,<2.3.27|>=2.4,<2.5.11|>=2.6,<2.6.6", + "symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8", + "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/routing": ">=2,<2.0.19", + "symfony/security": ">=2,<2.0.25|>=2.1,<2.1.13|>=2.2,<2.2.9|>=2.3,<2.3.37|>=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8.23,<2.8.25|>=3.2.10,<3.2.12|>=3.3.3,<3.3.5", + "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<2.8.6|>=2.8.23,<2.8.25|>=3,<3.0.6|>=3.2.10,<3.2.12|>=3.3.3,<3.3.5", + "symfony/security-csrf": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/serializer": ">=2,<2.0.11", + "symfony/symfony": ">=2,<2.3.41|>=2.4,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/translation": ">=2,<2.0.17", + "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", + "thelia/backoffice-default-template": ">=2.1,<2.1.2", + "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2", + "twig/twig": "<1.20", + "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5", + "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5", + "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4", + "willdurand/js-translation-bundle": "<2.1.1", + "yiisoft/yii": ">=1.1.14,<1.1.15", + "yiisoft/yii2": "<2.0.5", + "yiisoft/yii2-bootstrap": "<2.0.4", + "yiisoft/yii2-dev": "<2.0.4", + "yiisoft/yii2-gii": "<2.0.4", + "yiisoft/yii2-jui": "<2.0.4", + "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", + "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-diactoros": ">=1,<1.0.4", + "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-http": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.3,<2.3.8|>=2.4,<2.4.1", + "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", + "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-validator": ">=2.3,<2.3.6", + "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zendframework": ">=2,<2.4.11|>=2.5,<2.5.1", + "zendframework/zendframework1": "<1.12.20", + "zendframework/zendopenid": ">=2,<2.0.2", + "zendframework/zendxml": ">=1,<1.0.1", + "zetacomponents/mail": "<1.8.2", + "zf-commons/zfc-user": "<1.2.2", + "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", + "zfr/zfr-oauth2-server-module": "<0.1.2" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "role": "maintainer" + } + ], + "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", + "time": "2017-11-24 16:44:41" + }, { "name": "setasign/fpdi", "version": "1.6.2", @@ -8228,12 +8483,12 @@ "source": { "type": "git", "url": "https://github.com/simshaun/recurr.git", - "reference": "7d0e8942cb1d00d4bc11d5eb87fa990d77b0de61" + "reference": "7679f92be8e6046c40668b34dbf87000e4ab430f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simshaun/recurr/zipball/7d0e8942cb1d00d4bc11d5eb87fa990d77b0de61", - "reference": "7d0e8942cb1d00d4bc11d5eb87fa990d77b0de61", + "url": "https://api.github.com/repos/simshaun/recurr/zipball/7679f92be8e6046c40668b34dbf87000e4ab430f", + "reference": "7679f92be8e6046c40668b34dbf87000e4ab430f", "shasum": "" }, "require": { @@ -8274,7 +8529,7 @@ "recurring", "rrule" ], - "time": "2017-08-03 23:25:58" + "time": "2017-11-13 18:18:52" }, { "name": "softcommerce/omnipay-paytrace", @@ -8384,23 +8639,23 @@ }, { "name": "symfony/class-loader", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "7572c904b209fa9907c69a6a9a68243c265a4d01" + "reference": "e8d36a7b5568d232f5c3f8ef92665836b9f1e038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/7572c904b209fa9907c69a6a9a68243c265a4d01", - "reference": "7572c904b209fa9907c69a6a9a68243c265a4d01", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/e8d36a7b5568d232f5c3f8ef92665836b9f1e038", + "reference": "e8d36a7b5568d232f5c3f8ef92665836b9f1e038", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8" }, "require-dev": { - "symfony/finder": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0|~4.0", "symfony/polyfill-apcu": "~1.1" }, "suggest": { @@ -8409,7 +8664,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -8436,11 +8691,11 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-05 16:10:10" }, { "name": "symfony/config", - "version": "v3.2.13", + "version": "v3.2.14", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -8496,20 +8751,21 @@ }, { "name": "symfony/console", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "926061e74229e935d3c5b4e9ba87237316c6693f" + "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/926061e74229e935d3c5b4e9ba87237316c6693f", - "reference": "926061e74229e935d3c5b4e9ba87237316c6693f", + "url": "https://api.github.com/repos/symfony/console/zipball/047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", + "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", "shasum": "" }, "require": { "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { @@ -8525,7 +8781,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -8552,20 +8808,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-07-30 07:22:48" + "time": "2017-01-08 20:43:43" }, { "name": "symfony/css-selector", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "07447650225ca9223bd5c97180fe7c8267f7d332" + "reference": "7134b93e90ea7e7881fcb2da006d21b4c5f31908" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/07447650225ca9223bd5c97180fe7c8267f7d332", - "reference": "07447650225ca9223bd5c97180fe7c8267f7d332", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/7134b93e90ea7e7881fcb2da006d21b4c5f31908", + "reference": "7134b93e90ea7e7881fcb2da006d21b4c5f31908", "shasum": "" }, "require": { @@ -8574,7 +8830,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -8605,20 +8861,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-05 16:10:10" }, { "name": "symfony/debug", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + "reference": "c6661361626b3cf5cf2089df98b3b5006a197e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "url": "https://api.github.com/repos/symfony/debug/zipball/c6661361626b3cf5cf2089df98b3b5006a197e85", + "reference": "c6661361626b3cf5cf2089df98b3b5006a197e85", "shasum": "" }, "require": { @@ -8635,7 +8891,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -8662,11 +8918,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-07-30 07:22:48" + "time": "2017-01-28 00:04:57" }, { "name": "symfony/dependency-injection", - "version": "v3.2.13", + "version": "v3.2.14", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", @@ -8729,16 +8985,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.28", + "version": "v2.8.31", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "7fe089232554357efb8d4af65ce209fc6e5a2186" + "reference": "b59aacf238fadda50d612c9de73b74751872a903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fe089232554357efb8d4af65ce209fc6e5a2186", - "reference": "7fe089232554357efb8d4af65ce209fc6e5a2186", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b59aacf238fadda50d612c9de73b74751872a903", + "reference": "b59aacf238fadda50d612c9de73b74751872a903", "shasum": "" }, "require": { @@ -8785,20 +9041,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-10-01 21:00:16" + "time": "2017-11-05 15:25:56" }, { "name": "symfony/filesystem", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1" + "reference": "de56eee71e0a128d8c54ccc1909cdefd574bad0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/90bc45abf02ae6b7deb43895c1052cb0038506f1", - "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/de56eee71e0a128d8c54ccc1909cdefd574bad0f", + "reference": "de56eee71e0a128d8c54ccc1909cdefd574bad0f", "shasum": "" }, "require": { @@ -8807,7 +9063,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -8834,20 +9090,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-10-03 13:33:10" + "time": "2017-11-19 18:59:05" }, { "name": "symfony/finder", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9" + "reference": "59687a255d1562f2c17b012418273862083d85f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9", - "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9", + "url": "https://api.github.com/repos/symfony/finder/zipball/59687a255d1562f2c17b012418273862083d85f7", + "reference": "59687a255d1562f2c17b012418273862083d85f7", "shasum": "" }, "require": { @@ -8856,7 +9112,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -8883,35 +9139,33 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:40:00" + "time": "2017-01-02 20:31:54" }, { "name": "symfony/http-foundation", - "version": "v2.8.28", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e6e0170e134bf25d03030b71a19ca409e036157a" + "reference": "cef0ad49a2e90455cfc649522025b5a2929648c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e6e0170e134bf25d03030b71a19ca409e036157a", - "reference": "e6e0170e134bf25d03030b71a19ca409e036157a", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cef0ad49a2e90455cfc649522025b5a2929648c0", + "reference": "cef0ad49a2e90455cfc649522025b5a2929648c0", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -8938,20 +9192,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-10-05 23:06:47" + "time": "2017-01-08 20:43:43" }, { "name": "symfony/http-kernel", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3" + "reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d97ba4425e36e79c794e7d14ff36f00f081b37b3", - "reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c830387dec1b48c100473d10a6a356c3c3ae2a13", + "reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13", "shasum": "" }, "require": { @@ -8959,7 +9213,7 @@ "psr/log": "~1.0", "symfony/debug": "~2.8|~3.0", "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2" + "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2" }, "conflict": { "symfony/config": "<2.8" @@ -8993,7 +9247,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -9020,20 +9274,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2016-07-30 09:10:37" + "time": "2017-01-28 02:53:17" }, { "name": "symfony/options-resolver", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6" + "reference": "08748edfe6982f4d878cc42b8325b19a276fb1cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ee4e22978fe885b54ee5da8c7964f0a5301abfb6", - "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/08748edfe6982f4d878cc42b8325b19a276fb1cf", + "reference": "08748edfe6982f4d878cc42b8325b19a276fb1cf", "shasum": "" }, "require": { @@ -9042,7 +9296,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -9074,7 +9328,7 @@ "configuration", "options" ], - "time": "2017-07-29 21:54:42" + "time": "2017-11-05 16:10:10" }, { "name": "symfony/polyfill-mbstring", @@ -9135,120 +9389,6 @@ ], "time": "2017-10-11 12:05:26" }, - { - "name": "symfony/polyfill-php54", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "d7810a14b2c6c1aff415e1bb755f611b3d5327bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/d7810a14b2c6c1aff415e1bb755f611b3d5327bc", - "reference": "d7810a14b2c6c1aff415e1bb755f611b3d5327bc", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2017-10-11 12:05:26" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "b64e7f0c37ecf144ecc16668936eef94e628fbfd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/b64e7f0c37ecf144ecc16668936eef94e628fbfd", - "reference": "b64e7f0c37ecf144ecc16668936eef94e628fbfd", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2017-10-11 12:05:26" - }, { "name": "symfony/polyfill-php56", "version": "v1.6.0", @@ -9359,16 +9499,16 @@ }, { "name": "symfony/process", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "768debc5996f599c4372b322d9061dba2a4bf505" + "reference": "2605753c5f8c531623d24d002825ebb1d6a22248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/768debc5996f599c4372b322d9061dba2a4bf505", - "reference": "768debc5996f599c4372b322d9061dba2a4bf505", + "url": "https://api.github.com/repos/symfony/process/zipball/2605753c5f8c531623d24d002825ebb1d6a22248", + "reference": "2605753c5f8c531623d24d002825ebb1d6a22248", "shasum": "" }, "require": { @@ -9377,7 +9517,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -9404,20 +9544,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-07-28 11:13:34" + "time": "2017-01-21 17:13:55" }, { "name": "symfony/routing", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9038984bd9c05ab07280121e9e10f61a7231457b" + "reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9038984bd9c05ab07280121e9e10f61a7231457b", - "reference": "9038984bd9c05ab07280121e9e10f61a7231457b", + "url": "https://api.github.com/repos/symfony/routing/zipball/f25581d4eb0a82962c291917f826166f0dcd8a9a", + "reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a", "shasum": "" }, "require": { @@ -9446,7 +9586,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -9479,20 +9619,20 @@ "uri", "url" ], - "time": "2016-06-29 05:40:00" + "time": "2017-01-28 00:04:57" }, { "name": "symfony/translation", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "eee6c664853fd0576f21ae25725cfffeafe83f26" + "reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/eee6c664853fd0576f21ae25725cfffeafe83f26", - "reference": "eee6c664853fd0576f21ae25725cfffeafe83f26", + "url": "https://api.github.com/repos/symfony/translation/zipball/d5a20fab5f63f44c233c69b3041c3cb1d4945e45", + "reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45", "shasum": "" }, "require": { @@ -9516,7 +9656,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -9543,20 +9683,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-07-30 07:22:48" + "time": "2017-01-21 17:01:39" }, { "name": "symfony/var-dumper", - "version": "v3.0.9", + "version": "v3.1.10", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377" + "reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1f7e071aafc6676fcb6e3f0497f87c2397247377", - "reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/16df11647e5b992d687cb4eeeb9a882d5f5c26b9", + "reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9", "shasum": "" }, "require": { @@ -9572,7 +9712,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -9606,20 +9746,20 @@ "debug", "dump" ], - "time": "2016-07-26 08:03:56" + "time": "2017-01-24 13:02:38" }, { "name": "symfony/yaml", - "version": "v3.3.10", + "version": "v3.3.13", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46" + "reference": "0938408c4faa518d95230deabb5f595bf0de31b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46", - "reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0938408c4faa518d95230deabb5f595bf0de31b9", + "reference": "0938408c4faa518d95230deabb5f595bf0de31b9", "shasum": "" }, "require": { @@ -9661,7 +9801,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-10-05 14:43:42" + "time": "2017-11-10 18:26:04" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -10238,16 +10378,16 @@ }, { "name": "wildbit/laravel-postmark-provider", - "version": "3.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/wildbit/laravel-postmark-provider.git", - "reference": "b80815602f618abe24030ea6d3f117da49a72885" + "reference": "134f359" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wildbit/laravel-postmark-provider/zipball/b80815602f618abe24030ea6d3f117da49a72885", - "reference": "b80815602f618abe24030ea6d3f117da49a72885", + "url": "https://api.github.com/repos/wildbit/laravel-postmark-provider/zipball/134f359", + "reference": "134f359", "shasum": "" }, "require": { @@ -10265,7 +10405,7 @@ "MIT" ], "description": "An officially supported mail provider to send mail from Laravel through Postmark, see instructions for integrating it here: https://github.com/wildbit/laravel-postmark-provider/blob/master/README.md", - "time": "2016-02-10 14:15:58" + "time": "2017-01-19 19:52:38" }, { "name": "wildbit/swiftmailer-postmark", @@ -10758,25 +10898,25 @@ }, { "name": "zircote/swagger-php", - "version": "2.0.11", + "version": "2.0.13", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "d010ab67536784f8b578cb4ba7d15c906f3e1a45" + "reference": "8b42fdc3d8c5a5e0d1f8d344aa359822c9f085e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/d010ab67536784f8b578cb4ba7d15c906f3e1a45", - "reference": "d010ab67536784f8b578cb4ba7d15c906f3e1a45", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/8b42fdc3d8c5a5e0d1f8d344aa359822c9f085e0", + "reference": "8b42fdc3d8c5a5e0d1f8d344aa359822c9f085e0", "shasum": "" }, "require": { "doctrine/annotations": "*", "php": ">=5.6", - "symfony/finder": "*" + "symfony/finder": ">=2.2" }, "require-dev": { - "phpunit/phpunit": ">=4.8 <=5.6", + "phpunit/phpunit": ">=4.8.35 <=5.6", "squizlabs/php_codesniffer": ">=2.7", "zendframework/zend-form": "<2.8" }, @@ -10816,7 +10956,7 @@ "rest", "service discovery" ], - "time": "2017-08-16 08:32:59" + "time": "2017-12-01 09:22:05" } ], "packages-dev": [ @@ -10881,16 +11021,16 @@ }, { "name": "codeception/c3", - "version": "2.0.12", + "version": "2.0.14", "source": { "type": "git", "url": "https://github.com/Codeception/c3.git", - "reference": "f08f20b0b6191f0c58be022c6f20d5b1cdc1004c" + "reference": "777e3b626d9a5ecdfea3eff3d3de437045b41c92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/c3/zipball/f08f20b0b6191f0c58be022c6f20d5b1cdc1004c", - "reference": "f08f20b0b6191f0c58be022c6f20d5b1cdc1004c", + "url": "https://api.github.com/repos/Codeception/c3/zipball/777e3b626d9a5ecdfea3eff3d3de437045b41c92", + "reference": "777e3b626d9a5ecdfea3eff3d3de437045b41c92", "shasum": "" }, "require": { @@ -10927,7 +11067,7 @@ "code coverage", "codecoverage" ], - "time": "2017-04-06 00:08:55" + "time": "2017-10-29 23:14:30" }, { "name": "codeception/codeception", @@ -11079,32 +11219,40 @@ }, { "name": "facebook/webdriver", - "version": "1.2.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/facebook/php-webdriver.git", - "reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3" + "reference": "86b5ca2f67173c9d34340845dd690149c886a605" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/af21de3ae5306a8ca0bcc02a19735dadc43e83f3", - "reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3", + "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/86b5ca2f67173c9d34340845dd690149c886a605", + "reference": "86b5ca2f67173c9d34340845dd690149c886a605", "shasum": "" }, "require": { "ext-curl": "*", - "php": "^5.5 || ~7.0" + "ext-zip": "*", + "php": "^5.6 || ~7.0", + "symfony/process": "^2.8 || ^3.1 || ^4.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.11", + "friendsofphp/php-cs-fixer": "^2.0", + "guzzle/guzzle": "^3.4.1", + "php-coveralls/php-coveralls": "^1.0.2", "php-mock/php-mock-phpunit": "^1.1", - "phpunit/phpunit": "4.6.* || ~5.0", - "squizlabs/php_codesniffer": "^2.6" - }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" + "phpunit/phpunit": "^5.7", + "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", + "squizlabs/php_codesniffer": "^2.6", + "symfony/var-dumper": "^3.3 || ^4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-community": "1.5-dev" + } + }, "autoload": { "psr-4": { "Facebook\\WebDriver\\": "lib/" @@ -11114,7 +11262,7 @@ "license": [ "Apache-2.0" ], - "description": "A PHP client for WebDriver", + "description": "A PHP client for Selenium WebDriver", "homepage": "https://github.com/facebook/php-webdriver", "keywords": [ "facebook", @@ -11122,7 +11270,7 @@ "selenium", "webdriver" ], - "time": "2016-10-14 15:16:51" + "time": "2017-11-15 11:08:09" }, { "name": "phpdocumentor/reflection-common", @@ -11180,29 +11328,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.1.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" + "reference": "66465776cfc249844bde6d117abff1d22e06c2da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66465776cfc249844bde6d117abff1d22e06c2da", + "reference": "66465776cfc249844bde6d117abff1d22e06c2da", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/reflection-common": "^1.0.0", "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ @@ -11221,7 +11375,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-08-30 18:51:59" + "time": "2017-11-27 17:38:31" }, { "name": "phpdocumentor/type-resolver", @@ -11384,16 +11538,16 @@ }, { "name": "phpspec/prophecy", - "version": "v1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", "shasum": "" }, "require": { @@ -11405,7 +11559,7 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7" }, "type": "library", "extra": { @@ -11443,7 +11597,7 @@ "spy", "stub" ], - "time": "2017-09-04 11:05:03" + "time": "2017-11-24 13:59:53" }, { "name": "phpunit/php-code-coverage", @@ -11509,16 +11663,16 @@ }, { "name": "phpunit/php-file-iterator", - "version": "1.4.2", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -11552,7 +11706,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03 07:40:28" + "time": "2017-11-27 13:52:08" }, { "name": "phpunit/php-text-template", @@ -12240,25 +12394,25 @@ }, { "name": "symfony/browser-kit", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "317d5bdf0127f06db7ea294186132b4f5b036839" + "reference": "179522b5f0b5e6d00bb60f38a4d6b29962e4b61b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/317d5bdf0127f06db7ea294186132b4f5b036839", - "reference": "317d5bdf0127f06db7ea294186132b4f5b036839", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/179522b5f0b5e6d00bb60f38a4d6b29962e4b61b", + "reference": "179522b5f0b5e6d00bb60f38a4d6b29962e4b61b", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8", - "symfony/dom-crawler": "~2.8|~3.0" + "symfony/dom-crawler": "~2.8|~3.0|~4.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/process": "" @@ -12266,7 +12420,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -12293,20 +12447,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-07 14:20:24" }, { "name": "symfony/dom-crawler", - "version": "v3.3.10", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "40dafd42d5dad7fe5ad4e958413d92a207522ac1" + "reference": "7bf68716e400997a291ad42c9f9fe7972e6656d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/40dafd42d5dad7fe5ad4e958413d92a207522ac1", - "reference": "40dafd42d5dad7fe5ad4e958413d92a207522ac1", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/7bf68716e400997a291ad42c9f9fe7972e6656d2", + "reference": "7bf68716e400997a291ad42c9f9fe7972e6656d2", "shasum": "" }, "require": { @@ -12314,7 +12468,7 @@ "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0" + "symfony/css-selector": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/css-selector": "" @@ -12322,7 +12476,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -12349,7 +12503,7 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-05 16:10:10" }, { "name": "webmozart/assert", @@ -12410,40 +12564,28 @@ "package": "omnipay/authorizenet" } ], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": { - "dwolla/omnipay-dwolla": 20, - "alfaproject/omnipay-skrill": 20, - "anahkiasen/former": 20, "chumper/datatable": 20, "codedge/laravel-selfupdater": 20, "collizo4sky/omnipay-wepay": 20, - "delatbabel/omnipay-fatzebra": 20, - "dercoder/omnipay-paysafecard": 20, - "descubraomundo/omnipay-pagarme": 20, "digitickets/omnipay-gocardlessv2": 20, - "dioscouri/omnipay-cybersource": 20, "gatepay/fedachdir": 20, - "incube8/omnipay-multicards": 20, "intervention/image": 20, + "invoiceninja/omnipay-collection": 20, "jlapp/swaggervel": 20, "laracasts/presenter": 20, - "meebio/omnipay-creditcall": 20, - "meebio/omnipay-secure-trading": 20, - "omnipay/2checkout": 20, "omnipay/authorizenet": 20, - "omnipay/bitpay": 20, - "omnipay/braintree": 20, - "omnipay/gocardless": 20, - "omnipay/stripe": 20, + "roave/security-advisories": 20, "simshaun/recurr": 20, "webpatser/laravel-countries": 20, - "websight/l5-google-cloud-storage": 20 + "websight/l5-google-cloud-storage": 20, + "wildbit/laravel-postmark-provider": 20 }, - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=5.5.9", + "php": ">=7.0.0", "ext-gd": "*", "ext-gmp": "*" }, diff --git a/config/app.php b/config/app.php index 6ca510703771..adcd953d58e3 100644 --- a/config/app.php +++ b/config/app.php @@ -4,6 +4,8 @@ use App\Libraries\Utils; return [ + 'name' => env('APP_NAME', 'Invoice Ninja'), + /* |-------------------------------------------------------------------------- | Application Debug Mode @@ -139,6 +141,7 @@ return [ 'Illuminate\Validation\ValidationServiceProvider', 'Illuminate\View\ViewServiceProvider', 'Illuminate\Broadcasting\BroadcastServiceProvider', + 'Illuminate\Notifications\NotificationServiceProvider', /* * Additional Providers diff --git a/config/auth.php b/config/auth.php index 7b08fd473147..fce3eda0eb7d 100644 --- a/config/auth.php +++ b/config/auth.php @@ -39,10 +39,10 @@ return [ 'driver' => 'session', 'provider' => 'users', ], - + 'client' => [ 'driver' => 'session', - 'provider' => 'client', + 'provider' => 'clients', ], 'api' => [ @@ -73,8 +73,8 @@ return [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], - - 'client' => [ + + 'clients' => [ 'driver' => 'eloquent', 'model' => App\Models\Contact::class, ] @@ -102,16 +102,14 @@ return [ 'passwords' => [ 'users' => [ 'provider' => 'users', - 'email' => 'emails.password', 'table' => 'password_resets', 'expire' => 60, ], - 'client' => [ - 'provider' => 'client', - 'email' => 'emails.client_password', + 'clients' => [ + 'provider' => 'clients', 'table' => 'password_resets', 'expire' => 60, ], ], -]; \ No newline at end of file +]; diff --git a/config/ninja.php b/config/ninja.php index 64aad06c723f..a3e4e6abd15b 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -4,7 +4,8 @@ return [ 'video_urls' => [ 'all' => env('NINJA_VIDEOS_URL', 'https://www.youtube.com/channel/UCXAHcBvhW05PDtWYIq7WDFA/videos'), - 'custom_design' => env('NINJA_VIDEOS_CUSOTM_DESIGN_URL', 'https://www.youtube.com/watch?v=pXQ6jgiHodc'), + 'custom_design' => env('NINJA_VIDEOS_CUSTOM_DESIGN_URL', 'https://www.youtube.com/watch?v=pXQ6jgiHodc'), + 'getting_started' => env('NINJA_VIDEOS_GETTING_STARTED_URL', 'https://www.youtube.com/watch?v=i7fqfi5HWeo'), ], // invoice locking feature diff --git a/database/migrations/2014_10_13_054100_add_invoice_number_settings.php b/database/migrations/2014_10_13_054100_add_invoice_number_settings.php index c47f1b4835a0..26a33912d1fb 100644 --- a/database/migrations/2014_10_13_054100_add_invoice_number_settings.php +++ b/database/migrations/2014_10_13_054100_add_invoice_number_settings.php @@ -22,10 +22,10 @@ class AddInvoiceNumberSettings extends Migration }); // set initial counter value for accounts with invoices - $accounts = DB::table('accounts')->lists('id'); + $accounts = DB::table('accounts')->pluck('id'); foreach ($accounts as $accountId) { - $invoiceNumbers = DB::table('invoices')->where('account_id', $accountId)->lists('invoice_number'); + $invoiceNumbers = DB::table('invoices')->where('account_id', $accountId)->pluck('invoice_number'); $max = 0; foreach ($invoiceNumbers as $invoiceNumber) { diff --git a/database/migrations/2016_04_16_103943_enterprise_plan.php b/database/migrations/2016_04_16_103943_enterprise_plan.php index 15d75ef0777b..dfc808c71579 100644 --- a/database/migrations/2016_04_16_103943_enterprise_plan.php +++ b/database/migrations/2016_04_16_103943_enterprise_plan.php @@ -71,7 +71,7 @@ class EnterprisePlan extends Migration $query->whereNull('users.public_id'); $query->orWhere('users.public_id', '=', 0); }) - ->lists('users.account_id'); + ->pluck('users.account_id'); if (count($single_account_ids)) { foreach (Account::find($single_account_ids) as $account) { @@ -207,7 +207,7 @@ class EnterprisePlan extends Migration $query->whereNotNull('companies.plan_paid'); $query->orWhereNotNull('companies.trial_started'); }) - ->lists('companies.id'); + ->pluck('companies.id'); $company_ids = array_unique($company_ids); diff --git a/database/migrations/2017_11_15_114422_add_subdomain_to_lookups.php b/database/migrations/2017_11_15_114422_add_subdomain_to_lookups.php new file mode 100644 index 000000000000..3398938e68d7 --- /dev/null +++ b/database/migrations/2017_11_15_114422_add_subdomain_to_lookups.php @@ -0,0 +1,148 @@ +string('subdomain')->nullable()->unique(); + }); + + Schema::table('payments', function ($table) { + $table->decimal('exchange_rate', 13, 4)->default(1); + $table->unsignedInteger('exchange_currency_id')->nullable(false); + }); + + Schema::table('expenses', function ($table) { + $table->decimal('exchange_rate', 13, 4)->default(1)->change(); + }); + + Schema::table('clients', function ($table) { + $table->string('shipping_address1')->nullable(); + $table->string('shipping_address2')->nullable(); + $table->string('shipping_city')->nullable(); + $table->string('shipping_state')->nullable(); + $table->string('shipping_postal_code')->nullable(); + $table->unsignedInteger('shipping_country_id')->nullable(); + $table->boolean('show_tasks_in_portal')->default(0); + $table->boolean('send_reminders')->default(1); + }); + + Schema::table('clients', function ($table) { + $table->foreign('shipping_country_id')->references('id')->on('countries'); + }); + + Schema::table('account_gateways', function ($table) { + $table->boolean('show_shipping_address')->default(false)->nullable(); + }); + + Schema::dropIfExists('scheduled_reports'); + Schema::create('scheduled_reports', function ($table) { + $table->increments('id'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('account_id')->index(); + $table->timestamps(); + $table->softDeletes(); + + $table->text('config'); + $table->enum('frequency', ['daily', 'weekly', 'biweekly', 'monthly']); + $table->date('send_date'); + + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + + $table->unsignedInteger('public_id')->nullable(); + $table->unique(['account_id', 'public_id']); + }); + + Schema::table('subscriptions', function ($table) { + $table->unsignedInteger('public_id')->nullable(); + $table->unsignedInteger('user_id')->nullable(); + }); + + $accountPublicIds = []; + foreach (Subscription::withTrashed() + ->with('account.users') + ->orderBy('id') + ->get() as $subscription) { + $accountId = $subscription->account_id; + if (isset($accountPublicIds[$accountId])) { + $publicId = $accountPublicIds[$accountId]; + $accountPublicIds[$accountId]++; + } else { + $publicId = 1; + $accountPublicIds[$accountId] = 2; + } + $subscription->public_id = $publicId; + $subscription->user_id = $subscription->account->users[0]->id; + $subscription->save(); + } + + Schema::table('subscriptions', function ($table) { + $table->unique(['account_id', 'public_id']); + }); + + Schema::table('accounts', function ($table) { + $table->boolean('inclusive_taxes')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('lookup_accounts', function ($table) { + $table->dropColumn('subdomain'); + }); + + Schema::table('payments', function ($table) { + $table->dropColumn('exchange_rate'); + $table->dropColumn('exchange_currency_id'); + }); + + Schema::table('clients', function ($table) { + $table->dropForeign('clients_shipping_country_id_foreign'); + $table->dropColumn('shipping_address1'); + $table->dropColumn('shipping_address2'); + $table->dropColumn('shipping_city'); + $table->dropColumn('shipping_state'); + $table->dropColumn('shipping_postal_code'); + $table->dropColumn('shipping_country_id'); + $table->dropColumn('show_tasks_in_portal'); + $table->dropColumn('send_reminders'); + }); + + Schema::table('account_gateways', function ($table) { + $table->dropColumn('show_shipping_address'); + }); + + Schema::dropIfExists('scheduled_reports'); + + Schema::table('subscriptions', function ($table) { + $table->dropUnique('subscriptions_account_id_public_id_unique'); + }); + + Schema::table('subscriptions', function ($table) { + $table->dropColumn('public_id'); + $table->dropColumn('user_id'); + }); + + Schema::table('accounts', function ($table) { + $table->dropColumn('inclusive_taxes'); + }); + + } +} diff --git a/database/seeds/BanksSeeder.php b/database/seeds/BanksSeeder.php index 894cb74609c9..85f13ca491f2 100644 --- a/database/seeds/BanksSeeder.php +++ b/database/seeds/BanksSeeder.php @@ -21,7 +21,7 @@ class BanksSeeder extends Seeder $banks = json_decode($banks); foreach ($banks as $bank) { - if (! DB::table('banks')->where('remote_id', '=', $bank->id)->get()) { + if (! DB::table('banks')->where('remote_id', '=', $bank->id)->count()) { if (! isset($bank->fid) || ! isset($bank->org)) { continue; } diff --git a/database/seeds/FontsSeeder.php b/database/seeds/FontsSeeder.php index c1b569b57c97..ebb097a82d1a 100644 --- a/database/seeds/FontsSeeder.php +++ b/database/seeds/FontsSeeder.php @@ -245,7 +245,7 @@ class FontsSeeder extends Seeder ]; foreach ($fonts as $font) { - if (! DB::table('fonts')->where('name', '=', $font['name'])->get()) { + if (! DB::table('fonts')->where('name', '=', $font['name'])->count()) { Font::create($font); } } diff --git a/database/seeds/GatewayTypesSeeder.php b/database/seeds/GatewayTypesSeeder.php index c7a3075a4cfa..7e4bbf6cb961 100644 --- a/database/seeds/GatewayTypesSeeder.php +++ b/database/seeds/GatewayTypesSeeder.php @@ -19,6 +19,7 @@ class GatewayTypesSeeder extends Seeder ['alias' => 'sofort', 'name' => 'Sofort'], ['alias' => 'sepa', 'name' => 'SEPA'], ['alias' => 'gocardless', 'name' => 'GoCardless'], + ['alias' => 'apple_pay', 'name' => 'Apple Pay'], ]; foreach ($gateway_types as $gateway_type) { diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php index 30745b7e5620..c6ec1bd7eecc 100644 --- a/database/seeds/PaymentLibrariesSeeder.php +++ b/database/seeds/PaymentLibrariesSeeder.php @@ -9,7 +9,7 @@ class PaymentLibrariesSeeder extends Seeder Eloquent::unguard(); $gateways = [ - ['name' => 'Authorize.Net AIM', 'provider' => 'AuthorizeNet_AIM', 'sort_order' => 4], + ['name' => 'Authorize.Net AIM', 'provider' => 'AuthorizeNet_AIM', 'sort_order' => 5], ['name' => 'Authorize.Net SIM', 'provider' => 'AuthorizeNet_SIM', 'payment_library_id' => 2], ['name' => 'CardSave', 'provider' => 'CardSave'], ['name' => 'Eway Rapid', 'provider' => 'Eway_RapidShared', 'is_offsite' => true], @@ -17,7 +17,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'GoCardless', 'provider' => 'GoCardless', 'is_offsite' => true, 'payment_library_id' => 2], ['name' => 'Migs ThreeParty', 'provider' => 'Migs_ThreeParty'], ['name' => 'Migs TwoParty', 'provider' => 'Migs_TwoParty'], - ['name' => 'Mollie', 'provider' => 'Mollie', 'is_offsite' => true, 'sort_order' => 7], + ['name' => 'Mollie', 'provider' => 'Mollie', 'is_offsite' => true, 'sort_order' => 8], ['name' => 'MultiSafepay', 'provider' => 'MultiSafepay'], ['name' => 'Netaxept', 'provider' => 'Netaxept'], ['name' => 'NetBanx', 'provider' => 'NetBanx'], @@ -25,7 +25,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Payflow Pro', 'provider' => 'Payflow_Pro'], ['name' => 'PaymentExpress PxPay', 'provider' => 'PaymentExpress_PxPay'], ['name' => 'PaymentExpress PxPost', 'provider' => 'PaymentExpress_PxPost'], - ['name' => 'PayPal Express', 'provider' => 'PayPal_Express', 'is_offsite' => true, 'sort_order' => 3], + ['name' => 'PayPal Express', 'provider' => 'PayPal_Express', 'is_offsite' => true, 'sort_order' => 4], ['name' => 'PayPal Pro', 'provider' => 'PayPal_Pro'], ['name' => 'Pin', 'provider' => 'Pin'], ['name' => 'SagePay Direct', 'provider' => 'SagePay_Direct'], @@ -50,8 +50,8 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Realex', 'provider' => 'Realex_Remote'], ['name' => 'Sisow', 'provider' => 'Sisow'], ['name' => 'Skrill', 'provider' => 'Skrill', 'is_offsite' => true], - ['name' => 'BitPay', 'provider' => 'BitPay', 'is_offsite' => true, 'sort_order' => 6], - ['name' => 'Dwolla', 'provider' => 'Dwolla', 'is_offsite' => true, 'sort_order' => 5], + ['name' => 'BitPay', 'provider' => 'BitPay', 'is_offsite' => true, 'sort_order' => 7], + ['name' => 'Dwolla', 'provider' => 'Dwolla', 'is_offsite' => true, 'sort_order' => 6], ['name' => 'AGMS', 'provider' => 'Agms'], ['name' => 'Barclays', 'provider' => 'BarclaysEpdq\Essential'], ['name' => 'Cardgate', 'provider' => 'Cardgate'], @@ -68,11 +68,11 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Secure Trading', 'provider' => 'SecureTrading'], ['name' => 'SecPay', 'provider' => 'SecPay'], ['name' => 'WeChat Express', 'provider' => 'WeChat_Express', 'payment_library_id' => 2], - ['name' => 'WePay', 'provider' => 'WePay', 'is_offsite' => false], - ['name' => 'Braintree', 'provider' => 'Braintree', 'sort_order' => 2], - ['name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 9], + ['name' => 'WePay', 'provider' => 'WePay', 'is_offsite' => false, 'sort_order' => 3], + ['name' => 'Braintree', 'provider' => 'Braintree', 'sort_order' => 3], + ['name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 20], ['name' => 'FirstData Payeezy', 'provider' => 'FirstData_Payeezy'], - ['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 8, 'is_offsite' => true], + ['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 9, 'is_offsite' => true], ['name' => 'PagSeguro', 'provider' => 'PagSeguro'], ]; diff --git a/database/seeds/UserTableSeeder.php b/database/seeds/UserTableSeeder.php index a83cbbcde67a..f0837cb3888c 100644 --- a/database/seeds/UserTableSeeder.php +++ b/database/seeds/UserTableSeeder.php @@ -31,6 +31,7 @@ class UserTableSeeder extends Seeder 'city' => $faker->city, 'state' => $faker->state, 'postal_code' => $faker->postcode, + 'currency_id' => DEFAULT_CURRENCY, 'country_id' => Country::all()->random()->id, 'account_key' => strtolower(str_random(RANDOM_KEY_LENGTH)), 'invoice_terms' => $faker->text($faker->numberBetween(50, 300)), diff --git a/database/setup.sql b/database/setup.sql index dbc4f85fb8be..5c26a4f35143 100644 --- a/database/setup.sql +++ b/database/setup.sql @@ -164,6 +164,7 @@ CREATE TABLE `account_gateways` ( `show_address` tinyint(1) DEFAULT '1', `update_address` tinyint(1) DEFAULT '1', `require_cvv` tinyint(1) DEFAULT '1', + `show_shipping_address` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `account_gateways_account_id_public_id_unique` (`account_id`,`public_id`), KEY `account_gateways_gateway_id_foreign` (`gateway_id`), @@ -371,6 +372,7 @@ CREATE TABLE `accounts` ( `credit_number_prefix` text COLLATE utf8_unicode_ci, `credit_number_pattern` text COLLATE utf8_unicode_ci, `task_rate` decimal(12,4) NOT NULL DEFAULT '0.0000', + `inclusive_taxes` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `accounts_account_key_unique` (`account_key`), KEY `accounts_timezone_id_foreign` (`timezone_id`), @@ -627,6 +629,14 @@ CREATE TABLE `clients` ( `public_notes` text COLLATE utf8_unicode_ci, `credit_number_counter` int(11) DEFAULT '1', `task_rate` decimal(12,4) NOT NULL DEFAULT '0.0000', + `shipping_address1` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `shipping_address2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `shipping_city` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `shipping_state` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `shipping_postal_code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `shipping_country_id` int(10) unsigned DEFAULT NULL, + `show_tasks_in_portal` tinyint(1) NOT NULL DEFAULT '0', + `send_reminders` tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `clients_account_id_public_id_unique` (`account_id`,`public_id`), KEY `clients_user_id_foreign` (`user_id`), @@ -637,11 +647,13 @@ CREATE TABLE `clients` ( KEY `clients_account_id_index` (`account_id`), KEY `clients_public_id_index` (`public_id`), KEY `clients_language_id_foreign` (`language_id`), + KEY `clients_shipping_country_id_foreign` (`shipping_country_id`), CONSTRAINT `clients_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE, CONSTRAINT `clients_country_id_foreign` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`), CONSTRAINT `clients_currency_id_foreign` FOREIGN KEY (`currency_id`) REFERENCES `currencies` (`id`), CONSTRAINT `clients_industry_id_foreign` FOREIGN KEY (`industry_id`) REFERENCES `industries` (`id`), CONSTRAINT `clients_language_id_foreign` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`), + CONSTRAINT `clients_shipping_country_id_foreign` FOREIGN KEY (`shipping_country_id`) REFERENCES `countries` (`id`), CONSTRAINT `clients_size_id_foreign` FOREIGN KEY (`size_id`) REFERENCES `sizes` (`id`), CONSTRAINT `clients_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -1047,7 +1059,7 @@ CREATE TABLE `expenses` ( `client_id` int(10) unsigned DEFAULT NULL, `is_deleted` tinyint(1) NOT NULL DEFAULT '0', `amount` decimal(13,2) NOT NULL, - `exchange_rate` decimal(13,4) NOT NULL, + `exchange_rate` decimal(13,4) NOT NULL DEFAULT '1.0000', `expense_date` date DEFAULT NULL, `private_notes` text COLLATE utf8_unicode_ci NOT NULL, `public_notes` text COLLATE utf8_unicode_ci NOT NULL, @@ -1189,7 +1201,7 @@ CREATE TABLE `gateway_types` ( `alias` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1198,7 +1210,7 @@ CREATE TABLE `gateway_types` ( LOCK TABLES `gateway_types` WRITE; /*!40000 ALTER TABLE `gateway_types` DISABLE KEYS */; -INSERT INTO `gateway_types` VALUES (1,'credit_card','Credit Card'),(2,'bank_transfer','Bank Transfer'),(3,'paypal','PayPal'),(4,'bitcoin','Bitcoin'),(5,'dwolla','Dwolla'),(6,'custom','Custom'),(7,'alipay','Alipay'),(8,'sofort','Sofort'),(9,'sepa','SEPA'),(10,'gocardless','GoCardless'); +INSERT INTO `gateway_types` VALUES (1,'credit_card','Credit Card'),(2,'bank_transfer','Bank Transfer'),(3,'paypal','PayPal'),(4,'bitcoin','Bitcoin'),(5,'dwolla','Dwolla'),(6,'custom','Custom'),(7,'alipay','Alipay'),(8,'sofort','Sofort'),(9,'sepa','SEPA'),(10,'gocardless','GoCardless'),(11,'apple_pay','Apple Pay'); /*!40000 ALTER TABLE `gateway_types` ENABLE KEYS */; UNLOCK TABLES; @@ -1234,7 +1246,7 @@ CREATE TABLE `gateways` ( LOCK TABLES `gateways` WRITE; /*!40000 ALTER TABLE `gateways` DISABLE KEYS */; -INSERT INTO `gateways` VALUES (1,'2017-11-08 16:19:41','2017-11-08 16:19:41','Authorize.Net AIM','AuthorizeNet_AIM',1,1,4,0,NULL,0,0),(2,'2017-11-08 16:19:41','2017-11-08 16:19:41','Authorize.Net SIM','AuthorizeNet_SIM',1,2,10000,0,NULL,0,0),(3,'2017-11-08 16:19:41','2017-11-08 16:19:41','CardSave','CardSave',1,1,10000,0,NULL,0,0),(4,'2017-11-08 16:19:41','2017-11-08 16:19:41','Eway Rapid','Eway_RapidShared',1,1,10000,0,NULL,1,0),(5,'2017-11-08 16:19:41','2017-11-08 16:19:41','FirstData Connect','FirstData_Connect',1,1,10000,0,NULL,0,0),(6,'2017-11-08 16:19:42','2017-11-08 16:19:42','GoCardless','GoCardless',1,2,10000,0,NULL,1,0),(7,'2017-11-08 16:19:42','2017-11-08 16:19:42','Migs ThreeParty','Migs_ThreeParty',1,1,10000,0,NULL,0,0),(8,'2017-11-08 16:19:42','2017-11-08 16:19:42','Migs TwoParty','Migs_TwoParty',1,1,10000,0,NULL,0,0),(9,'2017-11-08 16:19:42','2017-11-08 16:19:42','Mollie','Mollie',1,1,7,0,NULL,1,0),(10,'2017-11-08 16:19:42','2017-11-08 16:19:42','MultiSafepay','MultiSafepay',1,1,10000,0,NULL,0,0),(11,'2017-11-08 16:19:42','2017-11-08 16:19:42','Netaxept','Netaxept',1,1,10000,0,NULL,0,0),(12,'2017-11-08 16:19:42','2017-11-08 16:19:42','NetBanx','NetBanx',1,1,10000,0,NULL,0,0),(13,'2017-11-08 16:19:42','2017-11-08 16:19:42','PayFast','PayFast',1,1,10000,0,NULL,1,0),(14,'2017-11-08 16:19:42','2017-11-08 16:19:42','Payflow Pro','Payflow_Pro',1,1,10000,0,NULL,0,0),(15,'2017-11-08 16:19:42','2017-11-08 16:19:42','PaymentExpress PxPay','PaymentExpress_PxPay',1,1,10000,0,NULL,0,0),(16,'2017-11-08 16:19:42','2017-11-08 16:19:42','PaymentExpress PxPost','PaymentExpress_PxPost',1,1,10000,0,NULL,0,0),(17,'2017-11-08 16:19:42','2017-11-08 16:19:42','PayPal Express','PayPal_Express',1,1,3,0,NULL,1,0),(18,'2017-11-08 16:19:42','2017-11-08 16:19:42','PayPal Pro','PayPal_Pro',1,1,10000,0,NULL,0,0),(19,'2017-11-08 16:19:42','2017-11-08 16:19:42','Pin','Pin',1,1,10000,0,NULL,0,0),(20,'2017-11-08 16:19:42','2017-11-08 16:19:42','SagePay Direct','SagePay_Direct',1,1,10000,0,NULL,0,0),(21,'2017-11-08 16:19:42','2017-11-08 16:19:42','SagePay Server','SagePay_Server',1,1,10000,0,NULL,0,0),(22,'2017-11-08 16:19:42','2017-11-08 16:19:42','SecurePay DirectPost','SecurePay_DirectPost',1,1,10000,0,NULL,0,0),(23,'2017-11-08 16:19:42','2017-11-08 16:19:42','Stripe','Stripe',1,1,1,0,NULL,0,0),(24,'2017-11-08 16:19:42','2017-11-08 16:19:42','TargetPay Direct eBanking','TargetPay_Directebanking',1,1,10000,0,NULL,0,0),(25,'2017-11-08 16:19:42','2017-11-08 16:19:42','TargetPay Ideal','TargetPay_Ideal',1,1,10000,0,NULL,0,0),(26,'2017-11-08 16:19:42','2017-11-08 16:19:42','TargetPay Mr Cash','TargetPay_Mrcash',1,1,10000,0,NULL,0,0),(27,'2017-11-08 16:19:42','2017-11-08 16:19:42','TwoCheckout','TwoCheckout',1,1,10000,0,NULL,1,0),(28,'2017-11-08 16:19:42','2017-11-08 16:19:42','WorldPay','WorldPay',1,1,10000,0,NULL,0,0),(29,'2017-11-08 16:19:42','2017-11-08 16:19:42','BeanStream','BeanStream',1,2,10000,0,NULL,0,0),(30,'2017-11-08 16:19:42','2017-11-08 16:19:42','Psigate','Psigate',1,2,10000,0,NULL,0,0),(31,'2017-11-08 16:19:42','2017-11-08 16:19:42','moolah','AuthorizeNet_AIM',1,1,10000,0,NULL,0,0),(32,'2017-11-08 16:19:42','2017-11-08 16:19:42','Alipay','Alipay_Express',1,1,10000,0,NULL,0,0),(33,'2017-11-08 16:19:42','2017-11-08 16:19:42','Buckaroo','Buckaroo_CreditCard',1,1,10000,0,NULL,0,0),(34,'2017-11-08 16:19:42','2017-11-08 16:19:42','Coinbase','Coinbase',1,1,10000,0,NULL,0,0),(35,'2017-11-08 16:19:42','2017-11-08 16:19:42','DataCash','DataCash',1,1,10000,0,NULL,0,0),(36,'2017-11-08 16:19:42','2017-11-08 16:19:42','Neteller','Neteller',1,2,10000,0,NULL,0,0),(37,'2017-11-08 16:19:42','2017-11-08 16:19:42','Pacnet','Pacnet',1,1,10000,0,NULL,0,0),(38,'2017-11-08 16:19:42','2017-11-08 16:19:42','PaymentSense','PaymentSense',1,2,10000,0,NULL,0,0),(39,'2017-11-08 16:19:42','2017-11-08 16:19:42','Realex','Realex_Remote',1,1,10000,0,NULL,0,0),(40,'2017-11-08 16:19:42','2017-11-08 16:19:42','Sisow','Sisow',1,1,10000,0,NULL,0,0),(41,'2017-11-08 16:19:42','2017-11-08 16:19:42','Skrill','Skrill',1,1,10000,0,NULL,1,0),(42,'2017-11-08 16:19:42','2017-11-08 16:19:42','BitPay','BitPay',1,1,6,0,NULL,1,0),(43,'2017-11-08 16:19:42','2017-11-08 16:19:42','Dwolla','Dwolla',1,1,5,0,NULL,1,0),(44,'2017-11-08 16:19:42','2017-11-08 16:19:42','AGMS','Agms',1,1,10000,0,NULL,0,0),(45,'2017-11-08 16:19:42','2017-11-08 16:19:42','Barclays','BarclaysEpdq\\Essential',1,1,10000,0,NULL,0,0),(46,'2017-11-08 16:19:42','2017-11-08 16:19:42','Cardgate','Cardgate',1,1,10000,0,NULL,0,0),(47,'2017-11-08 16:19:42','2017-11-08 16:19:42','Checkout.com','CheckoutCom',1,1,10000,0,NULL,0,0),(48,'2017-11-08 16:19:42','2017-11-08 16:19:42','Creditcall','Creditcall',1,1,10000,0,NULL,0,0),(49,'2017-11-08 16:19:42','2017-11-08 16:19:42','Cybersource','Cybersource',1,1,10000,0,NULL,0,0),(50,'2017-11-08 16:19:42','2017-11-08 16:19:42','ecoPayz','Ecopayz',1,1,10000,0,NULL,0,0),(51,'2017-11-08 16:19:42','2017-11-08 16:19:42','Fasapay','Fasapay',1,1,10000,0,NULL,0,0),(52,'2017-11-08 16:19:42','2017-11-08 16:19:42','Komoju','Komoju',1,1,10000,0,NULL,0,0),(53,'2017-11-08 16:19:42','2017-11-08 16:19:42','Multicards','Multicards',1,1,10000,0,NULL,0,0),(54,'2017-11-08 16:19:42','2017-11-08 16:19:42','Pagar.Me','Pagarme',1,2,10000,0,NULL,0,0),(55,'2017-11-08 16:19:42','2017-11-08 16:19:42','Paysafecard','Paysafecard',1,1,10000,0,NULL,0,0),(56,'2017-11-08 16:19:42','2017-11-08 16:19:42','Paytrace','Paytrace_CreditCard',1,1,10000,0,NULL,0,0),(57,'2017-11-08 16:19:42','2017-11-08 16:19:42','Secure Trading','SecureTrading',1,1,10000,0,NULL,0,0),(58,'2017-11-08 16:19:42','2017-11-08 16:19:42','SecPay','SecPay',1,1,10000,0,NULL,0,0),(59,'2017-11-08 16:19:42','2017-11-08 16:19:42','WeChat Express','WeChat_Express',1,2,10000,0,NULL,0,0),(60,'2017-11-08 16:19:42','2017-11-08 16:19:42','WePay','WePay',1,1,10000,0,NULL,0,0),(61,'2017-11-08 16:19:42','2017-11-08 16:19:42','Braintree','Braintree',1,1,2,0,NULL,0,0),(62,'2017-11-08 16:19:42','2017-11-08 16:19:42','Custom','Custom',1,1,9,0,NULL,1,0),(63,'2017-11-08 16:19:42','2017-11-08 16:19:42','FirstData Payeezy','FirstData_Payeezy',1,1,10000,0,NULL,0,0),(64,'2017-11-08 16:19:42','2017-11-08 16:19:42','GoCardless','GoCardlessV2\\Redirect',1,1,8,0,NULL,1,0),(65,'2017-11-08 16:19:42','2017-11-08 16:19:42','PagSeguro','PagSeguro',1,1,10000,0,NULL,0,0); +INSERT INTO `gateways` VALUES (1,'2017-12-11 17:28:32','2017-12-11 17:28:32','Authorize.Net AIM','AuthorizeNet_AIM',1,1,5,0,NULL,0,0),(2,'2017-12-11 17:28:32','2017-12-11 17:28:32','Authorize.Net SIM','AuthorizeNet_SIM',1,2,10000,0,NULL,0,0),(3,'2017-12-11 17:28:32','2017-12-11 17:28:32','CardSave','CardSave',1,1,10000,0,NULL,0,0),(4,'2017-12-11 17:28:32','2017-12-11 17:28:32','Eway Rapid','Eway_RapidShared',1,1,10000,0,NULL,1,0),(5,'2017-12-11 17:28:32','2017-12-11 17:28:32','FirstData Connect','FirstData_Connect',1,1,10000,0,NULL,0,0),(6,'2017-12-11 17:28:32','2017-12-11 17:28:32','GoCardless','GoCardless',1,2,10000,0,NULL,1,0),(7,'2017-12-11 17:28:32','2017-12-11 17:28:32','Migs ThreeParty','Migs_ThreeParty',1,1,10000,0,NULL,0,0),(8,'2017-12-11 17:28:32','2017-12-11 17:28:32','Migs TwoParty','Migs_TwoParty',1,1,10000,0,NULL,0,0),(9,'2017-12-11 17:28:32','2017-12-11 17:28:32','Mollie','Mollie',1,1,8,0,NULL,1,0),(10,'2017-12-11 17:28:32','2017-12-11 17:28:32','MultiSafepay','MultiSafepay',1,1,10000,0,NULL,0,0),(11,'2017-12-11 17:28:32','2017-12-11 17:28:32','Netaxept','Netaxept',1,1,10000,0,NULL,0,0),(12,'2017-12-11 17:28:32','2017-12-11 17:28:32','NetBanx','NetBanx',1,1,10000,0,NULL,0,0),(13,'2017-12-11 17:28:32','2017-12-11 17:28:32','PayFast','PayFast',1,1,10000,0,NULL,1,0),(14,'2017-12-11 17:28:32','2017-12-11 17:28:32','Payflow Pro','Payflow_Pro',1,1,10000,0,NULL,0,0),(15,'2017-12-11 17:28:32','2017-12-11 17:28:32','PaymentExpress PxPay','PaymentExpress_PxPay',1,1,10000,0,NULL,0,0),(16,'2017-12-11 17:28:33','2017-12-11 17:28:33','PaymentExpress PxPost','PaymentExpress_PxPost',1,1,10000,0,NULL,0,0),(17,'2017-12-11 17:28:33','2017-12-11 17:28:33','PayPal Express','PayPal_Express',1,1,4,0,NULL,1,0),(18,'2017-12-11 17:28:33','2017-12-11 17:28:33','PayPal Pro','PayPal_Pro',1,1,10000,0,NULL,0,0),(19,'2017-12-11 17:28:33','2017-12-11 17:28:33','Pin','Pin',1,1,10000,0,NULL,0,0),(20,'2017-12-11 17:28:33','2017-12-11 17:28:33','SagePay Direct','SagePay_Direct',1,1,10000,0,NULL,0,0),(21,'2017-12-11 17:28:33','2017-12-11 17:28:33','SagePay Server','SagePay_Server',1,1,10000,0,NULL,0,0),(22,'2017-12-11 17:28:33','2017-12-11 17:28:33','SecurePay DirectPost','SecurePay_DirectPost',1,1,10000,0,NULL,0,0),(23,'2017-12-11 17:28:33','2017-12-11 17:28:33','Stripe','Stripe',1,1,1,0,NULL,0,0),(24,'2017-12-11 17:28:33','2017-12-11 17:28:33','TargetPay Direct eBanking','TargetPay_Directebanking',1,1,10000,0,NULL,0,0),(25,'2017-12-11 17:28:33','2017-12-11 17:28:33','TargetPay Ideal','TargetPay_Ideal',1,1,10000,0,NULL,0,0),(26,'2017-12-11 17:28:33','2017-12-11 17:28:33','TargetPay Mr Cash','TargetPay_Mrcash',1,1,10000,0,NULL,0,0),(27,'2017-12-11 17:28:33','2017-12-11 17:28:33','TwoCheckout','TwoCheckout',1,1,10000,0,NULL,1,0),(28,'2017-12-11 17:28:33','2017-12-11 17:28:33','WorldPay','WorldPay',1,1,10000,0,NULL,0,0),(29,'2017-12-11 17:28:33','2017-12-11 17:28:33','BeanStream','BeanStream',1,2,10000,0,NULL,0,0),(30,'2017-12-11 17:28:33','2017-12-11 17:28:33','Psigate','Psigate',1,2,10000,0,NULL,0,0),(31,'2017-12-11 17:28:33','2017-12-11 17:28:33','moolah','AuthorizeNet_AIM',1,1,10000,0,NULL,0,0),(32,'2017-12-11 17:28:33','2017-12-11 17:28:33','Alipay','Alipay_Express',1,1,10000,0,NULL,0,0),(33,'2017-12-11 17:28:33','2017-12-11 17:28:33','Buckaroo','Buckaroo_CreditCard',1,1,10000,0,NULL,0,0),(34,'2017-12-11 17:28:33','2017-12-11 17:28:33','Coinbase','Coinbase',1,1,10000,0,NULL,0,0),(35,'2017-12-11 17:28:33','2017-12-11 17:28:33','DataCash','DataCash',1,1,10000,0,NULL,0,0),(36,'2017-12-11 17:28:33','2017-12-11 17:28:33','Neteller','Neteller',1,2,10000,0,NULL,0,0),(37,'2017-12-11 17:28:33','2017-12-11 17:28:33','Pacnet','Pacnet',1,1,10000,0,NULL,0,0),(38,'2017-12-11 17:28:33','2017-12-11 17:28:33','PaymentSense','PaymentSense',1,2,10000,0,NULL,0,0),(39,'2017-12-11 17:28:33','2017-12-11 17:28:33','Realex','Realex_Remote',1,1,10000,0,NULL,0,0),(40,'2017-12-11 17:28:33','2017-12-11 17:28:33','Sisow','Sisow',1,1,10000,0,NULL,0,0),(41,'2017-12-11 17:28:33','2017-12-11 17:28:33','Skrill','Skrill',1,1,10000,0,NULL,1,0),(42,'2017-12-11 17:28:33','2017-12-11 17:28:33','BitPay','BitPay',1,1,7,0,NULL,1,0),(43,'2017-12-11 17:28:33','2017-12-11 17:28:33','Dwolla','Dwolla',1,1,6,0,NULL,1,0),(44,'2017-12-11 17:28:33','2017-12-11 17:28:33','AGMS','Agms',1,1,10000,0,NULL,0,0),(45,'2017-12-11 17:28:33','2017-12-11 17:28:33','Barclays','BarclaysEpdq\\Essential',1,1,10000,0,NULL,0,0),(46,'2017-12-11 17:28:33','2017-12-11 17:28:33','Cardgate','Cardgate',1,1,10000,0,NULL,0,0),(47,'2017-12-11 17:28:33','2017-12-11 17:28:33','Checkout.com','CheckoutCom',1,1,10000,0,NULL,0,0),(48,'2017-12-11 17:28:33','2017-12-11 17:28:33','Creditcall','Creditcall',1,1,10000,0,NULL,0,0),(49,'2017-12-11 17:28:33','2017-12-11 17:28:33','Cybersource','Cybersource',1,1,10000,0,NULL,0,0),(50,'2017-12-11 17:28:33','2017-12-11 17:28:33','ecoPayz','Ecopayz',1,1,10000,0,NULL,0,0),(51,'2017-12-11 17:28:33','2017-12-11 17:28:33','Fasapay','Fasapay',1,1,10000,0,NULL,0,0),(52,'2017-12-11 17:28:33','2017-12-11 17:28:33','Komoju','Komoju',1,1,10000,0,NULL,0,0),(53,'2017-12-11 17:28:33','2017-12-11 17:28:33','Multicards','Multicards',1,1,10000,0,NULL,0,0),(54,'2017-12-11 17:28:33','2017-12-11 17:28:33','Pagar.Me','Pagarme',1,2,10000,0,NULL,0,0),(55,'2017-12-11 17:28:33','2017-12-11 17:28:33','Paysafecard','Paysafecard',1,1,10000,0,NULL,0,0),(56,'2017-12-11 17:28:33','2017-12-11 17:28:33','Paytrace','Paytrace_CreditCard',1,1,10000,0,NULL,0,0),(57,'2017-12-11 17:28:33','2017-12-11 17:28:33','Secure Trading','SecureTrading',1,1,10000,0,NULL,0,0),(58,'2017-12-11 17:28:33','2017-12-11 17:28:33','SecPay','SecPay',1,1,10000,0,NULL,0,0),(59,'2017-12-11 17:28:33','2017-12-11 17:28:33','WeChat Express','WeChat_Express',1,2,10000,0,NULL,0,0),(60,'2017-12-11 17:28:33','2017-12-11 17:28:33','WePay','WePay',1,1,3,0,NULL,0,0),(61,'2017-12-11 17:28:33','2017-12-11 17:28:33','Braintree','Braintree',1,1,3,0,NULL,0,0),(62,'2017-12-11 17:28:33','2017-12-11 17:28:33','Custom','Custom',1,1,20,0,NULL,1,0),(63,'2017-12-11 17:28:33','2017-12-11 17:28:33','FirstData Payeezy','FirstData_Payeezy',1,1,10000,0,NULL,0,0),(64,'2017-12-11 17:28:33','2017-12-11 17:28:33','GoCardless','GoCardlessV2\\Redirect',1,1,9,0,NULL,1,0),(65,'2017-12-11 17:28:33','2017-12-11 17:28:33','PagSeguro','PagSeguro',1,1,10000,0,NULL,0,0); /*!40000 ALTER TABLE `gateways` ENABLE KEYS */; UNLOCK TABLES; @@ -1332,7 +1344,7 @@ CREATE TABLE `invoice_designs` ( LOCK TABLES `invoice_designs` WRITE; /*!40000 ALTER TABLE `invoice_designs` DISABLE KEYS */; -INSERT INTO `invoice_designs` VALUES (1,'Clean','var GlobalY=0;//Y position of line at current page\n\n var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 550;\n layout.rowHeight = 15;\n\n doc.setFontSize(9);\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, 30);\n }\n \n if (!invoice.is_pro && logoImages.imageLogo1)\n {\n pageHeight=820;\n y=pageHeight-logoImages.imageLogoHeight1;\n doc.addImage(logoImages.imageLogo1, \'JPEG\', layout.marginLeft, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);\n }\n\n doc.setFontSize(9);\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n displayAccount(doc, invoice, 220, layout.accountTop, layout);\n\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n doc.setFontSize(\'11\');\n doc.text(50, layout.headerTop, (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase());\n\n\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontSize(9);\n\n var invoiceHeight = displayInvoice(doc, invoice, 50, 170, layout);\n var clientHeight = displayClient(doc, invoice, 220, 170, layout);\n var detailsHeight = Math.max(invoiceHeight, clientHeight);\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (3 * layout.rowHeight));\n \n doc.setLineWidth(0.3); \n doc.setDrawColor(200,200,200);\n doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + 6, layout.marginRight + layout.tablePadding, layout.headerTop + 6);\n doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + detailsHeight + 14, layout.marginRight + layout.tablePadding, layout.headerTop + detailsHeight + 14);\n\n doc.setFontSize(10);\n doc.setFontType(\'bold\');\n displayInvoiceHeader(doc, invoice, layout);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n doc.setFontSize(9);\n doc.setFontType(\'bold\');\n\n GlobalY=GlobalY+25;\n\n\n doc.setLineWidth(0.3);\n doc.setDrawColor(241,241,241);\n doc.setFillColor(241,241,241);\n var x1 = layout.marginLeft - 12;\n var y1 = GlobalY-layout.tablePadding;\n\n var w2 = 510 + 24;\n var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;\n\n if (invoice.discount) {\n h2 += doc.internal.getFontSize()*2;\n }\n if (invoice.tax_amount) {\n h2 += doc.internal.getFontSize()*2;\n }\n\n //doc.rect(x1, y1, w2, h2, \'FD\');\n\n doc.setFontSize(9);\n displayNotesAndTerms(doc, layout, invoice, y);\n y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n\n\n doc.setFontSize(10);\n Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());\n \n doc.text(TmpMsgX, y, Msg);\n\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n AmountText = formatMoney(invoice.balance_amount, currencyId);\n headerLeft=layout.headerRight+400;\n var AmountX = layout.lineTotalRight - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());\n doc.text(AmountX, y, AmountText);','{\n \"content\": [{\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\n \"stack\": \"$accountDetails\",\n \"margin\": [7, 0, 0, 0]\n },\n {\n \"stack\": \"$accountAddress\"\n }\n ]\n },\n {\n \"text\": \"$entityTypeUC\",\n \"margin\": [8, 30, 8, 5],\n \"style\": \"entityTypeLabel\"\n\n },\n {\n \"table\": {\n \"headerRows\": 1,\n \"widths\": [\"auto\", \"auto\", \"*\"],\n \"body\": [\n [\n {\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"margin\": [0, 0, 12, 0],\n \"layout\": \"noBorders\"\n },\n {\n \"stack\": \"$clientDetails\"\n },\n {\n \"text\": \"\"\n }\n ]\n ]\n },\n \"layout\": {\n \"hLineWidth\": \"$firstAndLast:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#D8D8D8\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:6\",\n \"paddingBottom\": \"$amount:6\"\n }\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#D8D8D8\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:14\",\n \"paddingBottom\": \"$amount:14\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"styles\": {\n \"entityTypeLabel\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#37a3c6\"\n },\n \"primaryColor\":{\n \"color\": \"$primaryColor:#37a3c6\"\n },\n \"accountName\": {\n \"color\": \"$primaryColor:#37a3c6\",\n \"bold\": true\n },\n \"invoiceDetails\": {\n \"margin\": [0, 0, 8, 0]\n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 2]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 2]\n },\n \"notesAndTerms\": {\n \"margin\": [0, 2, 0, 2]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 2]\n },\n \"odd\": {\n \"fillColor\": \"#fbfbfb\"\n },\n \"productKey\": {\n \"color\": \"$primaryColor:#37a3c6\",\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLarger\",\n \"color\": \"$primaryColor:#37a3c6\"\n },\n \"invoiceNumber\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 16, 0, 16]\n },\n \"clientName\": {\n \"bold\": true\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [7, 0, 7, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [40, 40, 40, 60]\n}\n'),(2,'Bold',' var GlobalY=0;//Y position of line at current page\n\n var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 150;\n layout.rowHeight = 15;\n layout.headerTop = 125;\n layout.tableTop = 300;\n\n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setFillColor(46,43,43);\n } \n\n var x1 =0;\n var y1 = 0;\n var w2 = 595;\n var h2 = 100;\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, 30);\n }\n\n doc.setLineWidth(0.5);\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setFillColor(46,43,43);\n doc.setDrawColor(46,43,43);\n } \n\n // return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour\n var x1 = 0;//tableLeft-tablePadding ;\n var y1 = 750;\n var w2 = 596;\n var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n if (!invoice.is_pro && logoImages.imageLogo2)\n {\n pageHeight=820;\n var left = 250;//headerRight ;\n y=pageHeight-logoImages.imageLogoHeight2;\n var headerRight=370;\n\n var left = headerRight - logoImages.imageLogoWidth2;\n doc.addImage(logoImages.imageLogo2, \'JPEG\', left, y, logoImages.imageLogoWidth2, logoImages.imageLogoHeight2);\n }\n\n doc.setFontSize(7);\n doc.setFontType(\'bold\');\n SetPdfColor(\'White\',doc);\n\n displayAccount(doc, invoice, 300, layout.accountTop, layout);\n\n\n var y = layout.accountTop;\n var left = layout.marginLeft;\n var headerY = layout.headerTop;\n\n SetPdfColor(\'GrayLogo\',doc); //set black color\n doc.setFontSize(7);\n\n //show left column\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontType(\'normal\');\n\n //publish filled box\n doc.setDrawColor(200,200,200);\n\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n } else {\n doc.setFillColor(54,164,152); \n } \n\n GlobalY=190;\n doc.setLineWidth(0.5);\n\n var BlockLenght=220;\n var x1 =595-BlockLenght;\n var y1 = GlobalY-12;\n var w2 = BlockLenght;\n var h2 = getInvoiceDetailsHeight(invoice, layout) + layout.tablePadding + 2;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n SetPdfColor(\'SomeGreen\', doc, \'secondary\');\n doc.setFontSize(\'14\');\n doc.setFontType(\'bold\');\n doc.text(50, GlobalY, (invoice.is_quote ? invoiceLabels.your_quote : invoiceLabels.your_invoice).toUpperCase());\n\n\n var z=GlobalY;\n z=z+30;\n\n doc.setFontSize(\'8\'); \n SetPdfColor(\'Black\',doc); \n var clientHeight = displayClient(doc, invoice, layout.marginLeft, z, layout);\n layout.tableTop += Math.max(0, clientHeight - 75);\n marginLeft2=395;\n\n //publish left side information\n SetPdfColor(\'White\',doc);\n doc.setFontSize(\'8\');\n var detailsHeight = displayInvoice(doc, invoice, marginLeft2, z-25, layout) + 75;\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));\n\n y=z+60;\n x = GlobalY + 100;\n doc.setFontType(\'bold\');\n\n doc.setFontSize(12);\n doc.setFontType(\'bold\');\n SetPdfColor(\'Black\',doc);\n displayInvoiceHeader(doc, invoice, layout);\n\n var y = displayInvoiceItems(doc, invoice, layout);\n doc.setLineWidth(0.3);\n displayNotesAndTerms(doc, layout, invoice, y);\n y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n\n doc.setFontType(\'bold\');\n\n doc.setFontSize(12);\n x += doc.internal.getFontSize()*4;\n Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());\n\n doc.text(TmpMsgX, y, Msg);\n\n //SetPdfColor(\'LightBlue\',doc);\n AmountText = formatMoney(invoice.balance_amount , currencyId);\n headerLeft=layout.headerRight+400;\n var AmountX = headerLeft - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());\n SetPdfColor(\'SomeGreen\', doc, \'secondary\');\n doc.text(AmountX, y, AmountText);','{\n \"content\": [\n {\n \"columns\": [\n {\n \"width\": 380,\n \"stack\": [\n {\"text\":\"$yourInvoiceLabelUC\", \"style\": \"yourInvoice\"},\n \"$clientDetails\"\n ],\n \"margin\": [60, 100, 0, 10]\n },\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 0,\n \"y\": 0,\n \"w\": 225,\n \"h\": \"$invoiceDetailsHeight\",\n \"r\":0,\n \"lineWidth\": 1,\n \"color\": \"$primaryColor:#36a498\"\n }\n ],\n \"width\":10,\n \"margin\":[-10,100,0,10]\n },\n {\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [0, 110, 0, 0]\n }\n ]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:14\",\n \"paddingBottom\": \"$amount:14\"\n }\n },\n {\n \"columns\": [\n {\n \"width\": 46,\n \"text\": \" \"\n },\n \"$notesAndTerms\",\n {\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\":\n [\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 600, \"y2\": 0,\"lineWidth\": 100,\"lineColor\":\"$secondaryColor:#292526\"}]},\n {\n \"columns\":\n [\n {\n \"text\": \"$invoiceFooter\",\n \"margin\": [40, -40, 40, 0],\n \"alignment\": \"left\",\n \"color\": \"#FFFFFF\"\n }\n ]\n }\n ],\n \"header\": [\n {\n \"canvas\": [\n {\n \"type\": \"line\",\n \"x1\": 0,\n \"y1\": 0,\n \"x2\": 600,\n \"y2\": 0,\n \"lineWidth\": 200,\n \"lineColor\": \"$secondaryColor:#292526\"\n }\n ],\n \"width\": 10\n },\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 60],\n \"margin\": [30, 16, 0, 0]\n },\n {\n \"stack\": \"$accountDetails\",\n \"margin\": [\n 0,\n 16,\n 0,\n 0\n ],\n \"width\": 140\n },\n {\n \"stack\": \"$accountAddress\",\n \"margin\": [\n 20,\n 16,\n 0,\n 0\n ]\n }\n ]\n }\n ],\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#36a498\"\n },\n \"accountName\": {\n \"bold\": true,\n \"margin\": [4, 2, 4, 1],\n \"color\": \"$primaryColor:#36a498\"\n },\n \"accountDetails\": {\n \"margin\": [4, 2, 4, 1],\n \"color\": \"#FFFFFF\"\n },\n \"accountAddress\": {\n \"margin\": [4, 2, 4, 1],\n \"color\": \"#FFFFFF\"\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"odd\": {\n \"fillColor\": \"#ebebeb\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#36a498\",\n \"bold\": true\n },\n \"invoiceDetails\": {\n \"color\": \"#ffffff\"\n },\n \"invoiceNumber\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"fontSize\": 12,\n \"bold\": true\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\",\n \"margin\": [0, 0, 40, 0]\n },\n \"firstColumn\": {\n \"margin\": [40, 0, 0, 0]\n },\n \"lastColumn\": {\n \"margin\": [0, 0, 40, 0]\n },\n \"productKey\": {\n \"color\": \"$primaryColor:#36a498\",\n \"bold\": true\n },\n \"yourInvoice\": {\n \"font\": \"$headerFont\",\n \"bold\": true,\n \"fontSize\": 14,\n \"color\": \"$primaryColor:#36a498\",\n \"margin\": [0,0,0,8]\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 26, 0, 16]\n },\n \"clientName\": {\n \"bold\": true\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\",\n \"margin\": [0,0,40,0]\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [47, 0, 47, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [0, 80, 0, 40]\n }\n'),(3,'Modern',' var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 400;\n layout.rowHeight = 15;\n\n\n doc.setFontSize(7);\n\n // add header\n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setDrawColor(242,101,34);\n doc.setFillColor(242,101,34);\n } \n\n var x1 =0;\n var y1 = 0;\n var w2 = 595;\n var h2 = Math.max(110, getInvoiceDetailsHeight(invoice, layout) + 30);\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n SetPdfColor(\'White\',doc);\n\n //second column\n doc.setFontType(\'bold\');\n var name = invoice.account.name; \n if (name) {\n doc.setFontSize(\'30\');\n doc.setFontType(\'bold\');\n doc.text(40, 50, name);\n }\n\n if (invoice.image)\n {\n y=130;\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, y);\n }\n\n // add footer \n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setDrawColor(242,101,34);\n doc.setFillColor(242,101,34);\n } \n\n var x1 = 0;//tableLeft-tablePadding ;\n var y1 = 750;\n var w2 = 596;\n var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n if (!invoice.is_pro && logoImages.imageLogo3)\n {\n pageHeight=820;\n // var left = 25;//250;//headerRight ;\n y=pageHeight-logoImages.imageLogoHeight3;\n //var headerRight=370;\n\n //var left = headerRight - invoice.imageLogoWidth3;\n doc.addImage(logoImages.imageLogo3, \'JPEG\', 40, y, logoImages.imageLogoWidth3, logoImages.imageLogoHeight3);\n }\n\n doc.setFontSize(10); \n var marginLeft = 340;\n displayAccount(doc, invoice, marginLeft, 780, layout);\n\n\n SetPdfColor(\'White\',doc); \n doc.setFontSize(\'8\');\n var detailsHeight = displayInvoice(doc, invoice, layout.headerRight, layout.accountTop-10, layout);\n layout.headerTop = Math.max(layout.headerTop, detailsHeight + 50);\n layout.tableTop = Math.max(layout.tableTop, detailsHeight + 150);\n\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontSize(7);\n doc.setFontType(\'normal\');\n displayClient(doc, invoice, layout.headerRight, layout.headerTop, layout);\n\n\n \n SetPdfColor(\'White\',doc); \n doc.setFontType(\'bold\');\n\n doc.setLineWidth(0.3);\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n setDocHexDraw(doc, NINJA.secondaryColor);\n } else {\n doc.setDrawColor(63,60,60);\n doc.setFillColor(63,60,60);\n } \n\n var left = layout.marginLeft - layout.tablePadding;\n var top = layout.tableTop - layout.tablePadding;\n var width = layout.marginRight - (2 * layout.tablePadding);\n var height = 20;\n doc.rect(left, top, width, height, \'FD\');\n \n\n displayInvoiceHeader(doc, invoice, layout);\n SetPdfColor(\'Black\',doc);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n\n var height1 = displayNotesAndTerms(doc, layout, invoice, y);\n var height2 = displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n y += Math.max(height1, height2);\n\n\n var left = layout.marginLeft - layout.tablePadding;\n var top = y - layout.tablePadding;\n var width = layout.marginRight - (2 * layout.tablePadding);\n var height = 20;\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n setDocHexDraw(doc, NINJA.secondaryColor);\n } else {\n doc.setDrawColor(63,60,60);\n doc.setFillColor(63,60,60);\n } \n doc.rect(left, top, width, height, \'FD\');\n \n doc.setFontType(\'bold\');\n SetPdfColor(\'White\', doc);\n doc.setFontSize(12);\n \n var label = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var labelX = layout.unitCostRight-(doc.getStringUnitWidth(label) * doc.internal.getFontSize());\n doc.text(labelX, y+2, label);\n\n\n doc.setFontType(\'normal\');\n var amount = formatMoney(invoice.balance_amount , currencyId);\n headerLeft=layout.headerRight+400;\n var amountX = layout.lineTotalRight - (doc.getStringUnitWidth(amount) * doc.internal.getFontSize());\n doc.text(amountX, y+2, amount);','{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"margin\": [0, 60, 0, 30]\n },\n {\n \"stack\": \"$clientDetails\",\n \"margin\": [0, 60, 0, 0]\n }\n ]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$notFirstAndLastColumn:.5\",\n \"hLineColor\": \"#888888\",\n \"vLineColor\": \"#FFFFFF\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:8\",\n \"paddingBottom\": \"$amount:8\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"columns\": [\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 0,\n \"y\": 0,\n \"w\": 515,\n \"h\": 26,\n \"r\": 0,\n \"lineWidth\": 1,\n \"color\": \"$secondaryColor:#403d3d\"\n }\n ],\n \"width\": 10,\n \"margin\": [\n 0,\n 10,\n 0,\n 0\n ]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\",\n \"margin\": [0, 16, 0, 0],\n \"width\": 370\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\",\n \"margin\": [0, 16, 8, 0]\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": [\n {\n \"canvas\": [\n {\n \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 600, \"y2\": 0,\"lineWidth\": 100,\"lineColor\":\"$primaryColor:#f26621\"\n }]\n ,\"width\":10\n },\n {\n \"columns\": [\n {\n \"width\": 350,\n \"stack\": [\n {\n \"text\": \"$invoiceFooter\",\n \"margin\": [40, -40, 40, 0],\n \"alignment\": \"left\",\n \"color\": \"#FFFFFF\"\n\n }\n ]\n },\n {\n \"stack\": \"$accountDetails\",\n \"margin\": [0, -40, 0, 0],\n \"width\": \"*\"\n },\n {\n \"stack\": \"$accountAddress\",\n \"margin\": [0, -40, 0, 0],\n \"width\": \"*\"\n }\n ]\n }\n ],\n \"header\": [\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 600, \"y2\": 0,\"lineWidth\": 200,\"lineColor\":\"$primaryColor:#f26621\"}],\"width\":10\n },\n {\n \"columns\": [\n {\n \"text\": \"$accountName\", \"bold\": true,\"font\":\"$headerFont\",\"fontSize\":30,\"color\":\"#ffffff\",\"margin\":[40,20,0,0],\"width\":350\n }\n ]\n },\n {\n \"width\": 300,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [400, -40, 0, 0]\n }\n ],\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountName\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountDetails\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"#FFFFFF\"\n },\n \"accountAddress\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"#FFFFFF\"\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 4, 2]\n },\n \"invoiceDetails\": {\n \"color\": \"#FFFFFF\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"productKey\": {\n \"bold\": true\n },\n \"clientName\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"#FFFFFF\",\n \"fontSize\": \"$fontSizeLargest\",\n \"fillColor\": \"$secondaryColor:#403d3d\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"alignment\":\"right\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"bold\": true,\n \"alignment\":\"right\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"invoiceNumberLabel\": {\n \"bold\": true\n },\n \"invoiceNumber\": {\n \"bold\": true\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [7, 0, 7, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [40, 120, 40, 50]\n}\n'),(4,'Plain',' var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id; \n \n layout.accountTop += 25;\n layout.headerTop += 25;\n layout.tableTop += 25;\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', left, 50);\n } \n \n /* table header */\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n \n var detailsHeight = getInvoiceDetailsHeight(invoice, layout);\n var left = layout.headerLeft - layout.tablePadding;\n var top = layout.headerTop + detailsHeight - layout.rowHeight - layout.tablePadding;\n var width = layout.headerRight - layout.headerLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 1;\n doc.rect(left, top, width, height, \'FD\'); \n\n doc.setFontSize(10);\n doc.setFontType(\'normal\');\n\n displayAccount(doc, invoice, layout.marginLeft, layout.accountTop, layout);\n displayClient(doc, invoice, layout.marginLeft, layout.headerTop, layout);\n\n displayInvoice(doc, invoice, layout.headerLeft, layout.headerTop, layout, layout.headerRight);\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));\n\n var headerY = layout.headerTop;\n var total = 0;\n\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n var left = layout.marginLeft - layout.tablePadding;\n var top = layout.tableTop - layout.tablePadding;\n var width = layout.headerRight - layout.marginLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 2;\n doc.rect(left, top, width, height, \'FD\'); \n\n displayInvoiceHeader(doc, invoice, layout);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n doc.setFontSize(10);\n\n displayNotesAndTerms(doc, layout, invoice, y+20);\n\n y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;\n\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n \n var left = layout.footerLeft - layout.tablePadding;\n var top = y - layout.tablePadding;\n var width = layout.headerRight - layout.footerLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 2;\n doc.rect(left, top, width, height, \'FD\'); \n \n doc.setFontType(\'bold\');\n doc.text(layout.footerLeft, y, invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due);\n\n total = formatMoney(invoice.balance_amount, currencyId);\n var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());\n doc.text(totalX, y, total); \n\n if (!invoice.is_pro) {\n doc.setFontType(\'normal\');\n doc.text(layout.marginLeft, 790, \'Created by InvoiceNinja.com\');\n }','{\n \"content\": [\n {\n \"columns\": [\n {\n \"stack\": \"$accountDetails\"\n },\n {\n \"stack\": \"$accountAddress\"\n },\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n }\n ] \n ]},\n {\n \"columns\": [\n {\n \"width\": 340,\n \"stack\": \"$clientDetails\",\n \"margin\": [0,40,0,0]\n },\n {\n \"width\":200,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#E6E6E6\",\n \"paddingLeft\": \"$amount:10\", \n \"paddingRight\": \"$amount:10\"\n }\n }\n ]\n }, \n {\n \"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 25,\"r\":0, \"lineWidth\": 1,\"color\":\"#e6e6e6\"}],\"width\":10,\"margin\":[0,30,0,-43]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:1\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#e6e6e6\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\" \n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"width\": 160,\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [60, 60],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:10\", \n \"paddingRight\": \"$amount:10\", \n \"paddingTop\": \"$amount:4\", \n \"paddingBottom\": \"$amount:4\" \n }\n }\n ]\n }, \n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\",\n \"margin\": [0, 0, 0, 12]\n\n }\n ],\n \"margin\": [40, -20, 40, 40]\n },\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"tableHeader\": {\n \"bold\": true\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"invoiceLineItemsTable\": {\n \"margin\": [0, 16, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"terms\": {\n \"margin\": [0, 0, 20, 0]\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"invoiceDetailBalanceDue\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"subtotalsBalanceDue\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [7, 0, 7, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [40, 40, 40, 60]\n}\n'),(5,'Business',NULL,'{\n \"content\": [\n {\n \"columns\":\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\n \"width\": 300,\n \"stack\": \"$accountDetails\",\n \"margin\": [140, 0, 0, 0]\n },\n {\n \"width\": 150,\n \"stack\": \"$accountAddress\"\n }\n ]\n },\n {\n \"columns\": [\n {\n \"width\": 120,\n \"stack\": [\n {\"text\": \"$invoiceIssuedToLabel\", \"style\":\"issuedTo\"},\n \"$clientDetails\"\n ],\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"canvas\": [{ \"type\": \"rect\", \"x\": 20, \"y\": 0, \"w\": 174, \"h\": \"$invoiceDetailsHeight\",\"r\":10, \"lineWidth\": 1,\"color\":\"$primaryColor:#eb792d\"}],\n \"width\":30,\n \"margin\":[200,25,0,0]\n },\n {\n \"table\": {\n \"widths\": [70, 76],\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [200, 34, 0, 0]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 32,\"r\":8, \"lineWidth\": 1,\"color\":\"$secondaryColor:#374e6b\"}],\"width\":10,\"margin\":[0,20,0,-45]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:1\",\n \"vLineWidth\": \"$notFirst:.5\",\n \"hLineColor\": \"#FFFFFF\",\n \"vLineColor\": \"#FFFFFF\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:12\",\n \"paddingBottom\": \"$amount:12\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"stack\": [\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n },\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 60,\n \"y\": 20,\n \"w\": 198,\n \"h\": 30,\n \"r\": 7,\n \"lineWidth\": 1,\n \"color\": \"$secondaryColor:#374e6b\"\n }\n ]\n },\n {\n \"style\": \"subtotalsBalance\",\n \"table\": {\n \"widths\": [\"*\", \"45%\"],\n \"body\": \"$subtotalsBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountName\": {\n \"bold\": true\n },\n \"accountDetails\": {\n \"color\": \"#AAA9A9\",\n \"margin\": [0,2,0,1]\n },\n \"accountAddress\": {\n \"color\": \"#AAA9A9\",\n \"margin\": [0,2,0,1]\n },\n \"even\": {\n \"fillColor\":\"#E8E8E8\"\n },\n \"odd\": {\n \"fillColor\":\"#F7F7F7\"\n },\n \"productKey\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"#ffffff\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true,\n \"color\":\"#ffffff\",\n \"alignment\":\"right\",\n \"noWrap\":true\n },\n \"invoiceDetails\": {\n \"color\": \"#ffffff\"\n },\n \"tableHeader\": {\n \"color\": \"#ffffff\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"secondTableHeader\": {\n \"color\": \"$secondaryColor:#374e6b\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"issuedTo\": {\n \"margin\": [0,2,0,1],\n \"bold\": true,\n \"color\": \"#374e6b\"\n },\n \"clientDetails\": {\n \"margin\": [0,2,0,1]\n },\n \"clientName\": {\n \"color\": \"$primaryColor:#eb792d\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 10, 0, 10]\n },\n \"invoiceDetailsValue\": {\n \"alignment\": \"right\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"subtotalsBalance\": {\n \"alignment\": \"right\",\n \"margin\": [0, -25, 0, 0]\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(6,'Creative',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"stack\": \"$clientDetails\"\n },\n {\n \"stack\": \"$accountDetails\"\n },\n {\n \"stack\": \"$accountAddress\"\n },\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"alignment\": \"right\"\n }\n ],\n \"margin\": [0, 0, 0, 20]\n },\n {\n \"columns\": [\n {\"text\":\n [\n {\"text\": \"$entityTypeUC\", \"style\": \"header1\"},\n {\"text\": \" #\", \"style\": \"header2\"},\n {\"text\": \"$invoiceNumber\", \"style\":\"header2\"}\n ],\n \"width\": \"*\"\n },\n {\n \"width\":200,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [16, 4, 0, 0]\n }\n ],\n \"margin\": [0, 0, 0, 20]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 3,\"lineColor\":\"$primaryColor:#AE1E54\"}]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"$primaryColor:#E8E8E8\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:8\",\n \"paddingBottom\": \"$amount:8\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 3,\"lineColor\":\"$primaryColor:#AE1E54\"}],\n \"margin\": [0, -8, 0, -8]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\"\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\"\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"accountName\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"$primaryColor:#AE1E54\",\n \"bold\": true\n },\n \"accountDetails\": {\n \"margin\": [4, 2, 4, 2]\n },\n \"accountAddress\": {\n \"margin\": [4, 2, 4, 2]\n },\n \"odd\": {\n \"fillColor\":\"#F4F4F4\"\n },\n \"productKey\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"margin\": [320,20,0,0]\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#AE1E54\",\n \"bold\": true,\n \"margin\":[0,-10,10,0],\n \"alignment\": \"right\"\n },\n \"invoiceDetailBalanceDue\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#AE1E54\",\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"clientName\": {\n \"bold\": true\n },\n \"clientDetails\": {\n \"margin\": [0,2,0,1]\n },\n \"header1\": {\n \"bold\": true,\n \"margin\": [0, 30, 0, 16],\n \"fontSize\": 42\n },\n \"header2\": {\n \"margin\": [0, 30, 0, 16],\n \"fontSize\": 42,\n \"italics\": true,\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 4, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(7,'Elegant',NULL,'{\n \"content\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"alignment\": \"center\",\n \"margin\": [0, 0, 0, 30]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 2}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 3, \"x2\": 515, \"y2\": 3, \"lineWidth\": 1}]},\n {\n \"columns\": [\n {\n \"width\": 120,\n \"stack\": [\n {\"text\": \"$invoiceToLabel\", \"style\": \"header\", \"margin\": [0, 0, 0, 6]},\n \"$clientDetails\"\n ]\n },\n {\n \"width\": 10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": -2, \"y1\": 18, \"x2\": -2, \"y2\": 80, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"width\": 120,\n \"stack\": \"$accountDetails\",\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"width\": 110,\n \"stack\": \"$accountAddress\",\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"stack\": [\n {\"text\": \"$detailsLabel\", \"style\": \"header\", \"margin\": [0, 0, 0, 6]},\n {\n \"width\":180,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\"\n }\n ]\n }],\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:12\",\n \"paddingBottom\": \"$amount:12\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 270, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\"\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\"\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 270, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }],\n \"footer\": [\n {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 35, \"y1\": 5, \"x2\": 555, \"y2\": 5, \"lineWidth\": 2,\"margin\": [30,0,0,0]}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 35, \"y1\": 3, \"x2\": 555, \"y2\": 3, \"lineWidth\": 1,\"margin\": [30,0,0,0]}]}\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientName\": {\n \"bold\": true\n },\n \"accountName\": {\n \"bold\": true\n },\n \"odd\": {\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#5a7b61\",\n \"margin\": [320,20,0,0]\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#5a7b61\",\n \"style\": true,\n \"margin\":[0,-14,8,0],\n \"alignment\":\"right\"\n },\n \"invoiceDetailBalanceDue\": {\n \"color\": \"$primaryColor:#5a7b61\",\n \"bold\": true\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"header\": {\n \"fontSize\": 14,\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#5a7b61\",\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 40, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"header\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(8,'Hipster',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"width\":10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 0, \"y2\": 75, \"lineWidth\": 0.5}]\n },\n {\n \"width\":120,\n \"stack\": [\n {\"text\": \"$fromLabelUC\", \"style\": \"fromLabel\"}, \n \"$accountDetails\" \n ]\n },\n {\n \"width\":120,\n \"stack\": [\n {\"text\": \" \"},\n \"$accountAddress\"\n ],\n \"margin\": [10, 0, 0, 16]\n },\n {\n \"width\":10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 0, \"y2\": 75, \"lineWidth\": 0.5}]\n },\n {\n \"stack\": [\n {\"text\": \"$toLabelUC\", \"style\": \"toLabel\"}, \n \"$clientDetails\"\n ]\n },\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n }\n ]\n ]\n },\n {\n \"text\": \"$entityTypeUC\",\n \"margin\": [0, 4, 0, 8],\n \"bold\": \"true\",\n \"fontSize\": 42\n },\n {\n \"columnGap\": 16,\n \"columns\": [\n {\n \"width\":\"auto\",\n \"text\": [\"$invoiceNoLabel\",\" \",\"$invoiceNumberValue\"],\n \"bold\": true,\n \"color\":\"$primaryColor:#bc9f2b\",\n \"fontSize\":10\n },\n {\n \"width\":\"auto\",\n \"text\": [\"$invoiceDateLabel\",\" \",\"$invoiceDateValue\"],\n \"fontSize\":10\n },\n {\n \"width\":\"auto\",\n \"text\": [\"$dueDateLabel?\",\" \",\"$dueDateValue\"],\n \"fontSize\":10\n },\n {\n \"width\":\"*\",\n \"text\": [\"$balanceDueLabel\",\" \",{\"text\":\"$balanceDue\", \"bold\":true, \"color\":\"$primaryColor:#bc9f2b\"}],\n \"fontSize\":10\n }\n ]\n },\n {\n \"margin\": [0, 26, 0, 0],\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$amount:.5\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\" \n }\n },\n {\n \"columns\": [\n {\n \"stack\": \"$notesAndTerms\",\n \"width\": \"*\",\n \"margin\": [0, 12, 0, 0]\n },\n {\n \"width\": 200,\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"36%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$notFirst:.5\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:12\", \n \"paddingBottom\": \"$amount:4\" \n }\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountName\": {\n \"bold\": true\n },\n \"clientName\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"fromLabel\": {\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true \n },\n \"toLabel\": {\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true \n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 16, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(9,'Playful',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 190, \"h\": \"$invoiceDetailsHeight\",\"r\":5, \"lineWidth\": 1,\"color\":\"$primaryColor:#009d91\"}],\"width\":10,\"margin\":[200,0,0,0]},\n {\n \"width\":400,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [210, 10, 10, 0]\n }\n ] \n },\n {\n \"margin\": [0, 18, 0, 0],\n \"columnGap\": 50,\n \"columns\": [\n {\n \"width\": 212,\n \"stack\": [\n {\"text\": \"$invoiceToLabel:\", \"style\": \"toLabel\"},\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 4, \"x2\": 150, \"y2\": 4, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}],\n \"margin\": [0, 0, 0, 4]\n },\n \"$clientDetails\",\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 9, \"x2\": 150, \"y2\": 9, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}]}\n ]\n },\n {\n \"width\": \"*\",\n \"stack\": [\n {\"text\": \"$fromLabel:\", \"style\": \"fromLabel\"},\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 4, \"x2\": 250, \"y2\": 4, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}],\n \"margin\": [0, 0, 0, 4]\n },\n {\"columns\":[\n \"$accountDetails\",\n \"$accountAddress\" \n ], \"columnGap\": 4}, \n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 9, \"x2\": 250, \"y2\": 9, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}]}\n ]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 35,\"r\":6, \"lineWidth\": 1,\"color\":\"$primaryColor:#009d91\"}],\"width\":10,\"margin\":[0,30,0,-30]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"$primaryColor:#009d91\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\"\n }\n }, \n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"stack\": [\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n },\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 76,\n \"y\": 20,\n \"w\": 182,\n \"h\": 30,\n \"r\": 4,\n \"lineWidth\": 1,\n \"color\": \"$primaryColor:#009d91\"\n }\n ]\n },\n {\n \"style\": \"subtotalsBalance\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n }\n ]\n }, \n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n], \n \"footer\": [\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 38, \"x2\": 68, \"y2\": 38, \"lineWidth\": 6,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 68, \"y1\": 0, \"x2\": 135, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#1d766f\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 135, \"y1\": 0, \"x2\": 201, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 201, \"y1\": 0, \"x2\": 267, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#bf9730\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 267, \"y1\": 0, \"x2\": 333, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ac2b50\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 333, \"y1\": 0, \"x2\": 399, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#e60042\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 399, \"y1\": 0, \"x2\": 465, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 465, \"y1\": 0, \"x2\": 532, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 532, \"y1\": 0, \"x2\": 600, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ac2b50\"}]},\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\",\n \"margin\": [40, -60, 40, 0]\n }\n ],\n \"header\": [\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 68, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 68, \"y1\": 0, \"x2\": 135, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#1d766f\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 135, \"y1\": 0, \"x2\": 201, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 201, \"y1\": 0, \"x2\": 267, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#bf9730\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 267, \"y1\": 0, \"x2\": 333, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ac2b50\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 333, \"y1\": 0, \"x2\": 399, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#e60042\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 399, \"y1\": 0, \"x2\": 465, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 465, \"y1\": 0, \"x2\": 532, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 532, \"y1\": 0, \"x2\": 600, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ac2b50\"}]}\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountName\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientName\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"even\": {\n \"fillColor\":\"#E8E8E8\"\n },\n \"odd\": {\n \"fillColor\":\"#F7F7F7\"\n },\n \"productKey\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"lineTotal\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"#FFFFFF\"\n },\n \"secondTableHeader\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true,\n \"color\":\"#FFFFFF\",\n \"alignment\":\"right\"\n },\n \"invoiceDetails\": {\n \"color\": \"#FFFFFF\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"bold\": true\n },\n \"invoiceDetailBalanceDue\": {\n \"bold\": true\n },\n \"fromLabel\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"toLabel\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"subtotalsBalance\": {\n \"alignment\": \"right\",\n \"margin\": [0, -25, 0, 0]\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(10,'Photo',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\n \"text\": \"\",\n \"width\": \"*\"\n },\n {\n \"width\":180,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\"\n }]\n },\n {\n \"image\": \"data:image/jpeg;base64,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\",\n \"margin\": [-40, 16, 0, 0],\n \"width\": 595\n },\n {\n \"margin\": [-20, -150, 0, 0],\n \"columnGap\": 8,\n \"columns\": [\n {\n \"width\": \"auto\",\n \"text\": \"$toLabel:\",\n \"style\": \"bold\",\n \"color\":\"#cd5138\"\n },\n {\n \"width\": \"*\",\n \"stack\": \"$clientDetails\",\n \"margin\": [4, 0, 0, 0]\n }\n ]\n },\n {\n \"margin\": [-20, 10, 0, 140],\n \"columnGap\": 8,\n \"columns\": [\n {\n \"width\": \"auto\",\n \"text\": \"$fromLabel:\",\n \"style\": \"bold\",\n \"color\":\"#cd5138\"\n },\n {\n \"width\": \"*\",\n \"stack\": [\n {\n \"width\": 150,\n \"stack\": \"$accountDetails\"\n },\n {\n \"width\": 150,\n \"stack\": \"$accountAddress\"\n }\n ]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 1.5}],\"margin\":[0,0,0,-30]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#000000\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:10\", \n \"paddingBottom\": \"$amount:10\" \n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"alignment\": \"right\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:4\", \n \"paddingBottom\": \"$amount:4\" \n }\n }]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"styles\": {\n \"accountDetails\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"accountAddress\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"clientDetails\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"productKey\": {\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"lineTotal\": {\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 30, 40, 30]\n}\n'),(11,'Custom1',NULL,NULL),(12,'Custom2',NULL,NULL),(13,'Custom3',NULL,NULL); +INSERT INTO `invoice_designs` VALUES (1,'Clean','var GlobalY=0;//Y position of line at current page\n\n var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 550;\n layout.rowHeight = 15;\n\n doc.setFontSize(9);\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, 30);\n }\n \n if (!invoice.is_pro && logoImages.imageLogo1)\n {\n pageHeight=820;\n y=pageHeight-logoImages.imageLogoHeight1;\n doc.addImage(logoImages.imageLogo1, \'JPEG\', layout.marginLeft, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);\n }\n\n doc.setFontSize(9);\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n displayAccount(doc, invoice, 220, layout.accountTop, layout);\n\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n doc.setFontSize(\'11\');\n doc.text(50, layout.headerTop, (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase());\n\n\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontSize(9);\n\n var invoiceHeight = displayInvoice(doc, invoice, 50, 170, layout);\n var clientHeight = displayClient(doc, invoice, 220, 170, layout);\n var detailsHeight = Math.max(invoiceHeight, clientHeight);\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (3 * layout.rowHeight));\n \n doc.setLineWidth(0.3); \n doc.setDrawColor(200,200,200);\n doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + 6, layout.marginRight + layout.tablePadding, layout.headerTop + 6);\n doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + detailsHeight + 14, layout.marginRight + layout.tablePadding, layout.headerTop + detailsHeight + 14);\n\n doc.setFontSize(10);\n doc.setFontType(\'bold\');\n displayInvoiceHeader(doc, invoice, layout);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n doc.setFontSize(9);\n doc.setFontType(\'bold\');\n\n GlobalY=GlobalY+25;\n\n\n doc.setLineWidth(0.3);\n doc.setDrawColor(241,241,241);\n doc.setFillColor(241,241,241);\n var x1 = layout.marginLeft - 12;\n var y1 = GlobalY-layout.tablePadding;\n\n var w2 = 510 + 24;\n var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;\n\n if (invoice.discount) {\n h2 += doc.internal.getFontSize()*2;\n }\n if (invoice.tax_amount) {\n h2 += doc.internal.getFontSize()*2;\n }\n\n //doc.rect(x1, y1, w2, h2, \'FD\');\n\n doc.setFontSize(9);\n displayNotesAndTerms(doc, layout, invoice, y);\n y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n\n\n doc.setFontSize(10);\n Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());\n \n doc.text(TmpMsgX, y, Msg);\n\n SetPdfColor(\'LightBlue\', doc, \'primary\');\n AmountText = formatMoney(invoice.balance_amount, currencyId);\n headerLeft=layout.headerRight+400;\n var AmountX = layout.lineTotalRight - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());\n doc.text(AmountX, y, AmountText);','{ \n \"content\":[ \n { \n \"columns\":[ \n { \n \"image\":\"$accountLogo\",\n \"fit\":[ \n 120,\n 80\n ]\n },\n { \n \"stack\":\"$accountDetails\",\n \"margin\":[ \n 7,\n 0,\n 0,\n 0\n ]\n },\n { \n \"stack\":\"$accountAddress\"\n }\n ]\n },\n { \n \"text\":\"$entityTypeUC\",\n \"margin\":[ \n 8,\n 30,\n 8,\n 5\n ],\n \"style\":\"entityTypeLabel\"\n },\n { \n \"table\":{ \n \"headerRows\":1,\n \"widths\":[ \n \"auto\",\n \"auto\",\n \"*\"\n ],\n \"body\":[ \n [ \n { \n \"table\":{ \n \"body\":\"$invoiceDetails\"\n },\n \"margin\":[ \n 0,\n 0,\n 12,\n 0\n ],\n \"layout\":\"noBorders\"\n },\n { \n \"stack\":\"$clientDetails\"\n },\n { \n \"text\":\"\"\n }\n ]\n ]\n },\n \"layout\":{ \n \"hLineWidth\":\"$firstAndLast:.5\",\n \"vLineWidth\":\"$none\",\n \"hLineColor\":\"#D8D8D8\",\n \"paddingLeft\":\"$amount:8\",\n \"paddingRight\":\"$amount:8\",\n \"paddingTop\":\"$amount:6\",\n \"paddingBottom\":\"$amount:6\"\n }\n },\n { \n \"style\":\"invoiceLineItemsTable\",\n \"table\":{ \n \"headerRows\":1,\n \"widths\":\"$invoiceLineItemColumns\",\n \"body\":\"$invoiceLineItems\"\n },\n \"layout\":{ \n \"hLineWidth\":\"$notFirst:.5\",\n \"vLineWidth\":\"$none\",\n \"hLineColor\":\"#D8D8D8\",\n \"paddingLeft\":\"$amount:8\",\n \"paddingRight\":\"$amount:8\",\n \"paddingTop\":\"$amount:14\",\n \"paddingBottom\":\"$amount:14\"\n }\n },\n { \n \"columns\":[ \n \"$notesAndTerms\",\n { \n \"table\":{ \n \"widths\":[ \n \"*\",\n \"40%\"\n ],\n \"body\":\"$subtotals\"\n },\n \"layout\":{ \n \"hLineWidth\":\"$none\",\n \"vLineWidth\":\"$none\",\n \"paddingLeft\":\"$amount:34\",\n \"paddingRight\":\"$amount:8\",\n \"paddingTop\":\"$amount:4\",\n \"paddingBottom\":\"$amount:4\"\n }\n }\n ]\n },\n { \n \"stack\":[ \n \"$invoiceDocuments\"\n ],\n \"style\":\"invoiceDocuments\"\n }\n ],\n \"defaultStyle\":{ \n \"font\":\"$bodyFont\",\n \"fontSize\":\"$fontSize\",\n \"margin\":[ \n 8,\n 4,\n 8,\n 4\n ]\n },\n \"footer\":{ \n \"columns\":[ \n { \n \"text\":\"$invoiceFooter\",\n \"alignment\":\"left\"\n }\n ],\n \"margin\":[ \n 40,\n -20,\n 40,\n 0\n ]\n },\n \"styles\":{ \n \"entityTypeLabel\":{ \n \"font\":\"$headerFont\",\n \"fontSize\":\"$fontSizeLargest\",\n \"color\":\"$primaryColor:#37a3c6\"\n },\n \"primaryColor\":{ \n \"color\":\"$primaryColor:#37a3c6\"\n },\n \"accountName\":{ \n \"color\":\"$primaryColor:#37a3c6\",\n \"bold\":true\n },\n \"invoiceDetails\":{ \n \"margin\":[ \n 0,\n 0,\n 8,\n 0\n ]\n },\n \"accountDetails\":{ \n \"margin\":[ \n 0,\n 2,\n 0,\n 2\n ]\n },\n \"clientDetails\":{ \n \"margin\":[ \n 0,\n 2,\n 0,\n 2\n ]\n },\n \"notesAndTerms\":{ \n \"margin\":[ \n 0,\n 2,\n 0,\n 2\n ]\n },\n \"accountAddress\":{ \n \"margin\":[ \n 0,\n 2,\n 0,\n 2\n ]\n },\n \"odd\":{ \n \"fillColor\":\"#fbfbfb\"\n },\n \"productKey\":{ \n \"color\":\"$primaryColor:#37a3c6\",\n \"bold\":true\n },\n \"subtotalsBalanceDueLabel\":{ \n \"fontSize\":\"$fontSizeLarger\"\n },\n \"subtotalsBalanceDue\":{ \n \"fontSize\":\"$fontSizeLarger\",\n \"color\":\"$primaryColor:#37a3c6\"\n },\n \"invoiceNumber\":{ \n \"bold\":true\n },\n \"tableHeader\":{ \n \"bold\":true,\n \"fontSize\":\"$fontSizeLarger\"\n },\n \"costTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"qtyTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"taxTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"lineTotalTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"invoiceLineItemsTable\":{ \n \"margin\":[ \n 0,\n 16,\n 0,\n 16\n ]\n },\n \"clientName\":{ \n \"bold\":true\n },\n \"cost\":{ \n \"alignment\":\"right\"\n },\n \"quantity\":{ \n \"alignment\":\"right\"\n },\n \"tax\":{ \n \"alignment\":\"right\"\n },\n \"lineTotal\":{ \n \"alignment\":\"right\"\n },\n \"subtotals\":{ \n \"alignment\":\"right\"\n },\n \"termsLabel\":{ \n \"bold\":true\n },\n \"fullheader\":{ \n \"font\":\"$headerFont\",\n \"fontSize\":\"$fontSizeLargest\",\n \"bold\":true\n },\n \"subheader\":{ \n \"font\":\"$headerFont\",\n \"fontSize\":\"$fontSizeLarger\"\n },\n \"help\":{ \n \"fontSize\":\"$fontSizeSmaller\",\n \"color\":\"#737373\"\n },\n \"invoiceDocuments\":{ \n \"margin\":[ \n 7,\n 0,\n 7,\n 0\n ]\n },\n \"invoiceDocument\":{ \n \"margin\":[ \n 0,\n 10,\n 0,\n 10\n ]\n }\n },\n \"pageMargins\":[ \n 40,\n 40,\n 40,\n 60\n ]\n}\n'),(2,'Bold',' var GlobalY=0;//Y position of line at current page\n\n var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 150;\n layout.rowHeight = 15;\n layout.headerTop = 125;\n layout.tableTop = 300;\n\n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setFillColor(46,43,43);\n } \n\n var x1 =0;\n var y1 = 0;\n var w2 = 595;\n var h2 = 100;\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, 30);\n }\n\n doc.setLineWidth(0.5);\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setFillColor(46,43,43);\n doc.setDrawColor(46,43,43);\n } \n\n // return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour\n var x1 = 0;//tableLeft-tablePadding ;\n var y1 = 750;\n var w2 = 596;\n var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n if (!invoice.is_pro && logoImages.imageLogo2)\n {\n pageHeight=820;\n var left = 250;//headerRight ;\n y=pageHeight-logoImages.imageLogoHeight2;\n var headerRight=370;\n\n var left = headerRight - logoImages.imageLogoWidth2;\n doc.addImage(logoImages.imageLogo2, \'JPEG\', left, y, logoImages.imageLogoWidth2, logoImages.imageLogoHeight2);\n }\n\n doc.setFontSize(7);\n doc.setFontType(\'bold\');\n SetPdfColor(\'White\',doc);\n\n displayAccount(doc, invoice, 300, layout.accountTop, layout);\n\n\n var y = layout.accountTop;\n var left = layout.marginLeft;\n var headerY = layout.headerTop;\n\n SetPdfColor(\'GrayLogo\',doc); //set black color\n doc.setFontSize(7);\n\n //show left column\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontType(\'normal\');\n\n //publish filled box\n doc.setDrawColor(200,200,200);\n\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n } else {\n doc.setFillColor(54,164,152); \n } \n\n GlobalY=190;\n doc.setLineWidth(0.5);\n\n var BlockLenght=220;\n var x1 =595-BlockLenght;\n var y1 = GlobalY-12;\n var w2 = BlockLenght;\n var h2 = getInvoiceDetailsHeight(invoice, layout) + layout.tablePadding + 2;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n SetPdfColor(\'SomeGreen\', doc, \'secondary\');\n doc.setFontSize(\'14\');\n doc.setFontType(\'bold\');\n doc.text(50, GlobalY, (invoice.is_quote ? invoiceLabels.your_quote : invoiceLabels.your_invoice).toUpperCase());\n\n\n var z=GlobalY;\n z=z+30;\n\n doc.setFontSize(\'8\'); \n SetPdfColor(\'Black\',doc); \n var clientHeight = displayClient(doc, invoice, layout.marginLeft, z, layout);\n layout.tableTop += Math.max(0, clientHeight - 75);\n marginLeft2=395;\n\n //publish left side information\n SetPdfColor(\'White\',doc);\n doc.setFontSize(\'8\');\n var detailsHeight = displayInvoice(doc, invoice, marginLeft2, z-25, layout) + 75;\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));\n\n y=z+60;\n x = GlobalY + 100;\n doc.setFontType(\'bold\');\n\n doc.setFontSize(12);\n doc.setFontType(\'bold\');\n SetPdfColor(\'Black\',doc);\n displayInvoiceHeader(doc, invoice, layout);\n\n var y = displayInvoiceItems(doc, invoice, layout);\n doc.setLineWidth(0.3);\n displayNotesAndTerms(doc, layout, invoice, y);\n y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n\n doc.setFontType(\'bold\');\n\n doc.setFontSize(12);\n x += doc.internal.getFontSize()*4;\n Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());\n\n doc.text(TmpMsgX, y, Msg);\n\n //SetPdfColor(\'LightBlue\',doc);\n AmountText = formatMoney(invoice.balance_amount , currencyId);\n headerLeft=layout.headerRight+400;\n var AmountX = headerLeft - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());\n SetPdfColor(\'SomeGreen\', doc, \'secondary\');\n doc.text(AmountX, y, AmountText);','{ \n \"content\":[ \n { \n \"columns\":[ \n { \n \"width\":380,\n \"stack\":[ \n { \n \"text\":\"$yourInvoiceLabelUC\",\n \"style\":\"yourInvoice\"\n },\n \"$clientDetails\"\n ],\n \"margin\":[ \n 60,\n 100,\n 0,\n 10\n ]\n },\n { \n \"canvas\":[ \n { \n \"type\":\"rect\",\n \"x\":0,\n \"y\":0,\n \"w\":225,\n \"h\":\"$invoiceDetailsHeight\",\n \"r\":0,\n \"lineWidth\":1,\n \"color\":\"$primaryColor:#36a498\"\n }\n ],\n \"width\":10,\n \"margin\":[ \n -10,\n 100,\n 0,\n 10\n ]\n },\n { \n \"table\":{ \n \"body\":\"$invoiceDetails\"\n },\n \"layout\":\"noBorders\",\n \"margin\":[ \n 0,\n 110,\n 0,\n 0\n ]\n }\n ]\n },\n { \n \"style\":\"invoiceLineItemsTable\",\n \"table\":{ \n \"headerRows\":1,\n \"widths\":\"$invoiceLineItemColumns\",\n \"body\":\"$invoiceLineItems\"\n },\n \"layout\":{ \n \"hLineWidth\":\"$none\",\n \"vLineWidth\":\"$none\",\n \"paddingLeft\":\"$amount:8\",\n \"paddingRight\":\"$amount:8\",\n \"paddingTop\":\"$amount:14\",\n \"paddingBottom\":\"$amount:14\"\n }\n },\n { \n \"columns\":[ \n { \n \"width\":46,\n \"text\":\" \"\n },\n \"$notesAndTerms\",\n { \n \"table\":{ \n \"widths\":[ \n \"*\",\n \"40%\"\n ],\n \"body\":\"$subtotals\"\n },\n \"layout\":{ \n \"hLineWidth\":\"$none\",\n \"vLineWidth\":\"$none\",\n \"paddingLeft\":\"$amount:8\",\n \"paddingRight\":\"$amount:8\",\n \"paddingTop\":\"$amount:4\",\n \"paddingBottom\":\"$amount:4\"\n }\n }\n ]\n },\n { \n \"stack\":[ \n \"$invoiceDocuments\"\n ],\n \"style\":\"invoiceDocuments\"\n }\n ],\n \"footer\":[ \n { \n \"canvas\":[ \n { \n \"type\":\"line\",\n \"x1\":0,\n \"y1\":0,\n \"x2\":600,\n \"y2\":0,\n \"lineWidth\":100,\n \"lineColor\":\"$secondaryColor:#292526\"\n }\n ]\n },\n { \n \"columns\":[ \n { \n \"text\":\"$invoiceFooter\",\n \"margin\":[ \n 40,\n -40,\n 40,\n 0\n ],\n \"alignment\":\"left\",\n \"color\":\"#FFFFFF\"\n }\n ]\n }\n ],\n \"header\":[ \n { \n \"canvas\":[ \n { \n \"type\":\"line\",\n \"x1\":0,\n \"y1\":0,\n \"x2\":600,\n \"y2\":0,\n \"lineWidth\":200,\n \"lineColor\":\"$secondaryColor:#292526\"\n }\n ],\n \"width\":10\n },\n { \n \"columns\":[ \n { \n \"image\":\"$accountLogo\",\n \"fit\":[ \n 120,\n 60\n ],\n \"margin\":[ \n 30,\n 16,\n 0,\n 0\n ]\n },\n { \n \"stack\":\"$accountDetails\",\n \"margin\":[ \n 0,\n 16,\n 0,\n 0\n ],\n \"width\":140\n },\n { \n \"stack\":\"$accountAddress\",\n \"margin\":[ \n 20,\n 16,\n 0,\n 0\n ]\n }\n ]\n }\n ],\n \"defaultStyle\":{ \n \"font\":\"$bodyFont\",\n \"fontSize\":\"$fontSize\",\n \"margin\":[ \n 8,\n 4,\n 8,\n 4\n ]\n },\n \"styles\":{ \n \"primaryColor\":{ \n \"color\":\"$primaryColor:#36a498\"\n },\n \"accountName\":{ \n \"bold\":true,\n \"margin\":[ \n 4,\n 2,\n 4,\n 1\n ],\n \"color\":\"$primaryColor:#36a498\"\n },\n \"accountDetails\":{ \n \"margin\":[ \n 4,\n 2,\n 4,\n 1\n ],\n \"color\":\"#FFFFFF\"\n },\n \"accountAddress\":{ \n \"margin\":[ \n 4,\n 2,\n 4,\n 1\n ],\n \"color\":\"#FFFFFF\"\n },\n \"clientDetails\":{ \n \"margin\":[ \n 0,\n 2,\n 0,\n 1\n ]\n },\n \"odd\":{ \n \"fillColor\":\"#ebebeb\"\n },\n \"subtotalsBalanceDueLabel\":{ \n \"fontSize\":\"$fontSizeLargest\",\n \"bold\":true\n },\n \"subtotalsBalanceDue\":{ \n \"fontSize\":\"$fontSizeLargest\",\n \"color\":\"$primaryColor:#36a498\",\n \"bold\":true\n },\n \"invoiceDetails\":{ \n \"color\":\"#ffffff\"\n },\n \"invoiceNumber\":{ \n \"bold\":true\n },\n \"tableHeader\":{ \n \"fontSize\":12,\n \"bold\":true\n },\n \"costTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"qtyTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"taxTableHeader\":{ \n \"alignment\":\"right\"\n },\n \"lineTotalTableHeader\":{ \n \"alignment\":\"right\",\n \"margin\":[ \n 0,\n 0,\n 40,\n 0\n ]\n },\n \"firstColumn\":{ \n \"margin\":[ \n 40,\n 0,\n 0,\n 0\n ]\n },\n \"lastColumn\":{ \n \"margin\":[ \n 0,\n 0,\n 40,\n 0\n ]\n },\n \"productKey\":{ \n \"color\":\"$primaryColor:#36a498\",\n \"bold\":true\n },\n \"yourInvoice\":{ \n \"font\":\"$headerFont\",\n \"bold\":true,\n \"fontSize\":14,\n \"color\":\"$primaryColor:#36a498\",\n \"margin\":[ \n 0,\n 0,\n 0,\n 8\n ]\n },\n \"invoiceLineItemsTable\":{ \n \"margin\":[ \n 0,\n 26,\n 0,\n 16\n ]\n },\n \"clientName\":{ \n \"bold\":true\n },\n \"cost\":{ \n \"alignment\":\"right\"\n },\n \"quantity\":{ \n \"alignment\":\"right\"\n },\n \"tax\":{ \n \"alignment\":\"right\"\n },\n \"lineTotal\":{ \n \"alignment\":\"right\"\n },\n \"subtotals\":{ \n \"alignment\":\"right\",\n \"margin\":[ \n 0,\n 0,\n 40,\n 0\n ]\n },\n \"termsLabel\":{ \n \"bold\":true,\n \"margin\":[ \n 0,\n 0,\n 0,\n 4\n ]\n },\n \"fullheader\":{ \n \"font\":\"$headerFont\",\n \"fontSize\":\"$fontSizeLargest\",\n \"bold\":true\n },\n \"subheader\":{ \n \"font\":\"$headerFont\",\n \"fontSize\":\"$fontSizeLarger\"\n },\n \"help\":{ \n \"fontSize\":\"$fontSizeSmaller\",\n \"color\":\"#737373\"\n },\n \"invoiceDocuments\":{ \n \"margin\":[ \n 47,\n 0,\n 47,\n 0\n ]\n },\n \"invoiceDocument\":{ \n \"margin\":[ \n 0,\n 10,\n 0,\n 10\n ]\n }\n },\n \"pageMargins\":[ \n 0,\n 80,\n 0,\n 40\n ]\n}\n'),(3,'Modern',' var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id;\n\n layout.headerRight = 400;\n layout.rowHeight = 15;\n\n\n doc.setFontSize(7);\n\n // add header\n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setDrawColor(242,101,34);\n doc.setFillColor(242,101,34);\n } \n\n var x1 =0;\n var y1 = 0;\n var w2 = 595;\n var h2 = Math.max(110, getInvoiceDetailsHeight(invoice, layout) + 30);\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n SetPdfColor(\'White\',doc);\n\n //second column\n doc.setFontType(\'bold\');\n var name = invoice.account.name; \n if (name) {\n doc.setFontSize(\'30\');\n doc.setFontType(\'bold\');\n doc.text(40, 50, name);\n }\n\n if (invoice.image)\n {\n y=130;\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', layout.marginLeft, y);\n }\n\n // add footer \n doc.setLineWidth(0.5);\n\n if (NINJA.primaryColor) {\n setDocHexFill(doc, NINJA.primaryColor);\n setDocHexDraw(doc, NINJA.primaryColor);\n } else {\n doc.setDrawColor(242,101,34);\n doc.setFillColor(242,101,34);\n } \n\n var x1 = 0;//tableLeft-tablePadding ;\n var y1 = 750;\n var w2 = 596;\n var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;\n\n doc.rect(x1, y1, w2, h2, \'FD\');\n\n if (!invoice.is_pro && logoImages.imageLogo3)\n {\n pageHeight=820;\n // var left = 25;//250;//headerRight ;\n y=pageHeight-logoImages.imageLogoHeight3;\n //var headerRight=370;\n\n //var left = headerRight - invoice.imageLogoWidth3;\n doc.addImage(logoImages.imageLogo3, \'JPEG\', 40, y, logoImages.imageLogoWidth3, logoImages.imageLogoHeight3);\n }\n\n doc.setFontSize(10); \n var marginLeft = 340;\n displayAccount(doc, invoice, marginLeft, 780, layout);\n\n\n SetPdfColor(\'White\',doc); \n doc.setFontSize(\'8\');\n var detailsHeight = displayInvoice(doc, invoice, layout.headerRight, layout.accountTop-10, layout);\n layout.headerTop = Math.max(layout.headerTop, detailsHeight + 50);\n layout.tableTop = Math.max(layout.tableTop, detailsHeight + 150);\n\n SetPdfColor(\'Black\',doc); //set black color\n doc.setFontSize(7);\n doc.setFontType(\'normal\');\n displayClient(doc, invoice, layout.headerRight, layout.headerTop, layout);\n\n\n \n SetPdfColor(\'White\',doc); \n doc.setFontType(\'bold\');\n\n doc.setLineWidth(0.3);\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n setDocHexDraw(doc, NINJA.secondaryColor);\n } else {\n doc.setDrawColor(63,60,60);\n doc.setFillColor(63,60,60);\n } \n\n var left = layout.marginLeft - layout.tablePadding;\n var top = layout.tableTop - layout.tablePadding;\n var width = layout.marginRight - (2 * layout.tablePadding);\n var height = 20;\n doc.rect(left, top, width, height, \'FD\');\n \n\n displayInvoiceHeader(doc, invoice, layout);\n SetPdfColor(\'Black\',doc);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n\n var height1 = displayNotesAndTerms(doc, layout, invoice, y);\n var height2 = displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);\n y += Math.max(height1, height2);\n\n\n var left = layout.marginLeft - layout.tablePadding;\n var top = y - layout.tablePadding;\n var width = layout.marginRight - (2 * layout.tablePadding);\n var height = 20;\n if (NINJA.secondaryColor) {\n setDocHexFill(doc, NINJA.secondaryColor);\n setDocHexDraw(doc, NINJA.secondaryColor);\n } else {\n doc.setDrawColor(63,60,60);\n doc.setFillColor(63,60,60);\n } \n doc.rect(left, top, width, height, \'FD\');\n \n doc.setFontType(\'bold\');\n SetPdfColor(\'White\', doc);\n doc.setFontSize(12);\n \n var label = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;\n var labelX = layout.unitCostRight-(doc.getStringUnitWidth(label) * doc.internal.getFontSize());\n doc.text(labelX, y+2, label);\n\n\n doc.setFontType(\'normal\');\n var amount = formatMoney(invoice.balance_amount , currencyId);\n headerLeft=layout.headerRight+400;\n var amountX = layout.lineTotalRight - (doc.getStringUnitWidth(amount) * doc.internal.getFontSize());\n doc.text(amountX, y+2, amount);','{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"margin\": [0, 60, 0, 30]\n },\n {\n \"stack\": \"$clientDetails\",\n \"margin\": [0, 60, 0, 0]\n }\n ]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$notFirstAndLastColumn:.5\",\n \"hLineColor\": \"#888888\",\n \"vLineColor\": \"#FFFFFF\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:8\",\n \"paddingBottom\": \"$amount:8\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"columns\": [\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 0,\n \"y\": 0,\n \"w\": 515,\n \"h\": 26,\n \"r\": 0,\n \"lineWidth\": 1,\n \"color\": \"$secondaryColor:#403d3d\"\n }\n ],\n \"width\": 10,\n \"margin\": [\n 0,\n 10,\n 0,\n 0\n ]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\",\n \"margin\": [0, 16, 0, 0],\n \"width\": 370\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\",\n \"margin\": [0, 16, 8, 0]\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": [\n {\n \"canvas\": [\n {\n \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 600, \"y2\": 0,\"lineWidth\": 100,\"lineColor\":\"$primaryColor:#f26621\"\n }]\n ,\"width\":10\n },\n {\n \"columns\": [\n {\n \"width\": 350,\n \"stack\": [\n {\n \"text\": \"$invoiceFooter\",\n \"margin\": [40, -40, 40, 0],\n \"alignment\": \"left\",\n \"color\": \"#FFFFFF\"\n\n }\n ]\n },\n {\n \"stack\": \"$accountDetails\",\n \"margin\": [0, -40, 0, 0],\n \"width\": \"*\"\n },\n {\n \"stack\": \"$accountAddress\",\n \"margin\": [0, -40, 0, 0],\n \"width\": \"*\"\n }\n ]\n }\n ],\n \"header\": [\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 600, \"y2\": 0,\"lineWidth\": 200,\"lineColor\":\"$primaryColor:#f26621\"}],\"width\":10\n },\n {\n \"columns\": [\n {\n \"text\": \"$accountName\", \"bold\": true,\"font\":\"$headerFont\",\"fontSize\":30,\"color\":\"#ffffff\",\"margin\":[40,20,0,0],\"width\":350\n }\n ]\n },\n {\n \"width\": 300,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [400, -40, 0, 0]\n }\n ],\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountName\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountDetails\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"#FFFFFF\"\n },\n \"accountAddress\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"#FFFFFF\"\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 4, 2]\n },\n \"invoiceDetails\": {\n \"color\": \"#FFFFFF\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"productKey\": {\n \"bold\": true\n },\n \"clientName\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"#FFFFFF\",\n \"fontSize\": \"$fontSizeLargest\",\n \"fillColor\": \"$secondaryColor:#403d3d\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"alignment\":\"right\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"bold\": true,\n \"alignment\":\"right\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"invoiceNumberLabel\": {\n \"bold\": true\n },\n \"invoiceNumber\": {\n \"bold\": true\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [7, 0, 7, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [40, 120, 40, 50]\n}\n'),(4,'Plain',' var client = invoice.client;\n var account = invoice.account;\n var currencyId = client.currency_id; \n \n layout.accountTop += 25;\n layout.headerTop += 25;\n layout.tableTop += 25;\n\n if (invoice.image)\n {\n var left = layout.headerRight - invoice.imageWidth;\n doc.addImage(invoice.image, \'JPEG\', left, 50);\n } \n \n /* table header */\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n \n var detailsHeight = getInvoiceDetailsHeight(invoice, layout);\n var left = layout.headerLeft - layout.tablePadding;\n var top = layout.headerTop + detailsHeight - layout.rowHeight - layout.tablePadding;\n var width = layout.headerRight - layout.headerLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 1;\n doc.rect(left, top, width, height, \'FD\'); \n\n doc.setFontSize(10);\n doc.setFontType(\'normal\');\n\n displayAccount(doc, invoice, layout.marginLeft, layout.accountTop, layout);\n displayClient(doc, invoice, layout.marginLeft, layout.headerTop, layout);\n\n displayInvoice(doc, invoice, layout.headerLeft, layout.headerTop, layout, layout.headerRight);\n layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));\n\n var headerY = layout.headerTop;\n var total = 0;\n\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n var left = layout.marginLeft - layout.tablePadding;\n var top = layout.tableTop - layout.tablePadding;\n var width = layout.headerRight - layout.marginLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 2;\n doc.rect(left, top, width, height, \'FD\'); \n\n displayInvoiceHeader(doc, invoice, layout);\n var y = displayInvoiceItems(doc, invoice, layout);\n\n doc.setFontSize(10);\n\n displayNotesAndTerms(doc, layout, invoice, y+20);\n\n y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;\n\n doc.setDrawColor(200,200,200);\n doc.setFillColor(230,230,230);\n \n var left = layout.footerLeft - layout.tablePadding;\n var top = y - layout.tablePadding;\n var width = layout.headerRight - layout.footerLeft + (2 * layout.tablePadding);\n var height = layout.rowHeight + 2;\n doc.rect(left, top, width, height, \'FD\'); \n \n doc.setFontType(\'bold\');\n doc.text(layout.footerLeft, y, invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due);\n\n total = formatMoney(invoice.balance_amount, currencyId);\n var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());\n doc.text(totalX, y, total); \n\n if (!invoice.is_pro) {\n doc.setFontType(\'normal\');\n doc.text(layout.marginLeft, 790, \'Created by InvoiceNinja.com\');\n }','{\n \"content\": [\n {\n \"columns\": [\n {\n \"stack\": \"$accountDetails\"\n },\n {\n \"stack\": \"$accountAddress\"\n },\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n }\n ] \n ]},\n {\n \"columns\": [\n {\n \"width\": 340,\n \"stack\": \"$clientDetails\",\n \"margin\": [0,40,0,0]\n },\n {\n \"width\":200,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#E6E6E6\",\n \"paddingLeft\": \"$amount:10\", \n \"paddingRight\": \"$amount:10\"\n }\n }\n ]\n }, \n {\n \"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 25,\"r\":0, \"lineWidth\": 1,\"color\":\"#e6e6e6\"}],\"width\":10,\"margin\":[0,30,0,-43]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:1\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#e6e6e6\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\" \n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"width\": 160,\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [60, 60],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:10\", \n \"paddingRight\": \"$amount:10\", \n \"paddingTop\": \"$amount:4\", \n \"paddingBottom\": \"$amount:4\" \n }\n }\n ]\n }, \n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\",\n \"margin\": [0, 0, 0, 12]\n\n }\n ],\n \"margin\": [40, -20, 40, 40]\n },\n \"defaultStyle\": {\n \"font\": \"$bodyFont\",\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"tableHeader\": {\n \"bold\": true\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"invoiceLineItemsTable\": {\n \"margin\": [0, 16, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"terms\": {\n \"margin\": [0, 0, 20, 0]\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"invoiceDetailBalanceDue\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"subtotalsBalanceDue\": {\n \"fillColor\": \"#e6e6e6\"\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n },\n \"invoiceDocuments\": {\n \"margin\": [7, 0, 7, 0]\n },\n \"invoiceDocument\": {\n \"margin\": [0, 10, 0, 10]\n }\n },\n \"pageMargins\": [40, 40, 40, 60]\n}\n'),(5,'Business',NULL,'{\n \"content\": [\n {\n \"columns\":\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\n \"width\": 300,\n \"stack\": \"$accountDetails\",\n \"margin\": [140, 0, 0, 0]\n },\n {\n \"width\": 150,\n \"stack\": \"$accountAddress\"\n }\n ]\n },\n {\n \"columns\": [\n {\n \"width\": 120,\n \"stack\": [\n {\"text\": \"$invoiceIssuedToLabel\", \"style\":\"issuedTo\"},\n \"$clientDetails\"\n ],\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"canvas\": [{ \"type\": \"rect\", \"x\": 20, \"y\": 0, \"w\": 174, \"h\": \"$invoiceDetailsHeight\",\"r\":10, \"lineWidth\": 1,\"color\":\"$primaryColor:#eb792d\"}],\n \"width\":30,\n \"margin\":[200,25,0,0]\n },\n {\n \"table\": {\n \"widths\": [70, 76],\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [200, 34, 0, 0]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 32,\"r\":8, \"lineWidth\": 1,\"color\":\"$secondaryColor:#374e6b\"}],\"width\":10,\"margin\":[0,20,0,-45]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:1\",\n \"vLineWidth\": \"$notFirst:.5\",\n \"hLineColor\": \"#FFFFFF\",\n \"vLineColor\": \"#FFFFFF\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:12\",\n \"paddingBottom\": \"$amount:12\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"stack\": [\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n },\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 60,\n \"y\": 20,\n \"w\": 198,\n \"h\": 30,\n \"r\": 7,\n \"lineWidth\": 1,\n \"color\": \"$secondaryColor:#374e6b\"\n }\n ]\n },\n {\n \"style\": \"subtotalsBalance\",\n \"table\": {\n \"widths\": [\"*\", \"45%\"],\n \"body\": \"$subtotalsBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#299CC2\"\n },\n \"accountName\": {\n \"bold\": true\n },\n \"accountDetails\": {\n \"color\": \"#AAA9A9\",\n \"margin\": [0,2,0,1]\n },\n \"accountAddress\": {\n \"color\": \"#AAA9A9\",\n \"margin\": [0,2,0,1]\n },\n \"even\": {\n \"fillColor\":\"#E8E8E8\"\n },\n \"odd\": {\n \"fillColor\":\"#F7F7F7\"\n },\n \"productKey\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"#ffffff\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true,\n \"color\":\"#ffffff\",\n \"alignment\":\"right\",\n \"noWrap\":true\n },\n \"invoiceDetails\": {\n \"color\": \"#ffffff\"\n },\n \"tableHeader\": {\n \"color\": \"#ffffff\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"secondTableHeader\": {\n \"color\": \"$secondaryColor:#374e6b\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"issuedTo\": {\n \"margin\": [0,2,0,1],\n \"bold\": true,\n \"color\": \"#374e6b\"\n },\n \"clientDetails\": {\n \"margin\": [0,2,0,1]\n },\n \"clientName\": {\n \"color\": \"$primaryColor:#eb792d\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 10, 0, 10]\n },\n \"invoiceDetailsValue\": {\n \"alignment\": \"right\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"subtotalsBalance\": {\n \"alignment\": \"right\",\n \"margin\": [0, -25, 0, 0]\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(6,'Creative',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"stack\": \"$clientDetails\"\n },\n {\n \"stack\": \"$accountDetails\"\n },\n {\n \"stack\": \"$accountAddress\"\n },\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"alignment\": \"right\"\n }\n ],\n \"margin\": [0, 0, 0, 20]\n },\n {\n \"columns\": [\n {\"text\":\n [\n {\"text\": \"$entityTypeUC\", \"style\": \"header1\"},\n {\"text\": \" #\", \"style\": \"header2\"},\n {\"text\": \"$invoiceNumber\", \"style\":\"header2\"}\n ],\n \"width\": \"*\"\n },\n {\n \"width\":200,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [16, 4, 0, 0]\n }\n ],\n \"margin\": [0, 0, 0, 20]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 3,\"lineColor\":\"$primaryColor:#AE1E54\"}]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"$primaryColor:#E8E8E8\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:8\",\n \"paddingBottom\": \"$amount:8\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 3,\"lineColor\":\"$primaryColor:#AE1E54\"}],\n \"margin\": [0, -8, 0, -8]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\"\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\"\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"primaryColor\":{\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"accountName\": {\n \"margin\": [4, 2, 4, 2],\n \"color\": \"$primaryColor:#AE1E54\",\n \"bold\": true\n },\n \"accountDetails\": {\n \"margin\": [4, 2, 4, 2]\n },\n \"accountAddress\": {\n \"margin\": [4, 2, 4, 2]\n },\n \"odd\": {\n \"fillColor\":\"#F4F4F4\"\n },\n \"productKey\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"margin\": [320,20,0,0]\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#AE1E54\",\n \"bold\": true,\n \"margin\":[0,-10,10,0],\n \"alignment\": \"right\"\n },\n \"invoiceDetailBalanceDue\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#AE1E54\",\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"clientName\": {\n \"bold\": true\n },\n \"clientDetails\": {\n \"margin\": [0,2,0,1]\n },\n \"header1\": {\n \"bold\": true,\n \"margin\": [0, 30, 0, 16],\n \"fontSize\": 42\n },\n \"header2\": {\n \"margin\": [0, 30, 0, 16],\n \"fontSize\": 42,\n \"italics\": true,\n \"color\": \"$primaryColor:#AE1E54\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 4, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(7,'Elegant',NULL,'{\n \"content\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80],\n \"alignment\": \"center\",\n \"margin\": [0, 0, 0, 30]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 2}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 3, \"x2\": 515, \"y2\": 3, \"lineWidth\": 1}]},\n {\n \"columns\": [\n {\n \"width\": 120,\n \"stack\": [\n {\"text\": \"$invoiceToLabel\", \"style\": \"header\", \"margin\": [0, 0, 0, 6]},\n \"$clientDetails\"\n ]\n },\n {\n \"width\": 10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": -2, \"y1\": 18, \"x2\": -2, \"y2\": 80, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"width\": 120,\n \"stack\": \"$accountDetails\",\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"width\": 110,\n \"stack\": \"$accountAddress\",\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"stack\": [\n {\"text\": \"$detailsLabel\", \"style\": \"header\", \"margin\": [0, 0, 0, 6]},\n {\n \"width\":180,\n \"table\": {\n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\"\n }\n ]\n }],\n \"margin\": [0, 20, 0, 0]\n },\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:8\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:12\",\n \"paddingBottom\": \"$amount:12\"\n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 270, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"text\": \"$balanceDueLabel\",\n \"style\": \"subtotalsBalanceDueLabel\"\n },\n {\n \"text\": \"$balanceDue\",\n \"style\": \"subtotalsBalanceDue\"\n },\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 270, \"y1\": 20, \"x2\": 515, \"y2\": 20, \"lineWidth\": 1,\"dash\": { \"length\": 2 }}]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }],\n \"footer\": [\n {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 35, \"y1\": 5, \"x2\": 555, \"y2\": 5, \"lineWidth\": 2,\"margin\": [30,0,0,0]}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 35, \"y1\": 3, \"x2\": 555, \"y2\": 3, \"lineWidth\": 1,\"margin\": [30,0,0,0]}]}\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientName\": {\n \"bold\": true\n },\n \"accountName\": {\n \"bold\": true\n },\n \"odd\": {\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#5a7b61\",\n \"margin\": [320,20,0,0]\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#5a7b61\",\n \"style\": true,\n \"margin\":[0,-14,8,0],\n \"alignment\":\"right\"\n },\n \"invoiceDetailBalanceDue\": {\n \"color\": \"$primaryColor:#5a7b61\",\n \"bold\": true\n },\n \"fullheader\": {\n \"font\": \"$headerFont\",\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"header\": {\n \"fontSize\": 14,\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"color\": \"$primaryColor:#5a7b61\",\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 40, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"header\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(8,'Hipster',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"width\":10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 0, \"y2\": 75, \"lineWidth\": 0.5}]\n },\n {\n \"width\":120,\n \"stack\": [\n {\"text\": \"$fromLabelUC\", \"style\": \"fromLabel\"}, \n \"$accountDetails\" \n ]\n },\n {\n \"width\":120,\n \"stack\": [\n {\"text\": \" \"},\n \"$accountAddress\"\n ],\n \"margin\": [10, 0, 0, 16]\n },\n {\n \"width\":10,\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 0, \"y2\": 75, \"lineWidth\": 0.5}]\n },\n {\n \"stack\": [\n {\"text\": \"$toLabelUC\", \"style\": \"toLabel\"}, \n \"$clientDetails\"\n ]\n },\n [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n }\n ]\n ]\n },\n {\n \"text\": \"$entityTypeUC\",\n \"margin\": [0, 4, 0, 8],\n \"bold\": \"true\",\n \"fontSize\": 42\n },\n {\n \"columnGap\": 16,\n \"columns\": [\n {\n \"width\":\"auto\",\n \"text\": [\"$invoiceNoLabel\",\" \",\"$invoiceNumberValue\"],\n \"bold\": true,\n \"color\":\"$primaryColor:#bc9f2b\",\n \"fontSize\":10\n },\n {\n \"width\":\"auto\",\n \"text\": [\"$invoiceDateLabel\",\" \",\"$invoiceDateValue\"],\n \"fontSize\":10\n },\n {\n \"width\":\"auto\",\n \"text\": [\"$dueDateLabel?\",\" \",\"$dueDateValue\"],\n \"fontSize\":10\n },\n {\n \"width\":\"*\",\n \"text\": [\"$balanceDueLabel\",\" \",{\"text\":\"$balanceDue\", \"bold\":true, \"color\":\"$primaryColor:#bc9f2b\"}],\n \"fontSize\":10\n }\n ]\n },\n {\n \"margin\": [0, 26, 0, 0],\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$amount:.5\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\" \n }\n },\n {\n \"columns\": [\n {\n \"stack\": \"$notesAndTerms\",\n \"width\": \"*\",\n \"margin\": [0, 12, 0, 0]\n },\n {\n \"width\": 200,\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"36%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$notFirst:.5\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:12\", \n \"paddingBottom\": \"$amount:4\" \n }\n }\n ]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountName\": {\n \"bold\": true\n },\n \"clientName\": {\n \"bold\": true\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"taxTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"fromLabel\": {\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true \n },\n \"toLabel\": {\n \"color\": \"$primaryColor:#bc9f2b\",\n \"bold\": true \n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 16, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(9,'Playful',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 190, \"h\": \"$invoiceDetailsHeight\",\"r\":5, \"lineWidth\": 1,\"color\":\"$primaryColor:#009d91\"}],\"width\":10,\"margin\":[200,0,0,0]},\n {\n \"width\":400,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\",\n \"margin\": [210, 10, 10, 0]\n }\n ] \n },\n {\n \"margin\": [0, 18, 0, 0],\n \"columnGap\": 50,\n \"columns\": [\n {\n \"width\": 212,\n \"stack\": [\n {\"text\": \"$invoiceToLabel:\", \"style\": \"toLabel\"},\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 4, \"x2\": 150, \"y2\": 4, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}],\n \"margin\": [0, 0, 0, 4]\n },\n \"$clientDetails\",\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 9, \"x2\": 150, \"y2\": 9, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}]}\n ]\n },\n {\n \"width\": \"*\",\n \"stack\": [\n {\"text\": \"$fromLabel:\", \"style\": \"fromLabel\"},\n {\n \"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 4, \"x2\": 250, \"y2\": 4, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}],\n \"margin\": [0, 0, 0, 4]\n },\n {\"columns\":[\n \"$accountDetails\",\n \"$accountAddress\" \n ], \"columnGap\": 4}, \n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 9, \"x2\": 250, \"y2\": 9, \"lineWidth\": 1,\"dash\": { \"length\": 3 },\"lineColor\":\"$primaryColor:#009d91\"}]}\n ]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"rect\", \"x\": 0, \"y\": 0, \"w\": 515, \"h\": 35,\"r\":6, \"lineWidth\": 1,\"color\":\"$primaryColor:#009d91\"}],\"width\":10,\"margin\":[0,30,0,-30]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"$primaryColor:#009d91\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:8\", \n \"paddingBottom\": \"$amount:8\"\n }\n }, \n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"stack\": [\n {\n \"style\": \"subtotals\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsWithoutBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n },\n {\n \"canvas\": [\n {\n \"type\": \"rect\",\n \"x\": 76,\n \"y\": 20,\n \"w\": 182,\n \"h\": 30,\n \"r\": 4,\n \"lineWidth\": 1,\n \"color\": \"$primaryColor:#009d91\"\n }\n ]\n },\n {\n \"style\": \"subtotalsBalance\",\n \"table\": {\n \"widths\": [\"*\", \"35%\"],\n \"body\": \"$subtotalsBalance\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\",\n \"paddingRight\": \"$amount:8\",\n \"paddingTop\": \"$amount:4\",\n \"paddingBottom\": \"$amount:4\"\n }\n }\n ]\n }\n ]\n }, \n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n], \n \"footer\": [\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 38, \"x2\": 68, \"y2\": 38, \"lineWidth\": 6,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 68, \"y1\": 0, \"x2\": 135, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#1d766f\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 135, \"y1\": 0, \"x2\": 201, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 201, \"y1\": 0, \"x2\": 267, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#bf9730\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 267, \"y1\": 0, \"x2\": 333, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ac2b50\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 333, \"y1\": 0, \"x2\": 399, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#e60042\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 399, \"y1\": 0, \"x2\": 465, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 465, \"y1\": 0, \"x2\": 532, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 532, \"y1\": 0, \"x2\": 600, \"y2\": 0, \"lineWidth\": 6,\"lineColor\":\"#ac2b50\"}]},\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\",\n \"margin\": [40, -60, 40, 0]\n }\n ],\n \"header\": [\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 0, \"x2\": 68, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 68, \"y1\": 0, \"x2\": 135, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#1d766f\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 135, \"y1\": 0, \"x2\": 201, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 201, \"y1\": 0, \"x2\": 267, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#bf9730\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 267, \"y1\": 0, \"x2\": 333, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ac2b50\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 333, \"y1\": 0, \"x2\": 399, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#e60042\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 399, \"y1\": 0, \"x2\": 465, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ffb800\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 465, \"y1\": 0, \"x2\": 532, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#009d91\"}]},\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 532, \"y1\": 0, \"x2\": 600, \"y2\": 0, \"lineWidth\": 9,\"lineColor\":\"#ac2b50\"}]}\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"styles\": {\n \"accountName\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"accountDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"accountAddress\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientDetails\": {\n \"margin\": [0, 2, 0, 1]\n },\n \"clientName\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"even\": {\n \"fillColor\":\"#E8E8E8\"\n },\n \"odd\": {\n \"fillColor\":\"#F7F7F7\"\n },\n \"productKey\": {\n \"color\": \"$secondaryColor:#bb3328\"\n },\n \"lineTotal\": {\n \"bold\": true\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"#FFFFFF\"\n },\n \"secondTableHeader\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"costTableHeader\": {\n \"alignment\": \"right\"\n },\n \"qtyTableHeader\": {\n \"alignment\": \"right\"\n },\n \"lineTotalTableHeader\": {\n \"alignment\": \"right\"\n }, \n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\":\"#FFFFFF\",\n \"bold\": true\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true,\n \"color\":\"#FFFFFF\",\n \"alignment\":\"right\"\n },\n \"invoiceDetails\": {\n \"color\": \"#FFFFFF\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"invoiceDetailBalanceDueLabel\": {\n \"bold\": true\n },\n \"invoiceDetailBalanceDue\": {\n \"bold\": true\n },\n \"fromLabel\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"toLabel\": {\n \"color\": \"$primaryColor:#009d91\"\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"subtotals\": {\n \"alignment\": \"right\"\n }, \n \"subtotalsBalance\": {\n \"alignment\": \"right\",\n \"margin\": [0, -25, 0, 0]\n }, \n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"subheader\": {\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 40, 40, 40]\n}\n'),(10,'Photo',NULL,'{\n \"content\": [\n {\n \"columns\": [\n {\n \"image\": \"$accountLogo\",\n \"fit\": [120, 80]\n },\n {\n \"text\": \"\",\n \"width\": \"*\"\n },\n {\n \"width\":180,\n \"table\": { \n \"body\": \"$invoiceDetails\"\n },\n \"layout\": \"noBorders\"\n }]\n },\n {\n \"image\": \"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAEZA4QDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0kT6iVJXXdaC++rXH/wAcpY59U+9/bmtED/qKXA/9nqmJuPlOR6Af/XpUuHRCD8o9CM1jqaWL5vb5+usa2p/7C1x/8XUbXOpQddd1pgf+opc//F1Thulx1B57ipzIoH3sfVR/hRqFiy11qP8A0G9aXj/oKXP9Xpst9qLfd1nWSe+dVuP/AIuq6XJjzl/M+rHj86ljuTnlwn4E0ahYkW81HIxretEjqDqtwP8A2pUp1PUFH/Ib1oH/ALCc/wD8XVQyqMmWHavZhhc0PtYDapPsGo1CxpDUtSA+XWdZc/8AYUn/APiqaNX1A5U63q6/9xOY/wDs9Uwcj5WOfRTzUABDHOB7nFGoWNRdQ1Numtaxjrk6jP8A/F1MdX1BYwF1rV947/2hPj/0Os3KvGFUqzemMVD5whbknjjAxj86Wo7I1DrGqj5v7Z1b6nUZ/wD4upY9c1Qr/wAhrVS3p/aE3/xVZJuAU3BcH+8TikS6GQMhpPTg/rRqBr/27qvT+2dVH11GX/4ulGt6sWA/tnVSPX7fN/8AFVlmd8ZZdq+o/wD1UhmV12s42nrRqFkbX9t6mqZOs6kCP+ojPn/0KmnXtVCk/wBs6qR1/wCP+b/4qsXfGg2ocnsN1Kk7KuNu0dTxmlqFjaj8R6mykHVtV3Z6i/l4/wDH6cNd1VcA63qjHt/p8v8A8VWTHdfKQGwKcWZ/u7XHtRqFjXTXdWHXWdT9s30v/wAVTh4k1dQf+JvqLfS/kP8A7NWPG4UESZU9gP8A9VIZPKI4IB/uGjUDZHiPWsYOr6muPW8l/wDiqcvifWG/5jOoJ7fa5ef/AB41lfaUf+IH6U2AomcyIc+wP9aNQNf/AISTWe2taifpdSn+tTnxTrSAY1i+Pt9sf+rVhCYHo3/juKPtYTopJ/2WH+NO4G9/wlmrr11nUfwvW/xpB4z1cMQNX1FuehupB/I1giQMclT+JpWkTHdP8/hSA6H/AIS7WTh/7Zv+ewu34/Wm/wDCW61jP9s354/5+n/xrCVuATkjseaa8odDgk0Aa7+LdcJx/bWoDtn7W/r9aRvF2tgEf2zqAPOD9qf/ABrn2uC7k8dfpmlnkAj5f5T05/SncDpdP8X65HqVp/xOb6U+cnym6cg8jqM9K96/aD8R3mj/AAN8Q3tpPNaXf2TaksUhV1YkDhhyOtfN3hhs+IdOUqWU3CjH1PSvo79pD7LD8C/EMdwuRJbBIwf75I2/ripd7j6H5r+KPiv4yhuXEXivXI8KBhdRm9P96uHk+Lvjdpc/8Jn4gA9Bqs//AMXR4uu/Nu50TAG7FcjtAfB6k4zXSYnaR/Ffxxt/5HLxDk/9RSf/AOLqKT4teOFOP+Ez8QEA/wDQVn/+KrmkxtI7gciopyVYZAz6UAd7afF3xoLQv/wmGvHA5J1Ocn/0Ks+6+LvjdiSvjLXwe/8AxNZ//i65mzkJjkjP3faqsn3zjnnJJoA6j/hbvjk8Hxl4g6f9BWf/AOLqZPiz44BH/FZ+Ic55/wCJpP8A/FVx/Qe3rihW3Px07EDqKAOuf4t+OCWx4z8Q9f8AoKT5/wDQqWL4teOB18ZeIT/3FZ//AIuuTGSrY6Z701pMD/CgDrn+Lfjlj8vjLxBg/wDUUn/+LqM/FnxyOP8AhM/EPoT/AGpPz/4/XKDO4n24BFPJAOcgY6UAdWfiz45C5PjPxD0/6Ck//wAVUY+LPjkgY8Z+IiP+wrPn/wBDrl3dSeB9eajHB657kCgDrf8AhbfjkjA8Z+IQfX+1J/8A4uhvi545PI8Z+If/AAaT8f8Aj9cox44zgU0A4PJIzQB1p+LXjnd/yOniEDH/AEFJ+v8A33TV+Lfjk9PGfiHr/wBBWf8A+LrlACV5GO4xSHIzgZOeMjrQB1Y+Lfjof8zp4h/8Gs//AMXQfi345Rs/8Jn4hPbH9qz+v+/XJ5U89D70jctwQD+lAHW/8Lb8dcZ8Z+Ic+2qT8f8Aj1TRfFvxuUP/ABWfiDP/AGFJ/wD4uuNOCeB26VYt8fN3oA67/hbPjgL/AMjl4hz0z/ak/wD8XSj4s+OWjLDxlr5AOONUn5/8erkJTzgfKB0p9ucQli2MngE0AdQnxX8cs2T408Qge2qTn/2elf4teOFGR4z8Qbv+wpP/APF1yUYLHAPHXk9KkkZQhVdpJoA6T/hbnjndz4y8QdP+grP/APF0J8WvHOB/xWniE/8AcUn/APi65XqT245+tNY7iDnAoA7Fvi545IGPGXiAf9xWf/4unRfFnxwAzHxnr+7/ALCk/wD8XXIrgoDuOAe1IXwRk4oA6g/FzxwW48aeIP8AwaT/APxdMHxb8dcg+M/EOPUapP8A/F1y7LkjHOfzppGAT0xQB1n/AAtvxycf8Vp4h6dP7Vn/APi6T/hbfjr/AKHTxBx/1FZ//iq5Xdkc5U9fSkAHHTHvQB1y/Fzxzjnxn4gBA6/2rP8A/FUjfFvx1/0OniE/9xSf/wCLrk0Hbj8KR2DA9/egDqx8WPHWT/xWniL/AMGs/wD8VS/8Lb8ckf8AI5+Icf8AYVn/APi65LkDvinYIIOcjv7UAdbH8XfHB/5nPxACRk/8TSc/+z00/FzxxuGfGfiHA7f2rP8A/FVyyozPsGc+nep7PT59QvobWCJpZ5nCIiclj0xQB7Jb+OPGFz4UbU/+Eu12Nkh4QapPyemfv+4NeweAdCvPib4o16PW/irrfhwWNrZrDawahKXlZrdCWwXAwD19zXIeNPhxp3gL4F6bcT38n/CRzNsvdKljw1sAepHX0/OvOvFlhp3iDxFcarpvjHTLZJ0iCxytNG64jVSDhO201F77FWsVPG3jnxn4T8Y6no8HxC1nU4bOdoVu4NUn2SgHgjL19O+E/hjfa34M0JLzxz4ntte1XSX1BZX12ZWRgoI2xAkMvIydw9q+SR4CjkYsvifQpGzyTeEZP4qP1rttK8UfEHR9MttO034gWCWVtG0UMKatF8iEYKgt29ulJ3toCaW56D4ff7J8FbHxv4n8eeNla41OSw8vTtSc9AcH5nHTBPWuh8NfD7Ur6+8H6bf/ABI8ZfbfE9pJf20tvfyeVDEBuUPl+WIPOOBXgs2l+LZ/C0Hht9a0y40S3uTdxWi6pblVkIILD5s9zX1Z8OPG3hnwL4V09TrI1OSwtRFbWhuYJbiJmUeYu44CqDnhX6AVMm0tGUrM8z8MeDvEF/a+F4dT+JniuHUPE93Pb6ebW9leOJY2K7pMyc5OOBWX4b+HPxR1S78WSap491/StF8OvPHNqQvbmRZ2jZgREocZPy/rWb4PvviloXkabpwtJbGG6eW0u7kQzNZl8hnjOSUyDkgZrsfjB4f8QWHwz0fwT4WsdR1uWadtR1vVIYnH2i4YfdBOCwySfwFF2na4tDzjxDB4+0fwT4V8RWnj/wAQaiPENxPb29ol9cCQeW+wH7/O7jj3rofFngv4heDtPcaj8VNQt9YjsU1GTTp9SuYzsbqiSM215BkEqKwnn+JK+A9N8L3PgWS4ttL8w2F41lMLm2Z2LMyurAA5xjjsKl8U+PviF4k0iS31XwX5+oS2iWEmpT2E0kpjUAZVWJVHOBllAJxVXYaGp4r8IfFbwh4ZbxLH8Tp9R8O/ZvPXU7PW53jaTgCAc/6wk4x9fSvMdJ+NPxMv7yG1tPGfiKa5lYJHEl/MxZicAAZ5JPFdrB8Z/Fen6Dc+Gr3wZDN4OmtVtn0Y20kaqR/y1V+SJM8lufpXkdhcaj4d16HVNOgnsZ7WcXFvvUs0ZVty/MQM4x1xTV+pLt0PcpvFXx0+HXi7w1Z+K9a8SafBqVwiJFfXL7Jl3AMOT6EZHUZFefeP/il42s/EF7bweLtehtEuJ1gRdTmGEWZ1UZ3c8D9K6ef40+JPjJ4+8F2uvbVjtNSjdVQN8zsy5Y5Pt2ry74hKTrrS7i4leZwCen+kS9Py7U0N+RMfi345PTxn4hA/7Ck5/wDZ6T/hbPjvkf8ACZ+If/BpP/8AF1yu35gPbr0oC7s55BqiTqx8WvHAbB8Z+If/AAaz/wDxVL/wtrxzyf8AhM/EOPQapP8A/F1yjAIOvPpUa5LYxt47CgDrn+LfjkjI8Z+IRz/0FJ//AIqj/hbfjkj/AJHLxBnrj+1Z/wD4uuUjG0+o96kRBu5A5oA6j/ha/joYz408QE/9hSf/AOLpU+LXjoLj/hM/EOR2/tSfn/x6uVnID8Dvio1k/izkfSgDrn+LPjrcSvjLxDt4/wCYpP8A/F0w/Fvx1/0OfiEn/sKz/wDxdc0kvG0qMetRuPn469R2NAHUr8WfHP8A0OniEH/sKz//ABdPX4ueOA4P/CZ+IOf+opP/APF1ybgdsH1NNiBJGT06ZoA7F/ir44wGXxl4hPv/AGrP/wDF0yT4t+OBhf8AhM/EC+/9qz//ABdc2TgKAQv0qvdMxc8g49KAOqT4teOiePGXiDPr/ak//wAXTf8AhbfjoHnxn4h+n9qT/wDxdcxEGI4+maRT8w4yAfXFAHXSfFvxygX/AIrLxCAQef7Un/8Aiqif4t+OOCfGniH3/wCJpP8A/Ff5zXNStuUEkn0AqCT5jkjB9KAOpPxd8dYwfGniH8NVn/8Ai6QfF3xyAD/wmniE8/8AQVn/APiq5PqRn+dKv3s9qAOs/wCFueOjyvjTxCOOB/as/wD8XSD4ueOTjPjPxFgeuqz/APxVcpx0wc0cY5INAHWj4u+OV/5nTxDgk/8AMVn/APi6P+FueOSf+R08Q4x/0FZ//i65IrkcGlPC8gD07GgDqm+LvjpTj/hM/EJ/7is//wAXRXK5UZ3Lk+9FAH22dzj7mffP/wBapYEKxnG4Y9+P5U1CAQPnxnsSRT2jDZKuVx2DYFZGoI28Zyn/AALGakc5HUj6DH8qqr5g/iz75zTstxuYP/vc4oAkgmZt29wcdN3NSEsBgv8AmwqBUOT1P1B/wpvmOB87F/QelAFmWRSq7MK3c1MjBVBZicj1AqtE5J+62KimkdP4QQT0Y0AaQ+f+79aa7YHrz3qiXMigOFAHT/IFSLLIv+7260AWGk3rtGQfYU0u4GCcL7kVHl+pOM/3s4pPM7BVz/fAOP5UAPMrpzuDKOwPNKtyWwC2F/u96rnyw5Zid3pt4pyy7XG1QB6gEGgCwZwjZUN+INAuBM20kDPY5zVaTcZN5II6fNk/pSoCxB+Xb6KMGkBa/wBX0xgejc/lSiZGPKknpzVUsqTD5W+pOTUruGOcZx03LRYCfzI1+QgBj0/yTUgYRAgsqnthg38qqKGdTkLn6UgYx8E4J6Bs0WAtK+8HMu3HtSI2z/VnGeuTiq5fb98Y9Nn9aXz8/ecKe3NFhNliSUqfmcH6im+cX+58nqACM/nVYjd987iO4JGKkBiH3irH/ZH/ANaiwx73ix44x9R/9amC5kUk9j0yMfzqIuT985HbjNRSXRAHU/T5aLAaBnYKCxU/pUQu9rcufpmq6z+YAC2O/HWomuI9xXauR36GgC/9oO3cQwB+vNK04YYwCPXPas03IOQJFwP4Rjio1uc5yQvP5e1FhXNZbr5l54zzzTRMBxwTWclySB0z/P3qUtkk8DsPrRYZ6T8DdPg1bx/YCUKRExkGR3AJH611H7enjE+F/hRptpGdrX16A3OCVVGOPzxWT+zhZC48aCXONkbZPrxjFcp/wU23ReFfBmDhDdTA+n3BUfaB7H5/T3L3Vw8jMTk5OTnrURiB6dj6U215Ygj8KsFsMMHmukyGpCWTLYUD1qvMSzf496mnuCAVHpwMcVTyScdqALEBwpI55596lcAxhiPzpLWLzEYE9TyKLsiMhFbgdRQBAeCcgZPOaarAPjocUEjJzwe1Mxg9MAdKAJy6hc45xTHbdzjBHfNHfPUYzkUmARQAuMlcjnPGacxxxweOtGCF5OSO9R7gR7ZoAGIJHGD3oUgn/Z44H+fpTm4OQcD86Z0Hp9KAFU59fqKX0JAOKavB/wAKCcg55zQAO2M9TntSglsj3pvXtn1ozznGKAAZOTzj1pBwDzu460vO0EDtk0oU9uOfzoAaQec8VZhASJifx4qsefqKsx/Kh5zngUAEmVOeuelA4jGMnrxURbccZJ/z61aVMxrzkA0AIzbUJxzj8qrE/PnJ49RxUsz5AHIXHWmiPoT39BQApGw881GTu6E4qe44Xr254qsCS3PA/nQBLswgP3hTMhScd/xqdiMKecEVGFyRt659PrQAiL16g4710/gf4eav8R9TNjo8AeRV3SSudscY9WY8AVzRIX5VyDjBr2DR/FkXw08FaTaRjf8A2rMLnUERtrvECMICOmcNSY0UPHH7O3ibwNo8OqSta6jasdrPYyF9h9+K8ve2kjJDIy9sEe9fd1h+1z8MrbwjBbRfD4nTI1WJ/N5XdjucHJ964G+8S/AvxVqVrOthdaf50wMsEM+UQE/7QB/I1mpPqiml0Z8qWWm3d9cpBbQSXEzHAjjXcT+VdBq/wy8UaFJHHf6JeWryxiZBJERvQ9xX3d8NtJ+CkfjGCDRZZtN1C2USR37Ou4naCcqwII69PSvcfG/wOsfHVkuq2eqy3WqRxnyJwU2yL12kgcex7Zo59dh8vmfkF/Y90JZIzA4Mf3l2nK/WrWn+G73VZ/ItbeSWb+6q5Nfeup2N18Ilng03w7aaXqFxKZb+41mKO4EyDqUyMY6HINfO3iXxhP478bDUp9NS10Z5yJrLSUFp5qDgMxUHk9faqUmyWrHk7aHp/hmWWLWJ/OukH/HnZkNg/wC1J0HvjNdh8B9F0vV/GSXN9rK+H/scguLZjCJSzAkhcnAH1Net6x+zx8OPGmitfeF/EN/o2tCIvJp2r4kRiBk4kCj26181tDJpG+MyL5schhOw5HHfPcdaaakLY9k+MHxR0XxFqmrypd3OoXl4cTXbxgbwDjgZAA/CvGVTRXBLPMD/ANcx/jWbJM8vyn5s+gqJYJCAdhz24ppWVg3Nd7XQsDFzMoP/AEzz/WnHTtHZsf2gwzxkxniskWrgDCN+VAtpHH3SPTApiNZdL0vzCv8AaYx/eEbU/wDsbTV4GrRg9fuMMn8qp2Oh3mpTpFDbyySMRhUXOa90+Hf7G3jLxeYZr+IaLaSjdvuR+8I9k6/nipcktxpN7HjiaDZkjbrUPT+62P5UsugxwSjydahJznKswxX2PafsHeHNKhRtS1nUbiXIAEISMH8CCaS//Yq8GNEPLv8AVLVscvJNHjP/AAJBWftYl8kj5AjsL1WIi8RopHTFyy/1q1AviNBui8TuvP8ADqLD/wBmr2nx7+xZq+kxLN4f1AaojZIhnHlOfQK33Tn8K+efEfhbVfC2ovZ6nZz2VwpIMcqEfiD3HvVpqWxLTR1BvPGcDDy/FN0c9NupsR/6FUy6v4+Vd6+JLyT6X5b+teds7tnLk+lAkZf4iD6DjNVYk9ETxF8QkZJE1e9aQHKuJQWB9j1pdU+G2u+IbfTZ9P0+7v2jtlSbyk3nzN7u2e/8Qrzr7TKp4kZenAatjRfFOpaLcRTWt5PEwOQVkIwcj0+lFuwEHiDw5eeH7g2+oWclhOqg+VOpQkH2NZC/I3TPHPevqr9p7W7X4l2XgS1mhU+IW8OQ3MdwmA0smSXjb1yoyPcY718qFTFlSCCDgqRzmkndXG1ZiO3y4C8HikVdo4JAx9KHJb2FPQlT2xjpiqEHIz6/SpYiRnI5qPzMr79OKWNjjB7Z6mgBkzAuTjg8c0q44J6E+lI6ZIYgk9eeaAcEKOOcn6UAOGAcZ+XpwaYww2TyPU04Ody4wOajcnK45oAl4fBGM05htXI69qi6kc9KlDl1YAE45oAUPlA2QSO9Qu3PI/KnRjoT1NOuArONuMfWgCOFm4x1p8q54A6/rUPKHJPHQEGpjl413AFSetADS3yAdulRuM5znr2p5wM9gfXmmdAQOCTgYHFADM88YGOc0uMHkhiOSelISc4wKU478H0xQAdMAdR7UcbuvFKOBgc59KUc9B0oAMZABAPamk9dtKWOecfWgn0GT1oAFOB1/KilPXg0UAfcn2MqcBR9QabJD5bAFyp7DOa62TR8Ngj9f/rU3+yEA5Rfq3NYXNTk3tJnGQCQBzzUcMT/ADbAR69v6V1v9lkfdVSO+FoOk89C305xRcDlngc427k+hzmjyHTqG/76rqptKiG3aFTPoKhfSsAYyP8AdWi4rHMPbStxGOffIqbyH2gfMx7gEHH510aaU0hwB09M019J6blP6Ci4zBjj8okhGyetJIrkZbp25NdDHphPBG76DNK2njOAMH0/yaLhY5tY3Q5J+X64/XFOWMh93Dg/w5FdCNNTdyoz7innTDj5Yx7HFFwMEKWXlSAf4dxxUbQMX9I/7o5/Wt4Wwjk2kDI9amWxjcbmA9yRxRcDnDbHblVKj+9/9akFuSOFJfs3T+tdCbFFn4K7Mfwnj8qc+nggsqk+4xSuBzgtCp3OhLDtn/65oa2LvlYiB0rfFi2RlMj1PWpBp6spyM/rTuBzzWzp/wAs8D6A01bZpOQgGP71dLFpaMhOChz0HFL/AGWMEnIPpwc0XA5l4HJGUA+gNJ9lVPu7UPtnmujFgCPmBX8c1GumqP4jID6Y4ouBzxtXbG5yf94EUvlPGOAy59Oa6NNKQZwhb3Apw04t1yfSi4WOSNsFPR1z7VH5BP3uR9K6waNtJ5FMj0vax2BGPei4HNmEoo2oM/7AOagZJQxOQeencV1SaaFdtq5PfcOKa+knO7YCSem00XCxzDx5UHysMOS1RSRMcDGD06V1i6M5OWVQp6Y7VXbRjheGGB0p3CxyyhlySPmJ6elTB9/94Y9q220fC/OvH1pY9Ey/3SPTPcUXEdn8ANSnsviHYpF80coZHAI6YzVn/gpFp6Xfwp8Pzuv7+PVFVGz0BifP8h+Vb3wK0JI/HFrOQp2xsQPf2rnP+Ck+oJF4I8HaeCMz6m8hX1CREf8As4qFrK43sfnH5TWrk54NSIcgsQMe5q1qMaJcFeMA8iqN1KMbVAx3IHIrpMivM+45GeBnOKYvBGeR6inqd2M/dPt+dPKhV7jJoAlsZdhZT355qO4+aX8KbCDvOO1OZgT83A5/CgCEZLd+vA9qV+Ae/wBaVjgDv2zSPgAn37UAJ91cEcdMU+IgAYJx71GPmyTyfSlPAxgCgBztzz0xwabgHHc+lByTnrn09acxxxjJ9hQAHjAOf51Gw3ZPY8c96cCeh60hAzzn0FAAOT0+bvSHgZPPtTycggmmjIYg4PrQAmdo4BFIecg+vel7gZ4pqkb/AJufxoAcFJ4zgYz0oY7gT1U5pq9+Mf0pwIHJGcetABkkjPGBVhV/EjpVZR82R261YjzkDt3oAcYtke48M3Sn2xMybB0J6Ypk7gtjoPWkiPlozZJI7YoASVMyHjg1Iqsyg456CmOfM29QCccVL/qFGep60AVnLMSDz1/Smfdx39sVK5AHDZHtTFwBk9e3FAEo5UYwD3qSIEZJwTkVEZRgjIxShio5PXpmgAb/AFgGM89q9D+K9qirouyPymFqibTxggen415/YWz3l/BEiF2dgB6nmvadVtUvvE1xqmpxK9ppEQQI33WcL8q9x2/SgDgPEjNofg3TNJZNsszfa5SDn733Rj6fzrjAxViwByOhzWl4j1ibXNWubuRi29jt7cfSsxgMkZNAHReGtav5tStAlyEkh4h3nb+Ga+vvgl8dvElloqfZdTeGWFissDgMjYPcYxXxFGMrnPNbmh+LNV8OzB7C+kgA5Kg5U49R3qWrjTsfo34o/aCt9Z0fyPFfh7TdWtEIYRzISN3r/OuY074ieBtWieTSPAGgxyEdie3qBXyr4M+JPiHx54n03SLqa0SKVtru0eBt68847U2L4j3vhnxDqUdilvCIpmSMrHnGDjPJxWfIXzHb/tJfGeS6t7PRNFS10eBlLXdtYWwj3H+H95jJHXgHFfO1hIJo2VhnBLHnnp/9avV9B1ez13wl48utX0yLVNUeFTBfzKpa3JlTlR26np615RbKRJMwwBtJrSOmhDd9SOBlMyYHGO3pV44IIB57VQgx56YyDt6DtV/B7Z/CqEKE3kDbknk10Hhvw/Nrt/BaW0DXEsrhFRFyST0wB1rEi+ZwOeK+yf2NPhhHHHP4pvoSTnyrMyICM4+dunUcAYPXNRKXKrjSu7HqPwR/Z60r4Z2EeoarbQ3uvEbhIp3CH/ZQHq3vXdeN/i5ofw+0432qXUdtGoIMRYF3H8OOMk+3bvXIfGf4p2fw60K41q4YtLGhitbUNhWcg4/HIPPBHzelfnf4++IOsfEHXJ7+/unnmkc4jDHbGD/Co7AZrmjBzd2bykoaI+pPHn7dyTytDo+lOYF5WSWXYT+Azn8a5TTP24dXt7pDdaak0WeQly0ZIz/s4/WvDPC/wa8YeM7c3GlaHd3sI48xY/k9/mPFQ+Kfg94t8IxedqmhXltCp5lMZKD8RxW6jDYycpbn298Nv2nPCXxCuf7PYtpF/ORiC5ChWb/eGFYnjhh+NdX8QvhXoXxE0prbUrNZWCEQyqfnibnleffO05B6gkV+ZVtcSWkoaMkFT696+yf2Ufj1LrLJ4R8Q3QkkCYsLiUnc+P8AliWPfup7EfnnKny+9EuMr6M+evib8NL74fa9LYXkYdcZiuE5SRfUHH5jtXFi1RtxKgem7jFfoX+0F8N4vG/gW+EcGb+BDPaOqDBcDO0E8qHUdB3HPQY/Pm5BimkjZdrA4IPY+lawlzozkrMqi3TB+QDB+lVpl2Soq4UYHvnnrVzgg8gdfWqE5zcgZB6VoSeqfG6/uINY8HKkpjkg0K0CuvVTgkEfQn9K4DxjYl7i11UbVOoIZJEXAKyqxV+nqRu/4FXoHxKtoH8b6RJcspgg06037idoHlj+ua+jfgHZ/BX4rfDu38H+IrW1tvE0ks7x3oUJKQznaVkxxgH7p44qL8qHa58LLjH6U5IwPTHTNejfHr4PX3wS+IV94duX8+EATWl12mhY/K314IPuK85xx7Hoaq9xETsqsQFHPTmkRiox+lNDbpO+Peng/N7ZxxTAeGynHb8qkjiWXOfrioG4HAz7mpoWAYAnBoAjnUI30/SoepAHJPepJypc9jTI8Ejn3oAM7Tg5P1qSKUDoCR796a6ds4BpI1yw7885FAEyxfODk8+tRvgyYUY+lWWXKbhxjqKp53OTg8+lAD5VBAGQD7UoyAAemfpmkcAlc8H1FOY4XGckUAMyNvTtjimB8A8d/WlYDA6/j3ppJA5GfwoATGcYwO9Gfm4HHbJo+7jnHsKCevp/KgBS2M5A6cYNG44yOPWkJOMd+tA9OaAAnt1OfSkY4GdxJ5FKMk49PUUuDg460AAfA5BooyO6hvfGaKAP1AksxtJJfGOmCaqrYKx4RvqT/wDWrrPsYB5O0+gBFNktV3j7xPYjGK4bnVY5SXTiSNrFB6AZzSppaAHPBP8AcGK6z7GT/AW+i002YTrETnuoxRcVjl20raBujK/VhzUi6Sx+7uH14/pXSvY7MY3HPoc/ypfspb+EH60XHY5T+xmBJTAbuc4pr6Gz/fYe3Oa6o2UYz5jYHbApRp4XlSSD0zRzCscf/YzDpGG+tKujeWS21CT2C12n2RIxkuV+nFBslYA9vU0+YLHGDS8HO1RTTphZiuVA9xgV1zWK7j8uR79P0pfsWPuxqvuAaOYLHHtpLDOTlfbOKP7N2oQBkex5rr1swW+YfUYofTkdiAuM980cwWORj01QM7HLe5pTaqW2FWX3B6fpXVf2WoO3AI/EUh0tS2wKQPXGaLhY5gWSqwVcn3LUj2A342BiR1INdQdLEJ4yWH+zx/Kmm1dpAGAXP0FHMFjmf7NIH3WVe+1TilGl7uUIIHXd1/pXUnTdpGN/4Hikex3NnaOP7opXCxy0mnqCNylj2Ix/hQunJz8pH511P2Mt7Un2Be0RH+8MU+YLHLiw8rgLnP8AdWiTTiOkefoa6g6aScjI+vNLNYsxGUQ/Q0rhY5MaZ6qE+oxSrpUjn5cD6viusuLAkLsH5Uw6dgAsD/KnzBY5X+zZ4+3meyij+ynYZEYDd811a6eAeRx6daP7NGSVDH6CjmCxyn9nM2EZQoHc0j6duBJXGB1JrrhpJI6HJ7EVE2k4IGOBz9afMFjipNP+XCx4FA03BUhOQOufrXZS6aDkbcKPbio/7KIOQn0J6mjmCx0PwSsvK8RMzH5whK5PavFv+CmLSR/8IExz5Hm3AyPXCV718OY2t9diwoGeCe4HNeT/APBSKygufh14VlfIuU1U+WB/dMT7v5LVQepMlZH53akwknZuo9h2rLlb94cDAFamoKEHc8dDWd5QlYY6n1rp2MBsRyd3Hp+NSScLuOTxT0tHywI4FDqdpBz16GmBXixux+tSeSzZOPl9+KbCP3ygirVy2IwB24/xoApSHB4+nrTCTxnn6dh70Dk5JxilzkdQcjpQAnBB9+1KCRn68c0mdx7mkwDjGfegBckcfzqQuQRyPY1GQAAQTn0FKOvuT1oAGBDE+tISfpTjnnA7Z5ppOTjjn0oAFUdWA6cUEkEjGM+opSD6Zz7dKTByQc4z270AB9/wpNuRnAz9KP4T0FABBGeOOnpQAm8dj2pQMDPb60dCMDnPQUDOBk8fyoAcvJ46+v8An6VMnLk9hzgdqjhz6DjualtlUAnkc9c/59KAGynGcAjPSlTCwjPQnvTJMNjByM9qmjUNCQfXPtQAsYBQHPH61FLKHbK5YU/cVjxgHng4qJRngYJ6YFACxkbQDgn2phY7jz+tOVcqc4xnFRtwdvb0oAk+Vfm+tKeRjOMGlUDy8cgg8ZphHTj8cUAdF8PLcz+KLV8lVgJmPfAUFv6V2PjzXHtPCVvZ5dLm/me4lLdWU9M/rXO+CIWtLPUb0xsQiCI7e248/oKoeNtYbXNUDbiY4kWNPTgUAZOoKtutukeOYwzH1Y/5/Sqe3cRnrUk1yZooldAxj4B7496iToD2HtigCUJ26ewNKgx0/wD1UB/vEAjk0xiAc/pQBoaRez6dercW7lJEBAYds8f1ok1GWW6kldss7Fi3rnvUdrbXE9ndzxRlooUDSOP4VLAfzIqrvBBB5Y/pQB6Foni60t/h94i04QKtzPEoEv8AEx81D/IGuNhYRGUnvH1HvVCGcpDMnB3AD9RVm5LREKVI+Toe9ICOFgs4boMVeEhx0zxmqEOTOvPUA5xzVsENkk9PU0wNHTwJJkyO4GOa/SjwJp3/AAj3wh0S0skEdy1nCPm3NlnAZs45xyfzr8z9Nm26hExAAyM1+qHw2mj1D4fadJhZF+xRMCwBx8lc9bZGtPqfEH7W/jq41/xydHWTdZ2CL+73ZBkI6/lt/Wqf7K3wXg+Kvjgf2ipOlWQE90BwWXso+pFcD8U5JL3x7rMjsSxuCCc556V9W/sCyRJpviSMAGcmE89Svz1cvdhoStZan1jaaLpejabFZafbRWlnCoVIUXAA9hXJaxoC6oJYJo45rdsh1cZBXnrXVXJ3E549+xrA1KdzbOFBGTjOe1cSZ1WR8FftR/BK18BX8et6TEsWmXR2vboDiJwO3sa8T8M6vcaHq1te2rtFNBIsqOpwQwOc/pX3Z+0zoyah8JtUllkAMQV13gdRXwfbWjQyZweBXdDWOpyyVmfp3pniAeIvBtrqscgCzWyXAUdMsnmDH4rIPbcfSvzx+MGmDR/iR4ghEflA3LSBAQdu/wCYAf8AfX6V9jfs46pcaj8MLC1ljLRw2+xXJz2uD+fP6V8m/tF3Yl+LuujG0oUQ5GOQoHas4aSaKlqkzzgHkj/Jqm2PtQJxncMgcd6kL4YHPHeq6tvuF6/eFdBkd38a74t4yaGMeWgtrf5QcgHyl9a47RdWuNK1O2u4ZSkkLhgVOO+cV0vxfmE/jq86jbHCmT14jWuZ0bT/ALfqNtbL96WQL+ZpdBn0Z+2L4ibxTpfw41OSNSZNNkQTA5ZwChCk+27/AMeNfNG4Ku7nHavZfjjdb/h98P4CAZIYJVVs9RhAf5CvFeoGSQOORSirIHuB5OcfTvTgeMcdacpXAyQCfWpBHGR83BxiqEQkllPb8KdEyj5iTmo3+90zTQCpGS2D+FAD5ARk9ulM4GDjPXjFT7tykYHTFRFmXjHTrxQA8fPnPapNg2ccFj3qEY6Z56YHSnr8yHJ4HPFAErECM7W/A1Vbjg5571NGh689CeT1qNlDM35ZFADx93Jxz2HWo1U5/vHpUikoMZ601lGDzgjgmgBjYK+m3rnmkyNvAzj1oY7cUmM8cHPrQAu3jByO1KAN2OPfPemEAkng0vQnoMc9KAAls8nPFHH0BNGcdCOnOKNu4Afn9aADjGR+vrSkjJ7ZpAuCR2zTsYOOmeaAGnGfu5opdq9yDRQB+vj2QZtxTH4809LUbCAq8/3jzW0lgCMjgehqVLPKkgMAOw6V5h22Oa+xlTgryac1gGPzIDj2roVstxycD6Ch7UcfcOf7v/1xQFjnBZq33F2+uTmhrDI5DfjXRLYqv3g3PqaDZhj8mfzphY53+z8fwk/Wl+yE8DPHbFbz2YAGCzH0TH9TSNaDA+Q575WkFjFXT2TkqSD0701dMy5+TH15/St4225QHUAds5/pSC0TPAP4UwMRtOBGBkGmpprI+5ThvUDn+dbXlEuVBC49qPszg8HcfzpBYxnsmIO4/N6sKQWpC7e3qpNbi22/5Tx64z/hSnTlHRst6YP+FAWMH7ASM7T9Tn+tOXTn25zx/d6GtxbQK2G4/MfoakEJUDaAV9zTAwPsH+zj680osMDorH1HFb32fc2/A/AUpgBGTjPp/kUAYSWTFcAED2JxSrYsoOFU+5Fbf2LzGDbM47jj9Kc8QTjAOR1IxSAwTaMcEqP+Ar/9ehrLzMYLPjru7VuRW4AOwfrmkFuc4ZTzQFjD/s8L0Gc/SnjTdmdij34xW2bHB4+X8RUhsfL6MWz68UAc8tishOE3EetPhtkjY5XcPQtjFbEln5fJAOfTNOWyJzuyw7AHpQBgpZK0jHaG6nC54pDZIGPBHsa3jpoXklgD/d60hsA4wuSfpz+tAGILNuMISvrjik+wAHBUZPQitv7EVBHUjtTfsuc9vw60wMF9PBJHXPWk+w7SOM10C2hK8DP1pGsse/4GgBnhO0EOtROi/lXhv/BQ6bz9D8HW/JP2mdxg8DEYFfQegWxj1GInjPb0rwT/AIKE6YYfB/hXVMk+XftbEf78bHP/AI5j8a1p7mU9j86NZZhcsueecin6LZmU7sZAGeOag1WNmuX4LHPOK2vDcWLdiwxgE8iu05yrqbpECADkce9YryFzjktnvV/Wd0k5ABK881TgtmlKgdDgH2oAIICULuCADjk+9JNLnICnFaN0qQwKgIPviqbQeZjBwM54oArEErgDgDnmkyQOQFHqakLAfLt4HeomJPB5oACOMEc+tA25xyCKB7np2xSjHXIzQAw8DnPPFKGIwcEnvinFc9DzSdwB0HqKAEDHaM/lQBkk9T1NBxjnk+g7Ui8AEflQAoyehIGOlK3IwBjHWms3Unn8KX7vI556CgBAOeeSOvFKCSMDjJznNJ9QfpQuTjGPQUADtjAHP49KQkhSMdKXAI565oUZI46DigB8Y4Y9B6ipYvuMQSOaiTIA4PIp8TDB9zzmgCSCNdzZzxRCS0jDk5pCML1685otm2Ox/Qj+VADpUKRgnrzUKL8o7Zp8jmQ/iaAuAT+FACMpQ4H/AALHeo1U98etOLZPbPrSZZR2oAfjzDinxruOevI5FRq20YOeantY2nmjjQEuzBRigDs9v9m+BhuAV7tvMLnnIHC4FcK24rwT6nvXa+NZhZ21rYB1zCio21uMgVxjctkjp6UAM5yTjoAeKVFywHXnFTQ2slyyxxRmR3bAUAk/lXr3gj9lP4k+NbZbqy8OXNvbsOJbseUD7jdzSbS3GlfY8icBMjr6c9KgKl2AHBPHvX0RffsO/E62tyfsNq5/urcAmvPvE37Pfj3wcjyX+gXBjXkvBiQfpS5k+oWZw9jqcmn6ZqFoqZF5Gsbc9MMrf+y1lgnB7fhVq4hlgZo5o2jdTgq4wR+dViuOf596oQighhjuRWjqLg3TqvZVHH0qvaoC6jA65z3qzqJIvJMjB4I46cCgCGElZjg5OMc8VZU4PrjqKhXHmHJ69ambIQnHbGKAHQt5UofkAc4HWv0M+AHiaLxd8GrFDO/nWkQhmwSpwmQRx1+Qsfwr87w2ZMkfSvdP2XPi+Ph94pOn38mdN1IojFj8sb9mwT781lNcyLg7MwPj/wCFbjw38Q7szR7Euvn3ZyN44b9RkexFbP7PHxim+Efi1Lx0aXT58Q3USgcoT1HuDyK+lPjp8IoPiT4d36c2buMB7WXAYNj+HIGSQOMd1CkZxXw5qejXvhrUJbK/he2uImxiQEdPT1HvTi1NWYO8XofqjoXjLTPGOmRX+jXsV7Yy/ddeo9QR1BFaVrpsd8kjyghB27Cvy38OeNtW8PP5mn6ncWTH+K3mKfng109z8aPFup2j2t34g1CWFxtaM3LhT+AOKxdHszT2h7n+1n8QdLvoI/DOh3ou0WTdeSRn92COiZ7nnnHTpXynNZSTzxW8ILz3DhVVe/Iq7e6qJN29i8mOFU8mvZ/2evg3d6rqsfiPWonRUx9lgI+YnqCB2b0z9TwBnbSETP4mfQvw40RPAfw8gjk+SK2tvMlZjjnbj9f3p/L1r89fiB4hPijxtrmqFt32q7kkBxtyCxxx24xX1/8AtY/FeHwb4TfwrYTh9S1CMrKIiAIk4B9wMDaPYe9fDmSQDnk85zU019pjm+hKhO0jk56ZpsRAmQkHO4fhTsnAHPTkVJp9lNeXsMcUbO7SABVGT1rYzPQvix4Vkmmn8Q2m+4sxcC1upQOIn2KyA9+RkZ/2a5Lwmjwaj9sVf+PWNpRnpnHH86978M/DLx7N4h1VbPwve6jpF0dk1ndQMtvdIR0ycDKnBB6iqF3+zN8RNOub5LTwVf29jO24Rr++KDOQNw6/lUKS7jszzb4sasb7T/C9pni2tXOOvVsf+y155jnnn8K9c+KXwq8Yxa7ufwxq0dpbW8cKyPZSBSQvzHOMdSa85k8ManDIUksriMjgq0bVSaAyGAOfUdeKfk7R/LNaZ8M6nKpKWVwcekTcfpVSW0lhZlkjZG/2lwRTEUFPzcdfWn8lRzux7YpWRkIG04pD83H64xQA9Tngj8ajkyXYj0p6YYc8MOlNbgkAZb0x1oAQHDZ6fpz0qaIgkqx4P/16hK7fQmnQjDgnkZ70ASqdm/bkKOntTIcMTnr1xUszKVJHB9KigfZkD6c0AMUHBOeKDyDkZI70oAXODupmPmH+NACZA/wFABJ9B70ZAJOOvWkZjyBgY5zQAAcdsZoPytjjP6UuFYjsetJjGB6UAIvJyOKXOR79KUHaOOaOgxzj19KADg5/WlXkZ9OKQg7/AMqABngcd6ADax/i/QUU0xljkAkdqKAP2r8puoXKdyc0CEN9w8e2ak4A+6R+VCmJgQcg9twrzDtEEe3g9/Rf/r1G0aRdC3PvViOJdpyyn6ik+6Rzu9+aAK6x5/8Ar5qXYyj5V2/U1OwDfeyPqMfzoxs5P8qAIzE6gFSmT/eP/wBaoPKyT1z3weKu7QevzfX/APXTWyeMqPwoAqvEGUZYcegpoXYfkYZ9xirqgjrIf+BEYpphOSc8f7PNAFIws3JwfoaUrhcbMf7W6rQQZ4x/wI0pRTwFQN6gc0AUvLZuOKkjjMZB4OOw61b8r5ecA+pNG0gYwGHqKAKcsRkfeFwfQjmnJAeCR+fFWzGAvCnPpmgKNmcAH0J5oAqta5O/BGO46UnlAnlVYf3gtXUAKbSgOe+OKaYwGxwoPYHigCqYUz8r49iKcIsg/KG984qw8aIeevoOaEhEwJwVA6hqAKvkIOq4+vNKqLHnBJJ7VO0K/wACKo796WKKNchTj2OaAIj+7GGBXPoM0BC+cBR/unNWRG46BU/HNL5Sxjs+fagCmItx+Y/9881KEJ6Fv+BDNSiLHTA+uaaUGfmJFAEflNn5SM+wxTmjLDHf2NThMD72fr2o2A9Tn2oAqiHJxs/Ekc0nkKMcDJ6VbwD8uwKB/FnrQRg5A5z/ADoApPDxx3zkHpTktxk4xmrDId3T8KXAIJIHsaADTkEF1G/Awe1cZ+1p4Dj8e/BLV4iha408DUbcg8howc/mpYfjXbxEKynqQfpVrxr/AKZ4B1qJcbpLGZeeQMxmtIOxEtT8WvLWfVzGMMGbr7VpXcjwOttbryeGHtTNMVbY3U7AbkYqDnvT9LnEUUt3KSxbODmu85Qlt0gT96AXIrBkuY4nZUGOcetWtT1b7QxIPPTHtWI7fN1Bz60ATvOH78+ppskpIODx+VQA8Y/HNLwf4j0oAQ9cnp+Ypw57ZWkVgByuacsmOSuT6gUAD53L1GTxTRgNnqe/FNLg5GM+9Lx7k0AP4ALHOPamFyQSM9OtLuI6Dj1poxnigBdvCnrnnmg4GcHHqB60hznOMg+1DEdP0H6UALlieDmkZvXn3oC9znn16UDg+g60AAILYJ6dMUvIOM8dPwpvfg9evpQeDjt60ADEg9MelOVx0HWjrjHSkXGSMcnvQBJzt5FLuOMk8j1700sWAwPwoTJPPftmgB8hGM/lSwnlgWz2wKjYkEc9OaIzhhnt1OaAHovz54NPkYqDxknrgUzooIJ4HNNZiy5yc460AIvzMRjJpCMcjsKmWF2ACIWPsCambTLt1O21lIPcIf8AP/6qAKeMHGcexrofBUSnXInbkQgyY9cc1Ss/Dl7PIB9naIY/5aDb+Ndro3h1fD9leX8sgkfy/LAHQZoA5XxPefbNWlccc9qyoYmmfaDkngClupjPPI/Tec8dq9z/AGP/AIRj4nfFC0+0xB9N09lubnK5DAHhT9aTdldjSvofQ/7G/wCyrBbWdl418T2aSyPHvsbSUZAB6SEfyr7S8sImFAVQOg7U2zgis4IoIEWKKNQqIvAUDgCpM88dDxj0rjbvqdCVitNAJEwwGO/Ga4PxxoEV5YygqAcHt1r0dl+Xgg+1YmuaZ9tt3XHOOKhrqNM/Pn46fC6xv5ppzbKkwPyzRDDc+uOtfK+saNJol48ErZIOVYdCK+5Pj5puo+GdWzdRSfY7g/JIq/KfYntXyV41torqORQMvGcqc84rtg7o55bnF2Dr5xJPHqata26yXEZAwAuKylyj8np34qzcztLtbJOO3rVkiwkmZs9hU5bC5IwMc1Wh4kPP4VLg+uQaAHlSw68ds0+NZFcleSvIPcfhVzS9NfUZgiIzbjgYHX6V9m/s5/sWf8JFa2niDxYGt9OcLJFZbSHlHXJz0FS2luNJs439m/4/X8SJ4a8RQTXViFIhvArFkwcgMV5wDzuzkV7N40+E3hj4sRh5FS4mcF47qAjzQxGclSQG7fdIPqpNdx8cdM+HngXwUdPis7bTH/5YwWCKJXb6Dlia+ePB/wAP/iRrkr3Hhuxl0PTXYGN9YkZDICeP3Y/xrn0fvLQ1V1o9Tjdc/ZN1KK8dNM1W3ZhnMNxII3X/AL72H/x2su0/ZV8UNOF1C9s7SAH7/wBojbP0G8V9Z6Z4e8caRbBNU1jTriUDkKHX9DxUd7p/jUh202XSXmYDCyFxt/FR/On7R9w5UeWfD39mTRvDZi1K6L30kbBo5ZvkiBHfkAn6Krf71aHxa+PmifCrS3stHmS91oKYkRV+VB3+gz3ySccnisjWdf8AGGl6/HH44gvbKyZv+PrT1MtqAD/GcBgPevT9T+BXgL4yeCoUVYUvDHm31ayKmVTjjOOGX2P6VLet5DXZH5y+JfEd/wCLNbn1PVJ2ubudixdh0yc4HoKzghcbR2/zzXr/AI//AGY/GPgvxtF4eWwfVJLk7rS5so2aKdPUHHBHGQele9fCf9hiG1FtfeMbo3EzYc6dZ/dB9HbjP0H51u5xSuZKLZ85fCf4I+JPizqHk6VabbWNlE15IcRxA+/c8dBX3p8Gf2WvCvwyjgu2tBqmrquXvblQcN1Oxei/zr0Twx4RtvCljHa2NjFYWUWAkMKBQPw/rXVwlRGPT19a5p1HLY3jBLccjmEKFX5QMcVoWV4TIqt096ypJ0XCscfypqXyRN8rZz71kaWOuRUdScZ7c1UudF0+5bMtlbyMP4niBP5kU6xvFcA542AkVaDBgcHJHb0rW6ZmZ6aPZRcJaxKv+ygFeafFT9mTwJ8W7eZ9S0uOy1VlKpqVmoSVTjALY4YfWvUZ2K5PrVNb1kIBywz371Kdh2ufkD8aPg/rHwZ8XXeh6xHypLQTp92aLJCyD646dQc156sKBSMHOSCK/Wn9p34MQ/Gf4eTtZwQt4h09Gls5HXJcYy0eevPb3r8qNc0e70LVbiyvYGiuoTseN1KlCOoIOOa64S5kc8lZmRKAmcHAHtUagk4ADetLJGxY54HXmmcMccjmtCSUjd69elHcDApFYZxUk6bSpHGe4oAZIxZffpTI8Bj2PQ4p7sVAUnA9qjDbCOM9896AFYAuTxz6U0HJHYHqacxGDzt+lNxt9v60AH8Pt1z60ZCjPHJzmkAz/EM9vSlxkYHNACDJA7++aM4HofTFAAHbvSgY6jA6k0ANxgfX2p643cDPvSE7cEd+lOA5POMUAKELJk8Zpqr6jHHSldjgDpz0FKqluilqADA78ewFFO2SKP4vwFFAH7XINq7VHH5/qKD8pA8wL7ZppuAvVvm9sChLncp5yPVmrzDtJVTcDj5/cdqYFZeFHB9aaZXX7nzL3xQsu4cL9cmgCVk2Ab1LZ/vc0wuvTIH/AAGkE4boAmKR3I6ZP+9QA9DgnOR6YGc099qgE4we5qJHZMlsYx705JFcn5h/wHrQA7IUZyT9OaCN3RQ30GDUYkidiGUcf7WKmQqPuqPxNAAN2MYb6Hn+tMVgJdo4ceuKewJHHyn1BpCUVQTs3dznBoAUtjpnf6gcU5G3L8zc96i8w/eHI7Y5pVIJ3HIb0FAEjAA8fMPbg0g2hs9/TPNNZ167mLf3etKpJIJ3H/ZJH8qABmYvnHye5p2FPzKAT24oLheCMfzpNwPIHHqaAAYkIL4D9gBTzI8fykkE9sVGdx5Vm2jqB0/lR9/nI49DQAKhXOVx+NAwDwfyo80/xAA07AH3QqjvQAoBPcj86bKSCOcfWnMFJBB59uKduY/fz7bcUAMH7vkc59R/9ekRNhJjKsT1p4K+o/nSE47E/pQAhC+mT3FKVYgZYAelPDK3DYSlUhDnJx+FADFRlOT0HIpQhySfwoVsyEc89Of6U9z8oPTNADDHycDAPJGKZs+bkA/hUgOAOp7UoUZ4IoAaEwenJPQ960btFm8PXaMOGgdf/HSKpIm0Y6GrmsyR6Z4Xv7mYiOOK2eR2Y4AAUnk1cSJH5D+I9CXSV1OGX5Cbl8jPoxGK4jUbnyYUhiPycnjvXa/EHWItQhuJyf3s8rygg9ixI/nXmTys3XPXv1rvRyiSuWzk8+tRM2D7HpSswOQST7imkcYIz/OmAAANxgADp70uQ5Ge9Aw56EfWrEFvlgWBGfXtQBDsLKeOvGKCmMZ464xU0jYYqO2ah3HnHPpzQAHI+h74pvOcfhT44zM2Ogz17f55qzPbpbBeQSRgjNAFQqeCelOJCqMgZ6cCgsxzwc9TxQE/dD1HrQAn3uAOD1oMRXGBnjin5AJH3cVJChdwD8vNAEBUsAQuR9elNVDgEAgVdNvxwc9+OamgEMZ2su5gO/0oAz1gfaeDinLbMO+MnvirV1ImdqlTx1BqJYpHXIBJ9cZoArlcE880hUg9unr2qV7Z14ZeT270ht5FXIXdxQAzp9AemKaOckDp/KnEEE8EDpkUsUDzkBELHOMCgABwOnNCKXYKBye2eauwaDe3EoAhdQfUcV3Hh7wUIwJrjCIhy0j8L9KAOV0vw1c37hdpOTxjmuos/CekWMRe9nMsvURRjP4Zq3eaqmxYNNUwQA4aZh8z1mDyBKI2O9jnJFAGvY39ppwZ47eKKPBAz8xxTJvGeFMdtC8hPAITr9KqBraBCoCk9PmOSKgj1SGBj80aKpyMYoASe/1a7bKW4jzyWc4FW9dvJtP8JfZ55d087lmCiqcviSCWRUQNKx6bab8SJPLmtIAwJ8tSVBHBwM/59qAOLDE4Az16HjFfop/wT70C30b4c6jq7Jtub65KbsfwJ/8ArNfnQBk5A9ua/Rn9jTUJbb4MWMhyVF1IpPT0rGr8JpDc+tIrpZOhIz0qyMkHn61xFlr6iQq7j6Z6109tfrNGPmHIHtmuVO2hvY1MBgOSQD1qjeXEUbbCwDsOKp6nq5soAc/M3Ari9f8AGkNtMUbB29CCMihu+wWsbPiDRrPXbKW2vbWC7hY/NFMgYH86+Kvj/wDsmT281xrHg5HlUF3m012BwOv7s/0P4V9Oz+PknmWONixYZYjoBVpNUN/KTwQ/XmhOUHcTSe5+Reo2ktneSQTRvFLGxVo3XDAjsQaVeY2weQc/Sv0D+Pv7LmmfFFH1XSiuma+qn59vyTYBwHA7+9fBOs6Je+GtUu9M1C2ktby2kMckUgIKkGu2ElJHPKLiVI+47H1q5axrM6LjAz8xz27VShbBfJJHcGuk8I6HNr+sWWn2ymSe7mWJEHU5OBx9TVkn1V+xh8AIvFt+PE+uW27RbNisEbdJpRjjHoAcmvrn4nfFH/hE7S20rR7V73Vro+TDbQJ93HU56AAfy4rM0WPSvhH4BttHtJUhh0y3JkaT5CzYy7kH3zzXMfDa1S5S/wDHWpPNO+o7XtLacbTGn8ChfU56981xOV3c6ErKw7Rvhjpmg6k3iTxLPJrmvSqWQ3O0CNe+0fdRR6mub+JP7R+heBQ0F9qIWVgf9DswScdhgYJ+rMo9BivP/wBo/wDaBPhO1nsrKZbnWLkEeYp4Ucjf1+6D90dyM18N6zrd5rF/Nd3k8lxcSsWeWQ5ZietaQp82shOXLoj6g1P9tmW3dk0fw9bR24PDXDLvP1AX+pq34d/bZik1C3Ou+HYpIQwYvauhYH1wy/1FfIhJbqTnPU0u49ug9619nHsZczP0r8J/GjSfikEi0y6tdctijm5srlPJvIuOAiHIYEk5OSAMVPa+FLnwNrltqfhKdI9PvJ1F3YSH5MMTlwP4WHPTg455FfnF4c8Tah4a1OC+0+7ltbuFg8c0TFWUj0P6V9o/B342XPxN0kxrEp8R2Ua/ardCAL2IkDzUHGHDYzyANxNZSg47bGilfc+x9M0xbrbNNmbjueFPsPyroUs4oUUqg2j9K8f8J/FKDyxDNIrTRHZKquCG9xivRLHxRa6haLLbTJMnQ7WBZfqK57W3NdzbuUjnhKNjIGAR2rjLi8aCSSM/IFPH0rVl1+FshJFMnXaDzWHqGo2kS7pZVMh68iluMilvgE67U75NYc2u+VceWDvIPas3W/F1vasVEgz7Yrlr3x3Z2iyTzfdAxzgfzquVibsew6R4jYJvkYKPU8cVv6f4njmOPMDZ6V84+L/iTb6H4Ri1CKcwPM5RU3DLYGSf5V5fp/7RkttMB5ryMxwcN/OqVOXQhzSPu2bVoyhKNuPfmsC61QLLkMeMHHt618/aH8cTfomZTlx8wByRXXaZ4yOr3yMjDbjnP8qlxa3LUk9j2zRdVVx83APGa+b/ANsH9nuDV9Hu/GXh/TUm1KIGa9iRctIoABcD1GBkV7bo8+4REEkBsnA6/wD1q7aBkvLYowDKw5UjjHvTjKzCSTR+QmmyaPqUkUF3YW6lmGHbI/Cq2qeH/C811KkkF5p+GOJI1LKCO/evsT9qz9mrw1Y+Hb/xBoVuul38ObhreL7rnqdo7fhXxj4X8SypcvHcTLvzgLcnCfQmu2MuZXOZqzsUJPht9q+fStShvAeiOdjfkaoXHgbWIEZZrRo9vViQcV6TKIWCvKlowc7gkTFSPTBq/BNhjIjybCn3GO9c0yTw2TR7vzjH5RxnGc1et/C15OoICk9MbhnFezS+HdK1tcvtguQNxaP5c/hXNeIvh/d6bG09nceaijovNAzzTUNCvbFj5sDbem4cis9oJUGChX6iunv9R1KxZobmKRCp6svBFT6RfMxSW6RZIN/zKy9vWmI48q4wSOKltdOnnU+XGXH+eK9abT9F1C1eO2SNpCNwxjmsMwy6QDvg2xDgsRQBxcWi3LAkxEY61N/Ys0zgJGwPof8APtXomi32nagskbpskbOWyOawNVM2m3rqUIj6rIBwfegDIPhi6ihLeSWCjk8UyxgUTFHgwT7ZrsPD3iCCa3ltZG2uw6sRVK9gezV5fLEqZGCgoAzU0i1nb5o9rE/rVR7BbO4ZF6Z5BrZ03ULfK5XkHGO9Z3iO3ltr77TEC0LgE47UAPaxU4IUdOflorNi12WJAuzHsc0UAfsKsyD+ID2IpJJwp+7n3GSKzRcZIPzA+g6U43W4gnj9K8w7S79qB/iA9hxUnn+nH+6f8Kzjdj0z+NMa78zk7xj1wKANYT56/J9VzmmyznA2AE96zDd5+5sHrtANAnUZ2HB7/wCcUAabTMyjAyfrihZMdMj1yTVDzmABUZPsaX7QABzz3GaAL5usfekB9iKd9qjx9/b78is5psAbUOfpmnjlQc/gRQBoG6CqCrkmn7w0YYlgT3LEVnIcN8x49lqUXAYbdpC+uKALokATAy3uOaRZ2U8sAvfJqj5iBsBefU08Nuwc/gOtAF37QM7sjHqOtKXwPMVz/KqYkI+X5j7HrSBsN0T/AHSeaALguAwydrP68GnLLuTaRye3SqbP/FgKB2HIpBIGO4ED2FAF9SI+GH5GnMwz8gBHfIFUkumII2Z9zz/KpI2dkY8YHrkUAWhKP936Gm5Y+h9dtVVnDdvzOaepVDyoXPvQBZTaAcMB9RQsqN0O76D/AOvUDNj7rLj601Zy3I3J+X9KALSzkE9RRGWUk56/3sVX+1GTv0oDM/3WGR14/wDrUAWjIF5JT6f5FOzuwV5J9M1VV2Jxu59uaUOMnK49wKALPmsRtYYA6E//AKqUMGPJIHt3qsZECnao3etSq/HrjtQBYz26EelIoySMZH9ajEmSB360/wAwAt0P1oAs2oDzICc5P5157+1742TwR8A/EE2/ZNfoNOhx/elyP5Zr0SwXfcIOgznNfOf/AAUTnVPhLokDN80urIwX12xSVtTMpn5ueIL95p+G4AwB6Vj7sZHGccjFWb9w0jswwfzNViQvT9a7TnGgDcO+KeqmTG3qamtLMzK0hGI1HJA600uq528dRjFAFiOCNIQ5+Zjxj0pHuSR82AfXiq4uG2lex557U0ZbIX9OgoAQKZn+U5J9K07fS1wTKe/SiygFsGkkGDjjP86iuLwzMQCQueRQBO2yFGCEY74HNZ0hMr7epz19anMchhGASTVm1tlgAeU5J6A0AKtksMGWHzHByRiqLRNPIUjXJyeP5VpX0uUIB6jpSaRZOxL7sKfagCsunMGG8dPSriac+zKrwPUd6uumWCggfpTmjIQKrHgde1AGJO3kZU561S3l2L9j+tXb92MhRh6c1paRpcUkaySKW9j2oAyobFpG3EYXrVz7U0PyRr0yOlaupWvlx4jTBPoO+KlsdMVFDNg4BOD2oA52Q3U0ofysiuj07T/tESh4xkDkYxV2aOIQ7QVQAjsOaii1HznMUJyqgjp3oAiudCsokLMOTxj0rX8PeGPtEyx28Y3d2YcCqtno8+p6jFDFmaaQgAKM4zX0F4T+HR0jThEWRpyoeWQ8Accik3YaOEs/BqW8D3V84isrcbpJQMYFed+KvFf/AAkd4LWwQQWEJ2qFyMj1PvWx8aPH/wBtuJNHsJCtpC+19jf6xh3P0rzGG+S1hZCCXY5JX+VJdwNbUNX8s+UiBUjxgDqTiqlvDqFwWaGNgWH3sVni7leTeqjI5x1ratdWmWE+bNtxwAB2qhCweHbqeUNc3QiGOfm6Vfh8PaSjDzZ5JmB6JyKzH1W2AJLNIx67jgVWbWdvEKDOeCoxQB2eiwWUeqxpBbJGpbq2Oe9cv451A3usP8gG0EfKPcmtHwjHez38l5IreXFEzAMD1IwD+tcrqUxl1CZzk/McUAVkwznP6Gv06/ZD0VB8C9PgkTBuC7k98k9a/MeMb5VXPPYV+sX7L+nNY/CLRISu1hECQfU81hW+E1prUZ4ue88MSJPIjGBcLvHX2NdL4S8Ww6np6zI+8AgZB6V0Ov6DBrVpJbzqCCOvQCvnjWVu/hTrJldHOnSn53jB2dep9DXMkpGzdme761rUFw4G/JUFtoNeQeLZxNK7K2XboKS88Yx3FvHdwymWGaMFWB6Dg4Nefap4gN1PguwQdVB+97ZrSMWiZNNWOy0gJC4Bbcz8swFdxo8zeWMqVyOM8cV5PpWvELgjCL3brXZabrKysqLIOeFFEkJM7p9ZhtVYuV3KNxA54rxb47fBXRfjRpL32myRReIbZGME0ZA83vsf8uD2r23wloMd7ALuZRJCc7VZc+Z/tfT0rXuvB1nIoeJfInH3ZE4P/wCqs0+V3RbVz8htZ0S98O6td6ZqMDW15buUlicYKmvZP2P9FGu/HLw6jr+6tWa6YE9QiFh+oFet/thfBQXWny+J7SELqlqo+0FEOLiIZGf94cfhXkH7IeryaR8Wo54n2v8AZJsfiAP8a7ObmjdHPblkfa/x61W6ubCx0y1EZe7uoYZPNQONjN8xI7jAPFXfHd/D4Y8Kwxq3lRWFtuAAwAxwi/kCx/CvMfiFr66r4w8EveTuhOqqEKqCpYRkAHPTgnnmug/aY1GK28Ba4PJTzmtXMc3n4YMofGE7jBbn3rlStZM2vuz8+viN4tn8ZeKL7VJmwssmIhg4WNeAB+FZmgeHZtduURNqIW2734H1P6VQnXknhua7nwBetp1m52bhICFbH3fp9f6V29DmOv1b4J6bo3h03JvjeXZIC7JAoJ74Xk49zXmep+E7hYZZYI3eGIEsxHQDgn+Vepy6jc31ms7FsF8AuvBqlq73TwfZbdl2SjMjbSO3Q8UkB4sylH5+X3rs/hd4vn8C+NNJ1aIlVimAlTs8ZOHU+oKk1i63oU+lXUSyhMPkqUOc44qKOLymjcjPI6c03sNH398UfDt9ofhW51/SgzPGHlTzHXEqAblxtGFAXdx9PSvEtI/aEu7MxvulgkKgsNzAgYB/qK+jY5GvfBlt5iOUGjRo+4HaGMRPXOOjemeDXBfCj4aWN54HivxLYXUzHi3VBJIowBk55HTI9iK54tWszVraxzI/avURhVu0U456A1iaj+0mtwxL3ikg5zvPT1/nXyvr1omm61f2qMWSCd4gWHUKxGT+VVUB9iORgitlCJnzM+mX/aJ0kzHzrppBnLMsbGuN8WfH8apdotpDJJbx5KhztBPqRXiWTkE8/UU8Eg+vOMCnZCudt4g+KOreJnjNzJ5UUS7Y4kJ2qO/41Fpt/kqXlcswzjFckgJAyckVt6Spk2AHnpmqEeq+FNWukliijctk449K+g/AN5ejyZXH7pHwxzy3r9a8T+EukyTyqz5S3DANnktx/Kvq7w5p9vcaVbQwQhdvPIOGHsR/WsJuyNYq56zoBX7LDJuK5QfKRXbaVLlF4AXtXnugWLSeSgYNCnCc5GOwNeh6dCYwDyOMHk1ydTfocP8AtB+EX8WfDTWBb5F7BbvJHjjIA5Br8k54X0bxIY7kBRHJ8wPIzX7YXUaXFrPC6ho5UKFcdQetfmB+1r8ILjwR4zuZI4G+ySkPC6oQrD6+vrXVTl0MZrqeUpok+pStPY6krhTkLkjb6DmpDYeKbGVQka3BXJDDmsnw5rAtt0bRyBAvzEHAB+tdPZ+JbaNg8F1MNvIUMGx6jBroMTPg8U32nvtvNPkV9mzjuc10mlfEmxQIj7kKsdyyjjmol1r7Y48p4ZnY5/e4BB9Kkkk0u/f/AE7SkiJG1ti9fU5FA0dLdS6b4qtsbYWl2H0IxXPaXowSxljNgDHExAyMllrIbwpaG6L6NqjWZAyI2c4Pt1pun65rXh7V0S8BdJOPNXlX/wDr0CJraKzudSU6cHsryMZNvKMK/ar9pr0N+ZtO1GBYzwMsM4PrXC+MLzUI/E096iyRZIZccY6Ulp4h+1yB7lfnHJcdTQBd8X6VPokqyWiEJvIBXoRWba67fbDHcW5uIewK5xXe+HvFdnJ5dpfhZrd2xl+oPFbGu6DZWUyS6eI2STlVPIOfelcDyHVJ4Comg3wzZ+6elMstW1EsqJLuQno1ehXWh6Zq3nIiLFd44Vu5rjItFk+0yrGuGU7Sc8A0wGas/wBnijlaMxT8E7elRweK5TFsZA+ex6VoXCS2YjjnjE0Trz3AOasQeGrK5t5Wt5FM23cEoAxZNQWVy32BD+FFSLDJHlXjBZeDmigD9Vxc7Tgkfkad9rKcAAjuQM/rVJ3Zm4AwRjGaFQAZIwR0wcV51jtZaN2D0fH0OKXz2fGCGA9TVVCHGWByPpSeYT3xUk3LvnA+h/3ef6Cn+aQeCx+tZpO3+Ld+A4qTzm7HH+9mqsUXo7gysVVeR68U9nPY8jrkVnq4kYjOPUgULJgkB1GPVgKQGgboJ2Vv0pPNyc7gfbPSqaTbSejZ/uqD/MUhmdieQoz2HNIDUS5TACjDeoqRrmTZjgr6FazA5AG45H+yRmk8zYc/Nj6UAaf2k7RjANCynO7Lf0qhHMHIHI9zj+VK0gBwpUn6/wBKANIXHPU7vYUvnbmxjJ/Ws5ZiOCuD/eVaeHYfvNxZfTofyoAvedsOCSn+yaeLjIyrDPpWeJmPzBcD0qRZSULccds0AXfPkYgkFfqDTzO4PKmT3YniqMdxGwzuKHPC461IJdw7D2zQBdNwB/AP+Aj/AApv2nb9xuvrzVQdD1/lSRlkzk7vTOBigC3HOwBy6k+1Sm6DY3YH05/lVJ7hc/Nx9KI5Q2fm/IUAXmudmD0z6nFKJR3P5KKo+dt/iB+oqTzD2cR+7Ec/nQBcEm7ofyp3nMeOmPbFUo5WydzhhTjKFOcBfcc0AXFk55cfTFTLICPU9qzkmG8Y4I7kVMkysMZzgd6ALyOSAc8A8CpY5cE84A4qgk3J7L14qaOQjGCMdaANrSZVNwCTjPSvkX/go7q+3/hD7LfmLFzKVzxnCqD+pr6x0yYG6UZ+h/Cviz/gpRayLqng28jYkGOeMr2/hOa2pbmc9mfDM7HzD9c4qMdTzn+lSSxsGPPP86lsrZppgoUsCcmu05jQuS1rpMUWMeZ82axgpI5PNbGtzGaQIPuooGM8Vn2cBkfr8vf3oAhK9cHOD+dXbNDAxkZeo4461a2QIjdyOhqhPdOcqOmegNAEl5ftMccAD0HFV4UaeUDGQTURbn1Fa2n3aW0GCuW7HFAGhtS2hUHr9KohhNdBc5XP5VWuL1ruQBeAT0NXLLT2gJkdhn60AS3FsqNubJ9Aau6UFkjyeEFZN00k8/lggkgDGc1pMo0+yCFhuI65oAZe3IWbCnIwefzqG2mknTCfO2cBfSsy4uPPZgD1P6Vf02X7Mh3d+mKAGzWReXcfulupNbdkwKARMuFGDxXPXWpFyRkNk9RUukzMBJMzkLjjOaANy8YKpdjj0z3pdKulkVmZQAOOO9YF1fPdXCqCWBOOeTV55l02x8tnBlb5j24oAfqOro6vGikc4FO0lHjiaYoNznj1/Ksyw8u4nMshConOCa9g+BPw4f4l+Isk7dJsyXmkYYHHRaTdlcaVz0D4GfDN0tH17UInWSUBYQRgAd2FXfjn8Srfwl4en0qzYLqFym1sDlV7817X4r1HTvAfhWaZvLht7aEhQOOAOAK/Pb4geLJPFviC5vHclHc4z2HYVlH33cuWhz0kj3ly8jEuznJJqxLEka7QAT1z6mm6dbrPIxJ2KvOT0q55lrEvzRlyOQzHGa2MyrGzNIAnLnoMdasRaPdXbAuNgPcn8qqyXYBzCuw9eO1S298QuHmYA+lAGjFodpESs0uXHbPWtGC1tbYosEAkl5PPGKxBqMEJDRx7245Y5pjajc3Eu2NXJI7f/WoA7O2uG/sfUC4+dQFIjbAA571548mXJIyc569a7bTo7ix8IXrToFMzg5YdgPX8a4g/McjgdARQBueBtHPiLxZpVgn/AC3uFUkdcZ5r9aPgtCtt4Ot4UOAjMo56DNfmZ+zToP8AbvxY0tc5WDdOT/uiv0n+D9yv/CORKcZPPX1rmrM2pnpEiAodvX3rhvG3h6HWbCaKWIOjKVIYcCu5RgehzkfWszUrcyI3AYduMVzbGx8Y+JbC5+FUs8ZR5tCnfevfyWPpz0rJ0/UbPXoftNlPkIeVYEFW9CK+j/HnheDUrOeC8t1e2k6g84r4/wDH3he++GmrSzafKRZSnKEchfZgeorqhLmRjJW1PS7eZ9ixqu8E447e9dHoZMl8kVwzRozBMngEd/0FeE+F/jbZ2l9HbaxE1o+donXlCf6V7hHqFj4jtIprSeJpU+aKRW3AnHqO3anJEpn0DpOtwx2kUEOCqqD8vYe1dDFeC4VCp4XHPrXh3h/xQhAiciKdTh492foR7V3Nt4ph06zeRpQDjI5rlcWbpkXxmu7OLwxdx3IUxiJi5PYEGvz3/Z/sr64+L1tc6XAZ7WFpmnw4ULCVYE8nsOcD0r6+13xr4c8Z6lqWleIdSjt7FbSSQxNKFLkDAUDIJ5PavmH4JWkVt4quE01mjVJnwQ3zeXyBkV001ZWMZu7Vj2P4uag3h2x07VUiScaffQzlpOdqnKsR6HmvV/ixYjxf4SguId7WuoWhXIjXbtlTIYvkEAHPAzn0rgvFmlw+J/DNxZzqW8yMo/tx1A9e9XP2bvGsHibwxd+CNdSObUtAbyxFMc+fCCcEA9cY/I4qXtcpb2Pgyewktbu4s5lZJ4nKFTwQQcEV2HgbVrFNNuNMvF8q5J3202Thj/dPp/8AXr1T9p/4V3aa/d+KtOsDapId11ZxAuVwMebkcc8ZA+teCw+TdkZIWQdVPc10Rd1cxasz1HS74alAsPl/MjAhsDrmvUIfgnNe6Ymp3d7FA7ReaQSFRAAeSe3HNfPekanqmjzJ9ku9hU5AdFfH5iuq1bxv4i8T2iW2p6rLNbKB+5XaienIUDP40NPoGnU5nxBZreavIiTC6hhPlpNg4Ye2ah8P+HpfEfi7SNEtIy81zMkZx2BPJ+gGfyp9/qMVm+xB5twwwqrzj619Ffs6fCafwtbyeJ9cQJqN7EqwwH78UT87T6O+Mf7K5NKUrIErs9m8Ya9daJ4F1QRqrPb2WLaOOPkF9wjXjrhCh/PtXD3caeCvhRql5IqLLa6c6iXHO4JsHP8AvYqz4gvrrxZ4q0/R7M7ra3l+03c6MCrzY+RPXC/exwAFxz24f9sDxfbeH/AemeE7SXF7dus04B5EKDv/ALzY/wC+TWKXQ1Z8dSFpXZnyxPzEtySTTov9YOOcGo/XPXrUsI2tu6ArjmukxK5UtnHFOyAo4yTXefCX4TXnxO1aSOOUWun2xU3M57ZzgAdycVzPirSI/D/iXUtPikMsVtO8aOepAJAov0AoW6FpFBz1rp9J09pZo0TljjHPvXN2OTKMkHH58V6/8M9Bjv8AFxJjI4XI+770gPWPA2mxafo0UIXfOfmz057/AIV9A/Dy/NtpsbSM0UKDp69K8R0m7t7WZIUBcKeVQZaQ17P4L0y91eRJrqPyLZTlLY8EfWsJ6o2ie2+HilxZxSBQdwBJ6c/T8a6y1AEYbbjAA4rktDkEUEabvlAHy11liymMgHgjiuZGzJpc9umPyrgvjR8MdO+J/gq8029T95tLRTL95G9jXoJPPXJxVa5P7iTIG0g8Gq2Efi9daWuh+ItW0W+aUGG4aBwgHQMRmtKX4eWN0c22pshPOJFIHbjNbfx0mW0+NHisxKJI/tr7tvHHf9a5qz1iyuNuI3jbcDlZD0967lqjkK934Q13Sw8sYW6gXpIjAg/h16VmRa1e2DL5sTxuhB4yMV00WuzQyEwXRZXJBilXAGPerkerJeB2uLVJUxtYhQwyaYGFbeLoZ43NwA8rqAMrjac9c1rN4ggm0+GBW3oHx5bHJHuDVe707RL9ZF+z/ZpAQPMQ4x+Fc/q/h240lfOt5zPCh/hPSgDo55TpzpMMXEMy7WEgzt/wrnfEenpZ+VeWqlYJx930PcUy31n7XA0Eny5xz7+9dBaQNqOjy2G9WZW3oT1/A0Ac5Y3rwx73XGMZJGQa7a58Qtqegxi0YGeBhhEBzj0rhLhm02d45VZSQRjHStSzv4007ER2TxfPuXjcPQ0rAdFaXbXqwXGSl3HzKjcHitqXw+l9C91bEeYw3Oi9M96yLXVrbXrFnEfl6hHHu3r/ABgdiKk8N6lviVo7jypF+Voh0b160AYKaq2J7W4QMFJXjqKzdPuJNO1JgMsnrntVfxPBPBrdzIAwVn3Z7VnRXLNjDHcec0wO8Fi9yTIrcMfQUVyUWt3cCBFmIA9DRQB+qcqq8oJOG9l4p+CgOWP0A/xqo0ygEbsD0AqITqrDEhX/AGfWvPOwuCQsRtX8xmpThcc8/WqzXJHt7ZzTFnDfxiP2VhzQItFhJ/GR+FR+bj+Db7//AKqYZ/M6MVx7ZpFuAc5x+NAE8CFmOSF+rAVKNrEj5iR1NVpLjCjbEXPoB/8AWpRK7Dpt9iaTAnLN2fGPTj+tLFhWyo3t35zVUOinLAn6E1KH7kbF7HbQO5Nw7EHKn36UKTu2kYX+9uqJXLnaQsi+meaYjhZyNuzHpSsItYAPA/HinCZQAp2n64NRCVeuDu9dwz+VDO0gwshGexbmiw0yyk3IVQmPTilMoZtnRvZQap7WQbSQT+FGGHIxn3xTsMvhgi8nkdyMUCX5SxIb8KqLIAvzk7vRTR5o+6uQT60rAWknV1J4U+wA/pSCTdyWPHvVYFkB3Zz7Himh9/LEZHT5qANA3oPqv4mgXAlOQ5O314rPZ92MjH0anxTbScdDRYDRMxkzgBvrxUQcHqxX6ZquZwh65+oFOkuy5H3h9TmiwFpbhf4WHvT0n2k7zkdu9Z5mB7Z+lDuuPl/d/TmiwGh54Y4WPHuP/rCnLIM8uD/s9SKzvtHHysQfU05JSpyWHPvRYDSSckkZwO2aUXG3gnNZ32jOMEe5yKe0+BjJwPypAaYn5B/A1KlwDwTgfyrF+04PB5/SpYpzyehAoA37S6CTxljgZ4rx79ubwDbeKfg42r7gt7o0n2mJxzlSCGU/Xj8q9HjuWmKoo+92zXCftcz3Vv8AAHWtjfK6BGx/dNXB2aJlqj8u2O+Tscn06V1kFhHpmjJMMGRwc4xXOabZG5vYlA6mtrW5HitmjDfKp24r0DkOevZvNmY45J6ehpkFx5LAKc54xUErmUn1FIhAkGeRnPHFAFq4mHA/MgYqqCW46fhzSyMHbKjj2NXIrMSxk4yxPXrQBTht2mYbRk1rxadIsIYr+BpdJtxDcEt0Heta6uwI8gcYwOelAHPpGkbnJwRyB6Ul3eSEbQ34VHesGl3KCGx64p9pps93gqCQOS2OKAFsYZZnZ1J6cse1Q3U0gdkMhcA/WtKeA2tqY42w38eD+fFY8qEsdwye2KAJ7EJvLyEcdiKsS3MYTIAzis2MbWwe57VahsZrl8Ipz3PpQAyHa9wNx2qT8xx2rUury2S22QYCgY4FQrpDxhmZcsPeqjwKcKeG9KAEt7lhc5RdzDpVi6tHY75CTIwzg9q1NK0yO1Xz5156qM0s81vK7Nswc9QetAGZpumSX93FbrjMrBRgZr9DPg74Msvht8MLWwQj7bdAS3D9yT2zXy7+zX8PbTxL4q/tK+/48bTDgEcM2eBX1N451+Pw54Pvrpgpt4o9ynODx/kVhUd3yo1hpqfPf7VfxMaa6Tw5aSgxQktMQf4uw/I/rXy+zBz1BOc4FbPizWZtb1e5upZGkeR2YljnqaxEXkY457VrFWVjNu7LvmhLfYhKn+dQTSliec4pNxw/GcU3GByOh9aoQ4MSCP8AJqSCJJZFVmwOp/Kq6jkjPHtUsb7HDY6HNAF+KxgiZurAfjWrbmSNAIo0iU5y7HpWMl+w+VF9Txz/AJ61LGLu7KYBHuxoA73xQv2P4faarOJHn3SMwHuQK8w2jcSGP5V3/j/UHk0XSrPyvJjghjXls7jjJP515+Rgd8elAHv37HVqH8falcFgvk2EmD9cCvtb4N6qr+H7TDhsrjjpxXwH+zdr39k/EGK3dgiXsbQnjocZH8hX2X8F7421pfabIdr2kxUZ646jFc9RbmsGfS1hKSg78etXnhDLk8E9u1c14auxcRqCSQRya6psEAE5/H2rlOg53W9LS7hZSgIOOtfPHxc+HwubKcBN8ZU8NX1Bc26upAGF7YHSuM8ReHUvI3LruJHGeeKafKyWuZH5a+P/AAxJo9xJGyssYY7f6Yrn9A8b634UlDWF9LDsOdhbKn6ivtT4v/CG2v0ncQ75CflP9a+MPHHhK58M37q6Hy8nnFd0ZKSOVqx6Fp37TN7NEiappySzRrhbm2cxuP0o8QftK6rdQeTao6oQMB2I59z3rw+Rdr+oz17VLIpJTuDzVcqC5c1bXL7W9QkurqZ3mfqQxxj0pNE16+8Patb6jp9w9tdQOGWRD6evt14qogyRntx1pGTAwOPWiwj608AftI6L4ht7Cw1SIaZq8jbHkY5hlJ+6Qf4ewwTS+NtG1HTPEUHirwzN9m1mzbeNvCzL/dbH6H3xXyrpE9raapaS3sLXNokqtLCj7S6gjIB7ZHGa+n5Pj54Ku9Xt7awtZtL0q5iRY4ZnMn2f5QpV2PJ6dai1noVc9n8DfEfw78cdHjtbhl03XoWJuNMdtj5HUKTyVPoP/rV5l4//AGUbbWrq7vbM/wBh3eA7bCptpZGJ+VFJBU8Z49cAVka94Gg1iddR0+VrW8A3Q31o+HX056MPr+dbuhfGf4heFojY63Z2njCyRBEGlIhmKD1Pfj3NZ8rT90u6e541ffADx/o1wY47MTrn76ybB09HANXdH/Z38fa7Osd0kenwH70jNvIHriMHNfY3wb1e3+LENzLH4f1Dw1BbnYTLMVVm67UC4z716k3wz01MC5Ml1ERgrLIWGfcEmpdVrRlKCPlf4Y/s66D4MuxqMhfWNVh5jllC7Ub/AGVGVTHqxJHZQa3fFXj/AAzaT4da21DUlISZxJ+6tI2zuYt/E3H1J7dq9S+JHwJ1/wATsi6T4iNjpSJtfTYIvKaQf3RKCcD8K8x1fw5pHwR0ea61e2NhbRvuGELF5MdQTkuxwfmJ/KhO+oWtsJoNvovwm8J3WtahI0Vvbh5WkmfdLI7Hkn1djwB2GBXxL8S/Ht18SPGmo67dqU899sUQORHGOFX8Bj8a6D4x/GPUfidquwB7HRYG/cWe7nP99z3b+VebhTng7T6ZreMbamTd9EIxIU+h55p+evOaaTgcdaFwN3pjp+NWSe8/s6eIo/DvhXxPcOyqd8ZA7n5WrxPxBfHUtcvrs43TTMxx7mr2k+I5dK8O3tjFkG4cMxHQgDisFiXOck59aVtbjLOnjdMiFcljivZ/BWqS2dvHBAm5zwqjjvXjeknddoSO/UfSvffhhp6RyC5mUs+PkXHOaAR7B4F0CPS1S7nHnX0oDM2P9WPQV7j4UivLxI/KCjPU5rzPwT4R1nWnilFs0cDEESScAj6V9C+F/CVzpMEaIVkGOQzc5rkqM6Io1tI8OukaSTXDbuDtTpXSwjyRjg44pthDLsw4AIHQd6nWNgdrdefaskW2SxOXTIOR7dqyPE+orpulXUrsFVELEn6Vsx8R4PY9cYrxn9p3xYvhf4Za7ciTZIINikEAktxV9iT8w/HOrDVfHWtXtwjN9quZHGxucFzVX/hFrSRJHt7mVSMcOnTPvWPqlzJ9ulZslS3BB6irdnrUcCkRrJGeuVk612rRHKTnw9qtmEkglSdTk4DdD6YNVnnv7GX99bSIQckAEc1d/wCEibyok8w5XJBZevetD+2zLCrIyyBzlhnnjrwaYGOviLd5qyAFHG3DDJz/AJNW11e1n0yW2YlS2MOpzRfzWV2pMtr5ZJyDjnHbpWZfaZbwwK8LFT6Z96AM6Qi3nIRty+oNdDouoJtG5skMCQpwQAa52JGjlL9QvJ962NCubOR5Fu0DszBR2IGeTmgDR+IUUJNlPbggMhLZ6k+9cnBdPFE4/hIxmuw8Q20Nx5fkMDCMqoc8j2964ogxsUK9DggUAdD4a1CW2uwI8FjhVLHg5rvbOzhtgZLiBYpsk5AyprymykxdRgHbgjJNehSX93NokkVt/pJkPy47Z9KAI/EOnI92hRlKSjqeRXB3Nm9tdyIcKA2B+fFdRHqP2u3jgaPbLGduD1FN1vT/AD4Wm8vDouOtAHPpCAo+br60VnMXLHacjNFAH6stIWPU01yc8gH3IJpSWU8sT+FJtMxDA4x/eFeedYbt33SPfBzQdqjnH/AqSRWyOn4Jj+dLGRzkE+lADS5Q/wAJ+jVJucDnIHsaQs5++px22nP9KbtlHUYoAsK2QN8jEeivSmbAG5jjt81QCNv4M579TTsnoyn8qALJkV1GGOaEnbOM/lVfp1BYemKU/KMht3+zjpQBbEjn77Ap2HQ/pTVkUPx09zmo4ic5xt98YqZF3tjcT7NgigCQuDFkZ/A01JGyORt9D1oztbZkcds4pdoduX2Z7nkUABcF8HAH1z/OnF1QZIBjHU8//qpohCnht/8AtDpSOiYOVy3ryaAJo50MfyY2/WgzDG0Dr7kmoURcYwAfXbQFCsFyefQUATKWUHPA/wBomhWUgkPjHbFQyx7WGCc4pyA4OcZ7c5pWAd5+ccDPuc0srsCpIwPoR/WmEYHzSc9uKZu3D5izHtimBYS5HOMAe3/6qDMh6Sn8gf5VSCuOx/PFSEB8bwGx0zQO5Y+1beuP1NLKwUAq+0nr1qmJWbrk49TTjISMIMeuOaBFpiQgJJHuBilEoIA3H9aovM7DCtk+gFOBAALZyeuBmgdy39oz8oA4/iz1pzT/ACAbsZqDewj+/kdhmmmTcAMce9KwXLAk+Y5Ofp3qx5vlpgnBIFZyuQeD05yecUplJOCc4HPaiwXNKG5KSqR69e9Zf7SWlt4m+BevQxg5S2MuB/EVBNSrJtKk8EelbN95eseFLyxmO9ZIGQqfcEf1prR3E9UflnoenfZ71h/GBwO9YWrXTtLPE55BJ59a6/xBpdxo3i6+tGUxm3mePbjoATj9K4bWIz9ulJOBuPSvQOQoRKGfDcckcU6VO4454qUQhIwT98mq7sxx6g9qAJrK28wksDtB5rRNwIIwgHA71n2140GMdD1461NPLkIuM/yoAla8JdVBzn0qxeysCIwTzg9elZ6YglVn5A9KtyuLu6LrkFuuO1ADbyycxKwBz1xV/TJZ7XT2LcMeMUTXEaqA3YVSutUJIiQYUGgCvdzsXbqc81W2uwGASOnvTrtsvnBHue1WrAjaS2MKaAIrDyhKEkU9c1stfCCPy7dQo6k1ms8IBOOeearGdnlChsDPftQBpxXkspxkH196qRkpe7niyD2NLZSLFdbWIx0+lX5byG0G4gNIRye1ADL67ik5JIPZR0qjZy+beKin5WYAcVWSczTOTzkE49K7f4L+F08V/ECwt5lBtUYyOD3AGf6Ck3YD6y+FvhuPwP4HtojCHuXUTSgDnJHQ/nXmv7SXjpk0OHTYZCBO4eSHPIA55/SvW9Z1hG09zpfyXUIwY26Nj0r4/wDjD4kuNe8TzPcRiKZQIiB6jviso6u5beh5/JlmyQcHnmmINvXg9qegYAcZpmPmxxu9Sa2IAqW5HTHNNJLA8ZI9BSrlm7jPWrMbKijBwfWgCGFSMkjgilDfvQOPriiSTIPYGmqeQQOT3zQBq2qbR8kYPpxV23cvOikhSSBjOSTWNDNNMNseSo61p6Jpck2qWgZwMzJ0+tAHRfFGJ7Q2FuxBZIlG3uOB1rg2Puev6V2nxRlI1xo2kDlSw4GCPY1xir1HcGgDY8GawdC8VaXfDhYZ0Yn8a+6PDt2lj8Q/PgJa1vo0kGG4/wA81+fpyNpzz3NfWvwX8Zt4g8P6JdPlp7GT7JISe3G39KzmtCo7n2x4UvVNwiKQowMt3NehQ7PKBIAJ6GvKvAyi4eGUDhlBJFekm7SNVzgHtiuLY6iwwVm4APOcmq13arJGRtB69qfBP5nzEgY7U25uRHlQRuPGKGCOB8VeG47uN12Ddyc9K+Ufjj8L1ntJ28vIAYg4/wA96+2LpVnTlN5HpzXmHj/wxFfWsyGIDKkEVcJcrFJXR+U+rWEmmX8tu45U4qCRcBCO4AzjmvVP2g/Br+GfE5kVNsEnKkDvzXlO7hcHgV2p3OXYkQZQjr9aXHGCOPUcmliwq5OSPbrTyAeD0NMREqjgNyuOoprDOe2KlwMZzgH88UjjHTr7GgDo/CPxL1zwXOrWd60luDk205LxHp2zx+FeoaZ+0XY3iBNX0p7diOZLZg65/wB09Pzrwkgjnoev60m0jJPOD2FKyA/Tf9nLxrpus+BrW40qVXhLuGGNrK245yOx6V7pZ3q3CfOd3HOTX5M/Bj4u6p8KvEUVxbTudNkcC6tQflde5x6jsa/SHwL42i17SrXUYG32dxbidHHIKkZ/P2rkqQs7nTCV1Y9Zt5gBlTx0x0qDVtKsNcspbS/s4L22kUh4biJZEYHg5B61i6Beed+9kkBXqB29q1hqkZkKx5xWJpY+Tvjr+wfpeuRXWreBCLDUcb/7JdgIJT3CE/cPXgkj6V8OeKvAmt+CtXn07WtPuNPvIWIaK4Qgn3HqD6iv2WN8h6Nn3/z+Nc34y+HHhT4mRQweJtFg1WKAny2l3K6E+jKQRx2zW0arW5k4X2PxuaJvTB/ummEnoOw9a/RL4j/8E9vD2vSNceEtTbRXbJNreZmj9gHzuX8c147qn/BO/wAeQhza6hpFxjp++ZM/mtdCqRZi4tHyaW4BoHTg19GD9g/4px3sdu2n2Yic/wDHyLxPLXHrzn9K9E0H/gmzr11Cjap4psLMkZIt7d5sH05K0OcV1Dll2PlHwRoc/iDxBb2VtG0ssjYAQZNfe/wT+BDadDFcX67mxkJIAcZ9q6r4M/sWaL8K5nupNRbV9RY/LcNB5e0dMAbj7175p3heOwRAGLAD0xisZzvpE1hG2rM7SPDUVpEoVPlAACgcV0VtYpEBsHC9qkW2NuB049RU8QUsQeW9PWsUtS2x0aBWx0J6UsiZOCMD61JtyeDz9aX765GQB61pYkrs+xGyeOuc18H/ALfXj8rpVto0Tjfd3G4pnkog/wASK+2/EOo/Y9PmbcFbBX6V+UX7V/jMeLvizfxQSebaWGIEx6gfN+uacFeQpaRPLVeK7tNkqlXjbO5TjIpi6fbFsJK4bn3FVPP3KxC4PqfWo0lVWywBAPO3iuswNKbRghQwTiUH14Oahe0u4MN5ZdexXmmwXeGJDEN2ycirsF2w4Do2eMMMYoAoR3k0DMTu56g06TUPtaFXQbs53KOat3Mm9yrKCobJz/Ks2RYnnxHlATj2FADXYhOhJ+uaiH7pweRz2qR1w+3sp49qJ41WP/a6fT3oA2oJ/tVqgZ8iIcZNY18266ckYz6VpaZ5ixuxGVx0IrJm5mYnJ5oAmskV5+u1iODXQ6HrdzZalDb/AHirYwD+lcsh5yOCPQ1bsJCl0G7+vf8Az1oA6HxDayWXiAOilJJiHwfWujS3luLR4yFMrDoG61h6oRqfkTM+5wuAT/hVG31021yRubegwKAK9xarHM6sgVgeQcUVYnjN9IZ8kF+Tg4ooA/UhLJgOV5pG04uwJXHrzXQtYjOec+vWgwopxIVDdge9ebc7LGB/ZwJ4Gfz/AMKebJxjJQfWtxrISEHbtx7U2SzGRkAn3ouFjDl04xgY3c+vFK9tvAAQcepxW29scDcv60SWrADAU/UUXGYZs8gbVGe+DSS2qKi85PfHat1LPP3l3j0Aoe0BAx8n40XFYwktmJ43j60xLc72yhP1X/8AXXQNB5YBywz3pqxjcSRjPf1p3CxifZwOe/pyP6UzyV3nh2PoAP51u/Z1BJAAPsaPsq5zz9SP/rUrhYwzASPlQhvUkH+VKYJfLPH4ZrZMO5tuD9QcUC0DfIVJz6n+tO4zESIqMspB9M04x7hwG3fga1/svlvt2bV9etDQEE7QT7jrSAx/LdWwSQP7pAFBTac7iuOxNaj25OdykN7mmrZR7fmUbv72aaYGdkPyWXPvQVI/hY+68VoLbGJSqcg+9MNs4HUD6DH9aLk2KBgZvvNn680eUYhgKefXmryRNzvYZ7E0zyXXrJuz6/8A1qLhYp7DHwQDn+7xSBdnbb9DirMkCqRuI9sLUjQAj5QU/wB7v+tFwKLljjCq35Cotu0+n+8P8KtNDu+6+KcsYP3g2PXBpgUslDkFT/u//XpGdgPlHP1zVlbVdx4x9KYYtzEZPB6EUBYi8zKAlW3e/FRsxwBVgxFSRuGPaq0w4woJB9KAF8wq3XdT/NJyTgA1XOQRkE4PY0ZLD8KALSyB1wOBn8a2tElxcBHIKt13DisOIcEjn8c/hV+2Vn+bPNJgj5w/bG+E66RdJ4y0eJirDbdwouQfR+K+L7+dZ52YZOfXsa/W++0u28SaXPaXqiZJE8sqx7V+Y/x1+Hj/AA6+IWqaasJisjIZLb/cPOPwziuqlK+jMakbO5575h3jBzTGyCDn6k0nrgHPrTmPGcYPqK3MhVTfk9hyKmB81kI7YqSxj3Jg/wAVSRQBLvPbsCeaANGe1SeFFJGSKda2yW67pHHfAqndTbiOSMcD8KoXN3JLtVzx0BPpQBZvpQxJHQkgc1QcEDdjJB7d6knbIyxyccE1Lp6JJkEemKAK8rmYgnrjqKlT93CGOcnvVk2sSc8j/PSqrzA4GOe4oAikk3Ee/pRGNjhuTjvTC5Bzz9a2tLhglt8P1FAFSyjM0pOCQOc066ZA5GDz1BHWrchhsLVth57j+lZk0xmXdxkmgCMqS2V4yO1e6fs86fBpllf6xcRu05IihGO3GTXhtm652nHPFe9eDNUOmeE7SG2AlJy7L6Z6Gkxo7XxHratBJNDcG3MYJ64IOD1/SvmDxNfyX2qyzyvvldy7MO5Ney+OdXnl8PzTmEZIww7jI6+9eD3blp23ZJFJAy4ZFS0A7nis44bJJ4/nUylplx2XpURU7s9cVQhv3cg05WO0j8Bn0pm0k/N+VPAKqTz9AaAE6DJOKfAR5gB5/rURI9hTlwnPT6UAaMLxRbiQR3wD1rX8JSxz+JdOUkKGmQFnPA56mudjTewLHAxXS+D7WJNdtpGG8pluT7UAM+IEgm8S3TBlYb2+6eOtc0MHpzz6961vEbLJqtw4BALHrx+FZgyMA8AmgACMx6ZA7mvWv2dda+z69faQzcXsRaMFv+Wi8jFeWRDKEA4HPWtHwlr8nhnxVp+qR43QSqzZ6EZ5FJjR+mXwd8WxS6Ukc77ZoQY5AT3Fdrc+JxcXJKvkY4UH+lfK2l+JpIZFv7KTzLS+jWSMD3/rXRad8Smt7t7e6LxkhcFgBnk/41yunrc3Uz6OtfGJCdvVeeamsddGoy7hIQTxn0rx7T9chvBG8c5MoJGM8AYruvCkyhCMg89u3+eaxasaJ3PS4kM0Kgdx1J6e1Z2r6OJIGG0MxBwCKt6fdo2BgBcdhnFa7FZV4wTjqKkZ8e/tI/AHW/HXh6eTS7KKS8iIkiTdtZ8Z4Ga+N9W+CHjbQbYz6j4evbeIE53Rn5cdc1+wU1ukjcDdntUNzpEc8ZUxjaRz71tGq46Gbgmfivc2NxY5E1vJF2y4I5qvuDbuB9c1+jv7QP7OvhPxVY3VybRdP1VvmS7gJB3YONw6GvkrSP2Q/iRrV3KkOlRw2gbal3czKiSL2YDk4/CulTTVzFxaPFfO2jATpz+NTWsEt5KI44ZJJGwAqLuJPsBX1fo3/BPvWp4kfUvElrav1ZYLdpQPxLD+VfRHwf8A2cPDPwogN2xbUtUwMXlxxs9lUcD+dS6sVsNQbPijwF+yv438aosz6edJsyM+ffAoxHsuN354r2PSP2HdLsoBJq+sXdxJgFkt1WNffqCa+sNT8RwWOERdzck7RzXB6/40gDl/ODKOoUcisvaSlsackVueRSfsyeB9DXizedgP+W0uSP6Vp+HPFOl/DFRpkLrFppkz5bSnCepAzx9KxPG/xIuCs8gYKqjG7jtXiN5q/wDaN+91fP50qt8ig8KDz+daqPMtTNtJ6H6Aab4ghudPjltJPMgdco4bOcis7V/GT2MkaBxknJPPSvl/4YfGweHohp92xNmM7Hxnb6/hzXpF541s9aiM8c6srjbGc5BHrWPs7M05z1nSviAl0wDsOeeTXVWfi2E/8tF9znrXzfpurbC7OTGRgY3Z/GtyHxKdoZST6Env9KHAakfSEPii3cDEgUY6A/yq0niCN8AYKn3r58sfE0itGGkIBPUV0en+LJYWG8sIz1J6Y71m4tFKVz26C9WXoc9+K1LaVSikgYI7V5lp3iaOSPzFYhAMk4rptN1lVCqzfP1K+lSnYq1zrlYDjI57VLGwAx+hrBl1RYlWRmHHJ+nrVV/EUSjJPsOevOKvmIsdNMyMjDp/Ws+S68p8jB561mjXreaMtv3bR16ADvWXqviGCFGyVw2RkHnH+f5UnIdjr0vFKltw9atxOGi4/DFeZQeKo48KZQVIzkdO/wD9augtPFdubQtkggZpqVgaPGf2u/i2nw28AXbRSqmp3itBbLnDbmGC2PYc1+W0tzJNO80rNJKxJZnOSSe9e+fto/FAfED4pSWcExe00hWtgpXgS7jvIP5D8K8CeJyFbBwwzmuqmrK5zzd2WBKuR+7XAGeR2p7Jbyvwnl467TiquJMHKHpx7UnnHbyMjvWpBObFN+0ORnmkayZcLvz6mhbpMDcpJ9RUnnxMf4sH3oAhlEyZOcHuQarbypPceueaszyIV+VjjJPNVx6qfm9aAHr1+YHPqan8kTQhRgY71AgLEdWHt61oxNGCFHMuPyoAsWWoeVC0ZwF24JFYTHcxb15xVmUiORlBOP5VXYckZyTQAn8PIIz3605GAkU9KZg4PGVpy/L3O4HigDatNRSBFLcuB0NN1aFGh8+NNuTgmskvuIIyG7/5/GtNJhJppjc9/wA6AC3nPlLkUUzzGhCrhunbFFAH7JLENvzGgQrg45H0oRNyEjr6nihELcsoPvmvMO0Y8WSMKAPTFARewCfj1qV228BtvsDnNEQ3A5Kj2FADHhAxx+XFRxRqxPB/4DUkpZMdVz6ikBEg6gEdytAAYh2wP97NMMBb/a/A1YRCTwdvuvNMcEfeG760AR+Tv4Zzx7UxoAf4Bx39atCJpe/H+yaaY16EdO+KAKT2yDkdfccU1YOe4988VfKoB8gOfejYFXcVIPrgYoAovFlSvG3+9nmmrAwHHT1JNXGIYdMD1oRBjgA/lmgCoV28MCfcYxSeWDzlQPrV9sGPYcken/16idUCFSAo9CaAKLW4L5zn/azmmPbjOS+T7girgRcYUj2xSCPJG5gPUf5NAFD7IrguWPHYGlTAUgA4960TbK6koRt+lMjhXaRtY++f/rUAZ6xAg7gKhe2IK7SD68YrTNmgxhc/QUfZ152AD1oAziACNzMD7U6UCXGBjHoDV5bQc7gx+pqIIrZ+Qt/wL/61AGatugPyqCfalNsHHz7WA6AAjH61daH02j8aSaEMoCjHrxQBnPAOysfYGo2t1Kj5efcVpCJeyFD3IPWoJISzEHIXPBxTuBnyW67SAFB9QOfxqjJH85A5+tbn2Qjnse5WoJbPAyQaLisYq2/zE5I4xz3qYRBgB3HYVa+zkYJ4444p/wBmH3uoHb/P1p3CxWjiKHaQcZq/BE2MgfQYzT4rcEKOOucitGG0wAQMZ9qVwQadFiRQTwTya8S/bP8Ag0nir4fHW7GIvqGnHzmKqMsm07h/X8K98hgOBjGBzV/UbKPWtFuLG4TfFLE0bKRngjFOLs7g1dWPxijty0hVvlPTP4VHJBsYjtjOPevUvj58LZ/hX47vNPdW+zTN5tq/qpPI/CvLixJYNXoJ3VzkatoOjdYY8DqeeKZJcsM8ADGM1E+5SeRn3oGHAOeT2xTETwzNK3JOaY43g7cn6VGoKtkZx705JCHyD+JoAY5LDaxxgYqxZEqjHoMVG/JJYZNIJdoGM47YoAnklZvUjt6VUJzIDgnnt0qyXyvHFRFd4JGD7CgCNzk5wAemBVq2kIi9D1qFYGPGcCn7/JxySOme1ADrgtIMZJB55qJfkXYw6d6d5gIyBgdsUoVGXJIGCOnagBlnEbi6hjGQXYDj3r25FXSoEiSRUdIwAF6HgeleS+HtNN5qsEcPMpYYX3r0mWK4tsJeRSnB70gMXx3qj/YUg858seVB4xXnaL5khzxjjPrXV+Nr6C6aFYySyZyecVycBy/BwM5zQBPhYt3Tnv61C5CtkcD0FOYbzjv0OaTASM7gc8Y4pgM34HPHoTTS+7IAGen9Kdj5SDjFN2AHj8jQAgUZxnFPiQyNk4H1pF+8e49RUokVRgYJz1HrQA/zwuRgE/Suk8CXZbWFjCBnKMAWOAOK5QDc/PI68Cuo8EsDrDr9zELnt0xzQBka07NqlyHOW3kHB4461R2kA9AKs6hhr6ZiAMuSD+NV9uG5PI5wDyKAJGjZ4VYYAzjrzTGhaMks249cd6es2EGclQfpUZdepBx7mgD2/wCBPj3zY4vD14RuiJe2djz2yvP419M6j4DsvFmko6LslAPzIOQa/Puwv5NPvIri3cpKjb1YdjX6Kfs3+J4/H/g6z1Dd+/QmG4XphgP6isammqNIaux5BqDa38Prwpue6tVfG4A5+v6V6h4B+J9teOI3kAlzkqzevtXXfErwtDeqwCc+u3/69fPXiHQ5dDvhd25a3kX5lPZsVKtNaj+E+v8AQPE6SRrhww7HrXbafqnmKVD7uhPPNfKnw78cm/tkhnYR3Cn5lJ78dPb/ABr23SvEkcaIysdzLu4PX68VhKLRspJnqcEo27i3HPfmpnkBjIxgGuT0rXluIEYEshPbuadqfiJbSNcfe67c+1ZlFK+0caz4gM1381lbgFUYZDv2/AVaub2JC0a/Lt444rj9S8bzEOq/cHbvUXhWafxbqhjRzDFHh5HP8Iz0Huaqwro7GXVd8LKmGYDI21zOu6zcW9q4MTqOSeDzXV61qlh4asiltEskmeVJ+ZvfNc1D8SdLvZ3gkHlv91o36g0khnkHi3x1JYRtMGB2xseTj8K8R8S/FFJruSVZMpIuRtbJBr6y8TfDvwz47tXjngClv+WkDFGH5Gvnzx1+xrqFu7TeHtZSeHqlvfDDD23Dg9e4FdMZRMJKR4LrfjSa9iZd4K4/M/nXJal4njhZgG3N6L/n1ra+IHwq8ZeCZiNU0maCDOPtCEPGc/7SkgfjiuSs/DU11Iu4EdyT2rdNdDIrXfiS8ucrGxhXvtJycepp+g+LNY8Pzb7G6lVc8xuxZG+orrtK+HqyAGQHPbI4rp7bwDY2sQZ4wx6e3amBN4O+NE12yQX9u8Up+UToSU/HvXrOm6xHewiaKTdgZ2q3NeQRaXb6cW2xqJDzyOnNTDxJLpXzwybCp7DANS9Que/6NqweVWlwFU9a7O51JWgSKGMSN0J6896+atH+L1lBtjvv3L9mX7p9D0r1TTPHumNYxSxXQl/djDKe/c/nWbiaJnpen+JJbN1WQeXBGN7sc/gP8+lbunfEu3unctKP3as2c9q8P174kwTWEdokokdvmfb/ACrDs/EsdlEyuwKEh3A5zjnaPqQPyqfZ33HzWPoTVvH7vZIm9455Bgq54zxzx9aqR+P5RbrufftByu/pXisnjmMRPNczpAhBOGIGOlcnqnxe0+1hkhtpXmY91yf1/Gj2Yuc+iNT+JqWXyifAAwCHyBXB6l8a5FkZTMNvLY3fdwOnXoeK8FvvGsmoQNIzyPKxykYXAHTrXN3FxeTyMzblycn61apoTmz6b0r4sHUryCJJNw4U4J57/wCFeoa74+i8EfC/VfEl22RDCdiZ++/RQP8AgRr59+B3wy1vxJcQ3UkH2axUhjNKcDGOw9eap/ti/E62toLP4f6QQUtCJrxweM7cqn65/KpcU5WRSbSuz5a1bUZdZ1a5vrg7prmVpXPuxyf501DtTbuXHfnpTIkWZiCdhx35qQWIxw4GOoroMQMzZGMe/NPEu6I5UMTyDxUbWbg5LgkDpUYhdB+vBoAsxiB1w6gEHrgjNNe2hJyrEDrVfLoDweO3rTRISNuMCgA2neQD3wD1pOA2BwOgx1pznG0DknpTGGBwOfUdTQBJbt+8BPrmr1ud9y0oIPNZqEDBOPqKt2mQ4Pbrj1oAlvo1SQt3Y/rVGT5mz1z1/OrF2wY5Axj+dVW6Enj60AIw98UYx7/SgbhkEcCgEAnnIxjPpQA7nHXaTVi2m8tlLDK8ZBqqGyuOvNStKSgXGR0oAvmZZSWIIz2FFVY5cIMqfzxRQB+zZbLYAJH+zxT1j6HBGPWq5uiHC4Vgf4sEmn/atoIzjPYqa8w7SV/3hBQkj2NOI2/d2CqyT9ssvsopzyeXwQefXn+QoAnb58bhJx7U0kD7w2iqobOc8/nTpJhgckfQ0AWVAQ5XBz/dH/1qbtyxJ69eKgaR4gGU5z6mlE4xls5PoKALKOqn5owfqc/1qNZVZyCgUf7tM84N1VnHs2KRJd7EJnPoDyKALDNxgqCtNBw2SQF9AuCKiY/LyCT6Cm/aT9wbRjtjJoAsByX43bfWhvvcAlvcVCJtoyDg+tPSc8MSSPY0AH3m+br6gcUvl4+ZRk+pFRuxkbKE59DTCXU4cg+oK/1oAlYsHycA+wwKcWVgQ33j24pse0pkDDeoPH5UrYwQxz+FAAsYVSRwPQ5zSA7hn5h7E0sKjYSMEZ74oZm7AN7igCJiHPPGO2etOCCToAuP739KbIq5HmcHttpUZnByOnYHFACMMY4BPuKRVYg7kDe4GKdsLAkjZ7LzQjc8up/CgCIwpxlsfXApn3P72PyqdF253Ae2M0eUrf3T7NigCsI85KjafdajKkHuD6ngVYO5ehApGfH8IY980AVjBn7zB89sHA/Go5LYEdOe9WYyWd8Nj/Z5wKV1yuMZ9c0AZEsI5I609UXvgE+tWpIRIo45pRDkqG54z+NAEVuhZgehB71pQxdO3H5VWiXnIHGc5zmtKCMHsSDxQBJChHr65q/AgVjjjI6dqhjABII5PcVaiXkH09aAPA/2uPg0PiN4KkurKDfqlkvmQlRknplfx5r8z9Rs3s7mSOSMxyIxVkcYwR1FftlLapdQtG65VhtOa+Av2uf2Z7/S9Wu/E/h21NxYzMZbi3iHzIepYDv9K6aU7aMxnHqj5AUbyAeR60NGYzjaeKlBKsVYFWU9DxinSSBsk8nvXUYDYotynjgUilEbJGCOKPN+TAXnpULyZ5OAfSgBZWBIOfxphJXJ7HpntSfUE9gKcR14755oAUcDjkn8qWOT2x60+PDqwPOPxpHYJg0ALJKQR1OfTtUT5ILc/WleTn1zTd3GT370APyNmPz9qIwWYrwv0pUQMnv0zThiNuDk/lQBveC4mOqbkZl8tdwZR0PrXbz6rO7Lul+0Mncn+dcv4Cit/KupJbowPgBMDIY1pSyCJzuJVfXHDUAcz4qvlv7xpEj8sHg46fWsKA7Bux+ArR1ecTXksiDapPA71mFyuAenrQBMXDKf6VZSGN4FPBXHIqlEOTk5HWrAyI+CSR0zQBFMFRhtxUJxnk/gKViSvv1pCozyMZPegBDnLDGPT3p/PIGQeo9KZ15AxinFtuMdfXFACh8E9z6eldD4KV31KaRfvJA+FzjORiubz1yRz3xXUeA5UF9dmRTKGtnVUBIznjrjtQBiXQDTSbjwCTnrUR6dMD1xzUl0As8ijghjwf5UwHnngjPegBD856HA5FJhVGAuQfxocEKMH64qMBicZx2wRQBKoGzG3FfVH7D/AI/h0bUNZ0O5nWMz7Z4EY/eIyGA/DFfKvzKhAOat6Lq954e1O3v7KdoLqBw6OvUGpkuZWGnZ3P1B1/XbeXJJXB5OO1eOeMprS6ZwroAR2P8AOvF/Dfxi8R+M7OVIoWuLm2jBmWJgGK5+8Afw6VieJviHqUylZbaa3OBkMuCcVlGFi3K528s7WNwJbdykig8g4zXqPgr4jSXMSQTOiXCEA5bgj1FfJEvjO8aR8swj6AE5xVvTvHV1BdJcJIVljYEEVo43JTsfopoHiFjbFlO5ScfL6/4Vd1LUYMEvITn+LGfwr5w+EPxntdaWO0upPIu1B+Rhw3HUf4V6PqfjeziikEkwAiXccjrnIH9a5XCzN1LQd4n8Ux2Ym+zjEi/xuwAarvwy+I9tpXhrUb24mWN3uCm44PRR/j+pr5x+KvxLW6kC2TlR0BA+teSnxjq9q7PFdyRq3LpnKt9R9K29ndWMubW59oXXxMa8vnmkbGfuhn5xWXq2v2GrosjPsnXlXUgHNfI9t8UbiKcCWfJHBYDIPSu28PeO5btg7OJUXoQQapQtsHOfR/hXxvcabMsU0nOccnqK9XsvFyXMCc5YjJ/GvjrTPFkt1qyyCTqQM9eK9Y0fxzbpEqyvyfu+prOUClI9uuxa6nEUnjRkYYIIyK8v1/8AZ78OazeSXEEb2Esh3Yt8Bc/7uP5Va0/x1ZXThBMTgZbOa63StdhnIIYMBj8PSs7SjsXozyPWPgJqOkxu9lPDcjjCuCp/wrz/AF3wj4g0gHdpFyy55aJd44OO3tX2FHfQypsbDZ5B61TvdNtrmLIUA5/Gmqj6icOx+fviTVLuyc+dZzQuB/y0jK4/MVy0UOteJpWj0/T5rhWPVIyV/PpX6D6z4Ns9RhZZYEkUjBDqCK5Wb4fRWMHl2kQijXgJGMAfhWyqJkcjPkOx+BPiC8VZL27t7IEZKElmH1wMVaX4P3OlvkazcoSMfuRtB/WvqKfwfIVAX5W287hnNUj4Ca44KqzdzjtT5xcp8+W3h64sD5aTSXTL0eXk/hxWhB4W1S/3KN6qeSyg8e1fQel/CQtLueMHJ7+n+c12ukfDCK1RTIgAx24/SpdRAoXPkOX4U6hcsfMMh4HzODzQPhPMhGVZ8dOMcV9j3XgqFYgEHyrw3A5rmtQ8PRANtXDE52gcY70lUvsPksfK6eAriC8VGiYgnnH1r1r4V/CC21K/iurmISIGyI5AMcH/AOtXY6voFtbTRtGgVX5bHr/n+Veh/Du1Szt0MaqylucevHr9f50TnoEY6nV+JY7T4cfDPV9aaFEg0+zefZjAO1eB+JwK/JbxJ4gu/FWv32rXzb7y7lMsjc4yew/Sv0b/AG4viTF4Y+BTaKHDXuuypboF7IpDSH9APxr81EYFhldx9+1FFaXCo9bEkLiMkk8+tSLcIMfKc46VKVgwp2ZJ7E0skEDRgiPB7kE10GRA0wGdufXrSGUY+8cj8jT2WN8AJ0+tNMC5HHfmgBjSAE4PHuc5qPOW4/AUOCpK9yOp6U1RznIx6igCYrnbz09qawwfQ56ZpN+OpIx1psjFh3OR09aADByR6d/QVajIMJOdrZwPWqi5OACT61IhyvB6AdsYoAmmJ8hRjkcdagCjHfGKdJMcY4GfT1qMZwQfpQAdCBik2k+mRS4BxxnvSN8p/HpQAD1HPehSW64zijGeBxSrnr2HOaALcdlLKgYdD70VH9plwMyMPTiigD9jt43AhialSfAIYhSfUc1TVio2k8/X+lPVeMkM2O4O39K8w7Sw5II+bd9KVlYcD/x6qe/zSDnfju1SmQg9Nv8AWgCdoxDgrsYn0NR4Jzlf50rswxyV/rQSH6gH9aAHb3jGSDjp8oyaQMGJ3Y/A80RlSSMZ/HFNWMFjzn6GgCTBYAKOnoCaRSwPCAe5p3lPHgggfX/9VR7WJJyDQA7c2eX49A2f0phJDHkkehFSbCAO3uKA/YEkigAByg4P8hSLLztwMeu7JpTknn9RTcKD0BPpzmgBxcK2SST6DrQWVh94g+hODSMqlfunP+fWlEQKcEj2oAaHCOBliPzFK5Z2yuQPQdKNmD/X/IpwUdPlJ9xQA0yuJApV+fcYqVoyzDkj6GkRCAVZV57gUuzyCBkHP+zQA8KYxyQCfxpWXOBkHPXmlLqeicd8c0weS/8AqwR68df0oAdsVBwQfrURzxnA+pp/C9AV/A00SGX/AGsepzQAS5iwUAbPXjGKia4YDksv0xVny/UbfqMVA0KycbOh780AIfmHIAz3FAY5ww+X161KoCgZGB7EVGQwYnaCp6dM0ACn5uAMdutNYAZ45z24NPEmQRyMUijr7880AR7QQT39aXbhsdOMUoUo2R8oI55pw5PHp370AOQfkPSrcQyOMdvwqqgCnOPwqeKQAdMHGSKAL8b46cf1qynIHIzWfDIc8Hn36Vbjkxkbu9AF6MgBc1Df6fb6nbPDOqurDBDAU1JfmA6U8O24Z5PTNAHxb+0n+yPDqTT6z4bgW3vACzQRrhZOfYcGviLVtIvNEv5bK/tpLW6hba8co2sPzr9qpoYr0MkgBXGBmvn/APaB/Zi0j4kWX2uGBbfU0OROgwenQ10QqW0ZjKHVH5jOGIA9O9NycmvbvGf7Lfi3w2sskMKXsEeT8jANgegrxq/025064eG5heCdDgo64INdSaexha25X6sMfnTsAqW9+/pSgBl6YpoJz82RxxTAfG21Sen9aY5yR3pM5Bx19+9NLfMR3x64oAD90cdKB8p6ZFBDMowO/c09cFRxnj1oAF4zwR6ihsswOM57UjY3DPB9aQMTzgfUUAdz4Uj0+HSf9KkKSSOWG3pxWjdhYjtWUzWuew5ArOsLqG00+3guLYOAm4Hvk96Z9t8sO0Qyn9wigDl9SIW4kKnK5OMiqLc9+ParF3L5szNjGTkj8aq8DPUn270AT26h5Am3rnvVh4vJQ5GfbpVeF9jLkYI/nU9wXaLGevPNAFQkkkjHPApEH59KVRwc4/E0hbHbmgBz/kAeopoAO05x/WnsAAp/Ooi24YwOOg680AHJ9OPXtXZfDFN+r3pwGIs5No9+AP1rjiRwcV1nw9cJdag4HItmGc4AyRyf0oAwr5Nl3OuApDnIqHouQOvc0+7C/aJFUhhkjI6Go+cnnjHOeaAGS/Lg4655NMLMccDj2p8mSAMYxzUZJ4IwB1oAUOScEcmgZ6kFfajcARgZPrTNxXAHWgDrvhh4zPgrxjZ6iVDWvMUyk8FDwfy/pX1D4x0PSfEFol5aiF0dMo8ZB3cdQa+L92Dntn8q7nwd8T77w9pr6e8peAf6ssNwTPUfSk1d3GmdLr/hBIZJim3CtzgZFcRd2DQvkcHPQ9a1Z/HEt08hLbjKcnn+Q7Vl3F3PcYLcHpz0piCCeaxlV4pGjZOQyNgivY/Al5rfxB03UERWluLWFd0m/DScnHHr1rxIyhXBOS3cV3fwu+KC+Bp78SxyMlzGqDZj5WB4P05P50mNDde0a8sLpory2uI51PMciHI9s1zF/A8+Y1Rkx1yME16Vq3imPXW+1SlyJeQ7DFYVwlvc7cYY4wKEB53JpTqCSOgzwKbbveaZIHhdwOpArs20zbcGMAD0BP8AhTrzw88YUgKc9hTESeFfHUKYjuAIZh3Ydfxrop/FhUiRTgkZGD90egrhrjw4sik457HtTRpGo28YCNvReitz+ApWA9A0bxndW4aQOWMjZHuK9U8H/EeQO5lkO3ds/Svm6C4uYZS1wjBsYLA10Ft4nMK8bvlI+7xx/nNJxTGm0fXdj8QUwpa4Bz3z07VuWXj2KX5DIOB94nvXxvZ+MZ4Osr7R0wcZ+tdHp/j2VQxWXk44JrN00Wpn1zbeL4p3RfNUjOOTWnHqVvcyr+8QjH3d2K+Y9E8etLGP3hE/QNnvXU6H42H20Ca4OFGSazcC+Y+hhYwTKJCFwcDC1ah0W2RN4KEEcHFec6F47tnbElwwRgAeOMe9bGqeNLLTtPM63AaFiI8rwyt0GfUdKy5WXdHe2q2scZRcHimzatDbPt3L7EdfyNeOp8S4vKkcylH3EA9u+c+3FZ+p/Fixs4N08xbAPIPcDgjNPkbDnR6zf60rhtsnyjOOnP4VwGr+LrSylYySAlmIwTjj1/z7V4V4r+PN1dPJDpm9pSNpkcYA7fjVn4eeG7jx9dldYu7iVnO8eS5Qg568VqocquzNzvsdP4i+KWniQIJ1Lbs8sPl5rS0P4y2Wi2H2u7uYrexjwWmd+N3Uj3Pt7V4H+0/4W0v4V+L9M0vQri4llltPtNyLmTzNhZiFAP0BP414lfa1e6jGsVzctJEhysecKD6gVoopoi7TPQvj78aLz40+MDftvh0qzUwWNsxzhM53kf3m4J/CvNUjdTjaemMAUyPlvT6Vaa5PzbzzjqT3rRJJWJbbGL5p7HPbigmcoAVYYoN02Rn6Ugm+YsTjA5piEDOoPGD9KGmkAxggjsaDcdOTj2pWlJHI565FACZ81WypZvUDpQtuNuSAc1f07XZ9Psr2ziSNlu1CSF0BIGc8E9KrzsEiQDG0UAVXKngdj3PShIgcMDnFKuGYkccdvWrkaqY8Z+btj+VAFIqAOeO9LHHuOc4xzihiWJ35yp5qeFV3HIOOM80AMFuDng/WoPLO7p7c1bnYwFSPun1qNHUNnGM8UAMNqwBOSPf1pvlkHBIPfp2q2ziSMjIyP1qszngk5x2oAfbweYDnr0FOmh8pTj8jwc06GZY1BwM561Jcf6Q4ZOT049aAKoU4HOKK2bbw9qVxEHitJpE/vIhINFAH63+WC424A/u5pziQN02jvkU13w2OPwNSI0YRuQD/ALteYdo1II2HBzjuRmnrEvPzA/QVF5/B+fP0FMWV2znH4UAWkZuc/o2aYkqqT8wJ9G4/lVdbgnPlMw9cGnM4HXAP4UAWDKG7KT/tCgHOcYX8arswAGWZh6Y6VLHKEGSSAaAHgH/lmzE98iiPKMcsM/71AQNyXJHXgGl+VjgMOPWgBzqrDn5hSps2gABR9KgmXavyr82fwpyvIIhjP0ycUASjcX24AT+9TvL2DIIIHcZFQlmdMEZPpnihW2jBXn0FAEwUsQxOB7808uEjOGBI7Dr/ACqOMGTthf7pp5UhSuF20AAlLpnaM/XmkV/73B96BgDGVpTGGGRgn2oAlWQBCAAQe5HNMRiB8u0/VajKSE8Lx35pdpB6tg/3aAJHfJBbt07UjzFyNwDY9cU1odx+Uk/lStE6YyTz0oAkWQsCVwvsaZCxlB4PH90Um3y/vnk9MU54ufn4+pxQAjtyMjd9BjFKmAepX6D/ABpSSAOW/CgB26bs+7EUAMOznnP50wgY+UHP0qRY2Qk7c/U//Xoyw6tj2FACBflB39e2elI5JOByc8HqacitvyQQD3zTwuSaAISpbBI5/WpQq45PJHr704IVAOevSkI4GT270AROnzZB5pqu2TnBA79KeAGJ68j/ADzQgz1yfp3oAmjc8fw++atwvtI556VSA28VYVjtyOSe9AF7zsYIPWhXzgc49qrIcjrT06jGM+lAFgtk5z/gKa8gckNjg1GWGcduahmbBLAkN7UAV7/S7O9BWSJTnPavIfid+zX4c8dWcwlskWdslXjXDIcccivXVkLZ3HPHFPWQjIIyKpNrYTSe5+VXxS+AviH4catcRG1mvbBclJ44ycDPQ4HWvNntGj4ZWRh/CwxX6++IfCmn+IY3W4hSTcMHIryLxF+yr4X18ySPYJvk43Lwa6Y1VbUxdN9D815Yhls5BB4JoVTgN3719WfEL9ijU9OaefQJWlRckRyt+OK+Z9b0S98OarcadfwmC6gba8b9j/nFbKSlsZNNbmXtC84z/wDrozj6ds1PtBYcAEHjFRFNwzk47iqEMYdx1PanJhnGeOccUALjkYP96prSItcxgdWYDp0oA7eW4FzHHE0ahVUKD0yMVn3YcBiDtA4x7Vbu7dopCWXg/wAQNZVwHSF2J3jpmgDnZ+ZM9T3NNIGevXnNOYZfIyM00RFhnHtmgCbavXIHtT5XG31+gqFRgEMfpTTknHABOKAAtkg+/btSAYPDZ9ADQT8pz/jTRkIeSfbtQA5m4BJ6d+1ITlc5x2puOeefWgnkk8DP50ADZx1wfTvXa/Dq3tZk1iS5u0tlFuVO5ckgkdK4sDAJ6rXVeCnK2+rMVDR/Z8HnocigDDlwHbaRtJPP+NRHAXgkdakfO4nI4JP1pvDdMn0oAhmBba3IGO1R7g3b8u9TXOeFBJA6GoW+negBFIDZ6D0pA20Z/kaXGOcHj9KTA6gcCgA5pd3POfbNGMlunNBGRkDoO9ABv+TAHvxWjY6y0AKT5lj9e4rN52EZ70YABJ5NAG893aMpII/4F2qlNcxZG0lvSs9V8wgY4J4qR43gZgwKMOobg0Aa+meJ7mwCo+JbfGNjn+VdTpur29+N1q6xSgfcc85rz0NkdB7UsMzwSLIjbHU5yKAPVLIPJOskwDDqea3Li6ijiXhTkYJZuRXKeF7+HXbcx7il0F5UH73vUuoNNaMyMPM7cnjFAGrG0dzclFbdgZJz3rQt7FNoYLuJ75rlNEufKkGWySTwBgmumXVFjAQSgtnDKB0/HvSYGimmRzRbWhVs/wB4cio28N285ZmiCY7KKkttZjAABGffrUi6rHL8xcE+g7e1IZnXPg+Byxjm288duaxLnTJ9PkYBQ6qeq11M98oj37gFbH/1qpRyLc5JbgjPzelFxGfba86RbUVkZflCnr6Voxa5NZxcNvI+cncOuKnbRra5DcHzPXpmrfw98H6brPii7t9VWWe1t1WTZFJsJycEZH4UXsMteGvGVzdMIJMjfIpLf3VByTn8MV1eqa3f3byxW7s8LHKbxgD3+veuu8YaJ4Y8N+FbFdJs4bZmuHJlILSMu3G0seSB6Vw1prtrEW807VzwP6YqFZ6lbaFE2V22ZJrllAJJOcZ//VWe2lK0hneViSuMNkj+VWfFHjmx0u1d2lGxVI/3jxxivJdW+LV3cborKERwdAX5OO9WI7iPRx9tRflYEgkV7d4d8U+H/hZof9t6rdRx+QCUiBG+V/4VUd818dv491fzPMSZY5B3UVl6rrmo65MJb65lunHTzGyB9PSk43FexqfELxtefELxjqniC/z515M0gQnIjTPyoPYDA/CudQfN1/Sm7m2/0pw+Q4PBq0IkAHbjnoDSNweg+vrTM5X0PekwcYPFADyOD0NIOBwOvOSKbnOewFOXOeq89sUAJzyffkClJxgYHHfvTQ2T/nrS9VyCR7H0oAcpDc9O/wBacZCYyrHFR4Ck7SB3+tKcgY7elADi2MDORjFAkIUkHn88U0FlI3cLSgktjH+NACudzZPB9u9LFMQuMnJpoyeDkY7etKeVP9fWgCV2yoBO761EGbG0ZFM3kknI68Vt+HNPiv7kRSAnkmgDJVSrEg4A7etXbLSbrVJUjt4Xd2IAwM81a1qw+xXjKoOwngnuK6f4YSj+37RGIwXGR70AaHhD4Janrut2Vneq1qtw2BuWvuf4a/sZ+FNL063lurWO6mGGMkiAk8ehry5EWLXNFkHIEq8j/P0r7b8Lyf8AEogPUlQf5Vzzk+hvCKsYem/CHw1ptnHbxafCEXoNgortQy/X8M0VjYo8Gu/Ed6rfKI8Y6BT/AI1BD4wvV+Voock90Of51XuBkDA+lUZLcuSR16UlYrU2f+EqvG6LGCOwB5/WnjxPdHlkiI9wf8a59VKHGeMVP5THbwPaiyC7NVvFF30jht+vXYen508+KL116RAeyn/GshEIY7vXr/n6VMsbMRjBAosguzT/AOEhvV7R/XH/ANercGu3bcbYiT0wP/r1kJCwxgfKfU1ftrdm4YgjOOtLQLs0o9TncZ2hsjoc4/nU0d9O4GQox6ZqvFEwwCTxxkGrix7VHHIHepKGefL1IBOehFJJdyheDj1FOkGBgDP09Ka0Qxk+vXvSAYupTEbT9M96UX0wA6D3HWoihVxjp1zQIPm3AEcfrQBdivJOCWyMfxd6nW9ZSOEx9KzVDbgOQRxntVmIYZQd3WgC+LyTI4AU+2AaeL45ICqM1UzgAf8A681FJL8qt+fuKALp1ByTgJke1RNqU3PCfiDWa1x3yeenrTftG0/L6UCuaZ1OdeyHPt/9emjUZwDhEGfY1nfasuB2xjB7VL5pZB3460DL8d/KMZI/AVPJqDsPmxxz3rJErLgd84wPWpBLjk49TQBoJcEZyA3GTSm7dTn5fxzVITELjPHcVCJ9zYA470Abcc+8DcF99uaek+H+XB+vaslbwgKF6nnmp4pweCc4/nQBpLtBaT+InqKUSDGeS39Koi83R4zjPvTkkJbtgCgC4z/MOn1puRjceWxUUcgbABzj0pWfB/iH0oANwVzxwTz/APWp6yZU8ZzxVV5QdvtT1kVVGCOeemDQBOTtY8Y4FTJLtyM4+lUi4xycepNTRuGXqQPSgC7u5I9egFSrIMYI9eM1ACRgn0BNKZdoJPBPfFAD2fPHaoXORyck9803zQDyPl9qZJJ3yM/1oAQnB64+tPKblGDj3pkbBgQRk570qkEYH/1qAIn+XoDwetRGcpyBjtmnykfMenU8HtVWUF2/zigDotPhje0Qugc/e+bmvzF/bPu7Sb49azFaIii3jiik2DgvsDH/ANCH5V+mqy/ZNPaTcFCR5+nFfkZ8btYbX/iz4r1BsES6hIBn0U4H6AVvR3uZVNjiRISSCOM5qVYmlGB19jUIAZvXBxzxW1p6FYicc9812HOY7q6MFIIP0q5pwX7ZEGb5QecCkv0Amzj/AOvVnRYEkv4gflAz1/GgDXdY5pHaK4JLMch+KqahFJHbtlSQP4lOQalfauTtXuQQcVVu3mEDFXAUjoTmgDF5wAMn19qE44HQ8+tMdxv4B4weeOab5uQCfrQBNtwMdT71Gy//AKj60iSdznHrSCUDJB49qAF7cgH1x2pMKpAznnOKa0mOBjnsTQBkY6elACDOQc9ecZp3GMDIPXPrSM20DPXuaQHjOOMUAKRz1GeT713Pw98uLStflMaSOtuoCOMjlh3z1rhCCTkdK7HwNdCPSdfjYtmSBQAOhww7/wCe9IDn5W/eNxncTwAcU0fMDxk5xjtRIn97Of8AaoZSSAcDA7UwIblApBI68Y9KrqODwRjpzVi8AKLjqKrsSqjHHfrxQAAkkkjr2oB46DHrQFyeMmjHOCP60AIcjtkHoaUYYn6d+aBhjgjn0oXkEZ/WgA5IHYe3al3ccdup70gwB2HHWgEqp7qeaAJo5BGQ/YHgCu78TaNJ4n0BPElu/mSRIkdzEByuAAG4rhDEfJBAG4nGCa6v4ea89lqg0yVwbK+/cyqegB7/AK0AcgOCeQvuBRwfU+oroPHfhSbwb4im0+U7o/vxODkMp6HNc6Mc5yOec96AJbS5ms5lmgkKSKeCDzXQN45ubmJVuI0dgMbhwTXNDGMDk0AAHPcd6AOwsNdtpnXe4jPo3FbL+RIoMVxhsZODkV5sMj2P0qSOeWJgysU9CD0oA78XsluQoYOv94GrNrq3mlVYlQpwGB61w1vr0sYG8B89SeuKsx+IUX/lmXPXrQB3f9oRmQYOQeSM1ctrm2YqNwwGB+Y9TXnNv4oeOfc0KEYwNvBAqw/ilZIdiREtjjJoA9Tk8VQwaWZJdqbgyjjrjvUXgfxJb2txc3k8yxNcMFAd9uQvc/UmvHr/AFm6ndVkmO1VAWMDgCqj3s0hKvKzEknHPWgZ6/8AFD4ySXLQaXpMkcsMCMXuBz85xkL24AFeWz+JdUu2zLeysewzx+VZgbJx60hAGOPmJ7mlsIknnlvGBlkaRj/E7ZqL7uQMnFLnpznPTNLgDGOhPSmADHQkEfzo4zx07YoPTHftTSMDPqemKAFAIzj+fNAPPYfSlI2gY4HbmkbPTueaAA/T6UegwAOtCpg8nrz60AE8HnHSgAzwT9e9BG4Hv9Dmhgoxx+GKAQOSeKADJBoHf+LHalXJPcd8+tN25yR3oAUYBznjrkUpJz1z7elLgbec5ppHGcEgetABjJ6n/GlwSB0J9e9KCc88DHANKoJfA4+lACdcc04jA4Ix60zAJx0p+AVyeSaAGMBzjFaWhymG9jOQoHY1n8MoyM/hUtnKySqwO3B7dqAO28SaaboJMDxtyazfC8htNUidHMbKww9a9vc/bNOZHzgjFY6wG2k2g8k9aAPrzR7lbvRtNuInEjI6NuHbmvs7wNLv0K3yf4fz4r4O+GF8s3gyGPd+9jXoD93mvuP4dSl/Dtqc8lBz+FclTQ3gdhvJ5Xp9KKrgj1orG5pY8KuLcg9RjPbvSxqUGSOcZwKnuf8AV/8AAv8AClj6H/dH9aYFFrfJ4GDnGTVqC3YjkY7UH/Vx/wC9/SrkX3n/AM9qAKi2YPBJYH/69PW26HOe30q2f9ZF9f6mm9l/3qAI/s2BuHWr1uhyMr17dBTIv9T+FX4f60mNIljiJ4CnFWFgyuSCpHvT4uj1NP8Af/Ef0qRlGaIdMexqsQxBBAwDz7Vem6tUL/6w/hQBXCEfNkilCAsc5HfFWD/q/wAf6VHF/F/vf4UANEQAJIPvUsKY46ZHanS/6lfqv9Kkj+8PxoAYylc88j9Kp3XL5PI61oH/AFZ+v9aqXPU/7g/nQBl3Hyk4xtyTxVGW6eJsYHPf0q5N1FZ1x/qx+H86skIrliQCMk+laUVwW+7xntWTF/r0rWtOn4UgTHxy7jk8ZHApxmxzkE+maiXp+NQt/rJPqP50FFvzgV4ORTlwW4I9/Wqyf8ekP1H8qmH+sT6j+tFhXHPcbXAIz34NIbwFB8xxzxmqdx/rX/3TSf8ALJvx/mKLBc0VvNy9e3ABqZbvGPmHPH1rLj/j/GrEf3D9P6UmFzThvAhIDA+9Sy3gJwcVlxfehpZPun8aQXLwuBu9M9jTluhkgnAz0zWeOq1Mf4fof60DL4nB7jJ71btn3c9j2rIH3H+n+NaVh/x7D8KAL5m2qTjtSeaCOx+tQP8A8e7fQ0k3RfrQBJJLt9+Oxqq8+SevPpTZPur9KhH+rSgC0LkDGOM+lSCfJHoO9Zs3+t/AVND0i/GgCw8mQfTFQp88oUtzmppev4VV07/j5T6igCx4x1JtK8J6nOqn5LZ2Htha/H3Vbp77Ubq4kbfJLKzsx5ySSa/XH4r/APJN/EH/AF5S/wDoLV+Qs3U/Q11UdmYVB0C5mXgelbMByMdyc8VlWn3k/D+Va1n/AK0V0mJUu4W84jqf5Vc0aJDdN5iZwjH8cUyf/Wy1NpX/AC1/3G/lQBUMkQb5g20eh61DdESREqCBjnJpYerfQ/zpLr+GgDLbls4GcZNNfGeO9L/Gf96kb7p/z60AGcHHYfpQB8vqSe9LJ0P0H9KVPuH/AHh/KgBu3PfJoIBYZAOTj260Sf6tqVf9b+P9BQA1QR0H45pMY4HanN9xv896G+8v4UAIMr3z7V1XgyJpLTVzlRH9nzuJPXIwOO9cr/y1b6j+tdX4K/5Buuf9c0/9CoAxThA2Y8sT1Jpo4P1p7f8AHw/1P9art94/UfzoAkuYXaNWVSVHX2qhnnA47Vp3f3F/H+VZ8fQ0ANJwccY6Ufe754ximxf6xvwpy/6t/wAf6UAGeQBScEZHI96Q/wCu/AVIv8X0oAavz8AY+tTWcv2e6ikZRIqtnDd6hj/4+Pw/oasCgDpfHWvL4p1x78WkOno0UaiG3QKi7VA6DvxXLwSlJY5AcFDnPpWzqH3pfqaw4/vH/d/woA7DxX44i8S+H7G0ltib62AHnsckgVxgwA3XpUz/AH3+pqB/utQA4Z7dugpSdx6A/WiP7zf71NX/AFRoAVBxjdjNBAXnrnj6Ui9D9aaPvPQBICe/b8BSEgEUkP8Aqm+n+NK33Y/92gA6ZBwTU0UZJxkHnAJqKTr/AMCP8qsfwxUAV5TukLYzRjpnIB5pF7fj/OkXt9aAHA8E9R3NNbOBhvwpZP8AGkfr+VAChRjII4PSjbk5J59qdH99Poak7r9KAIQCM59PWgjBHPFKP9bSS/w/73+FAAM5PqfT2pV9DwfY0qfeP+e1MX7rfUUAOLYIPB9c0NkdecUR/wAX1pF+6n0/pQAp7dCaQ4PUjPapE/1R+n+FQDqfoKAJQFyc+mc0Ke2CSfWkbt9KkH3V+tAERIz19hThg4PUUxfut9TUif6pP896AEHfnt2pyg99uT396IfvP9f8Klj/AIv9+gCuMhvQZqRSMcd+oph6r/u/1p9v/q2+tAEsibogxIHHJFV0J3A8881ZH/Hoah/5aH8aAOy8PzxtbhWxv96vahZbmVh0B/Wue8Nf6411d32/36APU/hTdCPSriHJwBkD07196/CW6W68MWbfeIjHJ+lfn98Kf9VP/uj+tfePwS/5FK2/3F/kK5avRm0D0URbucgfjRUbfeNFcxrc/9k=\",\n \"margin\": [-40, 16, 0, 0],\n \"width\": 595\n },\n {\n \"margin\": [-20, -150, 0, 0],\n \"columnGap\": 8,\n \"columns\": [\n {\n \"width\": \"auto\",\n \"text\": \"$toLabel:\",\n \"style\": \"bold\",\n \"color\":\"#cd5138\"\n },\n {\n \"width\": \"*\",\n \"stack\": \"$clientDetails\",\n \"margin\": [4, 0, 0, 0]\n }\n ]\n },\n {\n \"margin\": [-20, 10, 0, 140],\n \"columnGap\": 8,\n \"columns\": [\n {\n \"width\": \"auto\",\n \"text\": \"$fromLabel:\",\n \"style\": \"bold\",\n \"color\":\"#cd5138\"\n },\n {\n \"width\": \"*\",\n \"stack\": [\n {\n \"width\": 150,\n \"stack\": \"$accountDetails\"\n },\n {\n \"width\": 150,\n \"stack\": \"$accountAddress\"\n }\n ]\n }\n ]\n },\n {\"canvas\": [{ \"type\": \"line\", \"x1\": 0, \"y1\": 5, \"x2\": 515, \"y2\": 5, \"lineWidth\": 1.5}],\"margin\":[0,0,0,-30]},\n {\n \"style\": \"invoiceLineItemsTable\",\n \"table\": {\n \"headerRows\": 1,\n \"widths\": \"$invoiceLineItemColumns\",\n \"body\": \"$invoiceLineItems\"\n },\n \"layout\": {\n \"hLineWidth\": \"$notFirst:.5\",\n \"vLineWidth\": \"$none\",\n \"hLineColor\": \"#000000\",\n \"paddingLeft\": \"$amount:8\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:10\", \n \"paddingBottom\": \"$amount:10\" \n }\n },\n {\n \"columns\": [\n \"$notesAndTerms\",\n {\n \"alignment\": \"right\",\n \"table\": {\n \"widths\": [\"*\", \"40%\"],\n \"body\": \"$subtotals\"\n },\n \"layout\": {\n \"hLineWidth\": \"$none\",\n \"vLineWidth\": \"$none\",\n \"paddingLeft\": \"$amount:34\", \n \"paddingRight\": \"$amount:8\", \n \"paddingTop\": \"$amount:4\", \n \"paddingBottom\": \"$amount:4\" \n }\n }]\n },\n {\n \"stack\": [\n \"$invoiceDocuments\"\n ],\n \"style\": \"invoiceDocuments\"\n }\n ],\n \"defaultStyle\": {\n \"fontSize\": \"$fontSize\",\n \"margin\": [8, 4, 8, 4]\n },\n \"footer\": {\n \"columns\": [\n {\n \"text\": \"$invoiceFooter\",\n \"alignment\": \"left\"\n }\n ],\n \"margin\": [40, -20, 40, 0]\n },\n \"styles\": {\n \"accountDetails\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"accountAddress\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"clientDetails\": {\n \"margin\": [0, 0, 0, 3]\n },\n \"productKey\": {\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"lineTotal\": {\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"tableHeader\": {\n \"bold\": true,\n \"fontSize\": \"$fontSizeLarger\"\n },\n \"subtotalsBalanceDueLabel\": {\n \"fontSize\": \"$fontSizeLargest\"\n },\n \"subtotalsBalanceDue\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"color\": \"$primaryColor:#cd5138\"\n },\n \"invoiceLineItemsTable\": {\n \"margin\": [0, 0, 0, 16]\n },\n \"cost\": {\n \"alignment\": \"right\"\n },\n \"quantity\": {\n \"alignment\": \"right\"\n },\n \"tax\": {\n \"alignment\": \"right\"\n },\n \"lineTotal\": {\n \"alignment\": \"right\"\n },\n \"termsLabel\": {\n \"bold\": true,\n \"margin\": [0, 0, 0, 4]\n },\n \"fullheader\": {\n \"fontSize\": \"$fontSizeLargest\",\n \"bold\": true\n },\n \"help\": {\n \"fontSize\": \"$fontSizeSmaller\",\n \"color\": \"#737373\"\n }\n },\n \"pageMargins\": [40, 30, 40, 30]\n}\n'),(11,'Custom1',NULL,NULL),(12,'Custom2',NULL,NULL),(13,'Custom3',NULL,NULL); /*!40000 ALTER TABLE `invoice_designs` ENABLE KEYS */; UNLOCK TABLES; @@ -1622,8 +1634,10 @@ CREATE TABLE `lookup_accounts` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `lookup_company_id` int(10) unsigned NOT NULL, `account_key` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `subdomain` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `lookup_accounts_account_key_unique` (`account_key`), + UNIQUE KEY `lookup_accounts_subdomain_unique` (`subdomain`), KEY `lookup_accounts_lookup_company_id_index` (`lookup_company_id`), CONSTRAINT `lookup_accounts_lookup_company_id_foreign` FOREIGN KEY (`lookup_company_id`) REFERENCES `lookup_companies` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -1765,9 +1779,11 @@ DROP TABLE IF EXISTS `migrations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `migrations` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `migration` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `batch` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + `batch` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1776,7 +1792,7 @@ CREATE TABLE `migrations` ( LOCK TABLES `migrations` WRITE; /*!40000 ALTER TABLE `migrations` DISABLE KEYS */; -INSERT INTO `migrations` VALUES ('2013_11_05_180133_confide_setup_users_table',1),('2013_11_28_195703_setup_countries_table',1),('2014_02_13_151500_add_cascase_drops',1),('2014_02_19_151817_add_support_for_invoice_designs',1),('2014_03_03_155556_add_phone_to_account',1),('2014_03_19_201454_add_language_support',1),('2014_03_20_200300_create_payment_libraries',1),('2014_03_23_051736_enable_forcing_jspdf',1),('2014_03_25_102200_add_sort_and_recommended_to_gateways',1),('2014_04_03_191105_add_pro_plan',1),('2014_04_17_100523_add_remember_token',1),('2014_04_17_145108_add_custom_fields',1),('2014_04_23_170909_add_products_settings',1),('2014_04_29_174315_add_advanced_settings',1),('2014_05_17_175626_add_quotes',1),('2014_06_17_131940_add_accepted_credit_cards_to_account_gateways',1),('2014_07_13_142654_one_click_install',1),('2014_07_17_205900_support_hiding_quantity',1),('2014_07_24_171214_add_zapier_support',1),('2014_10_01_141248_add_company_vat_number',1),('2014_10_05_141856_track_last_seen_message',1),('2014_10_06_103529_add_timesheets',1),('2014_10_06_195330_add_invoice_design_table',1),('2014_10_13_054100_add_invoice_number_settings',1),('2014_10_14_225227_add_danish_translation',1),('2014_10_22_174452_add_affiliate_price',1),('2014_10_30_184126_add_company_id_number',1),('2014_11_04_200406_allow_null_client_currency',1),('2014_12_03_154119_add_discount_type',1),('2015_02_12_102940_add_email_templates',1),('2015_02_17_131714_support_token_billing',1),('2015_02_27_081836_add_invoice_footer',1),('2015_03_03_140259_add_tokens',1),('2015_03_09_151011_add_ip_to_activity',1),('2015_03_15_174122_add_pdf_email_attachment_option',1),('2015_03_30_100000_create_password_resets_table',1),('2015_04_12_093447_add_sv_language',1),('2015_04_13_100333_add_notify_approved',1),('2015_04_16_122647_add_partial_amount_to_invoices',1),('2015_05_21_184104_add_font_size',1),('2015_05_27_121828_add_tasks',1),('2015_05_27_170808_add_custom_invoice_labels',1),('2015_06_09_134208_add_has_tasks_to_invoices',1),('2015_06_14_093410_enable_resuming_tasks',1),('2015_06_14_173025_multi_company_support',1),('2015_07_07_160257_support_locking_account',1),('2015_07_08_114333_simplify_tasks',1),('2015_07_19_081332_add_custom_design',1),('2015_07_27_183830_add_pdfmake_support',1),('2015_08_13_084041_add_formats_to_datetime_formats_table',1),('2015_09_04_080604_add_swap_postal_code',1),('2015_09_07_135935_add_account_domain',1),('2015_09_10_185135_add_reminder_emails',1),('2015_10_07_135651_add_social_login',1),('2015_10_21_075058_add_default_tax_rates',1),('2015_10_21_185724_add_invoice_number_pattern',1),('2015_10_27_180214_add_is_system_to_activities',1),('2015_10_29_133747_add_default_quote_terms',1),('2015_11_01_080417_encrypt_tokens',1),('2015_11_03_181318_improve_currency_localization',1),('2015_11_30_133206_add_email_designs',1),('2015_12_27_154513_add_reminder_settings',1),('2015_12_30_042035_add_client_view_css',1),('2016_01_04_175228_create_vendors_table',1),('2016_01_06_153144_add_invoice_font_support',1),('2016_01_17_155725_add_quote_to_invoice_option',1),('2016_01_18_195351_add_bank_accounts',1),('2016_01_24_112646_add_bank_subaccounts',1),('2016_01_27_173015_add_header_footer_option',1),('2016_02_01_135956_add_source_currency_to_expenses',1),('2016_02_25_152948_add_client_password',1),('2016_02_28_081424_add_custom_invoice_fields',1),('2016_03_14_066181_add_user_permissions',1),('2016_03_14_214710_add_support_three_decimal_taxes',1),('2016_03_22_168362_add_documents',1),('2016_03_23_215049_support_multiple_tax_rates',1),('2016_04_16_103943_enterprise_plan',1),('2016_04_18_174135_add_page_size',1),('2016_04_23_182223_payments_changes',1),('2016_05_16_102925_add_swap_currency_symbol_to_currency',1),('2016_05_18_085739_add_invoice_type_support',1),('2016_05_24_164847_wepay_ach',1),('2016_07_08_083802_support_new_pricing',1),('2016_07_13_083821_add_buy_now_buttons',1),('2016_08_10_184027_add_support_for_bots',1),('2016_09_05_150625_create_gateway_types',1),('2016_10_20_191150_add_expense_to_activities',1),('2016_11_03_113316_add_invoice_signature',1),('2016_11_03_161149_add_bluevine_fields',1),('2016_11_28_092904_add_task_projects',1),('2016_12_13_113955_add_pro_plan_discount',1),('2017_01_01_214241_add_inclusive_taxes',1),('2017_02_23_095934_add_custom_product_fields',1),('2017_03_16_085702_add_gateway_fee_location',1),('2017_04_16_101744_add_custom_contact_fields',1),('2017_04_30_174702_add_multiple_database_support',1),('2017_05_10_144928_add_oauth_to_lookups',1),('2017_05_16_101715_add_default_note_to_client',1),('2017_06_19_111515_update_dark_mode',1),('2017_07_18_124150_add_late_fees',1),('2017_08_14_085334_increase_precision',1),('2017_10_17_083846_add_default_rates',1); +INSERT INTO `migrations` VALUES (1,'2013_11_05_180133_confide_setup_users_table',1),(2,'2013_11_28_195703_setup_countries_table',1),(3,'2014_02_13_151500_add_cascase_drops',1),(4,'2014_02_19_151817_add_support_for_invoice_designs',1),(5,'2014_03_03_155556_add_phone_to_account',1),(6,'2014_03_19_201454_add_language_support',1),(7,'2014_03_20_200300_create_payment_libraries',1),(8,'2014_03_23_051736_enable_forcing_jspdf',1),(9,'2014_03_25_102200_add_sort_and_recommended_to_gateways',1),(10,'2014_04_03_191105_add_pro_plan',1),(11,'2014_04_17_100523_add_remember_token',1),(12,'2014_04_17_145108_add_custom_fields',1),(13,'2014_04_23_170909_add_products_settings',1),(14,'2014_04_29_174315_add_advanced_settings',1),(15,'2014_05_17_175626_add_quotes',1),(16,'2014_06_17_131940_add_accepted_credit_cards_to_account_gateways',1),(17,'2014_07_13_142654_one_click_install',1),(18,'2014_07_17_205900_support_hiding_quantity',1),(19,'2014_07_24_171214_add_zapier_support',1),(20,'2014_10_01_141248_add_company_vat_number',1),(21,'2014_10_05_141856_track_last_seen_message',1),(22,'2014_10_06_103529_add_timesheets',1),(23,'2014_10_06_195330_add_invoice_design_table',1),(24,'2014_10_13_054100_add_invoice_number_settings',1),(25,'2014_10_14_225227_add_danish_translation',1),(26,'2014_10_22_174452_add_affiliate_price',1),(27,'2014_10_30_184126_add_company_id_number',1),(28,'2014_11_04_200406_allow_null_client_currency',1),(29,'2014_12_03_154119_add_discount_type',1),(30,'2015_02_12_102940_add_email_templates',1),(31,'2015_02_17_131714_support_token_billing',1),(32,'2015_02_27_081836_add_invoice_footer',1),(33,'2015_03_03_140259_add_tokens',1),(34,'2015_03_09_151011_add_ip_to_activity',1),(35,'2015_03_15_174122_add_pdf_email_attachment_option',1),(36,'2015_03_30_100000_create_password_resets_table',1),(37,'2015_04_12_093447_add_sv_language',1),(38,'2015_04_13_100333_add_notify_approved',1),(39,'2015_04_16_122647_add_partial_amount_to_invoices',1),(40,'2015_05_21_184104_add_font_size',1),(41,'2015_05_27_121828_add_tasks',1),(42,'2015_05_27_170808_add_custom_invoice_labels',1),(43,'2015_06_09_134208_add_has_tasks_to_invoices',1),(44,'2015_06_14_093410_enable_resuming_tasks',1),(45,'2015_06_14_173025_multi_company_support',1),(46,'2015_07_07_160257_support_locking_account',1),(47,'2015_07_08_114333_simplify_tasks',1),(48,'2015_07_19_081332_add_custom_design',1),(49,'2015_07_27_183830_add_pdfmake_support',1),(50,'2015_08_13_084041_add_formats_to_datetime_formats_table',1),(51,'2015_09_04_080604_add_swap_postal_code',1),(52,'2015_09_07_135935_add_account_domain',1),(53,'2015_09_10_185135_add_reminder_emails',1),(54,'2015_10_07_135651_add_social_login',1),(55,'2015_10_21_075058_add_default_tax_rates',1),(56,'2015_10_21_185724_add_invoice_number_pattern',1),(57,'2015_10_27_180214_add_is_system_to_activities',1),(58,'2015_10_29_133747_add_default_quote_terms',1),(59,'2015_11_01_080417_encrypt_tokens',1),(60,'2015_11_03_181318_improve_currency_localization',1),(61,'2015_11_30_133206_add_email_designs',1),(62,'2015_12_27_154513_add_reminder_settings',1),(63,'2015_12_30_042035_add_client_view_css',1),(64,'2016_01_04_175228_create_vendors_table',1),(65,'2016_01_06_153144_add_invoice_font_support',1),(66,'2016_01_17_155725_add_quote_to_invoice_option',1),(67,'2016_01_18_195351_add_bank_accounts',1),(68,'2016_01_24_112646_add_bank_subaccounts',1),(69,'2016_01_27_173015_add_header_footer_option',1),(70,'2016_02_01_135956_add_source_currency_to_expenses',1),(71,'2016_02_25_152948_add_client_password',1),(72,'2016_02_28_081424_add_custom_invoice_fields',1),(73,'2016_03_14_066181_add_user_permissions',1),(74,'2016_03_14_214710_add_support_three_decimal_taxes',1),(75,'2016_03_22_168362_add_documents',1),(76,'2016_03_23_215049_support_multiple_tax_rates',1),(77,'2016_04_16_103943_enterprise_plan',1),(78,'2016_04_18_174135_add_page_size',1),(79,'2016_04_23_182223_payments_changes',1),(80,'2016_05_16_102925_add_swap_currency_symbol_to_currency',1),(81,'2016_05_18_085739_add_invoice_type_support',1),(82,'2016_05_24_164847_wepay_ach',1),(83,'2016_07_08_083802_support_new_pricing',1),(84,'2016_07_13_083821_add_buy_now_buttons',1),(85,'2016_08_10_184027_add_support_for_bots',1),(86,'2016_09_05_150625_create_gateway_types',1),(87,'2016_10_20_191150_add_expense_to_activities',1),(88,'2016_11_03_113316_add_invoice_signature',1),(89,'2016_11_03_161149_add_bluevine_fields',1),(90,'2016_11_28_092904_add_task_projects',1),(91,'2016_12_13_113955_add_pro_plan_discount',1),(92,'2017_01_01_214241_add_inclusive_taxes',1),(93,'2017_02_23_095934_add_custom_product_fields',1),(94,'2017_03_16_085702_add_gateway_fee_location',1),(95,'2017_04_16_101744_add_custom_contact_fields',1),(96,'2017_04_30_174702_add_multiple_database_support',1),(97,'2017_05_10_144928_add_oauth_to_lookups',1),(98,'2017_05_16_101715_add_default_note_to_client',1),(99,'2017_06_19_111515_update_dark_mode',1),(100,'2017_07_18_124150_add_late_fees',1),(101,'2017_08_14_085334_increase_precision',1),(102,'2017_10_17_083846_add_default_rates',1),(103,'2017_11_15_114422_add_subdomain_to_lookups',1); /*!40000 ALTER TABLE `migrations` ENABLE KEYS */; UNLOCK TABLES; @@ -1827,7 +1843,7 @@ CREATE TABLE `payment_libraries` ( LOCK TABLES `payment_libraries` WRITE; /*!40000 ALTER TABLE `payment_libraries` DISABLE KEYS */; -INSERT INTO `payment_libraries` VALUES (1,'2017-11-08 16:19:40','2017-11-08 16:19:40','Omnipay',1),(2,'2017-11-08 16:19:40','2017-11-08 16:19:40','PHP-Payments [Deprecated]',1); +INSERT INTO `payment_libraries` VALUES (1,'2017-12-11 17:28:31','2017-12-11 17:28:31','Omnipay',1),(2,'2017-12-11 17:28:31','2017-12-11 17:28:31','PHP-Payments [Deprecated]',1); /*!40000 ALTER TABLE `payment_libraries` ENABLE KEYS */; UNLOCK TABLES; @@ -1928,7 +1944,7 @@ CREATE TABLE `payment_terms` ( PRIMARY KEY (`id`), UNIQUE KEY `payment_terms_account_id_public_id_unique` (`account_id`,`public_id`), KEY `payment_terms_public_id_index` (`public_id`) -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1937,7 +1953,7 @@ CREATE TABLE `payment_terms` ( LOCK TABLES `payment_terms` WRITE; /*!40000 ALTER TABLE `payment_terms` DISABLE KEYS */; -INSERT INTO `payment_terms` VALUES (1,7,'Net 7','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,1),(2,10,'Net 10','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,2),(3,14,'Net 14','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,3),(4,15,'Net 15','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,4),(5,30,'Net 30','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,5),(6,60,'Net 60','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,6),(7,90,'Net 90','2017-11-08 16:19:40','2017-11-08 16:19:40',NULL,0,0,7),(8,-1,'Net 0','2017-11-08 16:19:43','2017-11-08 16:19:43',NULL,0,0,0); +INSERT INTO `payment_terms` VALUES (1,7,'Net 7','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,1),(2,10,'Net 10','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,2),(3,14,'Net 14','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,3),(4,15,'Net 15','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,4),(5,30,'Net 30','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,5),(6,60,'Net 60','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,6),(7,90,'Net 90','2017-12-11 17:28:31','2017-12-11 17:28:31',NULL,0,0,7); /*!40000 ALTER TABLE `payment_terms` ENABLE KEYS */; UNLOCK TABLES; @@ -2006,6 +2022,8 @@ CREATE TABLE `payments` ( `ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `credit_ids` text COLLATE utf8_unicode_ci, `private_notes` text COLLATE utf8_unicode_ci, + `exchange_rate` decimal(13,4) NOT NULL DEFAULT '1.0000', + `exchange_currency_id` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `payments_account_id_public_id_unique` (`account_id`,`public_id`), KEY `payments_contact_id_foreign` (`contact_id`), @@ -2181,6 +2199,42 @@ LOCK TABLES `recurring_expenses` WRITE; /*!40000 ALTER TABLE `recurring_expenses` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `scheduled_reports` +-- + +DROP TABLE IF EXISTS `scheduled_reports`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `scheduled_reports` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL, + `account_id` int(10) unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + `config` text COLLATE utf8_unicode_ci NOT NULL, + `frequency` enum('daily','weekly','biweekly','monthly') COLLATE utf8_unicode_ci NOT NULL, + `send_date` date NOT NULL, + `public_id` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `scheduled_reports_account_id_public_id_unique` (`account_id`,`public_id`), + KEY `scheduled_reports_user_id_foreign` (`user_id`), + KEY `scheduled_reports_account_id_index` (`account_id`), + CONSTRAINT `scheduled_reports_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE, + CONSTRAINT `scheduled_reports_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `scheduled_reports` +-- + +LOCK TABLES `scheduled_reports` WRITE; +/*!40000 ALTER TABLE `scheduled_reports` DISABLE KEYS */; +/*!40000 ALTER TABLE `scheduled_reports` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `security_codes` -- @@ -2256,8 +2310,10 @@ CREATE TABLE `subscriptions` ( `deleted_at` timestamp NULL DEFAULT NULL, `event_id` int(10) unsigned DEFAULT NULL, `target_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `public_id` int(10) unsigned DEFAULT NULL, + `user_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), - KEY `subscriptions_account_id_foreign` (`account_id`), + UNIQUE KEY `subscriptions_account_id_public_id_unique` (`account_id`,`public_id`), CONSTRAINT `subscriptions_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2482,6 +2538,7 @@ CREATE TABLE `users` ( PRIMARY KEY (`id`), UNIQUE KEY `users_username_unique` (`username`), UNIQUE KEY `users_account_id_public_id_unique` (`account_id`,`public_id`), + UNIQUE KEY `users_oauth_user_id_oauth_provider_id_unique` (`oauth_user_id`,`oauth_provider_id`), KEY `users_account_id_index` (`account_id`), CONSTRAINT `users_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -2596,4 +2653,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2017-11-08 20:19:44 +-- Dump completed on 2017-12-11 21:28:35 diff --git a/docs/api.rst b/docs/api.rst index b67bb606619a..0b2e0f77914c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -126,8 +126,3 @@ To email an invoice use the email_invoice command passing the id of the invoice. curl -X POST ninja.dev/api/v1/email_invoice -d '{"id":1}' \ -H "Content-Type:application/json" -H "X-Ninja-Token: TOKEN" - -Subscriptions -""""""""""""" - -You can use subscriptions to have Invoice Ninja POST newly created records to a third-party application. To enable this feature you need to manually add a record to the subscriptions table. To determine the event_id find the associated EVENT_CREATE_ value from app/Constants.php. diff --git a/docs/conf.py b/docs/conf.py index 6fb28b430e54..b90f074bac90 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -57,9 +57,9 @@ author = u'Invoice Ninja' # built documents. # # The short X.Y version. -version = u'3.9' +version = u'4.0' # The full version, including alpha/beta/rc tags. -release = u'3.9.2' +release = u'4.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/configure.rst b/docs/configure.rst index 84aaf1943365..7e8c1273ff63 100644 --- a/docs/configure.rst +++ b/docs/configure.rst @@ -6,7 +6,7 @@ Review the `.env.example = 2.1.1, users have reported seeing 'Error: 0' with older versions. -- You can use `this script `_ to test from the command line, change ``__YOUR_LINK_HERE__`` to a 'View as recipient' link. +- You can use `this script `_ to test from the command line, change ``__YOUR_LINK_HERE__`` to the link in the error and then run ``phantomjs test.pjs``. - If you require contacts to enter a password to see their invoice you'll need to set a random value for ``PHANTOMJS_SECRET``. - If you're using a proxy and/or self-signed certificate `this comment `_ may help. - If you're using a custom design try using a standard one, if the PDF is outside the printable area it can fail. @@ -84,16 +84,25 @@ Follow these steps to add custom ttf fonts: ie, `Google fonts `_ to support our payment gateway integrations. +We use `Omnipay `_ to support our payment gateway integrations. -Follow these steps to add a driver. +Follow these steps to add a custom driver. -- Add the package to composer.json and then run ``composer install`` +- Run ``composer require `` - Add a row to the gateways table. ``name`` is used in the gateway select, ``provider`` needs to match the Omnipay driver name - Clear the cache by adding ``?clear_cache=true`` to the end of the URL .. NOTE:: Most drivers also require `code changes `_ to work correctly. +Security +"""""""" + +To require a password to update the app add ``UPDATE_SECRET=random_value`` to the .env file and then use /update?secret=random_value to update. + +By default the app clears the session when the browser is closed and automatically logs the user out after 8 hours. + +This can be modified by setting ``REMEMBER_ME_ENABLED`` and ``AUTO_LOGOUT_SECONDS`` in the .env file. + Google Map """""""""" @@ -128,12 +137,6 @@ If you need to set a list of trusted proxies you can add a TRUSTED_PROXIES value TRUSTED_PROXIES='10.0.0.0/8,172.16.0.0/12,192.168.0.0/16' -Stay logged in -"""""""""""""" - -By default the app clears the session when the browser is closed and automatically logs the user out after 8 hours. - -This can be modified by setting ``REMEMBER_ME_ENABLED`` and ``AUTO_LOGOUT_SECONDS`` in the .env file. Customizations """""""""""""" diff --git a/docs/install.rst b/docs/install.rst index 6cd6b3e5487b..cf4955fded75 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -3,7 +3,7 @@ Install Thanks for taking the time to setup Invoice Ninja. -.. Note:: The applications requires PHP >= 5.5.9 and MySQL. +.. Note:: The applications requires PHP >= 7.0.0 and MySQL. Detailed Guides ^^^^^^^^^^^^^^^ diff --git a/docs/invoice_settings.rst b/docs/invoice_settings.rst index ea52ebb4a53f..b49047d46225 100644 --- a/docs/invoice_settings.rst +++ b/docs/invoice_settings.rst @@ -1,69 +1,119 @@ Invoice Settings ================ -You can customize your invoice template by adding new details about the client, your company, header and footer information, adjusting the numbering format and more. Any changes you make to the Invoice Settings will apply to all your invoices. +You can customize your invoice template by pre-defining the various numbering formats, adding new fields for client, contact, company or invoice information, and adding default text to invoice terms, invoice footer, and more. Any changes you make to the Invoice Settings will apply to all your invoices. The Invoice Settings page has four sections: -- Invoice and Quote Numbers +- Generated Numbers - Custom Fields - Quote Settings -- Default Messages +- Defaults -Invoice and Quote Numbers -""""""""""""""""""""""""" +Generated Numbers +""""""""""""""""" -Want to create your own numbering system for invoices and quotes? +Your invoice and quote numbers are generated automatically. You can adjust the automated numbering system in this section. -To customize your invoice numbering system, click on the Invoice Number tab on the left. +The Generated Numbers section contains five tabs. Let's go through them: + +Invoice Number +^^^^^^^^^^^^^^ + +To customize your invoice numbering system, click on the Invoice Number tab. There are two ways to customize the invoice number: by adding a prefix or creating a pattern. To add a prefix, select the Prefix button. In the field immediately below, add your chosen prefix. For example, you may choose to add your company initials, such as M&D. The current invoice number appears in the Counter field. -All your invoices will automatically include the numbering change. So if you chose the prefix M&D, your invoice numbers will appear as M&D001, and so on. 3 +All your invoices will automatically include the numbering change. So if you chose the prefix M&D, your invoice numbers will appear as M&D001, and so on. To create a pattern, select the Pattern button. In the pattern field, enter the custom variable of your choice. For example, if you create a pattern of {$year}-{$counter}, then your invoices will be numbered with the current year and latest invoice number. To view available options for custom patterns, click on the question mark icon at the right end of the Pattern field. All your invoices will automatically display invoice numbers according to your customized pattern. -To customize your quote numbering system, click on the Quote Number tab on the right. +Quote Number +^^^^^^^^^^^^ + +To customize your quote numbering system, click on the Quote Number tab. There are two ways to customize the quote number: by adding a prefix or creating a pattern. - To add a prefix, select the Prefix button. In the field immediately below, add your chosen prefix. The prefix will appear before the quote number on all your quotes. -- To create a pattern, select the Pattern button. In the pattern field, enter the custom variable of your choice. To view available options for custom patterns, click on the question mark icon at the right end of the Pattern field. 4 +- To create a pattern, select the Pattern button. In the pattern field, enter the custom variable of your choice. To view available options for custom patterns, click on the question mark icon at the right end of the Pattern field. All your quotes will automatically display quote numbers according to your customized pattern. -.. TIP:: You can choose to integrate your quote numbers with the invoice number counter. This is an important feature as it allows you to keep the same number when converting a quote to an invoice. So, Quote-001 will automatically become Invoice-001. To number your quotes with your invoice numbering system, check the Share invoice counter button. To number your quotes separately, uncheck the Share invoice counter button. 5 +.. TIP:: You can choose to integrate your quote numbers with the invoice number counter. This is an important feature as it allows you to keep the same number when converting a quote to an invoice. So, Quote-001 will automatically become Invoice-001. To number your quotes with your invoice numbering system, check the Share invoice counter button. To number your quotes separately, uncheck the Share invoice counter button. + +Client Number +^^^^^^^^^^^^^ + +If you wish to use a numbering system for your clients, check the Enable box. + +You can then define your client numbering system according to the Prefix or Pattern function. + +- To add a prefix, select the Prefix button. In the field immediately below, add your chosen prefix. The prefix will appear before the client number on all your invoices. +- To create a pattern, select the Pattern button. In the pattern field, enter the custom variable of your choice. To view available options for custom patterns, click on the question mark icon at the right end of the Pattern field. + +Credit Number +^^^^^^^^^^^^^ + +If you wish to use a numbering system for your credits, check the Enable box. + +You can then define your credit numbering system according to the Prefix or Pattern function. + +- To add a prefix, select the Prefix button. In the field immediately below, add your chosen prefix. The prefix will appear before the credit number on all your invoices. +- To create a pattern, select the Pattern button. In the pattern field, enter the custom variable of your choice. To view available options for custom patterns, click on the question mark icon at the right end of the Pattern field. + +Options +^^^^^^^ + +There are a few extra options provided to manage the generated numbering systems for your invoices. Click the Options tab to open them. Let's go through the options available: + +- Padding: You can 'pad' your invoice numbers by adding as many zeros as you want before the invoice number. This gives you greater flexibility in your future invoicing numbers. To pad your invoice number, enter the amount of zeros you want to add before the invoice number. So if you want to add three zeros, enter the number 3. + +- Recurring Prefix: You can choose to add a prefix to all your recurring invoice numbers. This can help you distinguish and organize your recurring invoices separately from your regular invoices. To add a prefix to recurring invoices, enter the prefix in the field. + +- Reset Counter: If you want to define a time frame to periodically reset your invoice and quote number counters, you can do so by adjusting the frequency in the Reset Counter field. TIP: The default setting for your Reset Counter is set to Never. To change the setting, click the drop down menu and select a frequency from the list. Custom Fields """"""""""""" -You can create new fields for your client entries, company details and invoices by assigning new field values and labels in the Custom Fields section. All field changes will automatically appear in the PDF invoice. +You can create new fields for information that appears on your invoices by assigning new field values and labels in the Custom Fields section. All field changes will automatically appear in the PDF invoice. Client Fields ^^^^^^^^^^^^^ To add fields to your client entries, click on the Client Fields tab. -You have the option of adding one or two new fields which will appear on the Client/Create and Client/Edit pages. When creating or editing a client, complete these fields if they are relevant to the client. The field name and information you enter will appear in the Client details section of the PDF invoice. +You have the option of adding up to two new fields for client information. These will appear on the Client/Create and Client/Edit pages. When creating an invoice, the field name and information you entered for the client will be displayed in the Client details section of the PDF invoice. + +Contact Fields +^^^^^^^^^^^^^^ + +To add fields to your contact entries, click on the Contact Fields tab. + +You have the option of adding up to two new fields for contact information about your client. These will appear on the Client/Create and Client/Edit pages. When creating an invoice, the field name and information you entered for the contact will be displayed in the Client details section of the PDF invoice. Company Fields ^^^^^^^^^^^^^^ -To add fields to your company details, click on the Company Fields tab. Enter the Field Label and Field Value information in the relevant fields. The information you enter will automatically appear in the Company details section of the PDF invoice. +To add fields to your company details, click on the Company Fields tab. Enter the Field Label and Field Value information in the relevant fields. The information you entered will automatically appear in the Company details section of the PDF invoice. + +Product Fields +^^^^^^^^^^^^^^ + +To add fields to your product entries, click on the Product Fields tab. + +You have the option of adding up to two new fields for product information. These will appear on the Product/Create and Product/Edit pages. When creating an invoice, the field name and information you entered for the product will appear in the Item section of the PDF invoice. Invoice Fields ^^^^^^^^^^^^^^ Want to include customized information in your invoices? To add fields to your invoice entry, click on the Invoice Fields tab. Enter the new field name in the Field Label field. You can add one or two new invoice fields. The new fields will appear in the top part of the Create/Invoice page, and will automatically be included in the PDF invoice. -Invoice Charges -^^^^^^^^^^^^^^^ - -To add new invoice charge fields, click on the Invoice Charge tab. Enter the new charge in the fields provided. You can add one or two new invoice charge fields. The new charge field/s will appear in the Invoice Subtotals section. Amounts entered into these fields during the Create or Edit Invoice process will automatically appear in the PDF invoice. To apply the Tax feature for the new charge, check the Charge tax button. +To add new invoice charge fields, go to the Surcharge Labels section. Enter the new charge in the fields provided. You can add one or two new surcharge fields. The new charge field/s will appear in the Invoice Subtotals section. Amounts entered into these fields during the Create or Edit Invoice process will automatically appear in the PDF invoice. To apply the Tax feature for the new charge, check the Charge taxes button. Quote Settings """""""""""""" @@ -74,9 +124,9 @@ Want to convert accepted quotes into invoices at a click of a button? Check the To disable the auto convert function, uncheck the Enable button. -Default Messages -"""""""""""""""" +Defaults +"""""""" -Set any customized default text you want to Invoice Terms, Invoice Footer and Quote Terms. +Set any customized default text you want to Invoice Terms, Invoice Footer, Quote Terms and Documents. The text you enter will appear in the relevant sections on all future invoices. Completed all your Invoice Settings? Click the green Save button at the bottom of the page, and your customized changes will appear on all your invoices. diff --git a/docs/recurring_invoices.rst b/docs/recurring_invoices.rst index a97d0ec12f5d..55b4d3a4e101 100644 --- a/docs/recurring_invoices.rst +++ b/docs/recurring_invoices.rst @@ -6,27 +6,29 @@ As a busy freelancer, you work for a variety of clients. Some jobs are one-off, List Recurring Invoices """"""""""""""""""""""" -To view the Recurring Invoices list page, go to the Invoices tab on the main taskbar and click to open the drop-down menu. Select Recurring Invoices to open the Recurring Invoices list page. +To view the Recurring Invoices list page, go to the Invoices tab on the main sidebar and click to open the Invoices list page. To open the list page for Recurring Invoices, click the gray Recurring button located above the top right side of the invoices table. Overview ^^^^^^^^ -The recurring invoices list provides a display of the information and settings for all recurring invoices. It is not a list of the actual invoices as they are sent. Invoices sent by the recurring invoices feature are recorded as regular numbered invoices in the Invoices list page. +The recurring invoices list provides a display of all active recurring invoices. -Here is a description of the columns in the recurring invoices list, as displayed in the main header bar of the recurring invoices table, from left to right: +Here is a description of the columns in the recurring invoices list table, from left to right: - **Frequency**: How often the client is billed with this invoice, ie. Weekly, monthly, etc. -- **Client**: The client name -- **Start Date**: The date the recurring invoice first began -- **End Date**: The date the recurring invoice is due to stop -- **Invoice Total**: The amount due +- **Client name**: The client's name +- **Start Date**: The date the recurring invoice series started +- **Last sent**: The date the last invoice was sent for this recurring invoice series +- **Amount**: The amount due +- **Private notes**: Comments and notes that you added when creating the recurring invoice. Only you can see them. +- **Status**: The status of the recurring invoice (ie. Draft, Sent, Viewed, Paid, Overdue) - **Action**: Hover your mouse over the Action area of the relevant recurring invoice entry and a gray Select button will appear. Click on the arrow at the right side of the button to open a drop-down list. The drop-down list presents a range of possible actions for you to choose from: - **Edit Invoice**: Edit the recurring invoice information on the Edit Invoice page. - - **Archive Recurring**: Invoice Click here to archive the recurring invoice. It will be archived and removed from the Recurring Invoices list page. - - **Delete Recurring**: Invoice Click here to delete the recurring invoice. It will be deleted and removed from the Recurring Invoices list page. - -You can create a new recurring invoice directly from the Recurring Invoices list page by clicking on the blue New Recurring Invoice + button located at the top right side of the page. The Recurring Invoices / Create page will open. + - **Clone to Invoice**: Duplicate the recurring invoice as a new recurring invoice. + - **Clone to Quote**: Create a quote containing data duplicated from the recurring invoice. + - **Archive Recurring** Invoice: Click here to archive the recurring invoice. It will be archived and removed from the Recurring Invoices list page. + - **Delete Recurring Invoice**: Click here to delete the recurring invoice. It will be deleted and removed from the Recurring Invoices list page. Filter ^^^^^^ @@ -39,28 +41,40 @@ Archiving/Deleting To archive or delete a recurring invoice, hover over the Action area of the recurring invoice entry row, and open the Action drop-down list. Select Archive recurring invoice or Delete recurring invoice from the list. The Recurring Invoices table will automatically refresh, and archived or deleted recurring invoices will no longer appear in the list. You can also archive or delete one or more recurring invoice via the gray Archive button that appears at the top left side of the Recurring Invoices list page. To archive or delete recurring invoices, check the relevant recurring invoices in the check boxes that appear in the far left column next to the Frequency field. The number of recurring invoices selected for archiving/deleting will automatically update and show on the Archive button. Then click on the Archive button, open the drop-down list and select the desired action. -Want to view archived or deleted recurring invoices? Check the box marked Show archived/deleted invoices, situated to the right of the Archive button. The table will automatically refresh, and will now feature the full list of recurring invoices, including current, archived and deleted recurring invoices, with the status of archived or deleted recurring invoices displayed in the Action column. +Want to view archived or deleted recurring invoices? Locate the field just to the right of the Archive button at the top left of the recurring invoices table. The field has a default setting of "Active", which means that the table is displaying only Active recurring invoices. Click inside the field, and a drop-down list will open. Select Archived and/or Deleted to view the desired invoices. The table will automatically refresh, and will now feature the full list of recurring invoices, including active, archived and deleted recurring invoices. The status of archived or deleted recurring invoices is displayed in the Action column. - **Deleted recurring invoices** are displayed with a red Deleted button. To restore deleted recurring invoices, hover on the red Deleted button. A gray Select button will appear. Click on the Select arrow, and select Restore recurring invoice in the drop-down list. - **Archived recurring invoices** are displayed with an orange Archived button. To restore or delete the archived recurring invoice, hover on the orange Archived button. A gray Select button will appear. Click on the Select arrow, and choose Restore recurring invoice from the drop-down list. To delete an archived recurring invoice, select Delete recurring invoice from the drop-down list of the Select button. -.. TIP:: The Recurring Invoices page is rich in clickable links, providing you with a shortcut to relevant pages you may wish to view. For example, all client names are clickable, taking you directly to the specific client summary page. In addition, the Frequency data is clickable, and will take you to the specific Recurring invoice page where you can edit the frequency value or any other information for this recurring invoice. +.. TIP: The Recurring Invoices page is rich in clickable links, providing you with a shortcut to relevant pages you may wish to view. For example, all client names are clickable, taking you directly to the specific client summary page. In addition, the Frequency data is clickable, and will take you to the specific Recurring invoice page where you can edit the frequency value or any other information for this recurring invoice. Create Recurring Invoice """""""""""""""""""""""" -When you create a recurring invoice, you are creating a pre-defined frequency for invoicing a particular job and client. The recurring invoice entry as featured in the Recurring Invoices list is not the actual invoice sent. Once an invoice of a recurring invoice is created, it will appear as a regular numbered invoice in the Invoices list page. +When you create a recurring invoice, you are creating a pre-defined frequency for invoicing a particular job and client. The recurring invoice entry as featured in the Recurring Invoices list is not the actual invoice sent. Once an invoice of a recurring invoice series is created, it will appear as a numbered invoice in the Invoices list page. + +Recurring invoices are numbered with a prefix before the invoice number. This enables you to identify and keep track of your recurring invoices with ease. + +To define your recurring invoices number prefix, go to Advanced Settings > Invoice Settings. In the first box, click on the Options tab. Then, specify your prefix in the Recurring prefix field. Make sure to click the green Save button at the bottom of the page to save your prefix setting. Now, we’ll explore how to set up a recurring invoice. **Let’s Begin** -To create a recurring invoice, you'll first need to complete the data fields in the top section of the Recurring Invoice / Create page. Let's go over the fields to get a better understanding: +To create a new recurring invoice, you'll need to go to the Invoices list page. Then, click on the arrow at the right side of the gray Recurring button, located at the top right above the Invoices list table. Select New Recurring Invoice from the drop down menu. + +Next, you'll need to complete the invoice details. Let's go over the fields to get a better understanding: - **Client**: Click on the arrow at the right end of the Client field. Select the relevant client from the client list. TIP: You can create a new client while creating a new recurring invoice. Simply click on the Create new client link, situated below the Client field on the Recurring Invoices / Create page. A pop-up window will open, enabling you to complete the new client’s details. Then continue creating the recurring invoice for this new client. -- **How Often**: Select the frequency the invoice will be sent to the client. Click on the arrow at the right end of the How Often field to open the drop-down list of frequency options. -- **Start Date**: The date the recurring invoice begins -- **End Date**: The date the recurring invoice is due to stop -- **Auto-Bill**: Check the Enable box if you want the system to send the invoice automatically at the selected frequency. TIP: The Auto-Bill feature is currently only available if you use Stripe.com as your payment gateway. -- **PO #**: The purchase order number. Enter the purchase order number for easy reference. -- **Discount**: If you wish to apply a discount to the invoice, you can choose one of two methods: a monetary amount, or a percentage of the total amount due. To find out more about applying discounts to recurring invoices, refer to section +- **Frequency**: Select the frequency the invoice will be sent to the client. Click on the arrow at the right end of the Frequency field to open the drop-down list of frequency options. + +.. TIP:: You can create dynamic date variables to include in your invoice emails. Use :MONTH, :QUARTER or :YEAR for date variables, and basic math to modify them. For example, if you enter ":YEAR+1 yearly subscription", the date will appear as the current year + one, denoting subscription for next year. + +- **Start Date**: The date the recurring invoice series begins +- **End Date**: The date the recurring invoice series is due to stop +- **Due date**: The date each recurring invoice is due. This is the default date for all invoices in the recurring invoice series. For example, you may want the client to pay on the 1st of the month for each recurring invoice. If so, select "1st day of month" from the drop-down menu. TIP: You can also choose to define the due date according to the client's pre-defined terms. If so, select "Use client terms" from the drop-down menu. +- **Auto-Bill**: Select the applicable option if you want the system to bill the customer automatically at the selected frequency. To disable Auto Bill, select "Off". To enable Auto-Bill at all times, select "Always". To give your customers the option to manage their auto billing for the recurring invoice on their client portal, check the "Opt-In" or "Opt-Out" setting. +- **PO #**: Enter the purchase order number for easy reference. +- **Discount**: If you wish to apply a discount to the invoice, you can choose one of two methods: a monetary amount, or a percentage of the total amount due. + +Complete the rest of the recurring invoice as you would a regular invoice. Enter the item(s), quantities and amounts that you are charging on a recurring basis. diff --git a/docs/update.rst b/docs/update.rst index c8af0f37d3d7..70c5c1f6b0d0 100644 --- a/docs/update.rst +++ b/docs/update.rst @@ -13,6 +13,8 @@ If you're moving servers make sure to copy over the .env file. If the auto-update fails you can manually run the update with the following commands. Once completed add ``?clear_cache=true`` to the end of the URL to clear the application cache. +A common error with shared hosting is "open_basedir restriction in effect", if you see this you'll need to either temporarily modify your open_basedir settings or run the update from the command line. + .. code-block:: shell composer dump-autoload --optimize @@ -24,6 +26,11 @@ If the auto-update fails you can manually run the update with the following comm .. TIP:: You can see the detailed changes for each release on our `GitHub release notes `_. +Version 4.0 +""""""""""""" + +The minimum PHP version is now 7.0.0 + Version 3.2 """"""""""" @@ -36,7 +43,8 @@ Make sure the .env file includes ``APP_CIPHER=rijndael-128`` Version 2.5.1 """"""""""""" -Minimum PHP version is now 5.5.9 + +The minimum PHP version is now 5.5.9 Version 2.0 """"""""""" diff --git a/public/built.js b/public/built.js index 6007b2b89e15..40b08a1539cc 100644 --- a/public/built.js +++ b/public/built.js @@ -1,28 +1,28 @@ -function generatePDF(t,e,n,i){if(t&&e){if(!n)return refreshTimer&&clearTimeout(refreshTimer),void(refreshTimer=setTimeout(function(){generatePDF(t,e,!0,i)},500));refreshTimer=null,t=calculateAmounts(t);var o=GetPdfMake(t,e,i);return i&&o.getDataUrl(i),o}}function copyObject(t){return!!t&&JSON.parse(JSON.stringify(t))}function processVariables(t){if(!t)return"";for(var e=["MONTH","QUARTER","YEAR"],n=0;n1?c=r.split("+")[1]:r.split("-").length>1&&(c=parseInt(r.split("-")[1])*-1),t=t.replace(r,getDatePart(i,c))}}return t}function getDatePart(t,e){return e=parseInt(e),e||(e=0),"MONTH"==t?getMonth(e):"QUARTER"==t?getQuarter(e):"YEAR"==t?getYear(e):void 0}function getMonth(t){var e=new Date,n=["January","February","March","April","May","June","July","August","September","October","November","December"],i=e.getMonth();return i=parseInt(i)+t,i%=12,i<0&&(i+=12),n[i]}function getYear(t){var e=new Date,n=e.getFullYear();return parseInt(n)+t}function getQuarter(t){var e=new Date,n=Math.floor((e.getMonth()+3)/3);return n+=t,n%=4,0==n&&(n=4),"Q"+n}function isStorageSupported(){try{return"localStorage"in window&&null!==window.localStorage}catch(t){return!1}}function isValidEmailAddress(t){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);return e.test(t)}function enableHoverClick(t,e,n){}function setAsLink(t,e){e?(t.css("text-decoration","underline"),t.css("cursor","pointer")):(t.css("text-decoration","none"),t.css("cursor","text"))}function setComboboxValue(t,e,n){t.find("input").val(e),t.find("input.form-control").val(n),e&&n?(t.find("select").combobox("setSelected"),t.find(".combobox-container").addClass("combobox-selected")):t.find(".combobox-container").removeClass("combobox-selected")}function convertDataURIToBinary(t){var e=t.indexOf(BASE64_MARKER)+BASE64_MARKER.length,n=t.substring(e);return base64DecToArr(n)}function comboboxHighlighter(t){var e=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),n=t.replace(new RegExp("
","g"),"\n");return n=_.escape(n),n=n.replace(new RegExp("("+e+")","ig"),function(t,n){return n?""+n+"":e}),n.replace(new RegExp("\n","g"),"
")}function inIframe(){try{return window.self!==window.top}catch(t){return!0}}function getContactDisplayName(t){return t.first_name||t.last_name?$.trim((t.first_name||"")+" "+(t.last_name||"")):t.email}function getContactDisplayNameWithEmail(t){var e="";return(t.first_name||t.last_name)&&(e+=$.trim((t.first_name||"")+" "+(t.last_name||""))),t.email&&(e&&(e+=" - "),e+=t.email),$.trim(e)}function getClientDisplayName(t){var e=!!t.contacts&&t.contacts[0];return t.name?t.name:e?getContactDisplayName(e):""}function populateInvoiceComboboxes(t,e){for(var n={},i={},o={},a=$("select#client"),s=0;s1?t+=", ":n64&&t<91?t-65:t>96&&t<123?t-71:t>47&&t<58?t+4:43===t?62:47===t?63:0}function base64DecToArr(t,e){for(var n,i,o=t.replace(/[^A-Za-z0-9\+\/]/g,""),a=o.length,s=e?Math.ceil((3*a+1>>2)/e)*e:3*a+1>>2,r=new Uint8Array(s),c=0,l=0,u=0;u>>(16>>>n&24)&255;c=0}return r}function uint6ToB64(t){return t<26?t+65:t<52?t+71:t<62?t-4:62===t?43:63===t?47:65}function base64EncArr(t){for(var e=2,n="",i=t.length,o=0,a=0;a0&&4*a/3%76===0&&(n+="\r\n"),o|=t[a]<<(16>>>e&24),2!==e&&t.length-a!==1||(n+=String.fromCharCode(uint6ToB64(o>>>18&63),uint6ToB64(o>>>12&63),uint6ToB64(o>>>6&63),uint6ToB64(63&o)),o=0);return n.substr(0,n.length-2+e)+(2===e?"":1===e?"=":"==")}function UTF8ArrToStr(t){for(var e,n="",i=t.length,o=0;o251&&e<254&&o+5247&&e<252&&o+4239&&e<248&&o+3223&&e<240&&o+2191&&e<224&&o+1>>6),e[s++]=128+(63&n)):n<65536?(e[s++]=224+(n>>>12),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):n<2097152?(e[s++]=240+(n>>>18),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):n<67108864?(e[s++]=248+(n>>>24),e[s++]=128+(n>>>18&63),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):(e[s++]=252+n/1073741824,e[s++]=128+(n>>>24&63),e[s++]=128+(n>>>18&63),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n));return e}function hexToR(t){return parseInt(cutHex(t).substring(0,2),16)}function hexToG(t){return parseInt(cutHex(t).substring(2,4),16)}function hexToB(t){return parseInt(cutHex(t).substring(4,6),16)}function cutHex(t){return"#"==t.charAt(0)?t.substring(1,7):t}function setDocHexColor(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setTextColor(n,i,o)}function setDocHexFill(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setFillColor(n,i,o)}function setDocHexDraw(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setDrawColor(n,i,o)}function toggleDatePicker(t){$("#"+t).datepicker("show")}function getPrecision(t){return roundToPrecision(t,3)!=t?4:roundToPrecision(t,2)!=t?3:2}function roundSignificant(t,e){var n=getPrecision(t),i=roundToPrecision(t,n)||0;return e?i.toFixed(n):i}function roundToTwo(t,e){var n=roundToPrecision(t,2)||0;return e?n.toFixed(2):n}function roundToFour(t,e){var n=roundToPrecision(t,4)||0;return e?n.toFixed(4):n}function roundToPrecision(t,e){var n=t<0;return n&&(t*=-1),t=+(Math.round(t+"e+"+e)+"e-"+e),n&&(t*=-1),t}function truncate(t,e){return t&&t.length>e?t.substr(0,e-1)+"...":t}function endsWith(t,e){return t.indexOf(e,t.length-e.length)!==-1}function secondsToTime(t){t=Math.round(t);var e=Math.floor(t/3600),n=t%3600,i=Math.floor(n/60),o=n%60,a=Math.ceil(o),s={h:e,m:i,s:a};return s}function twoDigits(t){return t<10?"0"+t:t}function toSnakeCase(t){return t?t.replace(/([A-Z])/g,function(t){return"_"+t.toLowerCase()}):""}function snakeToCamel(t){return t.replace(/_([a-z])/g,function(t){return t[1].toUpperCase()})}function getDescendantProp(t,e){for(var n=e.split(".");n.length&&(t=t[n.shift()]););return t}function doubleDollarSign(t){return t?t.replace?t.replace(/\$/g,"$$$"):t:""}function truncate(t,e){return t.length>e?t.substring(0,e)+"...":t}function actionListHandler(){$("tbody tr .tr-action").closest("tr").mouseover(function(){$(this).closest("tr").find(".tr-action").show(),$(this).closest("tr").find(".tr-status").hide()}).mouseout(function(){$dropdown=$(this).closest("tr").find(".tr-action"),$dropdown.hasClass("open")||($dropdown.hide(),$(this).closest("tr").find(".tr-status").show())})}function loadImages(t){$(t+" img").each(function(t,e){var n=$(e).attr("data-src");$(e).attr("src",n),$(e).attr("data-src",n)})}function prettyJson(t){return"string"!=typeof t&&(t=JSON.stringify(t,void 0,2)),t=t.replace(/&/g,"&").replace(//g,">"),t.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,function(t){var e="number";return/^"/.test(t)?e=/:$/.test(t)?"key":"string":/true|false/.test(t)?e="boolean":/null/.test(t)&&(e="null"),t=snakeToCamel(t),''+t+""})}function searchData(t,e,n){return function(i,o){var a;if(n){var s={keys:[e]},r=new Fuse(t,s);a=r.search(i)}else a=[],substrRegex=new RegExp(escapeRegExp(i),"i"),$.each(t,function(t,n){substrRegex.test(n[e])&&a.push(n)});o(a)}}function escapeRegExp(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function firstJSONError(t){for(var e in t)if(t.hasOwnProperty(e)){var n=t[e];for(var i in n)if(n.hasOwnProperty(i))return n[i]}return!1}function pad(t,e,n){return n=n||"0",t+="",t.length>=e?t:new Array(e-t.length+1).join(n)+t}function brewerColor(t){var e=["#1c9f77","#d95d02","#716cb1","#e62a8b","#5fa213","#e6aa04","#a87821","#676767"],t=(t-1)%e.length;return e[t]}function formatXml(t){var e="",n=/(>)(<)(\/*)/g;t=t.replace(n,"$1\r\n$2$3");var i=0;return jQuery.each(t.split("\r\n"),function(t,n){var o=0;n.match(/.+<\/\w[^>]*>$/)?o=0:n.match(/^<\/\w/)?0!=i&&(i-=1):o=n.match(/^<\w[^>]*[^\/]>.*$/)?1:0;for(var a="",s=0;s0&&e-1 in t))}function i(t,e,n){if(ot.isFunction(e))return ot.grep(t,function(t,i){return!!e.call(t,i,t)!==n});if(e.nodeType)return ot.grep(t,function(t){return t===e!==n});if("string"==typeof e){if(dt.test(e))return ot.filter(e,t,n);e=ot.filter(e,t)}return ot.grep(t,function(t){return ot.inArray(t,e)>=0!==n})}function o(t,e){do t=t[e];while(t&&1!==t.nodeType);return t}function a(t){var e=yt[t]={};return ot.each(t.match(Mt)||[],function(t,n){e[n]=!0}),e}function s(){ft.addEventListener?(ft.removeEventListener("DOMContentLoaded",r,!1),t.removeEventListener("load",r,!1)):(ft.detachEvent("onreadystatechange",r),t.detachEvent("onload",r))}function r(){(ft.addEventListener||"load"===event.type||"complete"===ft.readyState)&&(s(),ot.ready())}function c(t,e,n){if(void 0===n&&1===t.nodeType){var i="data-"+e.replace(wt,"-$1").toLowerCase();if(n=t.getAttribute(i),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:Tt.test(n)?ot.parseJSON(n):n)}catch(o){}ot.data(t,e,n)}else n=void 0}return n}function l(t){var e;for(e in t)if(("data"!==e||!ot.isEmptyObject(t[e]))&&"toJSON"!==e)return!1;return!0}function u(t,e,n,i){if(ot.acceptData(t)){var o,a,s=ot.expando,r=t.nodeType,c=r?ot.cache:t,l=r?t[s]:t[s]&&s;if(l&&c[l]&&(i||c[l].data)||void 0!==n||"string"!=typeof e)return l||(l=r?t[s]=Y.pop()||ot.guid++:s),c[l]||(c[l]=r?{}:{toJSON:ot.noop}),"object"!=typeof e&&"function"!=typeof e||(i?c[l]=ot.extend(c[l],e):c[l].data=ot.extend(c[l].data,e)),a=c[l],i||(a.data||(a.data={}),a=a.data),void 0!==n&&(a[ot.camelCase(e)]=n),"string"==typeof e?(o=a[e],null==o&&(o=a[ot.camelCase(e)])):o=a,o}}function h(t,e,n){if(ot.acceptData(t)){var i,o,a=t.nodeType,s=a?ot.cache:t,r=a?t[ot.expando]:ot.expando;if(s[r]){if(e&&(i=n?s[r]:s[r].data)){ot.isArray(e)?e=e.concat(ot.map(e,ot.camelCase)):e in i?e=[e]:(e=ot.camelCase(e),e=e in i?[e]:e.split(" ")),o=e.length;for(;o--;)delete i[e[o]];if(n?!l(i):!ot.isEmptyObject(i))return}(n||(delete s[r].data,l(s[r])))&&(a?ot.cleanData([t],!0):nt.deleteExpando||s!=s.window?delete s[r]:s[r]=null)}}}function d(){return!0}function p(){return!1}function f(){try{return ft.activeElement}catch(t){}}function m(t){var e=Et.split("|"),n=t.createDocumentFragment();if(n.createElement)for(;e.length;)n.createElement(e.pop());return n}function g(t,e){var n,i,o=0,a=typeof t.getElementsByTagName!==zt?t.getElementsByTagName(e||"*"):typeof t.querySelectorAll!==zt?t.querySelectorAll(e||"*"):void 0;if(!a)for(a=[],n=t.childNodes||t;null!=(i=n[o]);o++)!e||ot.nodeName(i,e)?a.push(i):ot.merge(a,g(i,e));return void 0===e||e&&ot.nodeName(t,e)?ot.merge([t],a):a}function b(t){xt.test(t.type)&&(t.defaultChecked=t.checked)}function v(t,e){return ot.nodeName(t,"table")&&ot.nodeName(11!==e.nodeType?e:e.firstChild,"tr")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}function M(t){return t.type=(null!==ot.find.attr(t,"type"))+"/"+t.type,t}function y(t){var e=Vt.exec(t.type);return e?t.type=e[1]:t.removeAttribute("type"),t}function A(t,e){for(var n,i=0;null!=(n=t[i]);i++)ot._data(n,"globalEval",!e||ot._data(e[i],"globalEval"))}function _(t,e){if(1===e.nodeType&&ot.hasData(t)){var n,i,o,a=ot._data(t),s=ot._data(e,a),r=a.events;if(r){delete s.handle,s.events={};for(n in r)for(i=0,o=r[n].length;i")).appendTo(e.documentElement),e=(Qt[0].contentWindow||Qt[0].contentDocument).document,e.write(),e.close(),n=T(t,e),Qt.detach()),Zt[t]=n),n}function C(t,e){return{get:function(){var n=t();if(null!=n)return n?void delete this.get:(this.get=e).apply(this,arguments)}}}function O(t,e){if(e in t)return e;for(var n=e.charAt(0).toUpperCase()+e.slice(1),i=e,o=de.length;o--;)if(e=de[o]+n,e in t)return e;return i}function N(t,e){for(var n,i,o,a=[],s=0,r=t.length;s=0&&n=0},isEmptyObject:function(t){var e;for(e in t)return!1;return!0},isPlainObject:function(t){var e;if(!t||"object"!==ot.type(t)||t.nodeType||ot.isWindow(t))return!1;try{if(t.constructor&&!et.call(t,"constructor")&&!et.call(t.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}if(nt.ownLast)for(e in t)return et.call(t,e);for(e in t);return void 0===e||et.call(t,e)},type:function(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?Z[tt.call(t)]||"object":typeof t},globalEval:function(e){e&&ot.trim(e)&&(t.execScript||function(e){t.eval.call(t,e)})(e)},camelCase:function(t){return t.replace(st,"ms-").replace(rt,ct)},nodeName:function(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()},each:function(t,e,i){var o,a=0,s=t.length,r=n(t);if(i){if(r)for(;a_.cacheLength&&delete t[e.shift()],t[n+" "]=i}var e=[];return t}function i(t){return t[P]=!0,t}function o(t){var e=D.createElement("div");try{return!!t(e)}catch(n){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function a(t,e){for(var n=t.split("|"),i=t.length;i--;)_.attrHandle[n[i]]=e}function s(t,e){var n=e&&t,i=n&&1===t.nodeType&&1===e.nodeType&&(~e.sourceIndex||V)-(~t.sourceIndex||V);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function r(t){return function(e){var n=e.nodeName.toLowerCase();return"input"===n&&e.type===t}}function c(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function l(t){return i(function(e){return e=+e,i(function(n,i){for(var o,a=t([],n.length,e),s=a.length;s--;)n[o=a[s]]&&(n[o]=!(i[o]=n[o]))})})}function u(t){return t&&"undefined"!=typeof t.getElementsByTagName&&t}function h(){}function d(t){for(var e=0,n=t.length,i="";e1?function(e,n,i){for(var o=t.length;o--;)if(!t[o](e,n,i))return!1;return!0}:t[0]}function m(t,n,i){for(var o=0,a=n.length;o-1&&(i[l]=!(s[l]=h))}}else M=g(M===s?M.splice(f,M.length):M),a?a(null,s,M,c):Q.apply(s,M)})}function v(t){for(var e,n,i,o=t.length,a=_.relative[t[0].type],s=a||_.relative[" "],r=a?1:0,c=p(function(t){return t===e},s,!0),l=p(function(t){return tt(e,t)>-1},s,!0),u=[function(t,n,i){var o=!a&&(i||n!==N)||((e=n).nodeType?c(t,n,i):l(t,n,i));return e=null,o}];r1&&f(u),r>1&&d(t.slice(0,r-1).concat({value:" "===t[r-2].type?"*":""})).replace(ct,"$1"),n,r0,a=t.length>0,s=function(i,s,r,c,l){var u,h,d,p=0,f="0",m=i&&[],b=[],v=N,M=i||a&&_.find.TAG("*",l),y=R+=null==v?1:Math.random()||.1,A=M.length;for(l&&(N=s!==D&&s);f!==A&&null!=(u=M[f]);f++){if(a&&u){for(h=0;d=t[h++];)if(d(u,s,r)){c.push(u);break}l&&(R=y)}o&&((u=!d&&u)&&p--,i&&m.push(u))}if(p+=f,o&&f!==p){for(h=0;d=n[h++];)d(m,b,s,r);if(i){if(p>0)for(;f--;)m[f]||b[f]||(b[f]=K.call(c));b=g(b)}Q.apply(c,b),l&&!i&&b.length>0&&p+n.length>1&&e.uniqueSort(c)}return l&&(R=y,N=v),m};return o?i(s):s}var y,A,_,z,T,w,C,O,N,S,x,L,D,k,q,W,E,B,I,P="sizzle"+1*new Date,X=t.document,R=0,F=0,H=n(),j=n(),U=n(),$=function(t,e){return t===e&&(x=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],K=J.pop,G=J.push,Q=J.push,Z=J.slice,tt=function(t,e){for(var n=0,i=t.length;n+~]|"+nt+")"+nt+"*"),ht=new RegExp("="+nt+"*([^\\]'\"]*?)"+nt+"*\\]","g"),dt=new RegExp(st),pt=new RegExp("^"+ot+"$"),ft={ID:new RegExp("^#("+it+")"),CLASS:new RegExp("^\\.("+it+")"),TAG:new RegExp("^("+it.replace("w","w*")+")"),ATTR:new RegExp("^"+at),PSEUDO:new RegExp("^"+st),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+nt+"*(even|odd|(([+-]|)(\\d*)n|)"+nt+"*(?:([+-]|)"+nt+"*(\\d+)|))"+nt+"*\\)|)","i"),bool:new RegExp("^(?:"+et+")$","i"),needsContext:new RegExp("^"+nt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+nt+"*((?:-\\d)?\\d*)"+nt+"*\\)|)(?=[^-]|$)","i")},mt=/^(?:input|select|textarea|button)$/i,gt=/^h\d$/i,bt=/^[^{]+\{\s*\[native \w/,vt=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Mt=/[+~]/,yt=/'|\\/g,At=new RegExp("\\\\([\\da-f]{1,6}"+nt+"?|("+nt+")|.)","ig"),_t=function(t,e,n){var i="0x"+e-65536;return i!==i||n?e:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)},zt=function(){L()};try{Q.apply(J=Z.call(X.childNodes),X.childNodes),J[X.childNodes.length].nodeType}catch(Tt){Q={apply:J.length?function(t,e){G.apply(t,Z.call(e))}:function(t,e){for(var n=t.length,i=0;t[n++]=e[i++];);t.length=n-1}}}A=e.support={},T=e.isXML=function(t){var e=t&&(t.ownerDocument||t).documentElement;return!!e&&"HTML"!==e.nodeName},L=e.setDocument=function(t){var e,n,i=t?t.ownerDocument||t:X;return i!==D&&9===i.nodeType&&i.documentElement?(D=i,k=i.documentElement,n=i.defaultView,n&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",zt,!1):n.attachEvent&&n.attachEvent("onunload",zt)),q=!T(i),A.attributes=o(function(t){return t.className="i",!t.getAttribute("className")}),A.getElementsByTagName=o(function(t){return t.appendChild(i.createComment("")),!t.getElementsByTagName("*").length}),A.getElementsByClassName=bt.test(i.getElementsByClassName),A.getById=o(function(t){return k.appendChild(t).id=P,!i.getElementsByName||!i.getElementsByName(P).length}),A.getById?(_.find.ID=function(t,e){if("undefined"!=typeof e.getElementById&&q){var n=e.getElementById(t);return n&&n.parentNode?[n]:[]}},_.filter.ID=function(t){var e=t.replace(At,_t);return function(t){return t.getAttribute("id")===e}}):(delete _.find.ID,_.filter.ID=function(t){var e=t.replace(At,_t);return function(t){var n="undefined"!=typeof t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}}),_.find.TAG=A.getElementsByTagName?function(t,e){return"undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t):A.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,i=[],o=0,a=e.getElementsByTagName(t);if("*"===t){for(;n=a[o++];)1===n.nodeType&&i.push(n);return i}return a},_.find.CLASS=A.getElementsByClassName&&function(t,e){if(q)return e.getElementsByClassName(t)},E=[],W=[],(A.qsa=bt.test(i.querySelectorAll))&&(o(function(t){k.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&W.push("[*^$]="+nt+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||W.push("\\["+nt+"*(?:value|"+et+")"),t.querySelectorAll("[id~="+P+"-]").length||W.push("~="),t.querySelectorAll(":checked").length||W.push(":checked"),t.querySelectorAll("a#"+P+"+*").length||W.push(".#.+[+~]")}),o(function(t){var e=i.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&W.push("name"+nt+"*[*^$|!~]?="),t.querySelectorAll(":enabled").length||W.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),W.push(",.*:")})),(A.matchesSelector=bt.test(B=k.matches||k.webkitMatchesSelector||k.mozMatchesSelector||k.oMatchesSelector||k.msMatchesSelector))&&o(function(t){A.disconnectedMatch=B.call(t,"div"),B.call(t,"[s!='']:x"),E.push("!=",st)}),W=W.length&&new RegExp(W.join("|")),E=E.length&&new RegExp(E.join("|")),e=bt.test(k.compareDocumentPosition),I=e||bt.test(k.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,i=e&&e.parentNode;return t===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):t.compareDocumentPosition&&16&t.compareDocumentPosition(i)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},$=e?function(t,e){if(t===e)return x=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n?n:(n=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1,1&n||!A.sortDetached&&e.compareDocumentPosition(t)===n?t===i||t.ownerDocument===X&&I(X,t)?-1:e===i||e.ownerDocument===X&&I(X,e)?1:S?tt(S,t)-tt(S,e):0:4&n?-1:1)}:function(t,e){if(t===e)return x=!0,0;var n,o=0,a=t.parentNode,r=e.parentNode,c=[t],l=[e];if(!a||!r)return t===i?-1:e===i?1:a?-1:r?1:S?tt(S,t)-tt(S,e):0;if(a===r)return s(t,e);for(n=t;n=n.parentNode;)c.unshift(n);for(n=e;n=n.parentNode;)l.unshift(n);for(;c[o]===l[o];)o++;return o?s(c[o],l[o]):c[o]===X?-1:l[o]===X?1:0},i):D},e.matches=function(t,n){return e(t,null,null,n)},e.matchesSelector=function(t,n){if((t.ownerDocument||t)!==D&&L(t),n=n.replace(ht,"='$1']"),A.matchesSelector&&q&&(!E||!E.test(n))&&(!W||!W.test(n)))try{var i=B.call(t,n);if(i||A.disconnectedMatch||t.document&&11!==t.document.nodeType)return i}catch(o){}return e(n,D,null,[t]).length>0},e.contains=function(t,e){return(t.ownerDocument||t)!==D&&L(t),I(t,e)},e.attr=function(t,e){(t.ownerDocument||t)!==D&&L(t);var n=_.attrHandle[e.toLowerCase()],i=n&&Y.call(_.attrHandle,e.toLowerCase())?n(t,e,!q):void 0;return void 0!==i?i:A.attributes||!q?t.getAttribute(e):(i=t.getAttributeNode(e))&&i.specified?i.value:null},e.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},e.uniqueSort=function(t){var e,n=[],i=0,o=0;if(x=!A.detectDuplicates,S=!A.sortStable&&t.slice(0),t.sort($),x){for(;e=t[o++];)e===t[o]&&(i=n.push(o));for(;i--;)t.splice(n[i],1)}return S=null,t},z=e.getText=function(t){var e,n="",i=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=z(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[i++];)n+=z(e);return n},_=e.selectors={cacheLength:50,createPseudo:i,match:ft,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(At,_t),t[3]=(t[3]||t[4]||t[5]||"").replace(At,_t),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||e.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&e.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return ft.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&dt.test(n)&&(e=w(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(At,_t).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=H[t+" "];return e||(e=new RegExp("(^|"+nt+")"+t+"("+nt+"|$)"))&&H(t,function(t){return e.test("string"==typeof t.className&&t.className||"undefined"!=typeof t.getAttribute&&t.getAttribute("class")||"")})},ATTR:function(t,n,i){return function(o){var a=e.attr(o,t);return null==a?"!="===n:!n||(a+="","="===n?a===i:"!="===n?a!==i:"^="===n?i&&0===a.indexOf(i):"*="===n?i&&a.indexOf(i)>-1:"$="===n?i&&a.slice(-i.length)===i:"~="===n?(" "+a.replace(rt," ")+" ").indexOf(i)>-1:"|="===n&&(a===i||a.slice(0,i.length+1)===i+"-"))}},CHILD:function(t,e,n,i,o){var a="nth"!==t.slice(0,3),s="last"!==t.slice(-4),r="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,c){var l,u,h,d,p,f,m=a!==s?"nextSibling":"previousSibling",g=e.parentNode,b=r&&e.nodeName.toLowerCase(),v=!c&&!r;if(g){if(a){for(;m;){for(h=e;h=h[m];)if(r?h.nodeName.toLowerCase()===b:1===h.nodeType)return!1;f=m="only"===t&&!f&&"nextSibling"}return!0}if(f=[s?g.firstChild:g.lastChild],s&&v){for(u=g[P]||(g[P]={}),l=u[t]||[],p=l[0]===R&&l[1],d=l[0]===R&&l[2],h=p&&g.childNodes[p];h=++p&&h&&h[m]||(d=p=0)||f.pop();)if(1===h.nodeType&&++d&&h===e){u[t]=[R,p,d];break}}else if(v&&(l=(e[P]||(e[P]={}))[t])&&l[0]===R)d=l[1];else for(;(h=++p&&h&&h[m]||(d=p=0)||f.pop())&&((r?h.nodeName.toLowerCase()!==b:1!==h.nodeType)||!++d||(v&&((h[P]||(h[P]={}))[t]=[R,d]),h!==e)););return d-=o,d===i||d%i===0&&d/i>=0}}},PSEUDO:function(t,n){var o,a=_.pseudos[t]||_.setFilters[t.toLowerCase()]||e.error("unsupported pseudo: "+t);return a[P]?a(n):a.length>1?(o=[t,t,"",n],_.setFilters.hasOwnProperty(t.toLowerCase())?i(function(t,e){for(var i,o=a(t,n),s=o.length;s--;)i=tt(t,o[s]),t[i]=!(e[i]=o[s])}):function(t){return a(t,0,o)}):a}},pseudos:{not:i(function(t){var e=[],n=[],o=C(t.replace(ct,"$1"));return o[P]?i(function(t,e,n,i){for(var a,s=o(t,null,i,[]),r=t.length;r--;)(a=s[r])&&(t[r]=!(e[r]=a))}):function(t,i,a){return e[0]=t,o(e,null,a,n),e[0]=null,!n.pop()}}),has:i(function(t){return function(n){return e(t,n).length>0}}),contains:i(function(t){return t=t.replace(At,_t),function(e){return(e.textContent||e.innerText||z(e)).indexOf(t)>-1}}),lang:i(function(t){return pt.test(t||"")||e.error("unsupported lang: "+t),t=t.replace(At,_t).toLowerCase(),function(e){var n;do if(n=q?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return n=n.toLowerCase(),n===t||0===n.indexOf(t+"-");while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===k},focus:function(t){return t===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:function(t){return t.disabled===!1},disabled:function(t){return t.disabled===!0},checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,t.selected===!0},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!_.pseudos.empty(t)},header:function(t){return gt.test(t.nodeName)},input:function(t){return mt.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:l(function(){return[0]}),last:l(function(t,e){return[e-1]}),eq:l(function(t,e,n){return[n<0?n+e:n]}),even:l(function(t,e){for(var n=0;n=0;)t.push(i);return t}),gt:l(function(t,e,n){for(var i=n<0?n+e:n;++i2&&"ID"===(s=a[0]).type&&A.getById&&9===e.nodeType&&q&&_.relative[a[1].type]){if(e=(_.find.ID(s.matches[0].replace(At,_t),e)||[])[0],!e)return n;l&&(e=e.parentNode),t=t.slice(a.shift().value.length)}for(o=ft.needsContext.test(t)?0:a.length;o--&&(s=a[o],!_.relative[r=s.type]);)if((c=_.find[r])&&(i=c(s.matches[0].replace(At,_t),Mt.test(a[0].type)&&u(e.parentNode)||e))){if(a.splice(o,1),t=i.length&&d(a),!t)return Q.apply(n,i),n;break}}return(l||C(t,h))(i,e,!q,n,Mt.test(t)&&u(e.parentNode)||e),n},A.sortStable=P.split("").sort($).join("")===P,A.detectDuplicates=!!x,L(),A.sortDetached=o(function(t){return 1&t.compareDocumentPosition(D.createElement("div"))}),o(function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")})||a("type|href|height|width",function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)}),A.attributes&&o(function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")})||a("value",function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue}),o(function(t){return null==t.getAttribute("disabled")})||a(et,function(t,e,n){var i;if(!n)return t[e]===!0?e.toLowerCase():(i=t.getAttributeNode(e))&&i.specified?i.value:null}),e}(t);ot.find=lt,ot.expr=lt.selectors,ot.expr[":"]=ot.expr.pseudos,ot.unique=lt.uniqueSort,ot.text=lt.getText,ot.isXMLDoc=lt.isXML,ot.contains=lt.contains;var ut=ot.expr.match.needsContext,ht=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,dt=/^.[^:#\[\.,]*$/;ot.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?ot.find.matchesSelector(i,t)?[i]:[]:ot.find.matches(t,ot.grep(e,function(t){return 1===t.nodeType}))},ot.fn.extend({find:function(t){var e,n=[],i=this,o=i.length;if("string"!=typeof t)return this.pushStack(ot(t).filter(function(){for(e=0;e1?ot.unique(n):n),n.selector=this.selector?this.selector+" "+t:t,n},filter:function(t){return this.pushStack(i(this,t||[],!1))},not:function(t){return this.pushStack(i(this,t||[],!0))},is:function(t){return!!i(this,"string"==typeof t&&ut.test(t)?ot(t):t||[],!1).length}});var pt,ft=t.document,mt=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,gt=ot.fn.init=function(t,e){var n,i;if(!t)return this;if("string"==typeof t){if(n="<"===t.charAt(0)&&">"===t.charAt(t.length-1)&&t.length>=3?[null,t,null]:mt.exec(t),!n||!n[1]&&e)return!e||e.jquery?(e||pt).find(t):this.constructor(e).find(t);if(n[1]){if(e=e instanceof ot?e[0]:e,ot.merge(this,ot.parseHTML(n[1],e&&e.nodeType?e.ownerDocument||e:ft,!0)),ht.test(n[1])&&ot.isPlainObject(e))for(n in e)ot.isFunction(this[n])?this[n](e[n]):this.attr(n,e[n]);return this}if(i=ft.getElementById(n[2]),i&&i.parentNode){if(i.id!==n[2])return pt.find(t);this.length=1,this[0]=i}return this.context=ft,this.selector=t,this}return t.nodeType?(this.context=this[0]=t,this.length=1,this):ot.isFunction(t)?"undefined"!=typeof pt.ready?pt.ready(t):t(ot):(void 0!==t.selector&&(this.selector=t.selector,this.context=t.context),ot.makeArray(t,this))};gt.prototype=ot.fn,pt=ot(ft);var bt=/^(?:parents|prev(?:Until|All))/,vt={children:!0,contents:!0,next:!0,prev:!0};ot.extend({dir:function(t,e,n){for(var i=[],o=t[e];o&&9!==o.nodeType&&(void 0===n||1!==o.nodeType||!ot(o).is(n));)1===o.nodeType&&i.push(o),o=o[e];return i},sibling:function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n}}),ot.fn.extend({has:function(t){var e,n=ot(t,this),i=n.length;return this.filter(function(){for(e=0;e-1:1===n.nodeType&&ot.find.matchesSelector(n,t))){a.push(n);break}return this.pushStack(a.length>1?ot.unique(a):a)},index:function(t){return t?"string"==typeof t?ot.inArray(this[0],ot(t)):ot.inArray(t.jquery?t[0]:t,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(ot.unique(ot.merge(this.get(),ot(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),ot.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return ot.dir(t,"parentNode")},parentsUntil:function(t,e,n){return ot.dir(t,"parentNode",n)},next:function(t){return o(t,"nextSibling")},prev:function(t){return o(t,"previousSibling")},nextAll:function(t){return ot.dir(t,"nextSibling")},prevAll:function(t){return ot.dir(t,"previousSibling")},nextUntil:function(t,e,n){return ot.dir(t,"nextSibling",n)},prevUntil:function(t,e,n){return ot.dir(t,"previousSibling",n)},siblings:function(t){return ot.sibling((t.parentNode||{}).firstChild,t)},children:function(t){return ot.sibling(t.firstChild)},contents:function(t){return ot.nodeName(t,"iframe")?t.contentDocument||t.contentWindow.document:ot.merge([],t.childNodes)}},function(t,e){ot.fn[t]=function(n,i){var o=ot.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=ot.filter(i,o)),this.length>1&&(vt[t]||(o=ot.unique(o)),bt.test(t)&&(o=o.reverse())),this.pushStack(o)}});var Mt=/\S+/g,yt={};ot.Callbacks=function(t){t="string"==typeof t?yt[t]||a(t):ot.extend({},t);var e,n,i,o,s,r,c=[],l=!t.once&&[],u=function(a){for(n=t.memory&&a,i=!0,s=r||0,r=0,o=c.length,e=!0;c&&s-1;)c.splice(i,1),e&&(i<=o&&o--,i<=s&&s--)}),this},has:function(t){return t?ot.inArray(t,c)>-1:!(!c||!c.length)},empty:function(){return c=[],o=0,this},disable:function(){return c=l=n=void 0,this},disabled:function(){return!c},lock:function(){return l=void 0,n||h.disable(),this},locked:function(){return!l},fireWith:function(t,n){return!c||i&&!l||(n=n||[],n=[t,n.slice?n.slice():n],e?l.push(n):u(n)),this},fire:function(){return h.fireWith(this,arguments),this},fired:function(){return!!i}};return h},ot.extend({Deferred:function(t){var e=[["resolve","done",ot.Callbacks("once memory"),"resolved"],["reject","fail",ot.Callbacks("once memory"),"rejected"],["notify","progress",ot.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},then:function(){var t=arguments;return ot.Deferred(function(n){ot.each(e,function(e,a){var s=ot.isFunction(t[e])&&t[e];o[a[1]](function(){var t=s&&s.apply(this,arguments);t&&ot.isFunction(t.promise)?t.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a[0]+"With"](this===i?n.promise():this,s?[t]:arguments)})}),t=null}).promise()},promise:function(t){return null!=t?ot.extend(t,i):i}},o={};return i.pipe=i.then,ot.each(e,function(t,a){var s=a[2],r=a[3];i[a[1]]=s.add,r&&s.add(function(){n=r},e[1^t][2].disable,e[2][2].lock),o[a[0]]=function(){return o[a[0]+"With"](this===o?i:this,arguments),this},o[a[0]+"With"]=s.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(t){var e,n,i,o=0,a=J.call(arguments),s=a.length,r=1!==s||t&&ot.isFunction(t.promise)?s:0,c=1===r?t:ot.Deferred(),l=function(t,n,i){return function(o){n[t]=this,i[t]=arguments.length>1?J.call(arguments):o,i===e?c.notifyWith(n,i):--r||c.resolveWith(n,i)}};if(s>1)for(e=new Array(s),n=new Array(s),i=new Array(s);o0||(At.resolveWith(ft,[ot]),ot.fn.triggerHandler&&(ot(ft).triggerHandler("ready"),ot(ft).off("ready")))}}}),ot.ready.promise=function(e){if(!At)if(At=ot.Deferred(),"complete"===ft.readyState)setTimeout(ot.ready);else if(ft.addEventListener)ft.addEventListener("DOMContentLoaded",r,!1),t.addEventListener("load",r,!1);else{ft.attachEvent("onreadystatechange",r),t.attachEvent("onload",r);var n=!1;try{n=null==t.frameElement&&ft.documentElement}catch(i){}n&&n.doScroll&&!function o(){if(!ot.isReady){try{n.doScroll("left")}catch(t){return setTimeout(o,50)}s(),ot.ready()}}()}return At.promise(e)};var _t,zt="undefined";for(_t in ot(nt))break;nt.ownLast="0"!==_t,nt.inlineBlockNeedsLayout=!1,ot(function(){var t,e,n,i;n=ft.getElementsByTagName("body")[0],n&&n.style&&(e=ft.createElement("div"),i=ft.createElement("div"),i.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(i).appendChild(e),typeof e.style.zoom!==zt&&(e.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",nt.inlineBlockNeedsLayout=t=3===e.offsetWidth,t&&(n.style.zoom=1)),n.removeChild(i))}),function(){var t=ft.createElement("div");if(null==nt.deleteExpando){nt.deleteExpando=!0;try{delete t.test}catch(e){nt.deleteExpando=!1}}t=null}(),ot.acceptData=function(t){var e=ot.noData[(t.nodeName+" ").toLowerCase()],n=+t.nodeType||1;return(1===n||9===n)&&(!e||e!==!0&&t.getAttribute("classid")===e)};var Tt=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,wt=/([A-Z])/g;ot.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(t){return t=t.nodeType?ot.cache[t[ot.expando]]:t[ot.expando],!!t&&!l(t)},data:function(t,e,n){return u(t,e,n)},removeData:function(t,e){return h(t,e)},_data:function(t,e,n){return u(t,e,n,!0)},_removeData:function(t,e){return h(t,e,!0)}}),ot.fn.extend({data:function(t,e){var n,i,o,a=this[0],s=a&&a.attributes;if(void 0===t){if(this.length&&(o=ot.data(a),1===a.nodeType&&!ot._data(a,"parsedAttrs"))){for(n=s.length;n--;)s[n]&&(i=s[n].name,0===i.indexOf("data-")&&(i=ot.camelCase(i.slice(5)),c(a,i,o[i])));ot._data(a,"parsedAttrs",!0)}return o}return"object"==typeof t?this.each(function(){ot.data(this,t)}):arguments.length>1?this.each(function(){ot.data(this,t,e)}):a?c(a,t,ot.data(a,t)):void 0},removeData:function(t){return this.each(function(){ot.removeData(this,t)})}}),ot.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=ot._data(t,e),n&&(!i||ot.isArray(n)?i=ot._data(t,e,ot.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=ot.queue(t,e),i=n.length,o=n.shift(),a=ot._queueHooks(t,e),s=function(){ot.dequeue(t,e)};"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete a.stop,o.call(t,s,a)),!i&&a&&a.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return ot._data(t,n)||ot._data(t,n,{empty:ot.Callbacks("once memory").add(function(){ot._removeData(t,e+"queue"),ot._removeData(t,n)})})}}),ot.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length
a",nt.leadingWhitespace=3===e.firstChild.nodeType,nt.tbody=!e.getElementsByTagName("tbody").length,nt.htmlSerialize=!!e.getElementsByTagName("link").length,nt.html5Clone="<:nav>"!==ft.createElement("nav").cloneNode(!0).outerHTML,t.type="checkbox",t.checked=!0,n.appendChild(t),nt.appendChecked=t.checked,e.innerHTML="",nt.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,n.appendChild(e),e.innerHTML="",nt.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,nt.noCloneEvent=!0,e.attachEvent&&(e.attachEvent("onclick",function(){nt.noCloneEvent=!1}),e.cloneNode(!0).click()),null==nt.deleteExpando){nt.deleteExpando=!0;try{delete e.test}catch(i){nt.deleteExpando=!1}}}(),function(){var e,n,i=ft.createElement("div");for(e in{submit:!0,change:!0,focusin:!0})n="on"+e,(nt[e+"Bubbles"]=n in t)||(i.setAttribute(n,"t"),nt[e+"Bubbles"]=i.attributes[n].expando===!1);i=null}();var Lt=/^(?:input|select|textarea)$/i,Dt=/^key/,kt=/^(?:mouse|pointer|contextmenu)|click/,qt=/^(?:focusinfocus|focusoutblur)$/,Wt=/^([^.]*)(?:\.(.+)|)$/;ot.event={global:{},add:function(t,e,n,i,o){var a,s,r,c,l,u,h,d,p,f,m,g=ot._data(t);if(g){for(n.handler&&(c=n,n=c.handler,o=c.selector),n.guid||(n.guid=ot.guid++),(s=g.events)||(s=g.events={}),(u=g.handle)||(u=g.handle=function(t){return typeof ot===zt||t&&ot.event.triggered===t.type?void 0:ot.event.dispatch.apply(u.elem,arguments)},u.elem=t),e=(e||"").match(Mt)||[""],r=e.length;r--;)a=Wt.exec(e[r])||[],p=m=a[1],f=(a[2]||"").split(".").sort(),p&&(l=ot.event.special[p]||{},p=(o?l.delegateType:l.bindType)||p, -l=ot.event.special[p]||{},h=ot.extend({type:p,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&ot.expr.match.needsContext.test(o),namespace:f.join(".")},c),(d=s[p])||(d=s[p]=[],d.delegateCount=0,l.setup&&l.setup.call(t,i,f,u)!==!1||(t.addEventListener?t.addEventListener(p,u,!1):t.attachEvent&&t.attachEvent("on"+p,u))),l.add&&(l.add.call(t,h),h.handler.guid||(h.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,h):d.push(h),ot.event.global[p]=!0);t=null}},remove:function(t,e,n,i,o){var a,s,r,c,l,u,h,d,p,f,m,g=ot.hasData(t)&&ot._data(t);if(g&&(u=g.events)){for(e=(e||"").match(Mt)||[""],l=e.length;l--;)if(r=Wt.exec(e[l])||[],p=m=r[1],f=(r[2]||"").split(".").sort(),p){for(h=ot.event.special[p]||{},p=(i?h.delegateType:h.bindType)||p,d=u[p]||[],r=r[2]&&new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"),c=a=d.length;a--;)s=d[a],!o&&m!==s.origType||n&&n.guid!==s.guid||r&&!r.test(s.namespace)||i&&i!==s.selector&&("**"!==i||!s.selector)||(d.splice(a,1),s.selector&&d.delegateCount--,h.remove&&h.remove.call(t,s));c&&!d.length&&(h.teardown&&h.teardown.call(t,f,g.handle)!==!1||ot.removeEvent(t,p,g.handle),delete u[p])}else for(p in u)ot.event.remove(t,p+e[l],n,i,!0);ot.isEmptyObject(u)&&(delete g.handle,ot._removeData(t,"events"))}},trigger:function(e,n,i,o){var a,s,r,c,l,u,h,d=[i||ft],p=et.call(e,"type")?e.type:e,f=et.call(e,"namespace")?e.namespace.split("."):[];if(r=u=i=i||ft,3!==i.nodeType&&8!==i.nodeType&&!qt.test(p+ot.event.triggered)&&(p.indexOf(".")>=0&&(f=p.split("."),p=f.shift(),f.sort()),s=p.indexOf(":")<0&&"on"+p,e=e[ot.expando]?e:new ot.Event(p,"object"==typeof e&&e),e.isTrigger=o?2:3,e.namespace=f.join("."),e.namespace_re=e.namespace?new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=i),n=null==n?[e]:ot.makeArray(n,[e]),l=ot.event.special[p]||{},o||!l.trigger||l.trigger.apply(i,n)!==!1)){if(!o&&!l.noBubble&&!ot.isWindow(i)){for(c=l.delegateType||p,qt.test(c+p)||(r=r.parentNode);r;r=r.parentNode)d.push(r),u=r;u===(i.ownerDocument||ft)&&d.push(u.defaultView||u.parentWindow||t)}for(h=0;(r=d[h++])&&!e.isPropagationStopped();)e.type=h>1?c:l.bindType||p,a=(ot._data(r,"events")||{})[e.type]&&ot._data(r,"handle"),a&&a.apply(r,n),a=s&&r[s],a&&a.apply&&ot.acceptData(r)&&(e.result=a.apply(r,n),e.result===!1&&e.preventDefault());if(e.type=p,!o&&!e.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&ot.acceptData(i)&&s&&i[p]&&!ot.isWindow(i)){u=i[s],u&&(i[s]=null),ot.event.triggered=p;try{i[p]()}catch(m){}ot.event.triggered=void 0,u&&(i[s]=u)}return e.result}},dispatch:function(t){t=ot.event.fix(t);var e,n,i,o,a,s=[],r=J.call(arguments),c=(ot._data(this,"events")||{})[t.type]||[],l=ot.event.special[t.type]||{};if(r[0]=t,t.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,t)!==!1){for(s=ot.event.handlers.call(this,t,c),e=0;(o=s[e++])&&!t.isPropagationStopped();)for(t.currentTarget=o.elem,a=0;(i=o.handlers[a++])&&!t.isImmediatePropagationStopped();)t.namespace_re&&!t.namespace_re.test(i.namespace)||(t.handleObj=i,t.data=i.data,n=((ot.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,r),void 0!==n&&(t.result=n)===!1&&(t.preventDefault(),t.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,t),t.result}},handlers:function(t,e){var n,i,o,a,s=[],r=e.delegateCount,c=t.target;if(r&&c.nodeType&&(!t.button||"click"!==t.type))for(;c!=this;c=c.parentNode||this)if(1===c.nodeType&&(c.disabled!==!0||"click"!==t.type)){for(o=[],a=0;a=0:ot.find(n,this,null,[c]).length),o[n]&&o.push(i);o.length&&s.push({elem:c,handlers:o})}return r]","i"),Pt=/^\s+/,Xt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Rt=/<([\w:]+)/,Ft=/\s*$/g,Jt={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:nt.htmlSerialize?[0,"",""]:[1,"X
","
"]},Kt=m(ft),Gt=Kt.appendChild(ft.createElement("div"));Jt.optgroup=Jt.option,Jt.tbody=Jt.tfoot=Jt.colgroup=Jt.caption=Jt.thead,Jt.th=Jt.td,ot.extend({clone:function(t,e,n){var i,o,a,s,r,c=ot.contains(t.ownerDocument,t);if(nt.html5Clone||ot.isXMLDoc(t)||!It.test("<"+t.nodeName+">")?a=t.cloneNode(!0):(Gt.innerHTML=t.outerHTML,Gt.removeChild(a=Gt.firstChild)),!(nt.noCloneEvent&&nt.noCloneChecked||1!==t.nodeType&&11!==t.nodeType||ot.isXMLDoc(t)))for(i=g(a),r=g(t),s=0;null!=(o=r[s]);++s)i[s]&&z(o,i[s]);if(e)if(n)for(r=r||g(t),i=i||g(a),s=0;null!=(o=r[s]);s++)_(o,i[s]);else _(t,a);return i=g(a,"script"),i.length>0&&A(i,!c&&g(t,"script")),i=r=o=null,a},buildFragment:function(t,e,n,i){for(var o,a,s,r,c,l,u,h=t.length,d=m(e),p=[],f=0;f")+u[2],o=u[0];o--;)r=r.lastChild;if(!nt.leadingWhitespace&&Pt.test(a)&&p.push(e.createTextNode(Pt.exec(a)[0])),!nt.tbody)for(a="table"!==c||Ft.test(a)?""!==u[1]||Ft.test(a)?0:r:r.firstChild,o=a&&a.childNodes.length;o--;)ot.nodeName(l=a.childNodes[o],"tbody")&&!l.childNodes.length&&a.removeChild(l);for(ot.merge(p,r.childNodes),r.textContent="";r.firstChild;)r.removeChild(r.firstChild);r=d.lastChild}else p.push(e.createTextNode(a));for(r&&d.removeChild(r),nt.appendChecked||ot.grep(g(p,"input"),b),f=0;a=p[f++];)if((!i||ot.inArray(a,i)===-1)&&(s=ot.contains(a.ownerDocument,a),r=g(d.appendChild(a),"script"),s&&A(r),n))for(o=0;a=r[o++];)$t.test(a.type||"")&&n.push(a);return r=null,d},cleanData:function(t,e){for(var n,i,o,a,s=0,r=ot.expando,c=ot.cache,l=nt.deleteExpando,u=ot.event.special;null!=(n=t[s]);s++)if((e||ot.acceptData(n))&&(o=n[r],a=o&&c[o])){if(a.events)for(i in a.events)u[i]?ot.event.remove(n,i):ot.removeEvent(n,i,a.handle);c[o]&&(delete c[o],l?delete n[r]:typeof n.removeAttribute!==zt?n.removeAttribute(r):n[r]=null,Y.push(o))}}}),ot.fn.extend({text:function(t){return St(this,function(t){return void 0===t?ot.text(this):this.empty().append((this[0]&&this[0].ownerDocument||ft).createTextNode(t))},null,t,arguments.length)},append:function(){return this.domManip(arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=v(this,t);e.appendChild(t)}})},prepend:function(){return this.domManip(arguments,function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=v(this,t);e.insertBefore(t,e.firstChild)}})},before:function(){return this.domManip(arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this)})},after:function(){return this.domManip(arguments,function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)})},remove:function(t,e){for(var n,i=t?ot.filter(t,this):this,o=0;null!=(n=i[o]);o++)e||1!==n.nodeType||ot.cleanData(g(n)),n.parentNode&&(e&&ot.contains(n.ownerDocument,n)&&A(g(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var t,e=0;null!=(t=this[e]);e++){for(1===t.nodeType&&ot.cleanData(g(t,!1));t.firstChild;)t.removeChild(t.firstChild);t.options&&ot.nodeName(t,"select")&&(t.options.length=0)}return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map(function(){return ot.clone(this,t,e)})},html:function(t){return St(this,function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t)return 1===e.nodeType?e.innerHTML.replace(Bt,""):void 0;if("string"==typeof t&&!jt.test(t)&&(nt.htmlSerialize||!It.test(t))&&(nt.leadingWhitespace||!Pt.test(t))&&!Jt[(Rt.exec(t)||["",""])[1].toLowerCase()]){t=t.replace(Xt,"<$1>");try{for(;n1&&"string"==typeof d&&!nt.checkClone&&Ut.test(d))return this.each(function(n){var i=u.eq(n);p&&(t[0]=d.call(this,n,i.html())),i.domManip(t,e)});if(l&&(r=ot.buildFragment(t,this[0].ownerDocument,!1,this),n=r.firstChild,1===r.childNodes.length&&(r=n),n)){for(a=ot.map(g(r,"script"),M),o=a.length;c
t
",o=e.getElementsByTagName("td"),o[0].style.cssText="margin:0;border:0;padding:0;display:none",r=0===o[0].offsetHeight,r&&(o[0].style.display="",o[1].style.display="none",r=0===o[0].offsetHeight),n.removeChild(i))}var n,i,o,a,s,r,c;n=ft.createElement("div"),n.innerHTML="
a",o=n.getElementsByTagName("a")[0],i=o&&o.style,i&&(i.cssText="float:left;opacity:.5",nt.opacity="0.5"===i.opacity,nt.cssFloat=!!i.cssFloat,n.style.backgroundClip="content-box",n.cloneNode(!0).style.backgroundClip="",nt.clearCloneStyle="content-box"===n.style.backgroundClip,nt.boxSizing=""===i.boxSizing||""===i.MozBoxSizing||""===i.WebkitBoxSizing,ot.extend(nt,{reliableHiddenOffsets:function(){return null==r&&e(),r},boxSizingReliable:function(){return null==s&&e(),s},pixelPosition:function(){return null==a&&e(),a},reliableMarginRight:function(){return null==c&&e(),c}}))}(),ot.swap=function(t,e,n,i){var o,a,s={};for(a in e)s[a]=t.style[a],t.style[a]=e[a];o=n.apply(t,i||[]);for(a in e)t.style[a]=s[a];return o};var ae=/alpha\([^)]*\)/i,se=/opacity\s*=\s*([^)]*)/,re=/^(none|table(?!-c[ea]).+)/,ce=new RegExp("^("+Ct+")(.*)$","i"),le=new RegExp("^([+-])=("+Ct+")","i"),ue={position:"absolute",visibility:"hidden",display:"block"},he={letterSpacing:"0",fontWeight:"400"},de=["Webkit","O","Moz","ms"];ot.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=ee(t,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":nt.cssFloat?"cssFloat":"styleFloat"},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,a,s,r=ot.camelCase(e),c=t.style;if(e=ot.cssProps[r]||(ot.cssProps[r]=O(c,r)),s=ot.cssHooks[e]||ot.cssHooks[r],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(t,!1,i))?o:c[e];if(a=typeof n,"string"===a&&(o=le.exec(n))&&(n=(o[1]+1)*o[2]+parseFloat(ot.css(t,e)),a="number"),null!=n&&n===n&&("number"!==a||ot.cssNumber[r]||(n+="px"),nt.clearCloneStyle||""!==n||0!==e.indexOf("background")||(c[e]="inherit"),!(s&&"set"in s&&void 0===(n=s.set(t,n,i)))))try{c[e]=n}catch(l){}}},css:function(t,e,n,i){var o,a,s,r=ot.camelCase(e);return e=ot.cssProps[r]||(ot.cssProps[r]=O(t.style,r)),s=ot.cssHooks[e]||ot.cssHooks[r],s&&"get"in s&&(a=s.get(t,!0,n)),void 0===a&&(a=ee(t,e,i)),"normal"===a&&e in he&&(a=he[e]),""===n||n?(o=parseFloat(a),n===!0||ot.isNumeric(o)?o||0:a):a}}),ot.each(["height","width"],function(t,e){ot.cssHooks[e]={get:function(t,n,i){if(n)return re.test(ot.css(t,"display"))&&0===t.offsetWidth?ot.swap(t,ue,function(){return L(t,e,i)}):L(t,e,i)},set:function(t,n,i){var o=i&&te(t);return S(t,n,i?x(t,e,i,nt.boxSizing&&"border-box"===ot.css(t,"boxSizing",!1,o),o):0)}}}),nt.opacity||(ot.cssHooks.opacity={get:function(t,e){return se.test((e&&t.currentStyle?t.currentStyle.filter:t.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":e?"1":""},set:function(t,e){var n=t.style,i=t.currentStyle,o=ot.isNumeric(e)?"alpha(opacity="+100*e+")":"",a=i&&i.filter||n.filter||"";n.zoom=1,(e>=1||""===e)&&""===ot.trim(a.replace(ae,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===e||i&&!i.filter)||(n.filter=ae.test(a)?a.replace(ae,o):a+" "+o)}}),ot.cssHooks.marginRight=C(nt.reliableMarginRight,function(t,e){if(e)return ot.swap(t,{display:"inline-block"},ee,[t,"marginRight"])}),ot.each({margin:"",padding:"",border:"Width"},function(t,e){ot.cssHooks[t+e]={expand:function(n){for(var i=0,o={},a="string"==typeof n?n.split(" "):[n];i<4;i++)o[t+Ot[i]+e]=a[i]||a[i-2]||a[0];return o}},ne.test(t)||(ot.cssHooks[t+e].set=S)}),ot.fn.extend({css:function(t,e){return St(this,function(t,e,n){var i,o,a={},s=0;if(ot.isArray(e)){for(i=te(t),o=e.length;s1)},show:function(){return N(this,!0)},hide:function(){return N(this)},toggle:function(t){return"boolean"==typeof t?t?this.show():this.hide():this.each(function(){Nt(this)?ot(this).show():ot(this).hide()})}}),ot.Tween=D,D.prototype={constructor:D,init:function(t,e,n,i,o,a){this.elem=t,this.prop=n,this.easing=o||"swing",this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=a||(ot.cssNumber[n]?"":"px")},cur:function(){var t=D.propHooks[this.prop];return t&&t.get?t.get(this):D.propHooks._default.get(this)},run:function(t){var e,n=D.propHooks[this.prop];return this.options.duration?this.pos=e=ot.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):D.propHooks._default.set(this),this}},D.prototype.init.prototype=D.prototype,D.propHooks={_default:{get:function(t){var e;return null==t.elem[t.prop]||t.elem.style&&null!=t.elem.style[t.prop]?(e=ot.css(t.elem,t.prop,""),e&&"auto"!==e?e:0):t.elem[t.prop]},set:function(t){ot.fx.step[t.prop]?ot.fx.step[t.prop](t):t.elem.style&&(null!=t.elem.style[ot.cssProps[t.prop]]||ot.cssHooks[t.prop])?ot.style(t.elem,t.prop,t.now+t.unit):t.elem[t.prop]=t.now}}},D.propHooks.scrollTop=D.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},ot.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2}},ot.fx=D.prototype.init,ot.fx.step={};var pe,fe,me=/^(?:toggle|show|hide)$/,ge=new RegExp("^(?:([+-])=|)("+Ct+")([a-z%]*)$","i"),be=/queueHooks$/,ve=[E],Me={"*":[function(t,e){var n=this.createTween(t,e),i=n.cur(),o=ge.exec(e),a=o&&o[3]||(ot.cssNumber[t]?"":"px"),s=(ot.cssNumber[t]||"px"!==a&&+i)&&ge.exec(ot.css(n.elem,t)),r=1,c=20;if(s&&s[3]!==a){a=a||s[3],o=o||[],s=+i||1;do r=r||".5",s/=r,ot.style(n.elem,t,s+a);while(r!==(r=n.cur()/i)&&1!==r&&--c)}return o&&(s=n.start=+s||+i||0,n.unit=a,n.end=o[1]?s+(o[1]+1)*o[2]:+o[2]),n}]};ot.Animation=ot.extend(I,{tweener:function(t,e){ot.isFunction(t)?(e=t,t=["*"]):t=t.split(" ");for(var n,i=0,o=t.length;i
a",i=e.getElementsByTagName("a")[0],n=ft.createElement("select"),o=n.appendChild(ft.createElement("option")),t=e.getElementsByTagName("input")[0],i.style.cssText="top:1px",nt.getSetAttribute="t"!==e.className,nt.style=/top/.test(i.getAttribute("style")),nt.hrefNormalized="/a"===i.getAttribute("href"),nt.checkOn=!!t.value,nt.optSelected=o.selected,nt.enctype=!!ft.createElement("form").enctype,n.disabled=!0,nt.optDisabled=!o.disabled,t=ft.createElement("input"),t.setAttribute("value",""),nt.input=""===t.getAttribute("value"),t.value="t",t.setAttribute("type","radio"),nt.radioValue="t"===t.value}();var ye=/\r/g;ot.fn.extend({val:function(t){var e,n,i,o=this[0];{if(arguments.length)return i=ot.isFunction(t),this.each(function(n){var o;1===this.nodeType&&(o=i?t.call(this,n,ot(this).val()):t,null==o?o="":"number"==typeof o?o+="":ot.isArray(o)&&(o=ot.map(o,function(t){return null==t?"":t+""})),e=ot.valHooks[this.type]||ot.valHooks[this.nodeName.toLowerCase()],e&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))});if(o)return e=ot.valHooks[o.type]||ot.valHooks[o.nodeName.toLowerCase()],e&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:(n=o.value,"string"==typeof n?n.replace(ye,""):null==n?"":n)}}}),ot.extend({valHooks:{option:{get:function(t){var e=ot.find.attr(t,"value");return null!=e?e:ot.trim(ot.text(t))}},select:{get:function(t){for(var e,n,i=t.options,o=t.selectedIndex,a="select-one"===t.type||o<0,s=a?null:[],r=a?o+1:i.length,c=o<0?r:a?o:0;c=0)try{i.selected=n=!0}catch(r){i.scrollHeight}else i.selected=!1;return n||(t.selectedIndex=-1),o}}}}),ot.each(["radio","checkbox"],function(){ot.valHooks[this]={set:function(t,e){if(ot.isArray(e))return t.checked=ot.inArray(ot(t).val(),e)>=0}},nt.checkOn||(ot.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})});var Ae,_e,ze=ot.expr.attrHandle,Te=/^(?:checked|selected)$/i,we=nt.getSetAttribute,Ce=nt.input;ot.fn.extend({attr:function(t,e){return St(this,ot.attr,t,e,arguments.length>1)},removeAttr:function(t){return this.each(function(){ot.removeAttr(this,t)})}}),ot.extend({attr:function(t,e,n){var i,o,a=t.nodeType;if(t&&3!==a&&8!==a&&2!==a)return typeof t.getAttribute===zt?ot.prop(t,e,n):(1===a&&ot.isXMLDoc(t)||(e=e.toLowerCase(),i=ot.attrHooks[e]||(ot.expr.match.bool.test(e)?_e:Ae)),void 0===n?i&&"get"in i&&null!==(o=i.get(t,e))?o:(o=ot.find.attr(t,e),null==o?void 0:o):null!==n?i&&"set"in i&&void 0!==(o=i.set(t,n,e))?o:(t.setAttribute(e,n+""),n):void ot.removeAttr(t,e))},removeAttr:function(t,e){var n,i,o=0,a=e&&e.match(Mt);if(a&&1===t.nodeType)for(;n=a[o++];)i=ot.propFix[n]||n,ot.expr.match.bool.test(n)?Ce&&we||!Te.test(n)?t[i]=!1:t[ot.camelCase("default-"+n)]=t[i]=!1:ot.attr(t,n,""),t.removeAttribute(we?n:i)},attrHooks:{type:{set:function(t,e){if(!nt.radioValue&&"radio"===e&&ot.nodeName(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}}}),_e={set:function(t,e,n){return e===!1?ot.removeAttr(t,n):Ce&&we||!Te.test(n)?t.setAttribute(!we&&ot.propFix[n]||n,n):t[ot.camelCase("default-"+n)]=t[n]=!0,n}},ot.each(ot.expr.match.bool.source.match(/\w+/g),function(t,e){var n=ze[e]||ot.find.attr;ze[e]=Ce&&we||!Te.test(e)?function(t,e,i){var o,a;return i||(a=ze[e],ze[e]=o,o=null!=n(t,e,i)?e.toLowerCase():null,ze[e]=a),o}:function(t,e,n){if(!n)return t[ot.camelCase("default-"+e)]?e.toLowerCase():null}}),Ce&&we||(ot.attrHooks.value={set:function(t,e,n){return ot.nodeName(t,"input")?void(t.defaultValue=e):Ae&&Ae.set(t,e,n)}}),we||(Ae={set:function(t,e,n){var i=t.getAttributeNode(n);if(i||t.setAttributeNode(i=t.ownerDocument.createAttribute(n)),i.value=e+="","value"===n||e===t.getAttribute(n))return e}},ze.id=ze.name=ze.coords=function(t,e,n){var i;if(!n)return(i=t.getAttributeNode(e))&&""!==i.value?i.value:null},ot.valHooks.button={get:function(t,e){var n=t.getAttributeNode(e);if(n&&n.specified)return n.value},set:Ae.set},ot.attrHooks.contenteditable={ -set:function(t,e,n){Ae.set(t,""!==e&&e,n)}},ot.each(["width","height"],function(t,e){ot.attrHooks[e]={set:function(t,n){if(""===n)return t.setAttribute(e,"auto"),n}}})),nt.style||(ot.attrHooks.style={get:function(t){return t.style.cssText||void 0},set:function(t,e){return t.style.cssText=e+""}});var Oe=/^(?:input|select|textarea|button|object)$/i,Ne=/^(?:a|area)$/i;ot.fn.extend({prop:function(t,e){return St(this,ot.prop,t,e,arguments.length>1)},removeProp:function(t){return t=ot.propFix[t]||t,this.each(function(){try{this[t]=void 0,delete this[t]}catch(e){}})}}),ot.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(t,e,n){var i,o,a,s=t.nodeType;if(t&&3!==s&&8!==s&&2!==s)return a=1!==s||!ot.isXMLDoc(t),a&&(e=ot.propFix[e]||e,o=ot.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:t[e]=n:o&&"get"in o&&null!==(i=o.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=ot.find.attr(t,"tabindex");return e?parseInt(e,10):Oe.test(t.nodeName)||Ne.test(t.nodeName)&&t.href?0:-1}}}}),nt.hrefNormalized||ot.each(["href","src"],function(t,e){ot.propHooks[e]={get:function(t){return t.getAttribute(e,4)}}}),nt.optSelected||(ot.propHooks.selected={get:function(t){var e=t.parentNode;return e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex),null}}),ot.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ot.propFix[this.toLowerCase()]=this}),nt.enctype||(ot.propFix.enctype="encoding");var Se=/[\t\r\n\f]/g;ot.fn.extend({addClass:function(t){var e,n,i,o,a,s,r=0,c=this.length,l="string"==typeof t&&t;if(ot.isFunction(t))return this.each(function(e){ot(this).addClass(t.call(this,e,this.className))});if(l)for(e=(t||"").match(Mt)||[];r=0;)i=i.replace(" "+o+" "," ");s=t?ot.trim(i):"",n.className!==s&&(n.className=s)}return this},toggleClass:function(t,e){var n=typeof t;return"boolean"==typeof e&&"string"===n?e?this.addClass(t):this.removeClass(t):ot.isFunction(t)?this.each(function(n){ot(this).toggleClass(t.call(this,n,this.className,e),e)}):this.each(function(){if("string"===n)for(var e,i=0,o=ot(this),a=t.match(Mt)||[];e=a[i++];)o.hasClass(e)?o.removeClass(e):o.addClass(e);else n!==zt&&"boolean"!==n||(this.className&&ot._data(this,"__className__",this.className),this.className=this.className||t===!1?"":ot._data(this,"__className__")||"")})},hasClass:function(t){for(var e=" "+t+" ",n=0,i=this.length;n=0)return!0;return!1}}),ot.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(t,e){ot.fn[e]=function(t,n){return arguments.length>0?this.on(e,null,t,n):this.trigger(e)}}),ot.fn.extend({hover:function(t,e){return this.mouseenter(t).mouseleave(e||t)},bind:function(t,e,n){return this.on(t,null,e,n)},unbind:function(t,e){return this.off(t,null,e)},delegate:function(t,e,n,i){return this.on(e,t,n,i)},undelegate:function(t,e,n){return 1===arguments.length?this.off(t,"**"):this.off(e,t||"**",n)}});var xe=ot.now(),Le=/\?/,De=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;ot.parseJSON=function(e){if(t.JSON&&t.JSON.parse)return t.JSON.parse(e+"");var n,i=null,o=ot.trim(e+"");return o&&!ot.trim(o.replace(De,function(t,e,o,a){return n&&e&&(i=0),0===i?t:(n=o||e,i+=!a-!o,"")}))?Function("return "+o)():ot.error("Invalid JSON: "+e)},ot.parseXML=function(e){var n,i;if(!e||"string"!=typeof e)return null;try{t.DOMParser?(i=new DOMParser,n=i.parseFromString(e,"text/xml")):(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(e))}catch(o){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName("parsererror").length||ot.error("Invalid XML: "+e),n};var ke,qe,We=/#.*$/,Ee=/([?&])_=[^&]*/,Be=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ie=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Pe=/^(?:GET|HEAD)$/,Xe=/^\/\//,Re=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Fe={},He={},je="*/".concat("*");try{qe=location.href}catch(Ue){qe=ft.createElement("a"),qe.href="",qe=qe.href}ke=Re.exec(qe.toLowerCase())||[],ot.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qe,type:"GET",isLocal:Ie.test(ke[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":je,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":ot.parseJSON,"text xml":ot.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?R(R(t,ot.ajaxSettings),e):R(ot.ajaxSettings,t)},ajaxPrefilter:P(Fe),ajaxTransport:P(He),ajax:function(t,e){function n(t,e,n,i){var o,u,b,v,y,_=e;2!==M&&(M=2,r&&clearTimeout(r),l=void 0,s=i||"",A.readyState=t>0?4:0,o=t>=200&&t<300||304===t,n&&(v=F(h,A,n)),v=H(h,v,A,o),o?(h.ifModified&&(y=A.getResponseHeader("Last-Modified"),y&&(ot.lastModified[a]=y),y=A.getResponseHeader("etag"),y&&(ot.etag[a]=y)),204===t||"HEAD"===h.type?_="nocontent":304===t?_="notmodified":(_=v.state,u=v.data,b=v.error,o=!b)):(b=_,!t&&_||(_="error",t<0&&(t=0))),A.status=t,A.statusText=(e||_)+"",o?f.resolveWith(d,[u,_,A]):f.rejectWith(d,[A,_,b]),A.statusCode(g),g=void 0,c&&p.trigger(o?"ajaxSuccess":"ajaxError",[A,h,o?u:b]),m.fireWith(d,[A,_]),c&&(p.trigger("ajaxComplete",[A,h]),--ot.active||ot.event.trigger("ajaxStop")))}"object"==typeof t&&(e=t,t=void 0),e=e||{};var i,o,a,s,r,c,l,u,h=ot.ajaxSetup({},e),d=h.context||h,p=h.context&&(d.nodeType||d.jquery)?ot(d):ot.event,f=ot.Deferred(),m=ot.Callbacks("once memory"),g=h.statusCode||{},b={},v={},M=0,y="canceled",A={readyState:0,getResponseHeader:function(t){var e;if(2===M){if(!u)for(u={};e=Be.exec(s);)u[e[1].toLowerCase()]=e[2];e=u[t.toLowerCase()]}return null==e?null:e},getAllResponseHeaders:function(){return 2===M?s:null},setRequestHeader:function(t,e){var n=t.toLowerCase();return M||(t=v[n]=v[n]||t,b[t]=e),this},overrideMimeType:function(t){return M||(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(M<2)for(e in t)g[e]=[g[e],t[e]];else A.always(t[A.status]);return this},abort:function(t){var e=t||y;return l&&l.abort(e),n(0,e),this}};if(f.promise(A).complete=m.add,A.success=A.done,A.error=A.fail,h.url=((t||h.url||qe)+"").replace(We,"").replace(Xe,ke[1]+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=ot.trim(h.dataType||"*").toLowerCase().match(Mt)||[""],null==h.crossDomain&&(i=Re.exec(h.url.toLowerCase()),h.crossDomain=!(!i||i[1]===ke[1]&&i[2]===ke[2]&&(i[3]||("http:"===i[1]?"80":"443"))===(ke[3]||("http:"===ke[1]?"80":"443")))),h.data&&h.processData&&"string"!=typeof h.data&&(h.data=ot.param(h.data,h.traditional)),X(Fe,h,e,A),2===M)return A;c=ot.event&&h.global,c&&0===ot.active++&&ot.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Pe.test(h.type),a=h.url,h.hasContent||(h.data&&(a=h.url+=(Le.test(a)?"&":"?")+h.data,delete h.data),h.cache===!1&&(h.url=Ee.test(a)?a.replace(Ee,"$1_="+xe++):a+(Le.test(a)?"&":"?")+"_="+xe++)),h.ifModified&&(ot.lastModified[a]&&A.setRequestHeader("If-Modified-Since",ot.lastModified[a]),ot.etag[a]&&A.setRequestHeader("If-None-Match",ot.etag[a])),(h.data&&h.hasContent&&h.contentType!==!1||e.contentType)&&A.setRequestHeader("Content-Type",h.contentType),A.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+je+"; q=0.01":""):h.accepts["*"]);for(o in h.headers)A.setRequestHeader(o,h.headers[o]);if(h.beforeSend&&(h.beforeSend.call(d,A,h)===!1||2===M))return A.abort();y="abort";for(o in{success:1,error:1,complete:1})A[o](h[o]);if(l=X(He,h,e,A)){A.readyState=1,c&&p.trigger("ajaxSend",[A,h]),h.async&&h.timeout>0&&(r=setTimeout(function(){A.abort("timeout")},h.timeout));try{M=1,l.send(b,n)}catch(_){if(!(M<2))throw _;n(-1,_)}}else n(-1,"No Transport");return A},getJSON:function(t,e,n){return ot.get(t,e,n,"json")},getScript:function(t,e){return ot.get(t,void 0,e,"script")}}),ot.each(["get","post"],function(t,e){ot[e]=function(t,n,i,o){return ot.isFunction(n)&&(o=o||i,i=n,n=void 0),ot.ajax({url:t,type:e,dataType:o,data:n,success:i})}}),ot._evalUrl=function(t){return ot.ajax({url:t,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},ot.fn.extend({wrapAll:function(t){if(ot.isFunction(t))return this.each(function(e){ot(this).wrapAll(t.call(this,e))});if(this[0]){var e=ot(t,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){for(var t=this;t.firstChild&&1===t.firstChild.nodeType;)t=t.firstChild;return t}).append(this)}return this},wrapInner:function(t){return ot.isFunction(t)?this.each(function(e){ot(this).wrapInner(t.call(this,e))}):this.each(function(){var e=ot(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)})},wrap:function(t){var e=ot.isFunction(t);return this.each(function(n){ot(this).wrapAll(e?t.call(this,n):t)})},unwrap:function(){return this.parent().each(function(){ot.nodeName(this,"body")||ot(this).replaceWith(this.childNodes)}).end()}}),ot.expr.filters.hidden=function(t){return t.offsetWidth<=0&&t.offsetHeight<=0||!nt.reliableHiddenOffsets()&&"none"===(t.style&&t.style.display||ot.css(t,"display"))},ot.expr.filters.visible=function(t){return!ot.expr.filters.hidden(t)};var $e=/%20/g,Ve=/\[\]$/,Ye=/\r?\n/g,Je=/^(?:submit|button|image|reset|file)$/i,Ke=/^(?:input|select|textarea|keygen)/i;ot.param=function(t,e){var n,i=[],o=function(t,e){e=ot.isFunction(e)?e():null==e?"":e,i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(e)};if(void 0===e&&(e=ot.ajaxSettings&&ot.ajaxSettings.traditional),ot.isArray(t)||t.jquery&&!ot.isPlainObject(t))ot.each(t,function(){o(this.name,this.value)});else for(n in t)j(n,t[n],e,o);return i.join("&").replace($e,"+")},ot.fn.extend({serialize:function(){return ot.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var t=ot.prop(this,"elements");return t?ot.makeArray(t):this}).filter(function(){var t=this.type;return this.name&&!ot(this).is(":disabled")&&Ke.test(this.nodeName)&&!Je.test(t)&&(this.checked||!xt.test(t))}).map(function(t,e){var n=ot(this).val();return null==n?null:ot.isArray(n)?ot.map(n,function(t){return{name:e.name,value:t.replace(Ye,"\r\n")}}):{name:e.name,value:n.replace(Ye,"\r\n")}}).get()}}),ot.ajaxSettings.xhr=void 0!==t.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&U()||$()}:U;var Ge=0,Qe={},Ze=ot.ajaxSettings.xhr();t.attachEvent&&t.attachEvent("onunload",function(){for(var t in Qe)Qe[t](void 0,!0)}),nt.cors=!!Ze&&"withCredentials"in Ze,Ze=nt.ajax=!!Ze,Ze&&ot.ajaxTransport(function(t){if(!t.crossDomain||nt.cors){var e;return{send:function(n,i){var o,a=t.xhr(),s=++Ge;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(o in n)void 0!==n[o]&&a.setRequestHeader(o,n[o]+"");a.send(t.hasContent&&t.data||null),e=function(n,o){var r,c,l;if(e&&(o||4===a.readyState))if(delete Qe[s],e=void 0,a.onreadystatechange=ot.noop,o)4!==a.readyState&&a.abort();else{l={},r=a.status,"string"==typeof a.responseText&&(l.text=a.responseText);try{c=a.statusText}catch(u){c=""}r||!t.isLocal||t.crossDomain?1223===r&&(r=204):r=l.text?200:404}l&&i(r,c,l,a.getAllResponseHeaders())},t.async?4===a.readyState?setTimeout(e):a.onreadystatechange=Qe[s]=e:e()},abort:function(){e&&e(void 0,!0)}}}}),ot.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(t){return ot.globalEval(t),t}}}),ot.ajaxPrefilter("script",function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET",t.global=!1)}),ot.ajaxTransport("script",function(t){if(t.crossDomain){var e,n=ft.head||ot("head")[0]||ft.documentElement;return{send:function(i,o){e=ft.createElement("script"),e.async=!0,t.scriptCharset&&(e.charset=t.scriptCharset),e.src=t.url,e.onload=e.onreadystatechange=function(t,n){(n||!e.readyState||/loaded|complete/.test(e.readyState))&&(e.onload=e.onreadystatechange=null,e.parentNode&&e.parentNode.removeChild(e),e=null,n||o(200,"success"))},n.insertBefore(e,n.firstChild)},abort:function(){e&&e.onload(void 0,!0)}}}});var tn=[],en=/(=)\?(?=&|$)|\?\?/;ot.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var t=tn.pop()||ot.expando+"_"+xe++;return this[t]=!0,t}}),ot.ajaxPrefilter("json jsonp",function(e,n,i){var o,a,s,r=e.jsonp!==!1&&(en.test(e.url)?"url":"string"==typeof e.data&&!(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&en.test(e.data)&&"data");if(r||"jsonp"===e.dataTypes[0])return o=e.jsonpCallback=ot.isFunction(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,r?e[r]=e[r].replace(en,"$1"+o):e.jsonp!==!1&&(e.url+=(Le.test(e.url)?"&":"?")+e.jsonp+"="+o),e.converters["script json"]=function(){return s||ot.error(o+" was not called"),s[0]},e.dataTypes[0]="json",a=t[o],t[o]=function(){s=arguments},i.always(function(){t[o]=a,e[o]&&(e.jsonpCallback=n.jsonpCallback,tn.push(o)),s&&ot.isFunction(a)&&a(s[0]),s=a=void 0}),"script"}),ot.parseHTML=function(t,e,n){if(!t||"string"!=typeof t)return null;"boolean"==typeof e&&(n=e,e=!1),e=e||ft;var i=ht.exec(t),o=!n&&[];return i?[e.createElement(i[1])]:(i=ot.buildFragment([t],e,o),o&&o.length&&ot(o).remove(),ot.merge([],i.childNodes))};var nn=ot.fn.load;ot.fn.load=function(t,e,n){if("string"!=typeof t&&nn)return nn.apply(this,arguments);var i,o,a,s=this,r=t.indexOf(" ");return r>=0&&(i=ot.trim(t.slice(r,t.length)),t=t.slice(0,r)),ot.isFunction(e)?(n=e,e=void 0):e&&"object"==typeof e&&(a="POST"),s.length>0&&ot.ajax({url:t,type:a,dataType:"html",data:e}).done(function(t){o=arguments,s.html(i?ot("
").append(ot.parseHTML(t)).find(i):t)}).complete(n&&function(t,e){s.each(n,o||[t.responseText,e,t])}),this},ot.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(t,e){ot.fn[e]=function(t){return this.on(e,t)}}),ot.expr.filters.animated=function(t){return ot.grep(ot.timers,function(e){return t===e.elem}).length};var on=t.document.documentElement;ot.offset={setOffset:function(t,e,n){var i,o,a,s,r,c,l,u=ot.css(t,"position"),h=ot(t),d={};"static"===u&&(t.style.position="relative"),r=h.offset(),a=ot.css(t,"top"),c=ot.css(t,"left"),l=("absolute"===u||"fixed"===u)&&ot.inArray("auto",[a,c])>-1,l?(i=h.position(),s=i.top,o=i.left):(s=parseFloat(a)||0,o=parseFloat(c)||0),ot.isFunction(e)&&(e=e.call(t,n,r)),null!=e.top&&(d.top=e.top-r.top+s),null!=e.left&&(d.left=e.left-r.left+o),"using"in e?e.using.call(t,d):h.css(d)}},ot.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ot.offset.setOffset(this,t,e)});var e,n,i={top:0,left:0},o=this[0],a=o&&o.ownerDocument;if(a)return e=a.documentElement,ot.contains(e,o)?(typeof o.getBoundingClientRect!==zt&&(i=o.getBoundingClientRect()),n=V(a),{top:i.top+(n.pageYOffset||e.scrollTop)-(e.clientTop||0),left:i.left+(n.pageXOffset||e.scrollLeft)-(e.clientLeft||0)}):i},position:function(){if(this[0]){var t,e,n={top:0,left:0},i=this[0];return"fixed"===ot.css(i,"position")?e=i.getBoundingClientRect():(t=this.offsetParent(),e=this.offset(),ot.nodeName(t[0],"html")||(n=t.offset()),n.top+=ot.css(t[0],"borderTopWidth",!0),n.left+=ot.css(t[0],"borderLeftWidth",!0)),{top:e.top-n.top-ot.css(i,"marginTop",!0),left:e.left-n.left-ot.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||on;t&&!ot.nodeName(t,"html")&&"static"===ot.css(t,"position");)t=t.offsetParent;return t||on})}}),ot.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,e){var n=/Y/.test(e);ot.fn[t]=function(i){return St(this,function(t,i,o){var a=V(t);return void 0===o?a?e in a?a[e]:a.document.documentElement[i]:t[i]:void(a?a.scrollTo(n?ot(a).scrollLeft():o,n?o:ot(a).scrollTop()):t[i]=o)},t,i,arguments.length,null)}}),ot.each(["top","left"],function(t,e){ot.cssHooks[e]=C(nt.pixelPosition,function(t,n){if(n)return n=ee(t,e),ie.test(n)?ot(t).position()[e]+"px":n})}),ot.each({Height:"height",Width:"width"},function(t,e){ot.each({padding:"inner"+t,content:e,"":"outer"+t},function(n,i){ot.fn[i]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(i===!0||o===!0?"margin":"border");return St(this,function(e,n,i){var o;return ot.isWindow(e)?e.document.documentElement["client"+t]:9===e.nodeType?(o=e.documentElement,Math.max(e.body["scroll"+t],o["scroll"+t],e.body["offset"+t],o["offset"+t],o["client"+t])):void 0===i?ot.css(e,n,s):ot.style(e,n,i,s)},e,a?i:void 0,a,null)}})}),ot.fn.size=function(){return this.length},ot.fn.andSelf=ot.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return ot});var an=t.jQuery,sn=t.$;return ot.noConflict=function(e){return t.$===ot&&(t.$=sn),e&&t.jQuery===ot&&(t.jQuery=an),ot},typeof e===zt&&(t.jQuery=t.$=ot),ot}),function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){function e(e,i){var o,a,s,r=e.nodeName.toLowerCase();return"area"===r?(o=e.parentNode,a=o.name,!(!e.href||!a||"map"!==o.nodeName.toLowerCase())&&(s=t("img[usemap='#"+a+"']")[0],!!s&&n(s))):(/input|select|textarea|button|object/.test(r)?!e.disabled:"a"===r?e.href||i:i)&&n(e)}function n(e){return t.expr.filters.visible(e)&&!t(e).parents().addBack().filter(function(){return"hidden"===t.css(this,"visibility")}).length}function i(t){for(var e,n;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(n=parseInt(t.css("zIndex"),10),!isNaN(n)&&0!==n))return n;t=t.parent()}return 0}function o(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=a(t("
"))}function a(e){var n="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(n,"mouseout",function(){t(this).removeClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!==-1&&t(this).removeClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!==-1&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(n,"mouseover",s)}function s(){t.datepicker._isDisabledDatepicker(b.inline?b.dpDiv.parent()[0]:b.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!==-1&&t(this).addClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!==-1&&t(this).addClass("ui-datepicker-next-hover"))}function r(e,n){t.extend(e,n);for(var i in n)null==n[i]&&(e[i]=n[i]);return e}function c(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.extend(t.ui,{version:"1.11.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),t.fn.extend({scrollParent:function(e){var n=this.css("position"),i="absolute"===n,o=e?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var e=t(this);return(!i||"static"!==e.css("position"))&&o.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==n&&a.length?a:t(this[0].ownerDocument||document)},uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(n){return!!t.data(n,e)}}):function(e,n,i){return!!t.data(e,i[3])},focusable:function(n){return e(n,!isNaN(t.attr(n,"tabindex")))},tabbable:function(n){var i=t.attr(n,"tabindex"),o=isNaN(i);return(o||i>=0)&&e(n,!o)}}),t("").outerWidth(1).jquery||t.each(["Width","Height"],function(e,n){function i(e,n,i,a){return t.each(o,function(){n-=parseFloat(t.css(e,"padding"+this))||0,i&&(n-=parseFloat(t.css(e,"border"+this+"Width"))||0),a&&(n-=parseFloat(t.css(e,"margin"+this))||0)}),n}var o="Width"===n?["Left","Right"]:["Top","Bottom"],a=n.toLowerCase(),s={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+n]=function(e){return void 0===e?s["inner"+n].call(this):this.each(function(){t(this).css(a,i(this,e)+"px")})},t.fn["outer"+n]=function(e,o){return"number"!=typeof e?s["outer"+n].call(this,e):this.each(function(){t(this).css(a,i(this,e,!0,o)+"px")})}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t("").data("a-b","a").removeData("a-b").data("a-b")&&(t.fn.removeData=function(e){return function(n){return arguments.length?e.call(this,t.camelCase(n)):e.call(this)}}(t.fn.removeData)),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),t.fn.extend({focus:function(e){return function(n,i){return"number"==typeof n?this.each(function(){var e=this;setTimeout(function(){t(e).focus(),i&&i.call(e)},n)}):e.apply(this,arguments)}}(t.fn.focus),disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(e){if(void 0!==e)return this.css("zIndex",e);if(this.length)for(var n,i,o=t(this[0]);o.length&&o[0]!==document;){if(n=o.css("position"),("absolute"===n||"relative"===n||"fixed"===n)&&(i=parseInt(o.css("zIndex"),10),!isNaN(i)&&0!==i))return i;o=o.parent()}return 0}}),t.ui.plugin={add:function(e,n,i){var o,a=t.ui[e].prototype;for(o in i)a.plugins[o]=a.plugins[o]||[],a.plugins[o].push([n,i[o]])},call:function(t,e,n,i){var o,a=t.plugins[e];if(a&&(i||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o",options:{disabled:!1,create:null},_createWidget:function(e,n){n=t(n||this.defaultElement||this)[0],this.element=t(n),this.uuid=l++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),n!==this&&(t.data(n,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===n&&this.destroy()}}),this.document=t(n.style?n.ownerDocument:n.document||n),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(e,n){var i,o,a,s=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(s={},i=e.split("."),e=i.shift(),i.length){for(o=s[e]=t.widget.extend({},this.options[e]),a=0;a=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){function e(t,e,n){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?n/100:1)]}function n(e,n){return parseInt(t.css(e,n),10)||0}function i(e){var n=e[0];return 9===n.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(n)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:n.preventDefault?{width:0,height:0,offset:{top:n.pageY,left:n.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var o,a,s=Math.max,r=Math.abs,c=Math.round,l=/left|center|right/,u=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==o)return o;var e,n,i=t("
"),a=i.children()[0];return t("body").append(i),e=a.offsetWidth,i.css("overflow","scroll"),n=a.offsetWidth,e===n&&(n=i[0].clientWidth),i.remove(),o=e-n},getScrollInfo:function(e){var n=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),i=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),o="scroll"===n||"auto"===n&&e.width0?"right":"center",vertical:a<0?"top":i>0?"bottom":"middle"};ms(r(i),r(a))?c.important="horizontal":c.important="vertical",o.using.call(this,t,c)}),u.offset(t.extend(O,{using:l}))})},t.ui.position={fit:{left:function(t,e){var n,i=e.within,o=i.isWindow?i.scrollLeft:i.offset.left,a=i.width,r=t.left-e.collisionPosition.marginLeft,c=o-r,l=r+e.collisionWidth-a-o;e.collisionWidth>a?c>0&&l<=0?(n=t.left+c+e.collisionWidth-a-o,t.left+=c-n):l>0&&c<=0?t.left=o:c>l?t.left=o+a-e.collisionWidth:t.left=o:c>0?t.left+=c:l>0?t.left-=l:t.left=s(t.left-r,t.left)},top:function(t,e){var n,i=e.within,o=i.isWindow?i.scrollTop:i.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,c=o-r,l=r+e.collisionHeight-a-o;e.collisionHeight>a?c>0&&l<=0?(n=t.top+c+e.collisionHeight-a-o,t.top+=c-n):l>0&&c<=0?t.top=o:c>l?t.top=o+a-e.collisionHeight:t.top=o:c>0?t.top+=c:l>0?t.top-=l:t.top=s(t.top-r,t.top)}},flip:{left:function(t,e){var n,i,o=e.within,a=o.offset.left+o.scrollLeft,s=o.width,c=o.isWindow?o.scrollLeft:o.offset.left,l=t.left-e.collisionPosition.marginLeft,u=l-c,h=l+e.collisionWidth-s-c,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];u<0?(n=t.left+d+p+f+e.collisionWidth-s-a,(n<0||n0&&(i=t.left-e.collisionPosition.marginLeft+d+p+f-c,(i>0||r(i)u&&(i<0||i0&&(n=t.top-e.collisionPosition.marginTop+p+f+m-c,t.top+p+f+m>h&&(n>0||r(n)10&&o<11,e.innerHTML="",n.removeChild(e)}()}();t.ui.position,t.widget("ui.accordion",{version:"1.11.2",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),e.active<0&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?void this._activate(e):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void("disabled"===t&&(this.element.toggleClass("ui-state-disabled",!!e).attr("aria-disabled",e),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e))))},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var n=t.ui.keyCode,i=this.headers.length,o=this.headers.index(e.target),a=!1;switch(e.keyCode){case n.RIGHT:case n.DOWN:a=this.headers[(o+1)%i];break;case n.LEFT:case n.UP:a=this.headers[(o-1+i)%i];break;case n.SPACE:case n.ENTER:this._eventHandler(e);break;case n.HOME:a=this.headers[0];break;case n.END:a=this.headers[i-1]}a&&(t(e.target).attr("tabIndex",-1),t(a).attr("tabIndex",0),a.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.panels=this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide(),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,n=this.options,i=n.heightStyle,o=this.element.parent();this.active=this._findActive(n.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var e=t(this),n=e.uniqueId().attr("id"),i=e.next(),o=i.uniqueId().attr("id");e.attr("aria-controls",o),i.attr("aria-labelledby",n)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(n.event),"fill"===i?(e=o.height(),this.element.siblings(":visible").each(function(){var n=t(this),i=n.css("position");"absolute"!==i&&"fixed"!==i&&(e-=n.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===i&&(e=0,this.headers.next().each(function(){e=Math.max(e,t(this).css("height","").height())}).height(e))},_activate:function(e){var n=this._findActive(e)[0];n!==this.active[0]&&(n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var n={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){n[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,n),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var n=this.options,i=this.active,o=t(e.currentTarget),a=o[0]===i[0],s=a&&n.collapsible,r=s?t():o.next(),c=i.next(),l={oldHeader:i,oldPanel:c,newHeader:s?t():o,newPanel:r};e.preventDefault(),a&&!n.collapsible||this._trigger("beforeActivate",e,l)===!1||(n.active=!s&&this.headers.index(o),this.active=a?t():o,this._toggle(l),i.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),a||(o.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&o.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),o.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var n=e.newPanel,i=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=i,this.options.animate?this._animate(n,i,e):(i.hide(),n.show(),this._toggleComplete(e)),i.attr({"aria-hidden":"true"}),i.prev().attr("aria-selected","false"),n.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):n.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),n.attr("aria-hidden","false").prev().attr({"aria-selected":"true",tabIndex:0,"aria-expanded":"true"})},_animate:function(t,e,n){var i,o,a,s=this,r=0,c=t.length&&(!e.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var n=t(e.target);!this.mouseHandled&&n.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),n.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&t(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var n=t(e.currentTarget);n.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(e,n)}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var n=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,n)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){var n,i,o,a,s=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:s=!1,i=this.previousFilter||"",o=String.fromCharCode(e.keyCode),a=!1,clearTimeout(this.filterTimer),o===i?a=!0:o=i+o,n=this._filterMenuItems(o),n=a&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(o=String.fromCharCode(e.keyCode),n=this._filterMenuItems(o)),n.length?(this.focus(e,n),this.previousFilter=o,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}s&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(t):this.select(t))},refresh:function(){var e,n,i=this,o=this.options.icons.submenu,a=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),a.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),n=e.parent(),i=t("").addClass("ui-menu-icon ui-icon "+o).data("ui-menu-submenu-carat",!0);n.attr("aria-haspopup","true").prepend(i),e.attr("aria-labelledby",n.attr("id"))}),e=a.add(this.element),n=e.find(this.options.items),n.not(".ui-menu-item").each(function(){var e=t(this);i._isDivider(e)&&e.addClass("ui-widget-content ui-menu-divider")}),n.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),n.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),"disabled"===t&&this.element.toggleClass("ui-state-disabled",!!e).attr("aria-disabled",e),this._super(t,e)},focus:function(t,e){var n,i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=e.children(".ui-menu"),n.length&&t&&/^mouse/.test(t.type)&&this._startOpening(n),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var n,i,o,a,s,r;this._hasScroll()&&(n=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,i=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,o=e.offset().top-this.activeMenu.offset().top-n-i,a=this.activeMenu.scrollTop(),s=this.activeMenu.height(),r=e.outerHeight(),o<0?this.activeMenu.scrollTop(a+o):o+r>s&&this.activeMenu.scrollTop(a+o-s+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var n=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(e,n){clearTimeout(this.timer),this.timer=this._delay(function(){var i=n?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));i.length||(i=this.element),this._close(i),this.blur(e),this.activeMenu=i},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,n){var i;this.active&&(i="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),i&&i.length&&this.active||(i=this.activeMenu.find(this.options.items)[e]()),this.focus(n,i)},nextPage:function(e){var n,i,o;return this.active?void(this.isLastItem()||(this._hasScroll()?(i=this.active.offset().top,o=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=t(this),n.offset().top-i-o<0}),this.focus(e,n)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]()))):void this.next(e)},previousPage:function(e){var n,i,o;return this.active?void(this.isFirstItem()||(this._hasScroll()?(i=this.active.offset().top,o=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=t(this),n.offset().top-i+o>0}),this.focus(e,n)):this.focus(e,this.activeMenu.find(this.options.items).first()))):void this.next(e)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,n,i,o=this.element[0].nodeName.toLowerCase(),a="textarea"===o,s="input"===o;this.isMultiLine=!!a||!s&&this.element.prop("isContentEditable"),this.valueMethod=this.element[a||s?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(o){if(this.element.prop("readOnly"))return e=!0,i=!0,void(n=!0);e=!1,i=!1,n=!1;var a=t.ui.keyCode;switch(o.keyCode){case a.PAGE_UP:e=!0,this._move("previousPage",o);break;case a.PAGE_DOWN:e=!0,this._move("nextPage",o);break;case a.UP:e=!0,this._keyEvent("previous",o);break;case a.DOWN:e=!0,this._keyEvent("next",o);break;case a.ENTER:this.menu.active&&(e=!0,o.preventDefault(),this.menu.select(o));break;case a.TAB:this.menu.active&&this.menu.select(o);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(o),o.preventDefault());break;default:n=!0,this._searchTimeout(o)}},keypress:function(i){if(e)return e=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||i.preventDefault());if(!n){var o=t.ui.keyCode;switch(i.keyCode){case o.PAGE_UP:this._move("previousPage",i);break;case o.PAGE_DOWN:this._move("nextPage",i);break;case o.UP:this._keyEvent("previous",i);break;case o.DOWN:this._keyEvent("next",i)}}},input:function(t){return i?(i=!1,void t.preventDefault()):void this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?void delete this.cancelBlur:(clearTimeout(this.searching),this.close(t),void this._change(t))}}),this._initSource(),this.menu=t("
");var r=t("a",n),c=r[0],l=r[1],u=r[2],h=r[3];e.oApi._fnBindAction(c,{action:"first"},s),e.oApi._fnBindAction(l,{action:"previous"},s),e.oApi._fnBindAction(u,{action:"next"},s),e.oApi._fnBindAction(h,{action:"last"},s),e.aanFeatures.p||(n.id=e.sTableId+"_paginate",c.id=e.sTableId+"_first",l.id=e.sTableId+"_previous",u.id=e.sTableId+"_next",h.id=e.sTableId+"_last")},fnUpdate:function(e,n){if(e.aanFeatures.p){var i,o,a,s,r,c=e.oInstance.fnPagingInfo(),l=t.fn.dataTableExt.oPagination.iFullNumbersShowPages,u=Math.floor(l/2),h=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),d=Math.ceil(e._iDisplayStart/e._iDisplayLength)+1,p="",f=(e.oClasses,e.aanFeatures.p);for(e._iDisplayLength===-1?(i=1,o=1,d=1):h=h-u?(i=h-l+1,o=h):(i=d-Math.ceil(l/2)+1,o=i+l-1),a=i;a<=o;a++)p+=d!==a?'
  • '+e.fnFormatNumber(a)+"
  • ":'
  • '+e.fnFormatNumber(a)+"
  • ";for(a=0,s=f.length;a",o[0];);return 4h.a.l(e,t[n])&&e.push(t[n]);return e},ya:function(t,e){t=t||[];for(var n=[],i=0,o=t.length;ii?n&&t.push(e):n||t.splice(i,1)},na:l,extend:r,ra:c,sa:l?c:r,A:s,Oa:function(t,e){if(!t)return t;var n,i={};for(n in t)t.hasOwnProperty(n)&&(i[n]=e(t[n],n,t));return i},Fa:function(t){for(;t.firstChild;)h.removeNode(t.firstChild)},ec:function(t){t=h.a.R(t);for(var e=n.createElement("div"),i=0,o=t.length;if?t.setAttribute("selected",e):t.selected=e},ta:function(e){return null===e||e===t?"":e.trim?e.trim():e.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},oc:function(t,e){for(var n=[],i=(t||"").split(e),o=0,a=i.length;ot.length)&&t.substring(0,e.length)===e},Sb:function(t,e){if(t===e)return!0;if(11===t.nodeType)return!1;if(e.contains)return e.contains(3===t.nodeType?t.parentNode:t);if(e.compareDocumentPosition)return 16==(16&e.compareDocumentPosition(t));for(;t&&t!=e;)t=t.parentNode;return!!t},Ea:function(t){return h.a.Sb(t,t.ownerDocument.documentElement)},eb:function(t){return!!h.a.hb(t,h.a.Ea)},B:function(t){return t&&t.tagName&&t.tagName.toLowerCase()},q:function(t,e,n){var i=f&&p[e];if(!i&&o)o(t).bind(e,n);else if(i||"function"!=typeof t.addEventListener){if("undefined"==typeof t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");var a=function(e){n.call(t,e)},s="on"+e;t.attachEvent(s,a),h.a.u.ja(t,function(){t.detachEvent(s,a)})}else t.addEventListener(e,n,!1)},ha:function(t,i){if(!t||!t.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var a;if("input"===h.a.B(t)&&t.type&&"click"==i.toLowerCase()?(a=t.type,a="checkbox"==a||"radio"==a):a=!1,o&&!a)o(t).trigger(i);else if("function"==typeof n.createEvent){if("function"!=typeof t.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");a=n.createEvent(d[i]||"HTMLEvents"),a.initEvent(i,!0,!0,e,0,0,0,0,0,!1,!1,!1,!1,0,t),t.dispatchEvent(a)}else if(a&&t.click)t.click();else{if("undefined"==typeof t.fireEvent)throw Error("Browser doesn't support triggering events");t.fireEvent("on"+i)}},c:function(t){return h.v(t)?t():t},Sa:function(t){return h.v(t)?t.o():t},ua:function(t,e,n){if(e){var i=/\S+/g,o=t.className.match(i)||[];h.a.r(e.match(i),function(t){h.a.Y(o,t,n)}),t.className=o.join(" ")}},Xa:function(e,n){var i=h.a.c(n);null!==i&&i!==t||(i="");var o=h.e.firstChild(e);!o||3!=o.nodeType||h.e.nextSibling(o)?h.e.U(e,[e.ownerDocument.createTextNode(i)]):o.data=i, -h.a.Vb(e)},Cb:function(t,e){if(t.name=e,7>=f)try{t.mergeAttributes(n.createElement(""),!1)}catch(i){}},Vb:function(t){9<=f&&(t=1==t.nodeType?t:t.parentNode,t.style&&(t.style.zoom=t.style.zoom))},Tb:function(t){if(f){var e=t.style.width;t.style.width=0,t.style.width=e}},ic:function(t,e){t=h.a.c(t),e=h.a.c(e);for(var n=[],i=t;i<=e;i++)n.push(i);return n},R:function(t){for(var e=[],n=0,i=t.length;n",""]||!a.indexOf("",""]||(!a.indexOf("",""]||[0,"",""],t="ignored
    "+a[1]+t+a[2]+"
    ","function"==typeof e.innerShiv?i.appendChild(e.innerShiv(t)):i.innerHTML=t;a[0]--;)i=i.lastChild;i=h.a.R(i.lastChild.childNodes)}return i},h.a.Va=function(e,n){if(h.a.Fa(e),n=h.a.c(n),null!==n&&n!==t)if("string"!=typeof n&&(n=n.toString()),o)o(e).html(n);else for(var i=h.a.Qa(n),a=0;a"},Hb:function(e,i){var o=n[e];if(o===t)throw Error("Couldn't find any memo with ID "+e+". Perhaps it's already been unmemoized.");try{return o.apply(null,i||[]),!0}finally{delete n[e]}},Ib:function(t,n){var i=[];e(t,i);for(var o=0,a=i.length;oa[0]?c+a[0]:a[0]),c);for(var c=1===l?c:Math.min(e+(a[1]||0),c),l=e+l-2,u=Math.max(c,l),d=[],p=[],f=2;ee;e++)t=t();return t})},h.toJSON=function(t,e,n){return t=h.Gb(t),h.a.Ya(t,e,n)},i.prototype={save:function(t,e){var n=h.a.l(this.keys,t);0<=n?this.ab[n]=e:(this.keys.push(t),this.ab.push(e))},get:function(e){return e=h.a.l(this.keys,e),0<=e?this.ab[e]:t}}}(),h.b("toJS",h.Gb),h.b("toJSON",h.toJSON),function(){h.i={p:function(e){switch(h.a.B(e)){case"option":return!0===e.__ko__hasDomDataOptionValue__?h.a.f.get(e,h.d.options.Pa):7>=h.a.oa?e.getAttributeNode("value")&&e.getAttributeNode("value").specified?e.value:e.text:e.value;case"select":return 0<=e.selectedIndex?h.i.p(e.options[e.selectedIndex]):t;default:return e.value}},X:function(e,n,i){switch(h.a.B(e)){case"option":switch(typeof n){case"string":h.a.f.set(e,h.d.options.Pa,t),"__ko__hasDomDataOptionValue__"in e&&delete e.__ko__hasDomDataOptionValue__,e.value=n;break;default:h.a.f.set(e,h.d.options.Pa,n),e.__ko__hasDomDataOptionValue__=!0,e.value="number"==typeof n?n:""}break;case"select":""!==n&&null!==n||(n=t);for(var o,a=-1,s=0,r=e.options.length;s=c){e&&s.push(n?{key:e,value:n.join("")}:{unknown:e}),e=n=c=0;continue}}else if(58===d){if(!n)continue}else if(47===d&&u&&1"===n.createComment("test").text,s=a?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,r=a?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,c={ul:!0,ol:!0};h.e={Q:{},childNodes:function(e){return t(e)?i(e):e.childNodes},da:function(e){if(t(e)){e=h.e.childNodes(e);for(var n=0,i=e.length;n=h.a.oa&&n in g?(n=g[n],o?e.removeAttribute(n):e[n]=i):o||e.setAttribute(n,i.toString()),"name"===n&&h.a.Cb(e,o?"":i.toString())})}},function(){h.d.checked={after:["value","attr"],init:function(e,n,i){function o(){return i.has("checkedValue")?h.a.c(i.get("checkedValue")):e.value}function a(){var t=e.checked,a=d?o():t;if(!h.ca.pa()&&(!c||t)){var s=h.k.t(n);l?u!==a?(t&&(h.a.Y(s,a,!0),h.a.Y(s,u,!1)),u=a):h.a.Y(s,a,t):h.g.va(s,i,"checked",a,!0)}}function s(){var t=h.a.c(n());e.checked=l?0<=h.a.l(t,o()):r?t:o()===t}var r="checkbox"==e.type,c="radio"==e.type;if(r||c){var l=r&&h.a.c(n())instanceof Array,u=l?o():t,d=c||l;c&&!e.name&&h.d.uniqueName.init(e,function(){return!0}),h.ba(a,null,{G:e}),h.a.q(e,"click",a),h.ba(s,null,{G:e})}}},h.g.W.checked=!0,h.d.checkedValue={update:function(t,e){t.value=h.a.c(e())}}}(),h.d.css={update:function(t,e){var n=h.a.c(e());"object"==typeof n?h.a.A(n,function(e,n){n=h.a.c(n),h.a.ua(t,e,n)}):(n=String(n||""),h.a.ua(t,t.__ko__cssValue,!1),t.__ko__cssValue=n,h.a.ua(t,n,!0))}},h.d.enable={update:function(t,e){var n=h.a.c(e());n&&t.disabled?t.removeAttribute("disabled"):n||t.disabled||(t.disabled=!0)}},h.d.disable={update:function(t,e){h.d.enable.update(t,function(){return!h.a.c(e())})}},h.d.event={init:function(t,e,n,i,o){var a=e()||{};h.a.A(a,function(a){"string"==typeof a&&h.a.q(t,a,function(t){var s,r=e()[a];if(r){try{var c=h.a.R(arguments);i=o.$data,c.unshift(i),s=r.apply(i,c)}finally{!0!==s&&(t.preventDefault?t.preventDefault():t.returnValue=!1)}!1===n.get(a+"Bubble")&&(t.cancelBubble=!0,t.stopPropagation&&t.stopPropagation())}})})}},h.d.foreach={vb:function(t){return function(){var e=t(),n=h.a.Sa(e);return n&&"number"!=typeof n.length?(h.a.c(e),{foreach:n.data,as:n.as,includeDestroyed:n.includeDestroyed,afterAdd:n.afterAdd,beforeRemove:n.beforeRemove,afterRender:n.afterRender,beforeMove:n.beforeMove,afterMove:n.afterMove,templateEngine:h.K.Ja}):{foreach:e,templateEngine:h.K.Ja}}},init:function(t,e){return h.d.template.init(t,h.d.foreach.vb(e))},update:function(t,e,n,i,o){return h.d.template.update(t,h.d.foreach.vb(e),n,i,o)}},h.g.aa.foreach=!1,h.e.Q.foreach=!0,h.d.hasfocus={init:function(t,e,n){function i(i){t.__ko_hasfocusUpdating=!0;var o=t.ownerDocument;if("activeElement"in o){var a;try{a=o.activeElement}catch(s){a=o.body}i=a===t}o=e(),h.g.va(o,n,"hasfocus",i,!0),t.__ko_hasfocusLastValue=i,t.__ko_hasfocusUpdating=!1}var o=i.bind(null,!0),a=i.bind(null,!1);h.a.q(t,"focus",o),h.a.q(t,"focusin",o),h.a.q(t,"blur",a),h.a.q(t,"focusout",a)},update:function(t,e){var n=!!h.a.c(e());t.__ko_hasfocusUpdating||t.__ko_hasfocusLastValue===n||(n?t.focus():t.blur(),h.k.t(h.a.ha,null,[t,n?"focusin":"focusout"]))}},h.g.W.hasfocus=!0,h.d.hasFocus=h.d.hasfocus,h.g.W.hasFocus=!0,h.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(t,e){h.a.Va(t,e())}},u("if"),u("ifnot",!1,!0),u("with",!0,!1,function(t,e){return t.createChildContext(e)});var b={};h.d.options={init:function(t){if("select"!==h.a.B(t))throw Error("options binding applies only to SELECT elements");for(;0","#comment",o)})},Mb:function(t,e){return h.w.Na(function(n,i){var o=n.nextSibling;o&&o.nodeName.toLowerCase()===e&&h.xa(o,t,i)})}}}(),h.b("__tr_ambtns",h.Za.Mb),function(){h.n={},h.n.j=function(t){this.j=t},h.n.j.prototype.text=function(){var t=h.a.B(this.j),t="script"===t?"text":"textarea"===t?"value":"innerHTML";if(0==arguments.length)return this.j[t];var e=arguments[0];"innerHTML"===t?h.a.Va(this.j,e):this.j[t]=e};var e=h.a.f.L()+"_";h.n.j.prototype.data=function(t){return 1===arguments.length?h.a.f.get(this.j,e+t):void h.a.f.set(this.j,e+t,arguments[1])};var n=h.a.f.L();h.n.Z=function(t){this.j=t},h.n.Z.prototype=new h.n.j,h.n.Z.prototype.text=function(){if(0==arguments.length){var e=h.a.f.get(this.j,n)||{};return e.$a===t&&e.Ba&&(e.$a=e.Ba.innerHTML),e.$a}h.a.f.set(this.j,n,{$a:arguments[0]})},h.n.j.prototype.nodes=function(){return 0==arguments.length?(h.a.f.get(this.j,n)||{}).Ba:void h.a.f.set(this.j,n,{Ba:arguments[0]})},h.b("templateSources",h.n),h.b("templateSources.domElement",h.n.j),h.b("templateSources.anonymousTemplate",h.n.Z)}(),function(){function e(t,e,n){var i;for(e=h.e.nextSibling(e);t&&(i=t)!==e;)t=h.e.nextSibling(i),n(i,t)}function n(t,n){if(t.length){var i=t[0],o=t[t.length-1],a=i.parentNode,s=h.J.instance,r=s.preprocessNode;if(r){if(e(i,o,function(t,e){var n=t.previousSibling,a=r.call(s,t);a&&(t===i&&(i=a[0]||e),t===o&&(o=a[a.length-1]||n))}),t.length=0,!i)return;i===o?t.push(i):(t.push(i,o),h.a.ea(t,a))}e(i,o,function(t){1!==t.nodeType&&8!==t.nodeType||h.fb(n,t)}),e(i,o,function(t){1!==t.nodeType&&8!==t.nodeType||h.w.Ib(t,[n])}),h.a.ea(t,a)}}function i(t){return t.nodeType?t:0h.a.oa?0:t.nodes)?t.nodes():null;return e?h.a.R(e.cloneNode(!0).childNodes):(t=t.text(),h.a.Qa(t))},h.K.Ja=new h.K,h.Wa(h.K.Ja),h.b("nativeTemplateEngine",h.K),function(){h.La=function(){var t=this.ac=function(){if(!o||!o.tmpl)return 0;try{if(0<=o.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(t){}return 1}();this.renderTemplateSource=function(e,i,a){if(a=a||{},2>t)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var s=e.data("precompiled");return s||(s=e.text()||"",s=o.template(null,"{{ko_with $item.koBindingContext}}"+s+"{{/ko_with}}"),e.data("precompiled",s)),e=[i.$data],i=o.extend({koBindingContext:i},a.templateOptions),i=o.tmpl(s,e,i),i.appendTo(n.createElement("div")),o.fragments={},i},this.createJavaScriptEvaluatorBlock=function(t){return"{{ko_code ((function() { return "+t+" })()) }}"},this.addTemplate=function(t,e){n.write("")},0=0&&(u&&(u.splice(m,1),t.processAllDeferredBindingUpdates&&t.processAllDeferredBindingUpdates()),p.splice(g,0,A)),l(v,n,null),t.processAllDeferredBindingUpdates&&t.processAllDeferredBindingUpdates(),T.afterMove&&T.afterMove.call(this,b,s,r)}y&&y.apply(this,arguments)},connectWith:!!T.connectClass&&"."+T.connectClass})),void 0!==T.isEnabled&&t.computed({read:function(){A.sortable(r(T.isEnabled)?"enable":"disable")},disposeWhenNodeIsRemoved:u})},0);return t.utils.domNodeDisposal.addDisposeCallback(u,function(){(A.data("ui-sortable")||A.data("sortable"))&&A.sortable("destroy"),clearTimeout(w)}),{controlsDescendantBindings:!0}},update:function(e,n,i,a,s){var r=p(n,"foreach");l(e,o,r.foreach),t.bindingHandlers.template.update(e,function(){return r},i,a,s)},connectClass:"ko_container",allowDrop:!0,afterMove:null,beforeMove:null,options:{}},t.bindingHandlers.draggable={init:function(n,i,o,a,c){var u=r(i())||{},h=u.options||{},d=t.utils.extend({},t.bindingHandlers.draggable.options),f=p(i,"data"),m=u.connectClass||t.bindingHandlers.draggable.connectClass,g=void 0!==u.isEnabled?u.isEnabled:t.bindingHandlers.draggable.isEnabled;return u="data"in u?u.data:u,l(n,s,u),t.utils.extend(d,h),d.connectToSortable=!!m&&"."+m,e(n).draggable(d),void 0!==g&&t.computed({read:function(){e(n).draggable(r(g)?"enable":"disable")},disposeWhenNodeIsRemoved:n}),t.bindingHandlers.template.init(n,function(){return f},o,a,c)},update:function(e,n,i,o,a){var s=p(n,"data");return t.bindingHandlers.template.update(e,function(){return s},i,o,a)},connectClass:t.bindingHandlers.sortable.connectClass,options:{helper:"clone"}}}),function(){var t=this,e=t._,n=Array.prototype,i=Object.prototype,o=Function.prototype,a=n.push,s=n.slice,r=n.concat,c=i.toString,l=i.hasOwnProperty,u=Array.isArray,h=Object.keys,d=o.bind,p=function(t){return t instanceof p?t:this instanceof p?void(this._wrapped=t):new p(t)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=p),exports._=p):t._=p,p.VERSION="1.7.0";var f=function(t,e,n){if(void 0===e)return t;switch(null==n?3:n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,o){return t.call(e,n,i,o)};case 4:return function(n,i,o,a){return t.call(e,n,i,o,a)}}return function(){return t.apply(e,arguments)}};p.iteratee=function(t,e,n){return null==t?p.identity:p.isFunction(t)?f(t,e,n):p.isObject(t)?p.matches(t):p.property(t)},p.each=p.forEach=function(t,e,n){if(null==t)return t;e=f(e,n);var i,o=t.length;if(o===+o)for(i=0;i=0)},p.invoke=function(t,e){var n=s.call(arguments,2),i=p.isFunction(e);return p.map(t,function(t){return(i?e:t[e]).apply(t,n)})},p.pluck=function(t,e){return p.map(t,p.property(e))},p.where=function(t,e){return p.filter(t,p.matches(e))},p.findWhere=function(t,e){return p.find(t,p.matches(e))},p.max=function(t,e,n){var i,o,a=-(1/0),s=-(1/0);if(null==e&&null!=t){t=t.length===+t.length?t:p.values(t);for(var r=0,c=t.length;ra&&(a=i)}else e=p.iteratee(e,n),p.each(t,function(t,n,i){o=e(t,n,i),(o>s||o===-(1/0)&&a===-(1/0))&&(a=t,s=o)});return a},p.min=function(t,e,n){var i,o,a=1/0,s=1/0;if(null==e&&null!=t){t=t.length===+t.length?t:p.values(t);for(var r=0,c=t.length;ri||void 0===n)return 1;if(n>>1;n(t[r])=0;)if(t[i]===e)return i;return-1},p.range=function(t,e,n){arguments.length<=1&&(e=t||0,t=0),n=n||1;for(var i=Math.max(Math.ceil((e-t)/n),0),o=Array(i),a=0;ae?(clearTimeout(s),s=null,r=l,a=t.apply(i,o),s||(i=o=null)):s||n.trailing===!1||(s=setTimeout(c,u)),a}},p.debounce=function(t,e,n){var i,o,a,s,r,c=function(){var l=p.now()-s;l0?i=setTimeout(c,e-l):(i=null,n||(r=t.apply(a,o),i||(a=o=null)))};return function(){a=this,o=arguments,s=p.now();var l=n&&!i;return i||(i=setTimeout(c,e)),l&&(r=t.apply(a,o),a=o=null),r}},p.wrap=function(t,e){return p.partial(e,t)},p.negate=function(t){return function(){return!t.apply(this,arguments)}},p.compose=function(){var t=arguments,e=t.length-1;return function(){for(var n=e,i=t[e].apply(this,arguments);n--;)i=t[n].call(this,i);return i}},p.after=function(t,e){return function(){if(--t<1)return e.apply(this,arguments)}},p.before=function(t,e){ -var n;return function(){return--t>0?n=e.apply(this,arguments):e=null,n}},p.once=p.partial(p.before,2),p.keys=function(t){if(!p.isObject(t))return[];if(h)return h(t);var e=[];for(var n in t)p.has(t,n)&&e.push(n);return e},p.values=function(t){for(var e=p.keys(t),n=e.length,i=Array(n),o=0;o":">",'"':""","'":"'","`":"`"},A=p.invert(y),_=function(t){var e=function(e){return t[e]},n="(?:"+p.keys(t).join("|")+")",i=RegExp(n),o=RegExp(n,"g");return function(t){return t=null==t?"":""+t,i.test(t)?t.replace(o,e):t}};p.escape=_(y),p.unescape=_(A),p.result=function(t,e){if(null!=t){var n=t[e];return p.isFunction(n)?t[e]():n}};var z=0;p.uniqueId=function(t){var e=++z+"";return t?t+e:e},p.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,w={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},C=/\\|'|\r|\n|\u2028|\u2029/g,O=function(t){return"\\"+w[t]};p.template=function(t,e,n){!e&&n&&(e=n),e=p.defaults({},e,p.templateSettings);var i=RegExp([(e.escape||T).source,(e.interpolate||T).source,(e.evaluate||T).source].join("|")+"|$","g"),o=0,a="__p+='";t.replace(i,function(e,n,i,s,r){return a+=t.slice(o,r).replace(C,O),o=r+e.length,n?a+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":i?a+="'+\n((__t=("+i+"))==null?'':__t)+\n'":s&&(a+="';\n"+s+"\n__p+='"),e}),a+="';\n",e.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{var s=new Function(e.variable||"obj","_",a)}catch(r){throw r.source=a,r}var c=function(t){return s.call(this,t,p)},l=e.variable||"obj";return c.source="function("+l+"){\n"+a+"}",c},p.chain=function(t){var e=p(t);return e._chain=!0,e};var N=function(t){return this._chain?p(t).chain():t};p.mixin=function(t){p.each(p.functions(t),function(e){var n=p[e]=t[e];p.prototype[e]=function(){var t=[this._wrapped];return a.apply(t,arguments),N.call(this,n.apply(p,t))}})},p.mixin(p),p.each(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var e=n[t];p.prototype[t]=function(){var n=this._wrapped;return e.apply(n,arguments),"shift"!==t&&"splice"!==t||0!==n.length||delete n[0],N.call(this,n)}}),p.each(["concat","join","slice"],function(t){var e=n[t];p.prototype[t]=function(){return N.call(this,e.apply(this._wrapped,arguments))}}),p.prototype.value=function(){return this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return p})}.call(this),function(t,e){function n(){return new Date(Date.UTC.apply(Date,arguments))}function i(){var t=new Date;return n(t.getFullYear(),t.getMonth(),t.getDate())}function o(t,e){return t.getUTCFullYear()===e.getUTCFullYear()&&t.getUTCMonth()===e.getUTCMonth()&&t.getUTCDate()===e.getUTCDate()}function a(t){return function(){return this[t].apply(this,arguments)}}function s(e,n){function i(t,e){return e.toLowerCase()}var o,a=t(e).data(),s={},r=new RegExp("^"+n.toLowerCase()+"([A-Z])");n=new RegExp("^"+n.toLowerCase());for(var c in a)n.test(c)&&(o=c.replace(r,i),s[o]=a[c]);return s}function r(e){var n={};if(m[e]||(e=e.split("-")[0],m[e])){var i=m[e];return t.each(f,function(t,e){e in i&&(n[e]=i[e])}),n}}var c=function(){var e={get:function(t){return this.slice(t)[0]},contains:function(t){for(var e=t&&t.valueOf(),n=0,i=this.length;no?(this.picker.addClass("datepicker-orient-right"),p=u.left+d-e):this.picker.addClass("datepicker-orient-left");var m,g,b=this.o.orientation.y;if("auto"===b&&(m=-s+f-n,g=s+a-(f+h+n),b=Math.max(m,g)===g?"top":"bottom"),this.picker.addClass("datepicker-orient-"+b),"top"===b?f+=h:f-=n+parseInt(this.picker.css("padding-top")),this.o.rtl){var v=o-(p+d);this.picker.css({top:f,right:v,zIndex:l})}else this.picker.css({top:f,left:p,zIndex:l});return this},_allow_update:!0,update:function(){if(!this._allow_update)return this;var e=this.dates.copy(),n=[],i=!1;return arguments.length?(t.each(arguments,t.proxy(function(t,e){e instanceof Date&&(e=this._local_to_utc(e)),n.push(e)},this)),i=!0):(n=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val(),n=n&&this.o.multidate?n.split(this.o.multidateSeparator):[n],delete this.element.data().date),n=t.map(n,t.proxy(function(t){return g.parseDate(t,this.o.format,this.o.language)},this)),n=t.grep(n,t.proxy(function(t){return tthis.o.endDate||!t},this),!0),this.dates.replace(n),this.dates.length?this.viewDate=new Date(this.dates.get(-1)):this.viewDatethis.o.endDate&&(this.viewDate=new Date(this.o.endDate)),i?this.setValue():n.length&&String(e)!==String(this.dates)&&this._trigger("changeDate"),!this.dates.length&&e.length&&this._trigger("clearDate"),this.fill(),this},fillDow:function(){var t=this.o.weekStart,e="";if(this.o.calendarWeeks){this.picker.find(".datepicker-days thead tr:first-child .datepicker-switch").attr("colspan",function(t,e){return parseInt(e)+1});var n=' ';e+=n}for(;t'+m[this.o.language].daysMin[t++%7]+"";e+="",this.picker.find(".datepicker-days thead").append(e)},fillMonths:function(){for(var t="",e=0;e<12;)t+=''+m[this.o.language].monthsShort[e++]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=t.map(e,function(t){return t.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var n=[],i=this.viewDate.getUTCFullYear(),a=this.viewDate.getUTCMonth(),s=new Date;return e.getUTCFullYear()i||e.getUTCFullYear()===i&&e.getUTCMonth()>a)&&n.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&n.push("focused"),this.o.todayHighlight&&e.getUTCFullYear()===s.getFullYear()&&e.getUTCMonth()===s.getMonth()&&e.getUTCDate()===s.getDate()&&n.push("today"),this.dates.contains(e)!==-1&&n.push("active"),(e.valueOf()this.o.endDate||t.inArray(e.getUTCDay(),this.o.daysOfWeekDisabled)!==-1)&&n.push("disabled"),this.o.datesDisabled.length>0&&t.grep(this.o.datesDisabled,function(t){return o(e,t)}).length>0&&n.push("disabled","disabled-date"),this.range&&(e>this.range[0]&&e"),this.o.calendarWeeks)){var y=new Date(+p+(this.o.weekStart-p.getUTCDay()-7)%7*864e5),A=new Date(Number(y)+(11-y.getUTCDay())%7*864e5),_=new Date(Number(_=n(A.getUTCFullYear(),0,1))+(11-_.getUTCDay())%7*864e5),z=(A-_)/864e5/7+1;M.push(''+z+"")}if(v=this.getClassNames(p),v.push("day"),this.o.beforeShowDay!==t.noop){var T=this.o.beforeShowDay(this._utc_to_local(p));T===e?T={}:"boolean"==typeof T?T={enabled:T}:"string"==typeof T&&(T={classes:T}),T.enabled===!1&&v.push("disabled"),T.classes&&(v=v.concat(T.classes.split(/\s+/))),T.tooltip&&(i=T.tooltip)}v=t.unique(v),M.push('"+p.getUTCDate()+""),i=null,p.getUTCDay()===this.o.weekEnd&&M.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(M.join(""));var w=this.picker.find(".datepicker-months").find("th:eq(1)").text(a).end().find("span").removeClass("active");if(t.each(this.dates,function(t,e){e.getUTCFullYear()===a&&w.eq(e.getUTCMonth()).addClass("active")}),(al)&&w.addClass("disabled"),a===r&&w.slice(0,c).addClass("disabled"),a===l&&w.slice(u+1).addClass("disabled"),this.o.beforeShowMonth!==t.noop){var C=this;t.each(w,function(e,n){if(!t(n).hasClass("disabled")){var i=new Date(a,e,1),o=C.o.beforeShowMonth(i);o===!1&&t(n).addClass("disabled")}})}M="",a=10*parseInt(a/10,10);var O=this.picker.find(".datepicker-years").find("th:eq(1)").text(a+"-"+(a+9)).end().find("td");a-=1;for(var N,S=t.map(this.dates,function(t){return t.getUTCFullYear()}),x=-1;x<11;x++)N=["year"],x===-1?N.push("old"):10===x&&N.push("new"),t.inArray(a,S)!==-1&&N.push("active"),(al)&&N.push("disabled"),M+=''+a+"",a+=1;O.html(M)}},updateNavArrows:function(){if(this._allow_update){var t=new Date(this.viewDate),e=t.getUTCFullYear(),n=t.getUTCMonth();switch(this.viewMode){case 0:this.o.startDate!==-(1/0)&&e<=this.o.startDate.getUTCFullYear()&&n<=this.o.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.o.endDate!==1/0&&e>=this.o.endDate.getUTCFullYear()&&n>=this.o.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.o.startDate!==-(1/0)&&e<=this.o.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.o.endDate!==1/0&&e>=this.o.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}}},click:function(e){e.preventDefault();var i,o,a,s=t(e.target).closest("span, td, th");if(1===s.length)switch(s[0].nodeName.toLowerCase()){case"th":switch(s[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var r=g.modes[this.viewMode].navStep*("prev"===s[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,r),this._trigger("changeMonth",this.viewDate);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,r),1===this.viewMode&&this._trigger("changeYear",this.viewDate)}this.fill();break;case"today":var c=new Date;c=n(c.getFullYear(),c.getMonth(),c.getDate(),0,0,0),this.showMode(-2);var l="linked"===this.o.todayBtn?null:"view";this._setDate(c,l);break;case"clear":this.clearDates()}break;case"span":s.hasClass("disabled")||(this.viewDate.setUTCDate(1),s.hasClass("month")?(a=1,o=s.parent().find("span").index(s),i=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(o),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode&&this._setDate(n(i,o,a))):(a=1,o=0,i=parseInt(s.text(),10)||0,this.viewDate.setUTCFullYear(i),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(n(i,o,a))),this.showMode(-1),this.fill());break;case"td":s.hasClass("day")&&!s.hasClass("disabled")&&(a=parseInt(s.text(),10)||1,i=this.viewDate.getUTCFullYear(),o=this.viewDate.getUTCMonth(),s.hasClass("old")?0===o?(o=11,i-=1):o-=1:s.hasClass("new")&&(11===o?(o=0,i+=1):o+=1),this._setDate(n(i,o,a)))}this.picker.is(":visible")&&this._focused_from&&t(this._focused_from).focus(),delete this._focused_from},_toggle_multidate:function(t){var e=this.dates.contains(t);if(t||this.dates.clear(),e!==-1?(this.o.multidate===!0||this.o.multidate>1||this.o.toggleActive)&&this.dates.remove(e):this.o.multidate===!1?(this.dates.clear(),this.dates.push(t)):this.dates.push(t),"number"==typeof this.o.multidate)for(;this.dates.length>this.o.multidate;)this.dates.remove(0)},_setDate:function(t,e){e&&"date"!==e||this._toggle_multidate(t&&new Date(t)),e&&"view"!==e||(this.viewDate=t&&new Date(t)),this.fill(),this.setValue(),e&&"view"===e||this._trigger("changeDate");var n;this.isInput?n=this.element:this.component&&(n=this.element.find("input")),n&&n.change(),!this.o.autoclose||e&&"date"!==e||this.hide()},moveMonth:function(t,n){if(!t)return e;if(!n)return t;var i,o,a=new Date(t.valueOf()),s=a.getUTCDate(),r=a.getUTCMonth(),c=Math.abs(n);if(n=n>0?1:-1,1===c)o=n===-1?function(){return a.getUTCMonth()===r}:function(){return a.getUTCMonth()!==i},i=r+n,a.setUTCMonth(i),(i<0||i>11)&&(i=(i+12)%12);else{for(var l=0;l=this.o.startDate&&t<=this.o.endDate},keydown:function(t){if(!this.picker.is(":visible"))return void(27===t.keyCode&&this.show());var e,n,o,a=!1,s=this.focusDate||this.viewDate;switch(t.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),t.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;e=37===t.keyCode?-1:1,t.ctrlKey?(n=this.moveYear(this.dates.get(-1)||i(),e),o=this.moveYear(s,e),this._trigger("changeYear",this.viewDate)):t.shiftKey?(n=this.moveMonth(this.dates.get(-1)||i(),e),o=this.moveMonth(s,e),this._trigger("changeMonth",this.viewDate)):(n=new Date(this.dates.get(-1)||i()),n.setUTCDate(n.getUTCDate()+e),o=new Date(s),o.setUTCDate(s.getUTCDate()+e)),this.dateWithinRange(o)&&(this.focusDate=this.viewDate=o,this.setValue(),this.fill(),t.preventDefault());break;case 38:case 40:if(!this.o.keyboardNavigation)break;e=38===t.keyCode?-1:1,t.ctrlKey?(n=this.moveYear(this.dates.get(-1)||i(),e),o=this.moveYear(s,e),this._trigger("changeYear",this.viewDate)):t.shiftKey?(n=this.moveMonth(this.dates.get(-1)||i(),e),o=this.moveMonth(s,e),this._trigger("changeMonth",this.viewDate)):(n=new Date(this.dates.get(-1)||i()),n.setUTCDate(n.getUTCDate()+7*e),o=new Date(s),o.setUTCDate(s.getUTCDate()+7*e)),this.dateWithinRange(o)&&(this.focusDate=this.viewDate=o,this.setValue(),this.fill(),t.preventDefault());break;case 32:break;case 13:s=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(s),a=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(t.preventDefault(),"function"==typeof t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}if(a){this.dates.length?this._trigger("changeDate"):this._trigger("clearDate");var r;this.isInput?r=this.element:this.component&&(r=this.element.find("input")),r&&r.change()}},showMode:function(t){t&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+t))),this.picker.children("div").hide().filter(".datepicker-"+g.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var u=function(e,n){this.element=t(e),this.inputs=t.map(n.inputs,function(t){return t.jquery?t[0]:t}),delete n.inputs,d.call(t(this.inputs),n).bind("changeDate",t.proxy(this.dateUpdated,this)),this.pickers=t.map(this.inputs,function(e){return t(e).data("datepicker")}),this.updateDates()};u.prototype={updateDates:function(){this.dates=t.map(this.pickers,function(t){return t.getUTCDate()}),this.updateRanges()},updateRanges:function(){var e=t.map(this.dates,function(t){return t.valueOf()});t.each(this.pickers,function(t,n){n.setRange(e)})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=t(e.target).data("datepicker"),i=n.getUTCDate(),o=t.inArray(e.target,this.inputs),a=o-1,s=o+1,r=this.inputs.length;if(o!==-1){if(t.each(this.pickers,function(t,e){e.getUTCDate()||e.setUTCDate(i)}),i=0&&ithis.dates[s])for(;sthis.dates[s];)this.pickers[s++].setUTCDate(i);this.updateDates(),delete this.updating}}},remove:function(){t.map(this.pickers,function(t){t.remove()}),delete this.element.data().datepicker}};var h=t.fn.datepicker,d=function(n){var i=Array.apply(null,arguments);i.shift();var o;return this.each(function(){var a=t(this),c=a.data("datepicker"),h="object"==typeof n&&n;if(!c){var d=s(this,"date"),f=t.extend({},p,d,h),m=r(f.language),g=t.extend({},p,m,d,h);if(a.hasClass("input-daterange")||g.inputs){var b={inputs:g.inputs||a.find("input").toArray()};a.data("datepicker",c=new u(this,t.extend(g,b)))}else a.data("datepicker",c=new l(this,g))}if("string"==typeof n&&"function"==typeof c[n]&&(o=c[n].apply(c,i),o!==e))return!1}),o!==e?o:this};t.fn.datepicker=d;var p=t.fn.datepicker.defaults={autoclose:!1,beforeShowDay:t.noop,beforeShowMonth:t.noop,calendarWeeks:!1,clearBtn:!1,toggleActive:!1,daysOfWeekDisabled:[],datesDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,multidate:!1,multidateSeparator:",",orientation:"auto",rtl:!1,startDate:-(1/0),startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0,disableTouchKeyboard:!1,enableOnReadonly:!0,container:"body"},f=t.fn.datepicker.locale_opts=["format","rtl","weekStart"];t.fn.datepicker.Constructor=l;var m=t.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},g={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(t){return t%4===0&&t%100!==0||t%400===0},getDaysInMonth:function(t,e){return[31,g.isLeapYear(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(t){var e=t.replace(this.validParts,"\0").split("\0"),n=t.match(this.validParts);if(!e||!e.length||!n||0===n.length)throw new Error("Invalid date format."); -return{separators:e,parts:n}},parseDate:function(i,o,a){function s(){var t=this.slice(0,d[u].length),e=d[u].slice(0,t.length);return t.toLowerCase()===e.toLowerCase()}if(!i)return e;if(i instanceof Date)return i;"string"==typeof o&&(o=g.parseFormat(o));var r,c,u,h=/([\-+]\d+)([dmwy])/,d=i.match(/([\-+]\d+)([dmwy])/g);if(/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(i)){for(i=new Date,u=0;u«»',contTemplate:'',footTemplate:''};g.template='
    '+g.headTemplate+""+g.footTemplate+'
    '+g.headTemplate+g.contTemplate+g.footTemplate+'
    '+g.headTemplate+g.contTemplate+g.footTemplate+"
    ",t.fn.datepicker.DPGlobal=g,t.fn.datepicker.noConflict=function(){return t.fn.datepicker=h,this},t.fn.datepicker.version="1.4.0",t(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var n=t(this);n.data("datepicker")||(e.preventDefault(),d.call(n,"show"))}),t(function(){d.call(t('[data-provide="datepicker-inline"]'))})}(window.jQuery),!function(t){t.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag","Sonntag"],daysShort:["Son","Mon","Die","Mit","Don","Fre","Sam","Son"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa","So"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.da={days:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag","Søndag"],daysShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør","Søn"],daysMin:["Sø","Ma","Ti","On","To","Fr","Lø","Sø"],months:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],monthsShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],today:"I Dag",clear:"Nulstil"}}(jQuery),!function(t){t.fn.datepicker.dates["pt-BR"]={days:["Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado","Domingo"],daysShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb","Dom"],daysMin:["Do","Se","Te","Qu","Qu","Se","Sa","Do"],months:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthsShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],today:"Hoje",clear:"Limpar"}}(jQuery),!function(t){t.fn.datepicker.dates.nl={days:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag","zondag"],daysShort:["zo","ma","di","wo","do","vr","za","zo"],daysMin:["zo","ma","di","wo","do","vr","za","zo"],months:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthsShort:["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec"],today:"Vandaag",clear:"Wissen",weekStart:1,format:"dd-mm-yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam.","dim."],daysMin:["d","l","ma","me","j","v","s","d"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.it={days:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato","Domenica"],daysShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab","Dom"],daysMin:["Do","Lu","Ma","Me","Gi","Ve","Sa","Do"],months:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthsShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],today:"Oggi",clear:"Cancella",weekStart:1,format:"dd/mm/yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.lt={days:["Sekmadienis","Pirmadienis","Antradienis","Trečiadienis","Ketvirtadienis","Penktadienis","Šeštadienis","Sekmadienis"],daysShort:["S","Pr","A","T","K","Pn","Š","S"],daysMin:["Sk","Pr","An","Tr","Ke","Pn","Št","Sk"],months:["Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis","Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis"],monthsShort:["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rugp","Rugs","Spa","Lap","Gru"],today:"Šiandien",weekStart:1}}(jQuery),!function(t){t.fn.datepicker.dates.no={days:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],daysShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],daysMin:["Sø","Ma","Ti","On","To","Fr","Lø"],months:["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Des"],today:"I dag",clear:"Nullstill",weekStart:1,format:"dd.mm.yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.es={days:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"],daysShort:["Dom","Lun","Mar","Mié","Jue","Vie","Sáb","Dom"],daysMin:["Do","Lu","Ma","Mi","Ju","Vi","Sa","Do"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthsShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],today:"Hoy",clear:"Borrar",weekStart:1,format:"dd/mm/yyyy"}}(jQuery),!function(t){t.fn.datepicker.dates.sv={days:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag","Söndag"],daysShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör","Sön"],daysMin:["Sö","Må","Ti","On","To","Fr","Lö","Sö"],months:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],monthsShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"}}(jQuery),function(){var t,e,n,i,o,a,s,r,c=[].slice,l={}.hasOwnProperty,u=function(t,e){function n(){this.constructor=t}for(var i in e)l.call(e,i)&&(t[i]=e[i]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t};s=function(){},e=function(){function t(){}return t.prototype.addEventListener=t.prototype.on,t.prototype.on=function(t,e){return this._callbacks=this._callbacks||{},this._callbacks[t]||(this._callbacks[t]=[]),this._callbacks[t].push(e),this},t.prototype.emit=function(){var t,e,n,i,o,a;if(i=arguments[0],t=2<=arguments.length?c.call(arguments,1):[],this._callbacks=this._callbacks||{},n=this._callbacks[i])for(o=0,a=n.length;o
    '),this.element.appendChild(e)),i=e.getElementsByTagName("span")[0],i&&(null!=i.textContent?i.textContent=this.options.dictFallbackMessage:null!=i.innerText&&(i.innerText=this.options.dictFallbackMessage)),this.element.appendChild(this.getFallbackForm())},resize:function(t){var e,n,i;return e={srcX:0,srcY:0,srcWidth:t.width,srcHeight:t.height},n=t.width/t.height,e.optWidth=this.options.thumbnailWidth,e.optHeight=this.options.thumbnailHeight,null==e.optWidth&&null==e.optHeight?(e.optWidth=e.srcWidth,e.optHeight=e.srcHeight):null==e.optWidth?e.optWidth=n*e.optHeight:null==e.optHeight&&(e.optHeight=1/n*e.optWidth),i=e.optWidth/e.optHeight,t.heighti?(e.srcHeight=t.height,e.srcWidth=e.srcHeight*i):(e.srcWidth=t.width,e.srcHeight=e.srcWidth/i),e.srcX=(t.width-e.srcWidth)/2,e.srcY=(t.height-e.srcHeight)/2,e},drop:function(t){return this.element.classList.remove("dz-drag-hover")},dragstart:s,dragend:function(t){return this.element.classList.remove("dz-drag-hover")},dragenter:function(t){return this.element.classList.add("dz-drag-hover")},dragover:function(t){return this.element.classList.add("dz-drag-hover")},dragleave:function(t){return this.element.classList.remove("dz-drag-hover")},paste:s,reset:function(){return this.element.classList.remove("dz-started")},addedfile:function(t){var e,i,o,a,s,r,c,l,u,h,d,p,f;if(this.element===this.previewsContainer&&this.element.classList.add("dz-started"),this.previewsContainer){for(t.previewElement=n.createElement(this.options.previewTemplate.trim()),t.previewTemplate=t.previewElement,this.previewsContainer.appendChild(t.previewElement),h=t.previewElement.querySelectorAll("[data-dz-name]"),a=0,c=h.length;a'+this.options.dictRemoveFile+""),t.previewElement.appendChild(t._removeLink)),i=function(e){return function(i){return i.preventDefault(),i.stopPropagation(),t.status===n.UPLOADING?n.confirm(e.options.dictCancelUploadConfirmation,function(){return e.removeFile(t)}):e.options.dictRemoveFileConfirmation?n.confirm(e.options.dictRemoveFileConfirmation,function(){return e.removeFile(t)}):e.removeFile(t)}}(this),p=t.previewElement.querySelectorAll("[data-dz-remove]"),f=[],r=0,u=p.length;r\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n Check\n \n \n \n \n \n
    \n
    \n \n Error\n \n \n \n \n \n \n \n
    \n'},i=function(){var t,e,n,i,o,a,s;for(i=arguments[0],n=2<=arguments.length?c.call(arguments,1):[],a=0,s=n.length;a'+this.options.dictDefaultMessage+"")),this.clickableElements.length&&(i=function(t){return function(){return t.hiddenFileInput&&t.hiddenFileInput.parentNode.removeChild(t.hiddenFileInput),t.hiddenFileInput=document.createElement("input"),t.hiddenFileInput.setAttribute("type","file"),(null==t.options.maxFiles||t.options.maxFiles>1)&&t.hiddenFileInput.setAttribute("multiple","multiple"),t.hiddenFileInput.className="dz-hidden-input",null!=t.options.acceptedFiles&&t.hiddenFileInput.setAttribute("accept",t.options.acceptedFiles),null!=t.options.capture&&t.hiddenFileInput.setAttribute("capture",t.options.capture),t.hiddenFileInput.style.visibility="hidden",t.hiddenFileInput.style.position="absolute",t.hiddenFileInput.style.top="0",t.hiddenFileInput.style.left="0",t.hiddenFileInput.style.height="0",t.hiddenFileInput.style.width="0",document.querySelector(t.options.hiddenInputContainer).appendChild(t.hiddenFileInput),t.hiddenFileInput.addEventListener("change",function(){var e,n,o,a;if(n=t.hiddenFileInput.files,n.length)for(o=0,a=n.length;o',this.options.dictFallbackText&&(i+="

    "+this.options.dictFallbackText+"

    "),i+='',e=n.createElement(i),"FORM"!==this.element.tagName?(o=n.createElement('
    '),o.appendChild(e)):(this.element.setAttribute("enctype","multipart/form-data"),this.element.setAttribute("method",this.options.method)),null!=o?o:e)},n.prototype.getExistingFallback=function(){var t,e,n,i,o,a;for(e=function(t){var e,n,i;for(n=0,i=t.length;n0){for(s=["TB","GB","MB","KB","b"],n=r=0,c=s.length;r=e){i=t/Math.pow(this.options.filesizeBase,4-n),o=a;break}i=Math.round(10*i)/10}return""+i+" "+o},n.prototype._updateMaxFilesReachedClass=function(){return null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(this.getAcceptedFiles().length===this.options.maxFiles&&this.emit("maxfilesreached",this.files),this.element.classList.add("dz-max-files-reached")):this.element.classList.remove("dz-max-files-reached")},n.prototype.drop=function(t){var e,n;t.dataTransfer&&(this.emit("drop",t),e=t.dataTransfer.files,this.emit("addedfiles",e),e.length&&(n=t.dataTransfer.items,n&&n.length&&null!=n[0].webkitGetAsEntry?this._addFilesFromItems(n):this.handleFiles(e)))},n.prototype.paste=function(t){var e,n;if(null!=(null!=t&&null!=(n=t.clipboardData)?n.items:void 0))return this.emit("paste",t),e=t.clipboardData.items,e.length?this._addFilesFromItems(e):void 0},n.prototype.handleFiles=function(t){var e,n,i,o;for(o=[],n=0,i=t.length;n0){for(a=0,s=n.length;a1024*this.options.maxFilesize*1024?e(this.options.dictFileTooBig.replace("{{filesize}}",Math.round(t.size/1024/10.24)/100).replace("{{maxFilesize}}",this.options.maxFilesize)):n.isValidFile(t,this.options.acceptedFiles)?null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(e(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}",this.options.maxFiles)),this.emit("maxfilesexceeded",t)):this.options.accept.call(this,t,e):e(this.options.dictInvalidFileType)},n.prototype.addFile=function(t){return t.upload={progress:0,total:t.size,bytesSent:0},this.files.push(t),t.status=n.ADDED,this.emit("addedfile",t),this._enqueueThumbnail(t),this.accept(t,function(e){return function(n){return n?(t.accepted=!1,e._errorProcessing([t],n)):(t.accepted=!0,e.options.autoQueue&&e.enqueueFile(t)),e._updateMaxFilesReachedClass()}}(this))},n.prototype.enqueueFiles=function(t){var e,n,i;for(n=0,i=t.length;n=e)&&(i=this.getQueuedFiles(),i.length>0)){if(this.options.uploadMultiple)return this.processFiles(i.slice(0,e-n));for(;t=B;u=0<=B?++L:--L)a.append(this._getParamName(u),t[u],this._renameFilename(t[u].name));return this.submitRequest(_,a,t)},n.prototype.submitRequest=function(t,e,n){return t.send(e)},n.prototype._finished=function(t,e,i){var o,a,s;for(a=0,s=t.length;au;)e=o[4*(c-1)+3],0===e?a=c:u=c,c=a+u>>1;return l=c/s,0===l?1:l},a=function(t,e,n,i,a,s,r,c,l,u){var h;return h=o(e),t.drawImage(e,n,i,a,s,r,c,l,u/h)},i=function(t,e){var n,i,o,a,s,r,c,l,u;if(o=!1,u=!0,i=t.document,l=i.documentElement,n=i.addEventListener?"addEventListener":"attachEvent",c=i.addEventListener?"removeEventListener":"detachEvent",r=i.addEventListener?"":"on",a=function(n){if("readystatechange"!==n.type||"complete"===i.readyState)return("load"===n.type?t:i)[c](r+n.type,a,!1),!o&&(o=!0)?e.call(t,n.type||n):void 0},s=function(){var t;try{l.doScroll("left")}catch(e){return t=e,void setTimeout(s,50)}return a("poll")},"complete"!==i.readyState){if(i.createEventObject&&l.doScroll){try{u=!t.frameElement}catch(h){}u&&s()}return i[n](r+"DOMContentLoaded",a,!1),i[n](r+"readystatechange",a,!1),t[n](r+"load",a,!1)}},t._autoDiscoverFunction=function(){if(t.autoDiscover)return t.discover()},i(window,t._autoDiscoverFunction)}.call(this),function(t,e){"function"==typeof define&&define.amd?define("typeahead.js",["jquery"],function(t){return e(t)}):"object"==typeof exports?module.exports=e(require("jquery")):e(jQuery)}(this,function(t){var e=function(){"use strict";return{isMsie:function(){return!!/(msie|trident)/i.test(navigator.userAgent)&&navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]},isBlankString:function(t){return!t||/^\s*$/.test(t)},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(t){return"string"==typeof t},isNumber:function(t){return"number"==typeof t},isArray:t.isArray,isFunction:t.isFunction,isObject:t.isPlainObject,isUndefined:function(t){return"undefined"==typeof t},isElement:function(t){return!(!t||1!==t.nodeType)},isJQuery:function(e){return e instanceof t},toStr:function(t){return e.isUndefined(t)||null===t?"":t+""},bind:t.proxy,each:function(e,n){function i(t,e){return n(e,t)}t.each(e,i)},map:t.map,filter:t.grep,every:function(e,n){var i=!0;return e?(t.each(e,function(t,o){if(!(i=n.call(null,o,t,e)))return!1}),!!i):i},some:function(e,n){var i=!1;return e?(t.each(e,function(t,o){if(i=n.call(null,o,t,e))return!1}),!!i):i},mixin:t.extend,identity:function(t){return t},clone:function(e){return t.extend(!0,{},e)},getIdGenerator:function(){var t=0;return function(){return t++}},templatify:function(e){function n(){return String(e)}return t.isFunction(e)?e:n},defer:function(t){setTimeout(t,0)},debounce:function(t,e,n){var i,o;return function(){var a,s,r=this,c=arguments;return a=function(){i=null,n||(o=t.apply(r,c))},s=n&&!i,clearTimeout(i),i=setTimeout(a,e),s&&(o=t.apply(r,c)),o}},throttle:function(t,e){var n,i,o,a,s,r;return s=0,r=function(){s=new Date,o=null,a=t.apply(n,i)},function(){var c=new Date,l=e-(c-s);return n=this,i=arguments,l<=0?(clearTimeout(o),o=null,s=c,a=t.apply(n,i)):o||(o=setTimeout(r,l)),a}},stringify:function(t){return e.isString(t)?t:JSON.stringify(t)},noop:function(){}}}(),n=function(){"use strict";function t(t){var s,r;return r=e.mixin({},a,t),s={css:o(),classes:r,html:n(r),selectors:i(r)},{css:s.css,html:s.html,classes:s.classes,selectors:s.selectors,mixin:function(t){e.mixin(t,s)}}}function n(t){return{wrapper:'',menu:'
    '}}function i(t){var n={};return e.each(t,function(t,e){n[e]="."+t}),n}function o(){var t={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},menu:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return e.isMsie()&&e.mixin(t.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),t}var a={wrapper:"twitter-typeahead",input:"tt-input",hint:"tt-hint",menu:"tt-menu",dataset:"tt-dataset",suggestion:"tt-suggestion",selectable:"tt-selectable",empty:"tt-empty",open:"tt-open",cursor:"tt-cursor",highlight:"tt-highlight"};return t}(),i=function(){"use strict";function n(e){e&&e.el||t.error("EventBus initialized without el"),this.$el=t(e.el)}var i,o;return i="typeahead:",o={render:"rendered",cursorchange:"cursorchanged",select:"selected",autocomplete:"autocompleted"},e.mixin(n.prototype,{_trigger:function(e,n){var o;return o=t.Event(i+e),(n=n||[]).unshift(o),this.$el.trigger.apply(this.$el,n),o},before:function(t){var e,n;return e=[].slice.call(arguments,1),n=this._trigger("before"+t,e),n.isDefaultPrevented()},trigger:function(t){var e;this._trigger(t,[].slice.call(arguments,1)),(e=o[t])&&this._trigger(e,[].slice.call(arguments,1))}}),n}(),o=function(){"use strict";function t(t,e,n,i){var o;if(!n)return this;for(e=e.split(c),n=i?r(n,i):n,this._callbacks=this._callbacks||{};o=e.shift();)this._callbacks[o]=this._callbacks[o]||{sync:[],async:[]},this._callbacks[o][t].push(n);return this}function e(e,n,i){return t.call(this,"async",e,n,i)}function n(e,n,i){return t.call(this,"sync",e,n,i)}function i(t){var e;if(!this._callbacks)return this;for(t=t.split(c);e=t.shift();)delete this._callbacks[e];return this}function o(t){var e,n,i,o,s;if(!this._callbacks)return this;for(t=t.split(c),i=[].slice.call(arguments,1);(e=t.shift())&&(n=this._callbacks[e]);)o=a(n.sync,this,[e].concat(i)),s=a(n.async,this,[e].concat(i)),o()&&l(s);return this}function a(t,e,n){function i(){for(var i,o=0,a=t.length;!i&&o