Compare commits

..

No commits in common. "main" and "2.1.4" have entirely different histories.
main ... 2.1.4

197 changed files with 54036 additions and 118637 deletions

49
.env.example Normal file
View file

@ -0,0 +1,49 @@
APP_NAME=MyIdlers
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_idlers
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

3
.gitattributes vendored
View file

@ -3,6 +3,3 @@
*.scss linguist-vendored *.scss linguist-vendored
*.js linguist-vendored *.js linguist-vendored
CHANGELOG.md export-ignore CHANGELOG.md export-ignore
/public/css/* -diff
/public/js/* -diff

View file

@ -1,79 +1,28 @@
name: Docker
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on: on:
push: push:
branches: [ "main" ]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs: jobs:
build: build:
name: Build, push, and deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: if: github.ref == 'refs/heads/main'
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps: steps:
- name: Checkout repository
uses: actions/checkout@v3
# Install the cosign tool except on PR - name: Checkout
# https://github.com/sigstore/cosign-installer uses: actions/checkout@v2
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@main
with:
cosign-release: 'v1.11.0'
- name: Build container image
run: |
docker build \
--tag ghcr.io/cp6/my-idlers:$(echo $GITHUB_SHA | head -c7) \
--tag ghcr.io/cp6/my-idlers:latest \
.
- name: Container registry login
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
# Workaround: https://github.com/docker/build-push-action/issues/461 - name: Push image to GHCR
- name: Setup Docker buildx if: github.ref == 'refs/heads/main'
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf run: |
docker push ghcr.io/cp6/my-idlers:$(echo $GITHUB_SHA | head -c7)
# Login against a Docker registry except on PR docker push ghcr.io/cp6/my-idlers:latest
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
latest
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v2
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max

1
.gitignore vendored
View file

@ -57,4 +57,3 @@ fabric.properties
# .idea/misc.xml # .idea/misc.xml
# *.ipr # *.ipr
storage/clockwork/ storage/clockwork/
!public/

View file

@ -1,4 +1,4 @@
FROM php:8.2-fpm-alpine FROM php:8.1-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql sockets RUN docker-php-ext-install pdo pdo_mysql sockets
RUN curl -sS https://getcomposer.org/installer | php -- \ RUN curl -sS https://getcomposer.org/installer | php -- \

View file

@ -1,60 +1,49 @@
# My idlers # My idlers
A self-hosted web app for displaying, organizing and storing information about your servers (VPS/Dedi), shared & A web app for displaying, organizing and storing information about servers (VPS), shared & reseller hosting, seed boxes,
reseller hosting, seedboxes, domains,
domains, DNS and misc services. DNS and misc services.
Despite what the name infers this self-hosted web app isn't just for storing idling server information. By using Despite what the name infers this self hosted web app isn't just for storing idling server information. By using
a [YABS](https://github.com/masonr/yet-another-bench-script) output you can get disk & network speed values along with a [YABs](https://github.com/masonr/yet-another-bench-script) output you can get disk & network speed values along with
GeekBench 5 & 6 scores to do easier comparing and sorting. Of course storing other services e.g. web hosting is possible GeekBench 5 scores to do easier comparing and sorting.
and supported too with My idlers.
[![Generic badge](https://img.shields.io/badge/version-3.0.0-blue.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/Laravel-11.0-red.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/PHP-8.3-purple.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/Bootstrap-5.3-pink.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/version-2.1.3-blue.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/Laravel-9.0-red.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/PHP-8.1-purple.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/Bootstrap-5.1-pink.svg)](https://shields.io/)
<img src="https://raw.githubusercontent.com/cp6/my-idlers/main/public/My%20Idlers%20logo.jpg" width="128" height="128" /> <img src="https://raw.githubusercontent.com/cp6/my-idlers/main/public/My%20Idlers%20logo.jpg" width="128" height="128" />
[View demo site](https://demo.myidlers.com/) [Demo site](https://demo.myidlers.com/)
**Note:** Create, Update and Delete are disabled on the demo site. **Note:** Create, Update and Delete are disabled on demo site.
## Project sponsor ## Project sponsor
Currently seeking a project sponsor [Cloud Five Limited](https://cloud-v.net/) for providing the hosting for demo installation.
## 3.0.0 changes (9 December 2024): ## 2.1.3 changes (20th July 2022):
* Updated PHP version to 8.3 #### Please run the following if updating from existing install:
* Updated Laravel version to ^11
* Updated composer package versions
* Updated routes into middleware grouping for auth
* Updated login and register forms
* Updated servers, shared, reseller and domains pages to use Datatables
* Added icons to back and submit button components
* Added icon button to shared and reseller create pages
* Added several updated OS versions to OsSeeder
* Added Font awesome Brands webfont
* Added IP whois data columns to the ips table
* Added IP whois data fetching and updating DB
* Added Note to API
* Fixed OS icons not loading in servers index page
* Fixed Settings being called without being created (existing)
* Fixed issue with OS: `Call to a member function toJson() on array`
* Fixed due in (days) column showing a massive float
* Removed 1 user being seeded
* Removed doctrine/dbal
#### Please run the following if updating from an existing install:
```shell ```shell
composer update
php artisan migrate php artisan migrate
php artisan route:cache php artisan route:cache
php artisan cache:clear php artisan cache:clear
``` ```
* Added YABs to JSON output page
* Added uptime, distro and kernel to YABs inserting
* Added memory swap values to YABs inserting
* Added save YABs as txt file (setting)
* Added back and edit button component with icon
* Updated Reseller model to use relationships + caching
* Updated Misc model to use relationships + caching
* Updated SeedBoxes model to use relationships + caching
* Updated ApiController to use the new model relationship calling (& caching)
* Updated container large screen max width from 1320px to 1420px
## Requires ## Requires
* PHP 8.3 * PHP 8.1
## Features ## Features
@ -63,10 +52,10 @@ php artisan cache:clear
* Add domains * Add domains
* [Auto get IP's from hostname](https://cdn.write.corbpie.com/wp-content/uploads/2021/01/my-idlers-self-hosted-server-domain-information-ips-from-hostname.gif) * [Auto get IP's from hostname](https://cdn.write.corbpie.com/wp-content/uploads/2021/01/my-idlers-self-hosted-server-domain-information-ips-from-hostname.gif)
* [Check up/down status](https://cdn.write.corbpie.com/wp-content/uploads/2021/01/my-idlers-self-hosted-server-domain-information-ping-up-feature.gif) * [Check up/down status](https://cdn.write.corbpie.com/wp-content/uploads/2021/01/my-idlers-self-hosted-server-domain-information-ping-up-feature.gif)
* Get YABS data from output * Get YABs data from output
* Compare 2 servers * Compare 2 servers
* Save & view YABS output * Save & view YABs output
* Update YABS disk & network results * Update YABs disk & network results
* Next due date system * Next due date system
* Multi currency compatibility * Multi currency compatibility
* Multi payment-term compatibility * Multi payment-term compatibility
@ -74,7 +63,6 @@ php artisan cache:clear
* Assign labels * Assign labels
* Assign server type (KVM, OVZ, LXC & dedi) * Assign server type (KVM, OVZ, LXC & dedi)
* Easy to edit values * Easy to edit values
* Assign notes
## Install ## Install
@ -93,7 +81,6 @@ If you already have at least version 2.0 installed:
* Run `git clone https://github.com/cp6/my-idlers.git` * Run `git clone https://github.com/cp6/my-idlers.git`
* Run `composer install` * Run `composer install`
* Run `composer update`
* Run `php artisan migrate` * Run `php artisan migrate`
* Run `php artisan route:cache` * Run `php artisan route:cache`
* Run `php artisan cache:clear` * Run `php artisan cache:clear`
@ -118,22 +105,6 @@ Run with a single click on [PikaPods.com](https://www.pikapods.com/)
[![PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=my-idlers) [![PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=my-idlers)
## Adding a YABS benchmark
yabs.sh now has JSON formatted response and can POST the output directly from calling the script.
With My idlers you can use your API key and the server id to directly POST the benchmark result
`https://yourdomain.com/api/yabs/SERVERID/USERAPIKEYISHERE`
Example yabs.sh call to POST the result:
`curl -sL yabs.sh | bash -s -- -s "https://yourdomain.com/api/yabs/SERVERID/USERAPIKEYISHERE"`
## Credits
IP who is data provided by [ipwhois.io](https://ipwhois.io/documentation)
## API endpoints ## API endpoints
For GET requests the header must have `Accept: application/json` and your API token (found at `/account`) For GET requests the header must have `Accept: application/json` and your API token (found at `/account`)
@ -198,8 +169,6 @@ All API requests must be appended with `api/` e.g `mydomain.com/api/servers/gYk8
`shared/{id}` `shared/{id}`
`note/{id}`
**POST requests** **POST requests**
Create a server Create a server
@ -318,6 +287,10 @@ or
```curl -sL yabs.sh | bash -s -- -r``` ```curl -sL yabs.sh | bash -s -- -r```
**Make sure YABs output starts at the first line which is:**
```# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #```
Logo icons created by Freepik - Flaticon Logo icons created by Freepik - Flaticon
## Screenshots for v2 ## Screenshots for v2

View file

@ -2,12 +2,12 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\DiskSpeed;
use App\Models\Domains; use App\Models\Domains;
use App\Models\IPs; use App\Models\IPs;
use App\Models\Labels; use App\Models\Labels;
use App\Models\Misc; use App\Models\Misc;
use App\Models\NetworkSpeed; use App\Models\NetworkSpeed;
use App\Models\Note;
use App\Models\OS; use App\Models\OS;
use App\Models\Pricing; use App\Models\Pricing;
use App\Models\Providers; use App\Models\Providers;
@ -15,8 +15,8 @@ use App\Models\Reseller;
use App\Models\SeedBoxes; use App\Models\SeedBoxes;
use App\Models\Server; use App\Models\Server;
use App\Models\Shared; use App\Models\Shared;
use App\Models\User;
use App\Models\Yabs; use App\Models\Yabs;
use App\Process;
use DataTables; use DataTables;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
@ -59,7 +59,7 @@ class ApiController extends Controller
protected function getNetworkSpeeds($id) protected function getNetworkSpeeds($id)
{ {
$ns = NetworkSpeed::where('server_id', $id) $ns = NetworkSpeed::where('server_id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($ns, 200); return response($ns, 200);
} }
@ -72,7 +72,7 @@ class ApiController extends Controller
protected function getLabel($id) protected function getLabel($id)
{ {
$label = Labels::where('id', $id) $label = Labels::where('id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($label, 200); return response($label, 200);
} }
@ -147,7 +147,7 @@ class ApiController extends Controller
protected function getDns($id) protected function getDns($id)
{ {
$dns = DB::table('d_n_s') $dns = DB::table('d_n_s')
->where('id', $id) ->where('id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($dns, 200); return response($dns, 200);
} }
@ -162,7 +162,7 @@ class ApiController extends Controller
protected function getLocation($id) protected function getLocation($id)
{ {
$location = DB::table('locations') $location = DB::table('locations')
->where('id', $id) ->where('id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($location, 200); return response($location, 200);
} }
@ -177,7 +177,7 @@ class ApiController extends Controller
protected function getProvider($id) protected function getProvider($id)
{ {
$providers = DB::table('providers') $providers = DB::table('providers')
->where('id', $id) ->where('id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($providers, 200); return response($providers, 200);
} }
@ -198,7 +198,7 @@ class ApiController extends Controller
protected function getOs($id) protected function getOs($id)
{ {
$os = DB::table('os as o') $os = DB::table('os as o')
->where('o.id', $id) ->where('o.id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($os, 200); return response($os, 200);
} }
@ -212,7 +212,7 @@ class ApiController extends Controller
protected function getIP($id) protected function getIP($id)
{ {
$ip = DB::table('ips as i') $ip = DB::table('ips as i')
->where('i.id', $id) ->where('i.id', '=', $id)
->get()->toJson(JSON_PRETTY_PRINT); ->get()->toJson(JSON_PRETTY_PRINT);
return response($ip, 200); return response($ip, 200);
} }
@ -263,7 +263,7 @@ class ApiController extends Controller
protected function storeServer(Request $request) protected function storeServer(Request $request)
{ {
$rules = [ $rules = array(
'hostname' => 'min:3', 'hostname' => 'min:3',
'server_type' => 'required|integer', 'server_type' => 'required|integer',
'os_id' => 'required|integer', 'os_id' => 'required|integer',
@ -288,9 +288,9 @@ class ApiController extends Controller
'price' => 'required|numeric', 'price' => 'required|numeric',
'payment_term' => 'required|integer', 'payment_term' => 'required|integer',
'next_due_date' => 'date', 'next_due_date' => 'date',
]; );
$messages = [ $messages = array(
'required' => ':attribute is required', 'required' => ':attribute is required',
'min' => ':attribute must be longer than 3', 'min' => ':attribute must be longer than 3',
'integer' => ':attribute must be an integer', 'integer' => ':attribute must be an integer',
@ -299,7 +299,7 @@ class ApiController extends Controller
'numeric' => ':attribute must be a float', 'numeric' => ':attribute must be a float',
'ip' => ':attribute must be a valid IP address', 'ip' => ':attribute must be a valid IP address',
'date' => ':attribute must be a date Y-m-d', 'date' => ':attribute must be a date Y-m-d',
]; );
$validator = Validator::make($request->all(), $rules, $messages); $validator = Validator::make($request->all(), $rules, $messages);
@ -310,7 +310,10 @@ class ApiController extends Controller
$server_id = Str::random(8); $server_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(1, $server_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date);
$as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(1, $server_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
if (!is_null($request->ip1)) { if (!is_null($request->ip1)) {
IPs::insertIP($server_id, $request->ip1); IPs::insertIP($server_id, $request->ip1);
@ -374,7 +377,7 @@ class ApiController extends Controller
public function updateServer(Request $request) public function updateServer(Request $request)
{ {
$rules = [ $rules = array(
'hostname' => 'string|min:3', 'hostname' => 'string|min:3',
'server_type' => 'integer', 'server_type' => 'integer',
'os_id' => 'integer', 'os_id' => 'integer',
@ -397,9 +400,9 @@ class ApiController extends Controller
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'integer',
'next_due_date' => 'date', 'next_due_date' => 'date',
]; );
$messages = [ $messages = array(
'required' => ':attribute is required', 'required' => ':attribute is required',
'min' => ':attribute must be longer than 3', 'min' => ':attribute must be longer than 3',
'integer' => ':attribute must be an integer', 'integer' => ':attribute must be an integer',
@ -407,7 +410,7 @@ class ApiController extends Controller
'size' => ':attribute must be exactly :size characters', 'size' => ':attribute must be exactly :size characters',
'numeric' => ':attribute must be a float', 'numeric' => ':attribute must be a float',
'date' => ':attribute must be a date Y-m-d', 'date' => ':attribute must be a date Y-m-d',
]; );
$validator = Validator::make($request->all(), $rules, $messages); $validator = Validator::make($request->all(), $rules, $messages);
@ -429,22 +432,22 @@ class ApiController extends Controller
public function updatePricing(Request $request) public function updatePricing(Request $request)
{ {
$rules = [ $rules = array(
'price' => 'required|numeric', 'price' => 'required|numeric',
'currency' => 'required|string|size:3', 'currency' => 'required|string|size:3',
'term' => 'required|integer', 'term' => 'required|integer',
'active' => 'integer', 'active' => 'integer',
'next_due_date' => 'date', 'next_due_date' => 'date',
]; );
$messages = [ $messages = array(
'required' => ':attribute is required', 'required' => ':attribute is required',
'integer' => ':attribute must be an integer', 'integer' => ':attribute must be an integer',
'string' => ':attribute must be a string', 'string' => ':attribute must be a string',
'size' => ':attribute must be exactly :size characters', 'size' => ':attribute must be exactly :size characters',
'numeric' => ':attribute must be a float', 'numeric' => ':attribute must be a float',
'date' => ':attribute must be a date Y-m-d', 'date' => ':attribute must be a date Y-m-d',
]; );
$validator = Validator::make($request->all(), $rules, $messages); $validator = Validator::make($request->all(), $rules, $messages);
@ -470,23 +473,113 @@ class ApiController extends Controller
return response()->json(array('result' => 'fail', 'request' => $request->post()), 500); return response()->json(array('result' => 'fail', 'request' => $request->post()), 500);
} }
public function storeYabs(Request $request, Server $server, string $key): \Illuminate\Http\JsonResponse public function storeYabs(Request $request)
{ {
$r = User::where('api_token', $key)->first(); $rules = array(
if (!isset($r->id)) { 'server_id' => 'required|string|size:8',
return response()->json(['error' => 'Unauthenticated'], 401); 'yabs_output' => 'required|string',
);
$messages = array(
'required' => ':attribute is required',
'string' => ':attribute must be a string',
'size' => ':attribute must be exactly :size characters'
);
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return response()->json(['result' => 'fail', 'messages' => $validator->messages()], 400);
} }
$insert = Yabs::insertFromJson($request, $server->id); //dd($request->all());
$process = new Process();
$yabs = $process->yabsOutputAsJson($request->server_id, $request->yabs_output);
//dd($yabs);
$yabs_id = Str::random(8);
$yabs_insert = Yabs::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'has_ipv6' => $yabs['has_ipv6'],
'aes' => $yabs['aes'],
'vm' => $yabs['vm'],
'output_date' => $yabs['output_date'],
'cpu_cores' => $yabs['cpu_cores'],
'cpu_freq' => $yabs['cpu_freq'],
'cpu_model' => $yabs['cpu'],
'ram' => $yabs['ram'],
'ram_type' => $yabs['ram_type'],
'ram_mb' => $yabs['ram_mb'],
'swap' => $yabs['swap'],
'swap_type' => $yabs['swap_type'],
'swap_mb' => $yabs['swap_mb'],
'disk' => $yabs['disk'],
'disk_type' => $yabs['disk_type'],
'disk_gb' => $yabs['disk_gb'],
'gb5_single' => $yabs['GB5_single'],
'gb5_multi' => $yabs['GB5_mult'],
'gb5_id' => $yabs['GB5_id'],
'uptime' => $yabs['uptime'],
'distro' => $yabs['distro'],
'kernel' => $yabs['kernel']
]);
DiskSpeed::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'd_4k' => $yabs['disk_speed']['4k_total'],
'd_4k_type' => $yabs['disk_speed']['4k_total_type'],
'd_4k_as_mbps' => $yabs['disk_speed']['4k_total_mbps'],
'd_64k' => $yabs['disk_speed']['64k_total'],
'd_64k_type' => $yabs['disk_speed']['64k_total_type'],
'd_64k_as_mbps' => $yabs['disk_speed']['64k_total_mbps'],
'd_512k' => $yabs['disk_speed']['512k_total'],
'd_512k_type' => $yabs['disk_speed']['512k_total_type'],
'd_512k_as_mbps' => $yabs['disk_speed']['512k_total_mbps'],
'd_1m' => $yabs['disk_speed']['1m_total'],
'd_1m_type' => $yabs['disk_speed']['1m_total_type'],
'd_1m_as_mbps' => $yabs['disk_speed']['1m_total_mbps']
]);
foreach ($yabs['network_speed'] as $y) {
NetworkSpeed::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'location' => $y['location'],
'send' => $y['send'],
'send_type' => $y['send_type'],
'send_as_mbps' => $y['send_type_mbps'],
'receive' => $y['receive'],
'receive_type' => $y['receive_type'],
'receive_as_mbps' => $y['receive_type_mbps']
]);
}
$update_server = DB::table('servers')
->where('id', $request->server_id)
->update([
'ram' => $yabs['ram'],
'ram_type' => $yabs['ram_type'],
'ram_as_mb' => ($yabs['ram_type'] === 'GB') ? ($yabs['ram'] * 1024) : $yabs['ram'],
'disk' => $yabs['disk'],
'disk_type' => $yabs['disk_type'],
'disk_as_gb' => ($yabs['disk_type'] === 'TB') ? ($yabs['disk'] * 1024) : $yabs['disk'],
'cpu' => $yabs['cpu_cores'],
'has_yabs' => 1
]);
if ($insert) {
Cache::forget('all_active_servers');//all servers cache Cache::forget('all_active_servers');//all servers cache
Cache::forget('non_active_servers');//all servers cache Cache::forget('non_active_servers');//all servers cache
Cache::forget('all_yabs');//Forget the all YABS cache Cache::forget('all_yabs');//Forget the all YABs cache
return response()->json(array('message' => 'Successfully added YABS'), 200);
if ($yabs_insert) {
return response()->json(array('result' => 'success', 'yabs_id' => $yabs_id), 200);
} }
return response()->json(array('error' => 'Server error'), 500); return response()->json(array('result' => 'fail', 'request' => $request->post()), 500);
} }
public function getAllYabs() public function getAllYabs()
@ -501,10 +594,4 @@ class ApiController extends Controller
return response($yabs, 200); return response($yabs, 200);
} }
protected function getNote($id)
{
$note = Note::where('id', $id)->firstOrFail('note')->pluck('note');
return response($note, 200)->header('Content-Type', 'text/plain');
}
} }

View file

@ -8,6 +8,7 @@ use App\Models\Reseller;
use App\Models\Server; use App\Models\Server;
use App\Models\Domains; use App\Models\Domains;
use App\Models\Shared; use App\Models\Shared;
use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -33,13 +34,9 @@ class DNSController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'hostname' => 'required|string|min:2', 'hostname' => 'required|min:2',
'address' => 'required|string|min:2', 'address' => 'required|min:2',
'dns_type' => 'required|string', 'dns_type' => 'required'
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$dns_id = Str::random(8); $dns_id = Str::random(8);
@ -68,8 +65,8 @@ class DNSController extends Controller
$dns = DNS::findOrFail($dn->id); $dns = DNS::findOrFail($dn->id);
$labels = DB::table('labels_assigned as l') $labels = DB::table('labels_assigned as l')
->join('labels', 'l.label_id', 'labels.id') ->join('labels', 'l.label_id', '=', 'labels.id')
->where('l.service_id', $dn->id) ->where('l.service_id', '=', $dn->id)
->get(['labels.label']); ->get(['labels.label']);
return view('dns.show', compact(['dn', 'dns', 'labels'])); return view('dns.show', compact(['dn', 'dns', 'labels']));
@ -83,23 +80,19 @@ class DNSController extends Controller
$Resellers = Reseller::all(); $Resellers = Reseller::all();
$dn = DNS::findOrFail($dn->id); $dn = DNS::findOrFail($dn->id);
$labels = DB::table('labels_assigned as l') $labels = DB::table('labels_assigned as l')
->join('labels', 'l.label_id', 'labels.id') ->join('labels', 'l.label_id', '=', 'labels.id')
->where('l.service_id', $dn->id) ->where('l.service_id', '=', $dn->id)
->get(['labels.id']); ->get(['labels.id', 'labels.label']);
return view('dns.edit', compact(['dn', 'labels', 'Servers', 'Domains', 'Shareds', 'Resellers'])); return view('dns.edit', compact(['dn', 'labels', 'Servers', 'Domains', 'Shareds', 'Resellers']));
} }
public function update(Request $request, DNS $dn): \Illuminate\Http\RedirectResponse public function update(Request $request, DNS $dn)
{ {
$request->validate([ $request->validate([
'hostname' => 'required|string|min:2', 'hostname' => 'required|min:2',
'address' => 'required|string|min:2', 'address' => 'required|min:2',
'dns_type' => 'required|string', 'dns_type' => 'required'
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$dn->update([ $dn->update([
@ -120,18 +113,18 @@ class DNSController extends Controller
->with('success', 'DNS updated Successfully.'); ->with('success', 'DNS updated Successfully.');
} }
public function destroy(DNS $dn): \Illuminate\Http\RedirectResponse public function destroy(DNS $dn)
{ {
if ( $dn->delete()){ $id = $dn->id;
$items = DNS::find($id);
$items->delete();
Cache::forget('dns_count'); Cache::forget('dns_count');
Labels::deleteLabelsAssignedTo($dn->id); Labels::deleteLabelsAssignedTo($id);
return redirect()->route('dns.index') return redirect()->route('dns.index')
->with('success', 'DNS was deleted Successfully.'); ->with('success', 'DNS was deleted Successfully.');
} }
return redirect()->route('dns.index')
->with('error', 'DNS was not deleted.');
}
} }

View file

@ -7,5 +7,23 @@ use Illuminate\Http\Request;
class DiskSpeedController extends Controller class DiskSpeedController extends Controller
{ {
public function index()
{
//
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function destroy(DiskSpeed $diskSpeed)
{
//
}
} }

View file

@ -22,7 +22,7 @@ class DomainsController extends Controller
public function show(Domains $domain) public function show(Domains $domain)
{//Need to modern {//Need to modern
$domain_info = Domains::domain($domain->id); $domain_info = Domains::domain($domain->id)[0];
return view('domains.show', compact(['domain_info'])); return view('domains.show', compact(['domain_info']));
} }
@ -34,25 +34,17 @@ class DomainsController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'domain' => 'required|string|min:2', 'domain' => 'required|min:2',
'extension' => 'required|string|min:2', 'extension' => 'required|min:2',
'ns1' => 'sometimes|nullable|min:2', 'provider_id' => 'numeric',
'ns2' => 'sometimes|nullable|min:2',
'ns3' => 'sometimes|nullable|min:2',
'provider_id' => 'integer',
'payment_term' => 'integer',
'price' => 'numeric', 'price' => 'numeric',
'next_due_date' => 'required|date', 'next_due_date' => 'required|date'
'owned_since' => 'sometimes|nullable|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$domain_id = Str::random(8); $domain_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(4, $domain_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(4, $domain_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Domains::create([ Domains::create([
'id' => $domain_id, 'id' => $domain_id,
@ -76,31 +68,22 @@ class DomainsController extends Controller
public function edit(Domains $domain) public function edit(Domains $domain)
{ {
$domain_info = Domains::domain($domain->id); $domain_info = Domains::domain($domain->id)[0];
return view('domains.edit', compact(['domain_info'])); return view('domains.edit', compact(['domain_info']));
} }
public function update(Request $request, Domains $domain) public function update(Request $request, Domains $domain)
{ {
$request->validate([ $request->validate([
'domain' => 'required|string|min:2', 'domain' => 'required|min:2',
'extension' => 'required|string|min:2', 'extension' => 'required|min:2',
'ns1' => 'sometimes|nullable|min:2', 'provider_id' => 'numeric',
'ns2' => 'sometimes|nullable|min:2', 'price' => 'numeric'
'ns3' => 'sometimes|nullable|min:2',
'provider_id' => 'integer',
'payment_term' => 'integer',
'price' => 'numeric',
'next_due_date' => 'required|date',
'owned_since' => 'sometimes|nullable|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($domain->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->updatePricing($domain->id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
$domain->update([ $domain->update([
'domain' => $request->domain, 'domain' => $request->domain,
@ -127,7 +110,9 @@ class DomainsController extends Controller
public function destroy(Domains $domain) public function destroy(Domains $domain)
{ {
if ($domain->delete()){ $items = Domains::find($domain->id);
$items->delete();
$p = new Pricing(); $p = new Pricing();
$p->deletePricing($domain->id); $p->deletePricing($domain->id);
@ -141,8 +126,4 @@ class DomainsController extends Controller
->with('success', 'Domain was deleted Successfully.'); ->with('success', 'Domain was deleted Successfully.');
} }
return redirect()->route('domains.index')
->with('error', 'Domain was not deleted.');
}
} }

View file

@ -7,6 +7,9 @@ use App\Models\Home;
use App\Models\Labels; use App\Models\Labels;
use App\Models\Pricing; use App\Models\Pricing;
use App\Models\Settings; use App\Models\Settings;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use App\Process; use App\Process;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
@ -44,7 +47,7 @@ class HomeController extends Controller
$p->stopTimer(); $p->stopTimer();
$information = [ $information = array(
'servers' => $service_count['servers'], 'servers' => $service_count['servers'],
'domains' => $service_count['domains'], 'domains' => $service_count['domains'],
'shared' => $service_count['shared'], 'shared' => $service_count['shared'],
@ -56,7 +59,7 @@ class HomeController extends Controller
'total_services' => $service_count['total'], 'total_services' => $service_count['total'],
'total_inactive' => $pricing_breakdown['inactive_count'], 'total_inactive' => $pricing_breakdown['inactive_count'],
'total_cost_weekly' => number_format($pricing_breakdown['total_cost_weekly'], 2), 'total_cost_weekly' => number_format($pricing_breakdown['total_cost_weekly'], 2),
'total_cost_monthly' => number_format($pricing_breakdown['total_cost_monthly'], 2), 'total_cost_monthly' => number_format($pricing_breakdown['total_cost_montly'], 2),
'total_cost_yearly' => number_format($pricing_breakdown['total_cost_yearly'], 2), 'total_cost_yearly' => number_format($pricing_breakdown['total_cost_yearly'], 2),
'total_cost_2_yearly' => number_format(($pricing_breakdown['total_cost_yearly'] * 2), 2), 'total_cost_2_yearly' => number_format(($pricing_breakdown['total_cost_yearly'] * 2), 2),
'due_soon' => $due_soon, 'due_soon' => $due_soon,
@ -64,7 +67,7 @@ class HomeController extends Controller
'execution_time' => number_format($p->getTimeTaken(), 2), 'execution_time' => number_format($p->getTimeTaken(), 2),
'servers_summary' => $server_summary, 'servers_summary' => $server_summary,
'currency' => Session::get('dashboard_currency') 'currency' => Session::get('dashboard_currency')
]; );
return view('home', compact('information')); return view('home', compact('information'));
} }

View file

@ -2,13 +2,13 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\DNS;
use App\Models\IPs; use App\Models\IPs;
use App\Models\Reseller; use App\Models\Reseller;
use App\Models\SeedBoxes;
use App\Models\Server; use App\Models\Server;
use App\Models\Shared; use App\Models\Shared;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class IPsController extends Controller class IPsController extends Controller
@ -21,24 +21,22 @@ class IPsController extends Controller
public function create() public function create()
{ {
$servers = Server::all(); $Servers = Server::all();
$shareds = Shared::all(); $Shareds = Shared::all();
$resellers = Reseller::all(); $Resellers = Reseller::all();
$seed_boxes = SeedBoxes::all(); return view('ips.create', compact(['Servers', 'Shareds', 'Resellers']));
return view('ips.create', compact(['servers', 'shareds', 'resellers', 'seed_boxes']));
} }
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'address' => 'required|ip|min:2', 'address' => 'required|ip|min:2',
'ip_type' => 'required|string|size:4', 'ip_type' => 'required'
'service_id' => 'required|string'
]); ]);
$ip_id = Str::random(8); $ip_id = Str::random(8);
$ip = IPs::create([ IPs::create([
'id' => $ip_id, 'id' => $ip_id,
'address' => $request->address, 'address' => $request->address,
'is_ipv4' => ($request->ip_type === 'ipv4') ? 1 : 0, 'is_ipv4' => ($request->ip_type === 'ipv4') ? 1 : 0,
@ -46,32 +44,16 @@ class IPsController extends Controller
'active' => 1 'active' => 1
]); ]);
$fetch = IPs::getUpdateIpInfo($ip);
return redirect()->route('IPs.index') return redirect()->route('IPs.index')
->with('success', 'IP address created Successfully.'); ->with('success', 'IP address created Successfully.');
} }
public function destroy(IPs $IP) public function destroy(IPs $IP)
{ {
if ($IP->delete()) { $items = IPs::find($IP->id);
$items->delete();
return redirect()->route('IPs.index') return redirect()->route('IPs.index')
->with('success', 'IP address was deleted Successfully.'); ->with('success', 'IP address was deleted Successfully.');
} }
return redirect()->route('IPs.index')
->with('error', 'IP was not deleted.');
}
public function getUpdateWhoIs(IPs $IP): \Illuminate\Http\RedirectResponse
{
$result = IPs::getUpdateIpInfo($IP);
if ($result) {
return redirect()->route('IPs.index')
->with('success', 'IP address updated Successfully.');
}
return redirect()->route('IPs.index')
->with('error', 'IP was not updated.');
}
} }

View file

@ -25,7 +25,7 @@ class LabelsController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'label' => 'required|string|min:2' 'label' => 'required|min:2'
]); ]);
Labels::create([ Labels::create([
@ -43,31 +43,37 @@ class LabelsController extends Controller
public function show(Labels $label) public function show(Labels $label)
{ {
$labels = DB::table('labels_assigned as las') $labels = DB::table('labels_assigned as las')
->leftJoin('pricings as p', 'las.service_id', 'p.service_id') ->leftJoin('pricings as p', 'las.service_id', '=', 'p.service_id')
->leftJoin('servers as s', 'las.service_id', 's.id') ->leftJoin('servers as s', 'las.service_id', '=', 's.id')
->leftJoin('shared_hosting as sh', 'las.service_id', 'sh.id') ->leftJoin('shared_hosting as sh', 'las.service_id', '=', 'sh.id')
->leftJoin('reseller_hosting as r', 'las.service_id', 'r.id') ->leftJoin('reseller_hosting as r', 'las.service_id', '=', 'r.id')
->leftJoin('domains as d', 'las.service_id', 'd.id') ->leftJoin('domains as d', 'las.service_id', '=', 'd.id')
->where('las.label_id', $label->id) ->where('las.label_id', '=', $label->id)
->get(['p.service_type', 'p.service_id', 's.hostname', 'sh.main_domain as shared', 'r.main_domain as reseller', 'd.domain', 'd.extension']); ->get(['p.service_type', 'p.service_id', 's.hostname', 'sh.main_domain as shared', 'r.main_domain as reseller', 'd.domain', 'd.extension']);
return view('labels.show', compact(['label', 'labels'])); return view('labels.show', compact(['label', 'labels']));
} }
public function edit(Labels $label)
{
abort(404);
}
public function destroy(Labels $label) public function destroy(Labels $label)
{ {
if ($label->delete()) { $label_id = $label->id;
$items = Labels::find($label_id);
$items->delete();
Cache::forget('labels_count'); Cache::forget('labels_count');
Labels::deleteLabelAssignedAs($label->id); Labels::deleteLabelAssignedAs($label_id);
Cache::forget('all_labels'); Cache::forget('all_labels');
return redirect()->route('labels.index') return redirect()->route('labels.index')
->with('success', 'Label was deleted Successfully.'); ->with('success', 'Label was deleted Successfully.');
} }
return redirect()->route('labels.index')
->with('error', 'Label was not deleted.');
}
} }

View file

@ -24,7 +24,7 @@ class LocationsController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'location_name' => 'required|string|min:2|max:255' 'location_name' => 'required|min:2'
]); ]);
Locations::create([ Locations::create([
@ -40,17 +40,17 @@ class LocationsController extends Controller
public function show(Locations $location) public function show(Locations $location)
{ {
$servers = DB::table('servers as s') $servers = DB::table('servers as s')
->where('s.location_id', $location->id) ->where('s.location_id', '=', $location->id)
->get(['s.id', 's.hostname']) ->get(['s.id', 's.hostname'])
->toArray(); ->toArray();
$shared = DB::table('shared_hosting as s') $shared = DB::table('shared_hosting as s')
->where('s.location_id', $location->id) ->where('s.location_id', '=', $location->id)
->get(['s.id', 's.main_domain as main_domain_shared']) ->get(['s.id', 's.main_domain as main_domain_shared'])
->toArray(); ->toArray();
$reseller = DB::table('reseller_hosting as r') $reseller = DB::table('reseller_hosting as r')
->where('r.location_id', $location->id) ->where('r.location_id', '=', $location->id)
->get(['r.id', 'r.main_domain as main_domain_reseller']) ->get(['r.id', 'r.main_domain as main_domain_reseller'])
->toArray(); ->toArray();
@ -61,15 +61,13 @@ class LocationsController extends Controller
public function destroy(Locations $location) public function destroy(Locations $location)
{ {
if ($location->delete()){ $items = Locations::find($location->id);
$items->delete();
Cache::forget('locations'); Cache::forget('locations');
return redirect()->route('locations.index') return redirect()->route('locations.index')
->with('success', 'Location was deleted Successfully.'); ->with('success', 'Location was deleted Successfully.');
} }
return redirect()->route('locations.index')
->with('error', 'Location was not deleted.');
}
} }

View file

@ -7,6 +7,7 @@ use App\Models\Misc;
use App\Models\Pricing; use App\Models\Pricing;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class MiscController extends Controller class MiscController extends Controller
@ -24,25 +25,24 @@ class MiscController extends Controller
public function show(Misc $misc) public function show(Misc $misc)
{ {
$misc_data = Misc::misc($misc->id); $misc_data = Misc::misc($misc->id)[0];
return view('misc.show', compact(['misc_data'])); return view('misc.show', compact(['misc_data']));
} }
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'name' => 'required|string|min:3', 'name' => 'required|min:3',
'price' => 'required|numeric', 'price' => 'required|numeric',
'payment_term' => 'required|integer', 'owned_since' => 'date',
'currency' => 'required|string|size:3',
'owned_since' => 'sometimes|nullable|date',
'next_due_date' => 'required|date' 'next_due_date' => 'required|date'
]); ]);
$misc_id = Str::random(8); $misc_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(5, $misc_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(5, $misc_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Misc::create([ Misc::create([
'id' => $misc_id, 'id' => $misc_id,
@ -59,29 +59,28 @@ class MiscController extends Controller
public function edit(Misc $misc) public function edit(Misc $misc)
{ {
$misc_data = Misc::misc($misc->id); $misc_data = Misc::misc($misc->id)[0];
return view('misc.edit', compact('misc_data')); return view('misc.edit', compact('misc_data'));
} }
public function update(Request $request, Misc $misc) public function update(Request $request, Misc $misc)
{ {
$request->validate([ $request->validate([
'name' => 'required|string|min:3', 'name' => 'required',
'price' => 'required|numeric', 'owned_since' => 'date',
'payment_term' => 'required|integer',
'currency' => 'required|string|size:3',
'owned_since' => 'sometimes|nullable|date',
'next_due_date' => 'required|date'
]); ]);
$misc->update([ DB::table('misc_services')
->where('id', $misc->id)
->update([
'name' => $request->name, 'name' => $request->name,
'owned_since' => $request->owned_since, 'owned_since' => $request->owned_since,
'active' => (isset($request->is_active)) ? 1 : 0 'active' => (isset($request->is_active)) ? 1 : 0
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($misc->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->updatePricing($misc->id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Cache::forget("all_misc"); Cache::forget("all_misc");
Cache::forget("misc.{$misc->id}"); Cache::forget("misc.{$misc->id}");
@ -93,7 +92,9 @@ class MiscController extends Controller
public function destroy(Misc $misc) public function destroy(Misc $misc)
{ {
if ($misc->delete()) { $items = Misc::find($misc->id);
$items->delete();
$p = new Pricing(); $p = new Pricing();
$p->deletePricing($misc->id); $p->deletePricing($misc->id);
@ -104,8 +105,4 @@ class MiscController extends Controller
return redirect()->route('misc.index') return redirect()->route('misc.index')
->with('success', 'Misc service was deleted Successfully.'); ->with('success', 'Misc service was deleted Successfully.');
} }
return redirect()->route('misc.index')
->with('error', 'Misc service was not deleted.');
}
} }

View file

@ -7,4 +7,18 @@ use Illuminate\Http\Request;
class NetworkSpeedController extends Controller class NetworkSpeedController extends Controller
{ {
public function index()
{
//
}
public function show(NetworkSpeed $networkSpeed)
{
//
}
public function destroy(NetworkSpeed $networkSpeed)
{
//
}
} }

View file

@ -1,123 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\DNS;
use App\Models\Domains;
use App\Models\IPs;
use App\Models\Note;
use App\Models\Reseller;
use App\Models\Server;
use App\Models\Shared;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
class NoteController extends Controller
{
public function index()
{
$notes = Note::allNotes();
return view('notes.index', compact('notes'));
}
public function create()
{
$servers = Server::all();
$shareds = Shared::all();
$resellers = Reseller::all();
$domains = Domains::all();
$dns = DNS::all();
$ips = IPs::all();
return view('notes.create', compact(['servers', 'shareds', 'resellers', 'domains', 'dns', 'ips']));
}
public function store(Request $request)
{
$request->validate([
'service_id' => 'required|string|size:8',
'note' => 'required|string',
]);
try {
$note_id = Str::random(8);
$a = Note::create([
'id' => $note_id,
'service_id' => $request->service_id,
'note' => $request->note
]);
} catch (\Exception $e) {
if ($e->getCode() === "23000") {
$message = "A note already exists for this service";
} else {
$message = "Error inserting note";
}
return redirect()->route('notes.create')
->withInput($request->input())->with('error', $message);
}
Cache::forget('all_notes');
return redirect()->route('notes.index')
->with('success', 'Note created successfully.');
}
public function edit(Note $note)
{
$note = Note::note($note->service_id);
$servers = Server::all();
$shareds = Shared::all();
$resellers = Reseller::all();
$domains = Domains::all();
$dns = DNS::all();
$ips = IPs::all();
return view('notes.edit', compact(['note', 'servers', 'shareds', 'resellers', 'domains', 'dns', 'ips']));
}
public function update(Request $request, Note $note)
{
$request->validate([
'service_id' => 'required|string|size:8',
'note' => 'required|string'
]);
$note->update([
'service_id' => $request->service_id,
'note' => $request->note
]);
Cache::forget('all_notes');
Cache::forget("note.$note->service_id");
return redirect()->route('notes.index')
->with('success', 'Note was updated successfully.');
}
public function show(Note $note)
{
$note = Note::note($note->service_id);
return view('notes.show', compact(['note']));
}
public function destroy(Note $note)
{
if ($note->delete()) {
Cache::forget("all_notes");
Cache::forget("note.$note->service_id");
return redirect()->route('notes.index')
->with('success', 'Note was deleted successfully.');
}
return redirect()->route('notes.index')
->with('error', 'Note was not deleted.');
}
}

View file

@ -10,7 +10,7 @@ class OsController extends Controller
{ {
public function index() public function index()
{ {
$os = OS::allOS()->toArray(); $os = OS::allOS();
return view('os.index', compact(['os'])); return view('os.index', compact(['os']));
} }
@ -22,7 +22,7 @@ class OsController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'os_name' => 'required|string|min:2|max:255' 'os_name' => 'required|min:2'
]); ]);
OS::create([ OS::create([
@ -37,15 +37,13 @@ class OsController extends Controller
public function destroy(OS $o) public function destroy(OS $o)
{ {
if ($o->delete()) { $items = OS::find($o->id);
$items->delete();
Cache::forget('operating_systems'); Cache::forget('operating_systems');
return redirect()->route('os.index') return redirect()->route('os.index')
->with('success', 'OS was deleted Successfully.'); ->with('success', 'OS was deleted Successfully.');
} }
return redirect()->route('os.index')
->with('error', 'OS was not deleted.');
}
} }

View file

@ -7,5 +7,13 @@ use Illuminate\Http\Request;
class PricingController extends Controller class PricingController extends Controller
{ {
public function index()
{
//
}
public function destroy(Pricing $pricing)
{
//
}
} }

View file

@ -3,8 +3,10 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Providers; use App\Models\Providers;
use DataTables;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class ProvidersController extends Controller class ProvidersController extends Controller
{ {
@ -22,7 +24,7 @@ class ProvidersController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'provider_name' => 'required|string|min:2|max:255' 'provider_name' => 'required|min:2'
]); ]);
Providers::create([ Providers::create([
@ -44,16 +46,29 @@ class ProvidersController extends Controller
public function destroy(Providers $provider) public function destroy(Providers $provider)
{ {
if ($provider->delete()) { $items = Providers::find($provider->id);
$items->delete();
Cache::forget('providers'); Cache::forget('providers');
return redirect()->route('providers.index') return redirect()->route('providers.index')
->with('success', 'Provider was deleted Successfully.'); ->with('success', 'Provider was deleted Successfully.');
} }
return redirect()->route('providers.index') public function getProviders(Request $request)
->with('error', 'Provider was not deleted.'); {
if ($request->ajax()) {
$data = Providers::latest()->get();
$dt = Datatables::of($data)
->addIndexColumn()
->addColumn('action', function ($row) {
$actionBtn = '<a href="javascript:void(0)" class="edit btn btn-success btn-sm">Edit</a> <a href="javascript:void(0)" class="delete btn btn-danger btn-sm">Delete</a>';
return $actionBtn;
})
->rawColumns(['action'])
->make(true);
}
} }
} }

View file

@ -5,10 +5,13 @@ namespace App\Http\Controllers;
use App\Models\Home; use App\Models\Home;
use App\Models\IPs; use App\Models\IPs;
use App\Models\Labels; use App\Models\Labels;
use App\Models\Locations;
use App\Models\Pricing; use App\Models\Pricing;
use App\Models\Providers;
use App\Models\Reseller; use App\Models\Reseller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class ResellerController extends Controller class ResellerController extends Controller
@ -26,35 +29,36 @@ class ResellerController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'domain' => 'required|min:4', 'domain' => 'required|min:4',
'reseller_type' => 'required|string', 'reseller_type' => 'required',
'disk' => 'integer', 'dedicated_ip' => 'present',
'os_id' => 'integer', 'accounts' => 'numeric',
'provider_id' => 'integer', 'server_type' => 'numeric',
'location_id' => 'integer', 'ram' => 'numeric',
'disk' => 'numeric',
'os_id' => 'numeric',
'provider_id' => 'numeric',
'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'accounts' => 'integer', 'domains' => 'numeric',
'domains' => 'integer', 'sub_domains' => 'numeric',
'sub_domains' => 'integer', 'bandwidth' => 'numeric',
'bandwidth' => 'integer', 'email' => 'numeric',
'email' => 'integer', 'ftp' => 'numeric',
'ftp' => 'integer', 'db' => 'numeric',
'db' => 'integer', 'next_due_date' => 'required|date'
'next_due_date' => 'required|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$reseller_id = Str::random(8); $reseller_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(3, $reseller_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(3, $reseller_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
if (!is_null($request->dedicated_ip)) { if (!is_null($request->dedicated_ip)) {
IPs::insertIP($reseller_id, $request->dedicated_ip); IPs::insertIP($reseller_id, $request->dedicated_ip);
@ -91,49 +95,47 @@ class ResellerController extends Controller
public function show(Reseller $reseller) public function show(Reseller $reseller)
{ {
$reseller = Reseller::resellerHosting($reseller->id); $reseller = Reseller::resellerHosting($reseller->id)[0];
return view('reseller.show', compact(['reseller'])); return view('reseller.show', compact(['reseller']));
} }
public function edit(Reseller $reseller) public function edit(Reseller $reseller)
{ {
$reseller = Reseller::resellerHosting($reseller->id); $reseller = Reseller::resellerHosting($reseller->id)[0];
return view('reseller.edit', compact(['reseller'])); return view('reseller.edit', compact(['reseller']));
} }
public function update(Request $request, Reseller $reseller) public function update(Request $request, Reseller $reseller)
{ {
$request->validate([ $request->validate([
'id' => 'required|size:8',
'domain' => 'required|min:4', 'domain' => 'required|min:4',
'reseller_type' => 'required|string', 'reseller_type' => 'required',
'disk' => 'integer', 'dedicated_ip' => 'present',
'os_id' => 'integer', 'server_type' => 'numeric',
'provider_id' => 'integer', 'disk' => 'numeric',
'location_id' => 'integer', 'os_id' => 'numeric',
'provider_id' => 'numeric',
'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'accounts' => 'integer', 'domains' => 'numeric',
'domains' => 'integer', 'sub_domains' => 'numeric',
'sub_domains' => 'integer', 'bandwidth' => 'numeric',
'bandwidth' => 'integer', 'email' => 'numeric',
'email' => 'integer', 'ftp' => 'numeric',
'ftp' => 'integer', 'db' => 'numeric'
'db' => 'integer',
'next_due_date' => 'required|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$reseller->update([ DB::table('reseller_hosting')
->where('id', $request->id)
->update([
'main_domain' => $request->domain, 'main_domain' => $request->domain,
'reseller_type' => $request->reseller_type, 'reseller_type' => $request->reseller_type,
'provider_id' => $request->provider_id, 'provider_id' => $request->provider_id,
'location_id' => $request->location_id, 'location_id' => $request->location_id,
'accounts' => $request->accounts,
'disk' => $request->disk, 'disk' => $request->disk,
'disk_type' => 'GB', 'disk_type' => 'GB',
'disk_as_gb' => $request->disk, 'disk_as_gb' => $request->disk,
@ -148,20 +150,20 @@ class ResellerController extends Controller
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($reseller->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->updatePricing($request->id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Labels::deleteLabelsAssignedTo($reseller->id); Labels::deleteLabelsAssignedTo($request->id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $reseller->id); Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $request->id);
IPs::deleteIPsAssignedTo($reseller->id); IPs::deleteIPsAssignedTo($request->id);
if (!is_null($request->dedicated_ip)) { if (isset($request->dedicated_ip)) {
IPs::insertIP($reseller->id, $request->dedicated_ip); IPs::insertIP($request->id, $request->dedicated_ip);
} }
Cache::forget("all_reseller"); Cache::forget("reseller_hosting.{$request->id}");
Cache::forget("reseller_hosting.{$reseller->id}"); Cache::forget("labels_for_service.{$request->id}");
Cache::forget("labels_for_service.{$reseller->id}");
Home::homePageCacheForget(); Home::homePageCacheForget();
@ -171,24 +173,22 @@ class ResellerController extends Controller
public function destroy(Reseller $reseller) public function destroy(Reseller $reseller)
{ {
if ($reseller->delete()) { $reseller_id = $reseller->id;
$items = Reseller::find($reseller_id);
$items->delete();
$p = new Pricing(); $p = new Pricing();
$p->deletePricing($reseller->id); $p->deletePricing($reseller_id);
Labels::deleteLabelsAssignedTo($reseller->id); Labels::deleteLabelsAssignedTo($reseller_id);
IPs::deleteIPsAssignedTo($reseller->id); IPs::deleteIPsAssignedTo($reseller_id);
Cache::forget("all_reseller"); Cache::forget("all_reseller");
Cache::forget("reseller_hosting.$reseller->id"); Cache::forget("reseller_hosting.$reseller_id");
Home::homePageCacheForget(); Home::homePageCacheForget();
return redirect()->route('reseller.index') return redirect()->route('reseller.index')
->with('success', 'Reseller hosting was deleted Successfully.'); ->with('success', 'Reseller hosting was deleted Successfully.');
} }
return redirect()->route('reseller.index')
->with('error', 'Reseller was not deleted.');
}
} }

View file

@ -3,11 +3,14 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Home; use App\Models\Home;
use App\Models\IPs;
use App\Models\Labels; use App\Models\Labels;
use App\Models\Pricing; use App\Models\Pricing;
use App\Models\SeedBoxes; use App\Models\SeedBoxes;
use App\Models\Shared;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class SeedBoxesController extends Controller class SeedBoxesController extends Controller
@ -26,29 +29,26 @@ class SeedBoxesController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'title' => 'required|string|min:2', 'title' => 'required|string',
'hostname' => 'sometimes|nullable|string|min:2', 'hostname' => 'string|nullable',
'seed_box_type' => 'required|string', 'seed_box_type' => 'required',
'provider_id' => 'integer', 'provider_id' => 'numeric',
'location_id' => 'integer', 'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'disk' => 'integer', 'disk' => 'numeric',
'bandwidth' => 'integer', 'bandwidth' => 'numeric',
'port_speed' => 'integer', 'port_speed' => 'numeric',
'next_due_date' => 'required|date', 'next_due_date' => 'required|date'
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$seedbox_id = Str::random(8); $seedbox_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(6, $seedbox_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(6, $seedbox_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Labels::deleteLabelsAssignedTo($seedbox_id); Labels::deleteLabelsAssignedTo($seedbox_id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $seedbox_id); Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $seedbox_id);
@ -79,39 +79,37 @@ class SeedBoxesController extends Controller
public function show(SeedBoxes $seedbox) public function show(SeedBoxes $seedbox)
{ {
$seedbox_data = SeedBoxes::seedbox($seedbox->id); $seedbox_data = SeedBoxes::seedbox($seedbox->id)[0];
return view('seedboxes.show', compact(['seedbox_data'])); return view('seedboxes.show', compact(['seedbox_data']));
} }
public function edit(SeedBoxes $seedbox) public function edit(SeedBoxes $seedbox)
{ {
$seedbox_data = SeedBoxes::seedbox($seedbox->id); $seedbox_data = SeedBoxes::seedbox($seedbox->id)[0];
return view('seedboxes.edit', compact(['seedbox_data'])); return view('seedboxes.edit', compact(['seedbox_data']));
} }
public function update(Request $request, SeedBoxes $seedbox) public function update(Request $request, SeedBoxes $seedbox)
{ {
$request->validate([ $request->validate([
'title' => 'required|string|min:2', 'id' => 'required|size:8',
'hostname' => 'sometimes|nullable|string|min:2', 'title' => 'required|string',
'seed_box_type' => 'required|string', 'hostname' => 'string|nullable',
'provider_id' => 'integer', 'seed_box_type' => 'required',
'location_id' => 'integer', 'disk' => 'numeric',
'provider_id' => 'numeric',
'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'disk' => 'integer', 'bandwidth' => 'numeric',
'bandwidth' => 'integer', 'port_speed' => 'numeric'
'port_speed' => 'integer',
'next_due_date' => 'required|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$seedbox->update([ DB::table('seedboxes')
->where('id', $seedbox->id)
->update([
'title' => $request->title, 'title' => $request->title,
'hostname' => $request->hostname, 'hostname' => $request->hostname,
'seed_box_type' => $request->seed_box_type, 'seed_box_type' => $request->seed_box_type,
@ -127,7 +125,8 @@ class SeedBoxesController extends Controller
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($seedbox->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->updatePricing($seedbox->id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Labels::deleteLabelsAssignedTo($seedbox->id); Labels::deleteLabelsAssignedTo($seedbox->id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $seedbox->id); Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $seedbox->id);
@ -143,11 +142,14 @@ class SeedBoxesController extends Controller
public function destroy(SeedBoxes $seedbox) public function destroy(SeedBoxes $seedbox)
{ {
if ($seedbox->delete()) { $seedbox_id = $seedbox->id;
$p = new Pricing(); $items = SeedBoxes::find($seedbox_id);
$p->deletePricing($seedbox->id); $items->delete();
Labels::deleteLabelsAssignedTo($seedbox->id); $p = new Pricing();
$p->deletePricing($seedbox_id);
Labels::deleteLabelsAssignedTo($seedbox_id);
Cache::forget("all_seedboxes"); Cache::forget("all_seedboxes");
Cache::forget("seedbox.{$seedbox->id}"); Cache::forget("seedbox.{$seedbox->id}");
@ -156,8 +158,4 @@ class SeedBoxesController extends Controller
return redirect()->route('seedboxes.index') return redirect()->route('seedboxes.index')
->with('success', 'Seed box was deleted Successfully.'); ->with('success', 'Seed box was deleted Successfully.');
} }
return redirect()->route('seedboxes.index')
->with('error', 'Seed box was not deleted.');
}
} }

View file

@ -7,9 +7,12 @@ use App\Models\Labels;
use App\Models\Pricing; use App\Models\Pricing;
use App\Models\Server; use App\Models\Server;
use App\Models\Settings; use App\Models\Settings;
use App\Models\Yabs;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
class ServerController extends Controller class ServerController extends Controller
{ {
@ -17,20 +20,31 @@ class ServerController extends Controller
public function index() public function index()
{ {
$servers = Server::allActiveServers(); $servers = Server::allActiveServers();
$non_active_servers = Server::allNonActiveServers(); $non_active_servers = Server::allNonActiveServers();
return view('servers.index', compact(['servers', 'non_active_servers'])); return view('servers.index', compact(['servers', 'non_active_servers']));
} }
public function showServersPublic() public function showServersPublic()
{ {
$settings = Settings::getSettings(); $settings = Settings::getSettings();
Settings::setSettingsToSession($settings);
Session::put('timer_version_footer', $settings[0]->show_versions_footer ?? 1);
Session::put('show_servers_public', $settings[0]->show_servers_public ?? 0);
Session::put('show_server_value_ip', $settings[0]->show_server_value_ip ?? 0);
Session::put('show_server_value_hostname', $settings[0]->show_server_value_hostname ?? 0);
Session::put('show_server_value_price', $settings[0]->show_server_value_price ?? 0);
Session::put('show_server_value_yabs', $settings[0]->show_server_value_yabs ?? 0);
Session::put('show_server_value_provider', $settings[0]->show_server_value_provider ?? 0);
Session::put('show_server_value_location', $settings[0]->show_server_value_location ?? 0);
Session::save();
if ((Session::get('show_servers_public') === 1)) { if ((Session::get('show_servers_public') === 1)) {
$servers = Server::allPublicServers(); $servers = Server::allPublicServers();
return view('servers.public-index', compact('servers')); return view('servers.public-index', compact('servers'));
} }
abort(404); return response()->view('errors.404', array("status" => 404, "title" => "Page not found", "message" => ""), 404);
} }
public function create() public function create()
@ -40,35 +54,31 @@ class ServerController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'hostname' => 'required|min:5', 'hostname' => 'required|min:5',
'ip1' => 'sometimes|nullable|ip', 'ip1' => 'nullable|ip',
'ip2' => 'sometimes|nullable|ip', 'ip2' => 'nullable|ip',
'ns1' => 'sometimes|nullable|string', 'service_type' => 'numeric',
'ns2' => 'sometimes|nullable|string', 'server_type' => 'numeric',
'server_type' => 'integer', 'ram' => 'numeric',
'ssh_port' => 'integer', 'disk' => 'numeric',
'bandwidth' => 'integer', 'os_id' => 'numeric',
'ram' => 'required|numeric', 'provider_id' => 'numeric',
'disk' => 'required|integer', 'location_id' => 'numeric',
'os_id' => 'required|integer', 'price' => 'numeric',
'provider_id' => 'required|integer', 'cpu' => 'numeric',
'location_id' => 'required|integer', 'was_promo' => 'numeric',
'price' => 'required|numeric', 'next_due_date' => 'required|date'
'cpu' => 'required|integer',
'was_promo' => 'integer',
'next_due_date' => 'required|date',
'owned_since' => 'sometimes|nullable|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$server_id = Str::random(8); $server_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(1, $server_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date);
$as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(1, $server_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
if (!is_null($request->ip1)) { if (!is_null($request->ip1)) {
IPs::insertIP($server_id, $request->ip1); IPs::insertIP($server_id, $request->ip1);
@ -111,14 +121,14 @@ class ServerController extends Controller
public function show(Server $server) public function show(Server $server)
{ {
$server_data = Server::server($server->id); $server_data = Server::server($server->id)[0];
return view('servers.show', compact(['server_data'])); return view('servers.show', compact(['server_data']));
} }
public function edit(Server $server) public function edit(Server $server)
{ {
$server_data = Server::server($server->id); $server_data = Server::server($server->id)[0];
return view('servers.edit', compact(['server_data'])); return view('servers.edit', compact(['server_data']));
} }
@ -127,34 +137,26 @@ class ServerController extends Controller
{ {
$request->validate([ $request->validate([
'hostname' => 'required|min:5', 'hostname' => 'required|min:5',
'ip1' => 'sometimes|nullable|ip', 'ram' => 'numeric',
'ip2' => 'sometimes|nullable|ip', 'disk' => 'numeric',
'ns1' => 'sometimes|nullable|string', 'os_id' => 'numeric',
'ns2' => 'sometimes|nullable|string', 'provider_id' => 'numeric',
'server_type' => 'integer', 'location_id' => 'numeric',
'ssh_port' => 'integer', 'price' => 'numeric',
'bandwidth' => 'integer', 'cpu' => 'numeric',
'ram' => 'required|numeric', 'was_promo' => 'numeric',
'disk' => 'required|integer', 'next_due_date' => 'date'
'os_id' => 'required|integer',
'provider_id' => 'required|integer',
'location_id' => 'required|integer',
'price' => 'required|numeric',
'cpu' => 'required|integer',
'was_promo' => 'integer',
'next_due_date' => 'required|date',
'owned_since' => 'sometimes|nullable|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$server->update([ $server_id = $request->server_id;
DB::table('servers')
->where('id', $server_id)
->update([
'hostname' => $request->hostname, 'hostname' => $request->hostname,
'server_type' => $request->server_type, 'server_type' => $request->server_type,
'os_id' => $request->os_id, 'os_id' => $request->os_id,
'ssh' => $request->ssh_port, 'ssh' => $request->ssh,
'provider_id' => $request->provider_id, 'provider_id' => $request->provider_id,
'location_id' => $request->location_id, 'location_id' => $request->location_id,
'ram' => $request->ram, 'ram' => $request->ram,
@ -174,23 +176,26 @@ class ServerController extends Controller
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($server->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date);
Labels::deleteLabelsAssignedTo($server->id); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $server->id); $pricing->updatePricing($server_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
IPs::deleteIPsAssignedTo($server->id); Labels::deleteLabelsAssignedTo($server_id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $server_id);
IPs::deleteIPsAssignedTo($server_id);
for ($i = 1; $i <= 8; $i++) {//Max of 8 ips for ($i = 1; $i <= 8; $i++) {//Max of 8 ips
$obj = 'ip' . $i; $obj = 'ip' . $i;
if (isset($request->$obj) && !is_null($request->$obj)) { if (isset($request->$obj) && !is_null($request->$obj)) {
IPs::insertIP($server->id, $request->$obj); IPs::insertIP($server_id, $request->$obj);
} }
} }
Server::serverRelatedCacheForget(); Server::serverRelatedCacheForget();
Server::serverSpecificCacheForget($server->id); Server::serverSpecificCacheForget($server_id);
return redirect()->route('servers.index') return redirect()->route('servers.index')
->with('success', 'Server Updated Successfully.'); ->with('success', 'Server Updated Successfully.');
@ -198,7 +203,10 @@ class ServerController extends Controller
public function destroy(Server $server) public function destroy(Server $server)
{ {
if ($server->delete()) { $items = Server::find($server->id);
$items->delete();
$p = new Pricing(); $p = new Pricing();
$p->deletePricing($server->id); $p->deletePricing($server->id);
@ -212,34 +220,24 @@ class ServerController extends Controller
->with('success', 'Server was deleted Successfully.'); ->with('success', 'Server was deleted Successfully.');
} }
return redirect()->route('servers.index')
->with('error', 'Server was not deleted.');
}
public function chooseCompare() public function chooseCompare()
{//NOTICE: Selecting servers is not cached yet {//NOTICE: Selecting servers is not cached yet
$all_servers = Server::where('has_yabs', 1)->get(); $all_servers = Server::where('has_yabs', 1)->get();
if (isset($all_servers[1])) {
return view('servers.choose-compare', compact('all_servers')); return view('servers.choose-compare', compact('all_servers'));
} }
return redirect()->route('servers.index')
->with('error', 'You need atleast 2 servers with a YABS to do a compare');
}
public function compareServers($server1, $server2) public function compareServers($server1, $server2)
{ {
$server1_data = Server::server($server1); $server1_data = Server::server($server1);
if (!isset($server1_data[0]->yabs[0])) { if (!isset($server1_data[0]->yabs[0])) {
abort(404); return response()->view('errors.404', array("status" => 404, "title" => "Page not found", "message" => "No server with YABs data was found for id '$server1'"), 404);
} }
$server2_data = Server::server($server2); $server2_data = Server::server($server2);
if (!isset($server2_data[0]->yabs[0])) { if (!isset($server2_data[0]->yabs[0])) {
abort(404); return response()->view('errors.404', array("status" => 404, "title" => "Page not found", "message" => "No server with YABs data was found for id '$server2'"), 404);
} }
return view('servers.compare', compact('server1_data', 'server2_data')); return view('servers.compare', compact('server1_data', 'server2_data'));
} }

View file

@ -5,52 +5,42 @@ namespace App\Http\Controllers;
use App\Models\Settings; use App\Models\Settings;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class SettingsController extends Controller class SettingsController extends Controller
{ {
public function index() public function index()
{ {
return view('settings.index', ['setting' => Settings::where('id', 1)->first()]); $setting = DB::table('settings')
->where('id', '=', 1)
->get();
return view('settings.index', compact(['setting']));
} }
public function update(Request $request) public function update(Request $request, Settings $settings)
{ {
$request->validate([ $request->validate([
'dark_mode' => 'required|integer|min:0|max:1', 'dark_mode' => 'required|boolean',
'show_versions_footer' => 'required|integer|min:0|max:1', 'show_versions_footer' => 'required|boolean',
'show_server_value_ip' => 'required|integer|min:0|max:1', 'show_server_value_ip' => 'required|boolean',
'show_server_value_hostname' => 'required|integer|min:0|max:1', 'show_server_value_hostname' => 'required|boolean',
'show_server_value_provider' => 'required|integer|min:0|max:1', 'show_server_value_provider' => 'required|boolean',
'show_server_value_location' => 'required|integer|min:0|max:1', 'show_server_value_location' => 'required|boolean',
'show_server_value_price' => 'required|integer|min:0|max:1', 'show_server_value_price' => 'required|boolean',
'show_server_value_yabs' => 'required|integer|min:0|max:1', 'show_server_value_yabs' => 'required|boolean',
'save_yabs_as_txt' => 'integer|min:0|max:1', 'save_yabs_as_txt' => 'required|boolean',
'default_currency' => 'required|string|size:3', 'default_currency' => 'required',
'default_server_os' => 'required|integer', 'default_server_os' => 'required',
'due_soon_amount' => 'required|integer|between:0,12', 'due_soon_amount' => 'required|integer|between:0,12',
'recently_added_amount' => 'required|integer|between:0,12', 'recently_added_amount' => 'required|integer|between:0,12',
'currency' => 'required|string|size:3', 'currency' => 'required|string|size:3'
'sort_on' => 'required|integer|between:1,10',
'favicon' => 'sometimes|nullable|mimes:ico,jpg,png|max:40',
]); ]);
$settings = Settings::where('id', 1)->first(); DB::table('settings')
->where('id', 1)
if ($request->favicon) {//Has a favicon upload ->update([
$file = $request->favicon;
$extension = $file->getClientOriginalExtension();
$favicon_filename = "favicon.$extension";
if ($favicon_filename !== $settings->favicon && $settings->favicon !== 'favicon.ico') {
Storage::disk('public_uploads')->delete($settings->favicon);//Delete old favicon
}
$file->storeAs("", $favicon_filename, "public_uploads");//Save into /public
}
$do_update = $settings->update([
'dark_mode' => $request->dark_mode, 'dark_mode' => $request->dark_mode,
'show_versions_footer' => $request->show_versions_footer, 'show_versions_footer' => $request->show_versions_footer,
'show_servers_public' => $request->show_servers_public, 'show_servers_public' => $request->show_servers_public,
@ -60,39 +50,24 @@ class SettingsController extends Controller
'show_server_value_location' => $request->show_server_value_location, 'show_server_value_location' => $request->show_server_value_location,
'show_server_value_price' => $request->show_server_value_price, 'show_server_value_price' => $request->show_server_value_price,
'show_server_value_yabs' => $request->show_server_value_yabs, 'show_server_value_yabs' => $request->show_server_value_yabs,
'save_yabs_as_txt' => 0, 'save_yabs_as_txt' => $request->save_yabs_as_txt,
'default_currency' => $request->default_currency, 'default_currency' => $request->default_currency,
'default_server_os' => $request->default_server_os, 'default_server_os' => $request->default_server_os,
'due_soon_amount' => $request->due_soon_amount, 'due_soon_amount' => $request->due_soon_amount,
'recently_added_amount' => $request->recently_added_amount, 'recently_added_amount' => $request->recently_added_amount,
'dashboard_currency' => $request->currency, 'dashboard_currency' => $request->currency,
'sort_on' => $request->sort_on,
'favicon' => $favicon_filename ?? $settings->favicon
]); ]);
Settings::setSettingsToSession($settings);
Cache::forget('due_soon');//Main page due_soon cache Cache::forget('due_soon');//Main page due_soon cache
Cache::forget('recently_added');//Main page recently_added cache Cache::forget('recently_added');//Main page recently_added cache
Cache::forget('pricing_breakdown');//Main page pricing breakdown Cache::forget('pricing_breakdown');//Main page pricing breakdown
Cache::forget('settings');//Main page settings cache Cache::forget('settings');//Main page settings cache
//Clear because they are affected by settings change (sort_on)
Cache::forget('all_servers');
Cache::forget('all_active_servers');
Cache::forget('all_shared');
Cache::forget('all_seedboxes');
Cache::forget('all_reseller');
Cache::forget('all_misc');
Cache::forget('all_domains');
Settings::setSettingsToSession(Settings::getSettings());
if ($do_update) {
return redirect()->route('settings.index') return redirect()->route('settings.index')
->with('success', 'Settings Updated Successfully.'); ->with('success', 'Settings Updated Successfully.');
} }
return redirect()->route('settings.index')
->with('error', 'Settings failed to update.');
}
} }

View file

@ -9,6 +9,7 @@ use App\Models\Pricing;
use App\Models\Shared; use App\Models\Shared;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class SharedController extends Controller class SharedController extends Controller
@ -28,32 +29,31 @@ class SharedController extends Controller
{ {
$request->validate([ $request->validate([
'domain' => 'required|min:4', 'domain' => 'required|min:4',
'shared_type' => 'required|string', 'shared_type' => 'required',
'disk' => 'integer', 'server_type' => 'numeric',
'os_id' => 'integer', 'ram' => 'numeric',
'provider_id' => 'integer', 'disk' => 'numeric',
'location_id' => 'integer', 'os_id' => 'numeric',
'provider_id' => 'numeric',
'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'domains' => 'integer', 'domains' => 'numeric',
'sub_domains' => 'integer', 'sub_domains' => 'numeric',
'bandwidth' => 'integer', 'bandwidth' => 'numeric',
'email' => 'integer', 'email' => 'numeric',
'ftp' => 'integer', 'ftp' => 'numeric',
'db' => 'integer', 'db' => 'numeric',
'next_due_date' => 'required|date', 'next_due_date' => 'required|date'
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$shared_id = Str::random(8); $shared_id = Str::random(8);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->insertPricing(2, $shared_id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->insertPricing(2, $shared_id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Labels::deleteLabelsAssignedTo($shared_id); Labels::deleteLabelsAssignedTo($shared_id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $shared_id); Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $shared_id);
@ -91,43 +91,43 @@ class SharedController extends Controller
public function show(Shared $shared) public function show(Shared $shared)
{ {
$shared = Shared::sharedHosting($shared->id); $shared = Shared::sharedHosting($shared->id)[0];
return view('shared.show', compact(['shared'])); return view('shared.show', compact(['shared']));
} }
public function edit(Shared $shared) public function edit(Shared $shared)
{ {
$shared = Shared::sharedHosting($shared->id); $shared = Shared::sharedHosting($shared->id)[0];
return view('shared.edit', compact(['shared'])); return view('shared.edit', compact(['shared']));
} }
public function update(Request $request, Shared $shared) public function update(Request $request, Shared $shared)
{ {
$request->validate([ $request->validate([
'id' => 'required|size:8',
'domain' => 'required|min:4', 'domain' => 'required|min:4',
'shared_type' => 'required|string', 'shared_type' => 'required',
'disk' => 'integer', 'dedicated_ip' => 'present',
'os_id' => 'integer', 'server_type' => 'numeric',
'provider_id' => 'integer', 'disk' => 'numeric',
'location_id' => 'integer', 'os_id' => 'numeric',
'provider_id' => 'numeric',
'location_id' => 'numeric',
'price' => 'numeric', 'price' => 'numeric',
'payment_term' => 'integer', 'payment_term' => 'numeric',
'was_promo' => 'integer', 'was_promo' => 'numeric',
'owned_since' => 'sometimes|nullable|date', 'owned_since' => 'date',
'domains' => 'integer', 'domains' => 'numeric',
'sub_domains' => 'integer', 'sub_domains' => 'numeric',
'bandwidth' => 'integer', 'bandwidth' => 'numeric',
'email' => 'integer', 'email' => 'numeric',
'ftp' => 'integer', 'ftp' => 'numeric',
'db' => 'integer', 'db' => 'numeric'
'next_due_date' => 'required|date',
'label1' => 'sometimes|nullable|string',
'label2' => 'sometimes|nullable|string',
'label3' => 'sometimes|nullable|string',
'label4' => 'sometimes|nullable|string',
]); ]);
$shared->update([ DB::table('shared_hosting')
->where('id', $request->id)
->update([
'main_domain' => $request->domain, 'main_domain' => $request->domain,
'shared_type' => $request->shared_type, 'shared_type' => $request->shared_type,
'provider_id' => $request->provider_id, 'provider_id' => $request->provider_id,
@ -146,18 +146,19 @@ class SharedController extends Controller
]); ]);
$pricing = new Pricing(); $pricing = new Pricing();
$pricing->updatePricing($shared->id, $request->currency, $request->price, $request->payment_term, $request->next_due_date); $as_usd = $pricing->convertToUSD($request->price, $request->currency);
$pricing->updatePricing($request->id, $request->currency, $request->price, $request->payment_term, $as_usd, $request->next_due_date);
Labels::deleteLabelsAssignedTo($shared->id); Labels::deleteLabelsAssignedTo($request->id);
Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $shared->id); Labels::insertLabelsAssigned([$request->label1, $request->label2, $request->label3, $request->label4], $request->id);
Cache::forget("labels_for_service.{$shared->id}"); Cache::forget("labels_for_service.{$request->id}");
IPs::deleteIPsAssignedTo($shared->id); IPs::deleteIPsAssignedTo($request->id);
if (isset($request->dedicated_ip)) { if (isset($request->dedicated_ip)) {
IPs::insertIP($shared->id, $request->dedicated_ip); IPs::insertIP($request->id, $request->dedicated_ip);
} }
Cache::forget("shared_hosting.{$shared->id}"); Cache::forget("shared_hosting.{$request->id}");
Cache::forget('all_shared'); Cache::forget('all_shared');
Home::homePageCacheForget(); Home::homePageCacheForget();
@ -167,15 +168,18 @@ class SharedController extends Controller
public function destroy(Shared $shared) public function destroy(Shared $shared)
{ {
if ($shared->delete()) { $shared_id = $shared->id;
$items = Shared::find($shared_id);
$items->delete();
$p = new Pricing(); $p = new Pricing();
$p->deletePricing($shared->id); $p->deletePricing($shared_id);
Labels::deleteLabelsAssignedTo($shared->id); Labels::deleteLabelsAssignedTo($shared_id);
IPs::deleteIPsAssignedTo($shared->id); IPs::deleteIPsAssignedTo($shared_id);
Cache::forget("shared_hosting.$shared->id"); Cache::forget("shared_hosting.$shared_id");
Cache::forget('all_shared'); Cache::forget('all_shared');
Home::homePageCacheForget(); Home::homePageCacheForget();
@ -183,8 +187,4 @@ class SharedController extends Controller
->with('success', 'Shared hosting was deleted Successfully.'); ->with('success', 'Shared hosting was deleted Successfully.');
} }
return redirect()->route('shared.index')
->with('error', 'Shared was not deleted.');
}
} }

View file

@ -4,24 +4,131 @@ namespace App\Http\Controllers;
use App\Models\Server; use App\Models\Server;
use App\Models\Yabs; use App\Models\Yabs;
use App\Process;
use App\Models\DiskSpeed;
use App\Models\NetworkSpeed;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class YabsController extends Controller class YabsController extends Controller
{ {
public function index() public function index()
{ {
return view('yabs.index', ['yabs' => Yabs::allYabs()]); $yabs = Yabs::allYabs();
return view('yabs.index', compact(['yabs']));
}
public function create()
{
$Servers = Server::all();
return view('yabs.create', compact(['Servers']));
}
public function store(Request $request)
{
$process = new Process();
$yabs = $process->yabsOutputAsJson($request->server_id, $request->yabs);
if (isset($yabs['error_id'])) {
return back()->withErrors(["yabs" => 'Problem inserting YABs. Error id ' . $yabs['error_id']])->withInput();
}
//No errors, do insert
$yabs_id = Str::random(8);
Yabs::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'has_ipv6' => $yabs['has_ipv6'],
'aes' => $yabs['aes'],
'vm' => $yabs['vm'],
'output_date' => $yabs['output_date'],
'cpu_cores' => $yabs['cpu_cores'],
'cpu_freq' => $yabs['cpu_freq'],
'cpu_model' => $yabs['cpu'],
'ram' => $yabs['ram'],
'ram_type' => $yabs['ram_type'],
'ram_mb' => $yabs['ram_mb'],
'swap' => $yabs['swap'],
'swap_type' => $yabs['swap_type'],
'swap_mb' => $yabs['swap_mb'],
'disk' => $yabs['disk'],
'disk_type' => $yabs['disk_type'],
'disk_gb' => $yabs['disk_gb'],
'gb5_single' => $yabs['GB5_single'],
'gb5_multi' => $yabs['GB5_mult'],
'gb5_id' => $yabs['GB5_id'],
'uptime' => $yabs['uptime'],
'distro' => $yabs['distro'],
'kernel' => $yabs['kernel']
]);
DiskSpeed::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'd_4k' => $yabs['disk_speed']['4k_total'],
'd_4k_type' => $yabs['disk_speed']['4k_total_type'],
'd_4k_as_mbps' => $yabs['disk_speed']['4k_total_mbps'],
'd_64k' => $yabs['disk_speed']['64k_total'],
'd_64k_type' => $yabs['disk_speed']['64k_total_type'],
'd_64k_as_mbps' => $yabs['disk_speed']['64k_total_mbps'],
'd_512k' => $yabs['disk_speed']['512k_total'],
'd_512k_type' => $yabs['disk_speed']['512k_total_type'],
'd_512k_as_mbps' => $yabs['disk_speed']['512k_total_mbps'],
'd_1m' => $yabs['disk_speed']['1m_total'],
'd_1m_type' => $yabs['disk_speed']['1m_total_type'],
'd_1m_as_mbps' => $yabs['disk_speed']['1m_total_mbps']
]);
foreach ($yabs['network_speed'] as $y) {
NetworkSpeed::create([
'id' => $yabs_id,
'server_id' => $request->server_id,
'location' => $y['location'],
'send' => $y['send'],
'send_type' => $y['send_type'],
'send_as_mbps' => $y['send_type_mbps'],
'receive' => $y['receive'],
'receive_type' => $y['receive_type'],
'receive_as_mbps' => $y['receive_type_mbps']
]);
}
$update_server = DB::table('servers')
->where('id', $request->server_id)
->update([
'ram' => $yabs['ram'],
'ram_type' => $yabs['ram_type'],
'ram_as_mb' => ($yabs['ram_type'] === 'GB') ? ($yabs['ram'] * 1024) : $yabs['ram'],
'disk' => $yabs['disk'],
'disk_type' => $yabs['disk_type'],
'disk_as_gb' => ($yabs['disk_type'] === 'TB') ? ($yabs['disk'] * 1024) : $yabs['disk'],
'cpu' => $yabs['cpu_cores'],
'has_yabs' => 1
]);
Cache::forget('all_active_servers');//all servers cache
Cache::forget('non_active_servers');//all servers cache
Cache::forget('all_yabs');//Forget the all YABs cache
return redirect()->route('yabs.index')
->with('success', 'Success inserting YABs');
} }
public function show(Yabs $yab) public function show(Yabs $yab)
{ {
return view('yabs.show', ['yabs' => Yabs::yabs($yab->id)]); $yab = Yabs::yabs($yab->id);
return view('yabs.show', compact(['yab']));
} }
public function destroy(Yabs $yab) public function destroy(Yabs $yab)
{ {
if ($yab->delete()) { $yabs = Yabs::find($yab->id);
$yabs->delete();
if (Server::serverYabsAmount($yab->server_id) === 0) { if (Server::serverYabsAmount($yab->server_id) === 0) {
DB::table('servers') DB::table('servers')
->where('id', $yab->server_id) ->where('id', $yab->server_id)
@ -32,37 +139,27 @@ class YabsController extends Controller
Cache::forget("yabs.{$yab->id}"); Cache::forget("yabs.{$yab->id}");
return redirect()->route('yabs.index') return redirect()->route('yabs.index')
->with('success', 'YABS was deleted Successfully.'); ->with('success', 'YABs was deleted Successfully.');
}
return redirect()->route('yabs.index')
->with('error', 'YABS was not deleted.');
} }
public function chooseYabsCompare() public function chooseYabsCompare()
{ {
$all_yabs = Yabs::allYabs(); $all_yabs = Yabs::allYabs();
if (isset($all_yabs[1])) {
return view('yabs.choose-compare', compact('all_yabs')); return view('yabs.choose-compare', compact('all_yabs'));
} }
return redirect()->route('yabs.index') public function compareYabs($yabs1, $yabs2)
->with('error', 'You need atleast 2 YABS to do a compare');
}
public function compareYabs(string $yabs1, string $yabs2)
{ {
$yabs1_data = Yabs::yabs($yabs1); $yabs1_data = Yabs::yabs($yabs1);
if (is_null($yabs1_data)) { if (count($yabs1_data) === 0) {
abort(404); return response()->view('errors.404', array("status" => 404, "title" => "Page not found", "message" => "No YABs data was found for id '$yabs1'"), 404);
} }
$yabs2_data = Yabs::yabs($yabs2); $yabs2_data = Yabs::yabs($yabs2);
if (is_null($yabs2_data)) { if (count($yabs2_data) === 0) {
abort(404); return response()->view('errors.404', array("status" => 404, "title" => "Page not found", "message" => "No YABs data was found for id '$server2'"), 404);
} }
return view('yabs.compare', compact('yabs1_data', 'yabs2_data')); return view('yabs.compare', compact('yabs1_data', 'yabs2_data'));
@ -74,4 +171,5 @@ class YabsController extends Controller
return Yabs::buildYabsArray($all_yabs); return Yabs::buildYabsArray($all_yabs);
} }
} }

View file

@ -17,7 +17,7 @@ class Kernel extends HttpKernel
protected $middleware = [ protected $middleware = [
// \App\Http\Middleware\TrustHosts::class, // \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class, \Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class, \App\Http\Middleware\TrimStrings::class,

View file

@ -22,13 +22,7 @@ class DNS extends Model
public static function dnsCount() public static function dnsCount()
{ {
return Cache::remember('dns_count', now()->addMonth(1), function () { return Cache::remember('dns_count', now()->addMonth(1), function () {
return DNS::count(); return DB::table('d_n_s')->count();
}); });
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
} }

View file

@ -17,7 +17,7 @@ class DiskSpeed extends Model
protected $fillable = ['id', 'server_id', 'd_4k', 'd_4k_type', 'd_4k_as_mbps', 'd_64k', 'd_64k_type', 'd_64k_as_mbps', 'd_512k', 'd_512k_type', 'd_512k_as_mbps', 'd_1m', 'd_1m_type', 'd_1m_as_mbps']; protected $fillable = ['id', 'server_id', 'd_4k', 'd_4k_type', 'd_4k_as_mbps', 'd_64k', 'd_64k_type', 'd_64k_as_mbps', 'd_512k', 'd_512k_type', 'd_512k_as_mbps', 'd_1m', 'd_1m_type', 'd_1m_as_mbps'];
public function yabs(): \Illuminate\Database\Eloquent\Relations\BelongsTo public function yabs()
{ {
return $this->belongsTo(Yabs::class, 'id', 'id'); return $this->belongsTo(Yabs::class, 'id', 'id');
} }

View file

@ -5,7 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\DB;
class Domains extends Model class Domains extends Model
{ {
@ -23,12 +23,7 @@ class Domains extends Model
public static function allDomains() public static function allDomains()
{//All domains and relationships (no using joins) {//All domains and relationships (no using joins)
return Cache::remember("all_domains", now()->addMonth(1), function () { return Cache::remember("all_domains", now()->addMonth(1), function () {
$query = Domains::with(['provider', 'price', 'labels']); return Domains::with(['provider', 'price', 'labels', 'labels.label'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "domains.id"), $options[1]);
}
return $query->get();
}); });
} }
@ -36,28 +31,23 @@ class Domains extends Model
{//Single domains and relationships (no using joins) {//Single domains and relationships (no using joins)
return Cache::remember("domain.$domain_id", now()->addMonth(1), function () use ($domain_id) { return Cache::remember("domain.$domain_id", now()->addMonth(1), function () use ($domain_id) {
return Domains::where('id', $domain_id) return Domains::where('id', $domain_id)
->with(['provider', 'price', 'labels'])->first(); ->with(['provider', 'price', 'labels', 'labels.label'])->get();
}); });
} }
public function provider(): \Illuminate\Database\Eloquent\Relations\HasOne public function provider()
{ {
return $this->hasOne(Providers::class, 'id', 'provider_id'); return $this->hasOne(Providers::class, 'id', 'provider_id');
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }
public function labels(): \Illuminate\Database\Eloquent\Relations\HasMany public function labels()
{ {
return $this->hasMany(LabelsAssigned::class, 'service_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'service_id', 'id');
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
} }

View file

@ -13,7 +13,7 @@ class Home extends Model
{ {
use HasFactory; use HasFactory;
public static function homePageCacheForget(): void public static function homePageCacheForget()
{ {
Cache::forget('services_count');//Main page services_count cache Cache::forget('services_count');//Main page services_count cache
Cache::forget('due_soon');//Main page due_soon cache Cache::forget('due_soon');//Main page due_soon cache
@ -25,26 +25,26 @@ class Home extends Model
public static function servicesCount() public static function servicesCount()
{ {
return Cache::remember('services_count', now()->addHours(6), function () { return Cache::remember('services_count', now()->addHour(6), function () {
return DB::table('pricings') return DB::table('pricings')
->select('service_type', DB::raw('COUNT(*) as amount')) ->select('service_type', DB::raw('COUNT(*) as amount'))
->groupBy('service_type') ->groupBy('service_type')
->where('active', 1) ->where('active', '=', 1)
->get(); ->get();
}); });
} }
public static function dueSoonData() public static function dueSoonData()
{ {
return Cache::remember('due_soon', now()->addHours(6), function () { return Cache::remember('due_soon', now()->addHour(6), function () {
return DB::table('pricings as p') return DB::table('pricings as p')
->leftJoin('servers as s', 'p.service_id', 's.id') ->leftJoin('servers as s', 'p.service_id', '=', 's.id')
->leftJoin('shared_hosting as sh', 'p.service_id', 'sh.id') ->leftJoin('shared_hosting as sh', 'p.service_id', '=', 'sh.id')
->leftJoin('reseller_hosting as r', 'p.service_id', 'r.id') ->leftJoin('reseller_hosting as r', 'p.service_id', '=', 'r.id')
->leftJoin('domains as d', 'p.service_id', 'd.id') ->leftJoin('domains as d', 'p.service_id', '=', 'd.id')
->leftJoin('misc_services as ms', 'p.service_id', 'ms.id') ->leftJoin('misc_services as ms', 'p.service_id', '=', 'ms.id')
->leftJoin('seedboxes as sb', 'p.service_id', 'sb.id') ->leftJoin('seedboxes as sb', 'p.service_id', '=', 'sb.id')
->where('p.active', 1) ->where('p.active', '=', 1)
->orderBy('next_due_date', 'ASC') ->orderBy('next_due_date', 'ASC')
->limit(Session::get('due_soon_amount')) ->limit(Session::get('due_soon_amount'))
->get(['p.*', 's.hostname', 'd.domain', 'd.extension', 'r.main_domain as reseller', 'sh.main_domain', 'ms.name', 'sb.title']); ->get(['p.*', 's.hostname', 'd.domain', 'd.extension', 'r.main_domain as reseller', 'sh.main_domain', 'ms.name', 'sb.title']);
@ -53,13 +53,13 @@ class Home extends Model
public static function serverSummary() public static function serverSummary()
{ {
return Cache::remember('servers_summary', now()->addHours(6), function () { return Cache::remember('servers_summary', now()->addHour(6), function () {
$cpu_sum = DB::table('servers')->get()->where('active', 1)->sum('cpu'); $cpu_sum = DB::table('servers')->get()->where('active', '=', 1)->sum('cpu');
$ram_mb = DB::table('servers')->get()->where('active', 1)->sum('ram_as_mb'); $ram_mb = DB::table('servers')->get()->where('active', '=', 1)->sum('ram_as_mb');
$disk_gb = DB::table('servers')->get()->where('active', 1)->sum('disk_as_gb'); $disk_gb = DB::table('servers')->get()->where('active', '=', 1)->sum('disk_as_gb');
$bandwidth = DB::table('servers')->get()->where('active', 1)->sum('bandwidth'); $bandwidth = DB::table('servers')->get()->where('active', '=', 1)->sum('bandwidth');
$locations_sum = DB::table('servers')->get()->where('active', 1)->groupBy('location_id')->count(); $locations_sum = DB::table('servers')->get()->where('active', '=', 1)->groupBy('location_id')->count();
$providers_sum = DB::table('servers')->get()->where('active', 1)->groupBy('provider_id')->count(); $providers_sum = DB::table('servers')->get()->where('active', '=', 1)->groupBy('provider_id')->count();
return array( return array(
'cpu_sum' => $cpu_sum, 'cpu_sum' => $cpu_sum,
'ram_mb_sum' => $ram_mb, 'ram_mb_sum' => $ram_mb,
@ -73,15 +73,15 @@ class Home extends Model
public static function recentlyAdded() public static function recentlyAdded()
{ {
return Cache::remember('recently_added', now()->addHours(6), function () { return Cache::remember('recently_added', now()->addHour(6), function () {
return DB::table('pricings as p') return DB::table('pricings as p')
->leftJoin('servers as s', 'p.service_id', 's.id') ->leftJoin('servers as s', 'p.service_id', '=', 's.id')
->leftJoin('shared_hosting as sh', 'p.service_id', 'sh.id') ->leftJoin('shared_hosting as sh', 'p.service_id', '=', 'sh.id')
->leftJoin('reseller_hosting as r', 'p.service_id', 'r.id') ->leftJoin('reseller_hosting as r', 'p.service_id', '=', 'r.id')
->leftJoin('domains as d', 'p.service_id', 'd.id') ->leftJoin('domains as d', 'p.service_id', '=', 'd.id')
->leftJoin('misc_services as ms', 'p.service_id', 'ms.id') ->leftJoin('misc_services as ms', 'p.service_id', '=', 'ms.id')
->leftJoin('seedboxes as sb', 'p.service_id', 'sb.id') ->leftJoin('seedboxes as sb', 'p.service_id', '=', 'sb.id')
->where('p.active', 1) ->where('p.active', '=', 1)
->orderBy('created_at', 'DESC') ->orderBy('created_at', 'DESC')
->limit(Session::get('recently_added_amount')) ->limit(Session::get('recently_added_amount'))
->get(['p.*', 's.hostname', 'd.domain', 'd.extension', 'r.main_domain as reseller', 'sh.main_domain', 'ms.name', 'sb.title']); ->get(['p.*', 's.hostname', 'd.domain', 'd.extension', 'r.main_domain as reseller', 'sh.main_domain', 'ms.name', 'sb.title']);
@ -163,7 +163,7 @@ class Home extends Model
return array( return array(
'total_cost_weekly' => $total_cost_weekly, 'total_cost_weekly' => $total_cost_weekly,
'total_cost_monthly' => $total_cost_pm, 'total_cost_montly' => $total_cost_pm,
'total_cost_yearly' => $total_cost_yearly, 'total_cost_yearly' => $total_cost_yearly,
'inactive_count' => $inactive_count, 'inactive_count' => $inactive_count,
); );

View file

@ -6,7 +6,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class IPs extends Model class IPs extends Model
@ -17,18 +16,18 @@ class IPs extends Model
protected $keyType = 'string'; protected $keyType = 'string';
protected $fillable = ['id', 'service_id', 'address', 'is_ipv4', 'active', 'continent', 'country', 'region', 'city', 'org', 'isp', 'asn', 'timezone_gmt', 'fetched_at']; protected $fillable = ['id', 'active', 'service_id', 'address', 'is_ipv4'];
public $incrementing = false; public $incrementing = false;
public static function deleteIPsAssignedTo($service_id): void public static function deleteIPsAssignedTo($service_id)
{ {
DB::table('ips')->where('service_id', $service_id)->delete(); DB::table('ips')->where('service_id', '=', $service_id)->delete();
} }
public static function insertIP(string $service_id, string $address): IPs public static function insertIP(string $service_id, string $address)
{ {
return self::create( self::create(
[ [
'id' => Str::random(8), 'id' => Str::random(8),
'service_id' => $service_id, 'service_id' => $service_id,
@ -41,41 +40,11 @@ class IPs extends Model
public static function ipsForServer(string $server_id) public static function ipsForServer(string $server_id)
{ {
return Cache::remember("ip_addresses.$server_id", now()->addHours(1), function () use ($server_id) { return Cache::remember("ip_addresses.$server_id", now()->addHour(1), function () use ($server_id) {
return json_decode(DB::table('ips as i') return json_decode(DB::table('ips as i')
->where('i.service_id', $server_id) ->where('i.service_id', '=', $server_id)
->get(), true); ->get(), true);
}); });
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
public static function getUpdateIpInfo(IPs $IP): bool
{
$response = Http::get("https://ipwhois.app/json/{$IP->address}");
if ($response->ok()) {
$data = $response->json();
$IP->update([
'continent' => $data['continent'],
'country' => $data['country'],
'region' => $data['region'],
'city' => $data['city'],
'org' => $data['org'],
'isp' => $data['isp'],
'asn' => $data['asn'],
'timezone_gmt' => $data['timezone_gmt'],
'fetched_at' => now()
]);
}
return $response->ok();
}
} }

View file

@ -5,7 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Mockery\Exception; use Illuminate\Support\Facades\DB;
class Labels extends Model class Labels extends Model
{ {
@ -19,40 +19,33 @@ class Labels extends Model
protected $fillable = ['id', 'label', 'server_id', 'server_id_2', 'domain_id', 'domain_id_2', 'shared_id', 'shared_id_2']; protected $fillable = ['id', 'label', 'server_id', 'server_id_2', 'domain_id', 'domain_id_2', 'shared_id', 'shared_id_2'];
public static function deleteLabelsAssignedTo($service_id): void public static function deleteLabelsAssignedTo($service_id)
{ {
LabelsAssigned::where('service_id', $service_id)->delete(); DB::table('labels_assigned')->where('service_id', '=', $service_id)->delete();
} }
public static function deleteLabelAssignedAs($label_id): void public static function deleteLabelAssignedAs($label_id)
{ {
LabelsAssigned::where('label_id', $label_id)->delete(); DB::table('labels_assigned')->where('label_id', '=', $label_id)->delete();
} }
public static function insertLabelsAssigned(array $labels_array, string $service_id): void public static function insertLabelsAssigned(array $labels_array, string $service_id)
{ {
for ($i = 1; $i <= 4; $i++) { for ($i = 1; $i <= 4; $i++) {
if (!is_null($labels_array[($i - 1)])) { if (!is_null($labels_array[($i - 1)])) {
try { DB::insert('INSERT INTO labels_assigned (label_id, service_id) values (?, ?)', [$labels_array[($i - 1)], $service_id]);
LabelsAssigned::create([
'label_id' => $labels_array[($i - 1)],
'service_id' => $service_id
]);
} catch (Exception $exception) {
}
} }
} }
} }
public static function labelsCount(): int public static function labelsCount()
{ {
return Cache::remember('labels_count', now()->addMonth(1), function () { return Cache::remember('labels_count', now()->addMonth(1), function () {
return Labels::count(); return DB::table('labels')->count();
}); });
} }
public function assigned(): \Illuminate\Database\Eloquent\Relations\HasMany public function assigned()
{ {
return $this->hasMany(LabelsAssigned::class, 'label_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'label_id', 'id');
} }

View file

@ -11,15 +11,13 @@ class LabelsAssigned extends Model
public $incrementing = false; public $incrementing = false;
public $timestamps = false;
public $table = 'labels_assigned'; public $table = 'labels_assigned';
protected $fillable = ['label_id', 'service_id']; protected $fillable = ['label_id', 'service_id'];
protected $keyType = 'string'; protected $keyType = 'string';
public function label(): \Illuminate\Database\Eloquent\Relations\HasOne public function label()
{ {
return $this->hasOne(Labels::class, 'id', 'label_id'); return $this->hasOne(Labels::class, 'id', 'label_id');
} }

View file

@ -5,6 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class Locations extends Model class Locations extends Model
{ {
@ -19,7 +20,7 @@ class Locations extends Model
public static function allLocations(): array public static function allLocations(): array
{ {
return Cache::remember("locations", now()->addMonth(1), function () { return Cache::remember("locations", now()->addMonth(1), function () {
return self::orderBy('name')->get()->toArray(); return DB::table('locations')->get()->toArray();
}); });
} }
} }

View file

@ -2,11 +2,9 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
class Misc extends Model class Misc extends Model
{ {
@ -20,27 +18,10 @@ class Misc extends Model
protected $fillable = ['id', 'name', 'owned_since']; protected $fillable = ['id', 'name', 'owned_since'];
protected static function boot()
{
parent::boot();
static::addGlobalScope('order', function (Builder $builder) {
$array = Settings::orderByProcess(Session::get('sort_on') ?? 2);//created_at desc if not set
if (!in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$builder->orderBy($array[0], $array[1]);
}
});
}
public static function allMisc() public static function allMisc()
{//All misc and relationships (no using joins) {//All misc and relationships (no using joins)
return Cache::remember("all_misc", now()->addMonth(1), function () { return Cache::remember("all_misc", now()->addMonth(1), function () {
$query = Misc::with(['price']); return Misc::with(['price'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "misc_services.id"), $options[1]);
}
return $query->get();
}); });
} }
@ -48,11 +29,11 @@ class Misc extends Model
{//Single misc and relationships (no using joins) {//Single misc and relationships (no using joins)
return Cache::remember("misc.$misc_id", now()->addMonth(1), function () use ($misc_id) { return Cache::remember("misc.$misc_id", now()->addMonth(1), function () use ($misc_id) {
return Misc::where('id', $misc_id) return Misc::where('id', $misc_id)
->with(['price'])->first(); ->with(['price'])->get();
}); });
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }

View file

@ -17,7 +17,7 @@ class NetworkSpeed extends Model
protected $fillable = ['id', 'server_id', 'location', 'send', 'send_type', 'send_as_mbps', 'receive', 'receive_type', 'receive_as_mbps', 'created_at', 'updated_at']; protected $fillable = ['id', 'server_id', 'location', 'send', 'send_type', 'send_as_mbps', 'receive', 'receive_type', 'receive_as_mbps', 'created_at', 'updated_at'];
public function yabs(): \Illuminate\Database\Eloquent\Relations\BelongsTo public function yabs()
{ {
return $this->belongsTo(Yabs::class, 'id', 'id'); return $this->belongsTo(Yabs::class, 'id', 'id');
} }

View file

@ -1,65 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Note extends Model
{
use HasFactory;
public $incrementing = false;
protected $table = 'notes';
protected $keyType = 'string';
protected $fillable = ['id', 'service_id', 'note'];
public static function note(string $service_id): Note
{
return Cache::remember("note.$service_id", now()->addMonth(1), function () use ($service_id) {
return self::where('service_id', $service_id)->with(['server', 'shared', 'reseller', 'domain', 'dns', 'ip'])->first();
});
}
public static function allNotes()
{
return Cache::remember("all_notes", now()->addMonth(1), function () {
return self::with(['server', 'shared', 'reseller', 'domain', 'dns', 'ip'])->orderBy('created_at', 'desc')->get();
});
}
public function server(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Server::class, 'service_id', 'id');
}
public function shared(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Shared::class, 'service_id', 'id');
}
public function reseller(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Reseller::class, 'service_id', 'id');
}
public function domain(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Domains::class, 'service_id', 'id');
}
public function dns(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(DNS::class, 'service_id', 'id');
}
public function ip(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(IPs::class, 'service_id', 'id');
}
}

View file

@ -5,6 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class OS extends Model class OS extends Model
{ {
@ -16,10 +17,10 @@ class OS extends Model
protected $table = 'os'; protected $table = 'os';
public static function allOS() public static function allOS(): array
{ {
return Cache::remember("operating_systems", now()->addMonth(1), function () { return Cache::remember("operating_systems", now()->addMonth(1), function () {
return self::orderBy('name')->get(); return DB::table('os')->get()->toArray();
}); });
} }
} }

View file

@ -48,7 +48,7 @@ class Pricing extends Model
private static function getRates($currency): float private static function getRates($currency): float
{ {
$rate = self::refreshRates()->$currency; $rate = self::refreshRates()->$currency;
return $rate ?? 1.00; return $rate === null ? 1.00 : $rate;
} }
public static function getCurrencyList(): array public static function getCurrencyList(): array
@ -106,12 +106,11 @@ class Pricing extends Model
public function deletePricing($id): void public function deletePricing($id): void
{ {
DB::table('pricings')->where('service_id', $id)->delete(); DB::table('pricings')->where('service_id', '=', $id)->delete();
} }
public function insertPricing(int $type, string $service_id, string $currency, float $price, int $term, string $next_due_date, int $is_active = 1): Pricing public function insertPricing(int $type, string $service_id, string $currency, float $price, int $term, float $as_usd, string $next_due_date, int $is_active = 1)
{ {
$as_usd = $this->convertToUSD($price, $currency);
return self::create([ return self::create([
'service_type' => $type, 'service_type' => $type,
'service_id' => $service_id, 'service_id' => $service_id,
@ -121,13 +120,12 @@ class Pricing extends Model
'as_usd' => $as_usd, 'as_usd' => $as_usd,
'usd_per_month' => $this->costAsPerMonth($as_usd, $term), 'usd_per_month' => $this->costAsPerMonth($as_usd, $term),
'next_due_date' => $next_due_date, 'next_due_date' => $next_due_date,
'active' => $is_active 'active' => ($is_active) ? 1 : 0
]); ]);
} }
public function updatePricing(string $service_id, string $currency, float $price, int $term, string $next_due_date, int $is_active = 1): int public function updatePricing(string $service_id, string $currency, float $price, int $term, float $as_usd, string $next_due_date, int $is_active = 1)
{ {
$as_usd = $this->convertToUSD($price, $currency);
return DB::table('pricings') return DB::table('pricings')
->where('service_id', $service_id) ->where('service_id', $service_id)
->update([ ->update([
@ -137,14 +135,15 @@ class Pricing extends Model
'as_usd' => $as_usd, 'as_usd' => $as_usd,
'usd_per_month' => $this->costAsPerMonth($as_usd, $term), 'usd_per_month' => $this->costAsPerMonth($as_usd, $term),
'next_due_date' => $next_due_date, 'next_due_date' => $next_due_date,
'active' => $is_active 'active' => ($is_active) ? 1 : 0
]); ]);
} }
public static function allPricing() public static function allPricing()
{ {
return Cache::remember('all_active_pricing', now()->addWeek(1), function () { return Cache::remember('all_pricing', now()->addWeek(1), function () {
return Pricing::where('active', 1)->get(); return DB::table('pricings')
->get();
}); });
} }

View file

@ -20,24 +20,24 @@ class Providers extends Model
public static function allProviders(): array public static function allProviders(): array
{ {
return Cache::remember("providers", now()->addMonth(1), function () { return Cache::remember("providers", now()->addMonth(1), function () {
return self::orderBy('name')->get()->toArray(); return DB::table('providers')->get()->toArray();
}); });
} }
public static function showServicesForProvider($provider): array public static function showServicesForProvider($provider): array
{ {
$servers = DB::table('servers as s') $servers = DB::table('servers as s')
->where('s.provider_id', $provider) ->where('s.provider_id', '=', $provider)
->get(['s.id', 's.hostname']) ->get(['s.id', 's.hostname'])
->toArray(); ->toArray();
$shared = DB::table('shared_hosting as s') $shared = DB::table('shared_hosting as s')
->where('s.provider_id', $provider) ->where('s.provider_id', '=', $provider)
->get(['s.id', 's.main_domain as main_domain_shared']) ->get(['s.id', 's.main_domain as main_domain_shared'])
->toArray(); ->toArray();
$reseller = DB::table('reseller_hosting as r') $reseller = DB::table('reseller_hosting as r')
->where('r.provider_id', $provider) ->where('r.provider_id', '=', $provider)
->get(['r.id', 'r.main_domain as main_domain_reseller']) ->get(['r.id', 'r.main_domain as main_domain_reseller'])
->toArray(); ->toArray();

View file

@ -2,12 +2,10 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class Reseller extends Model class Reseller extends Model
{ {
@ -21,66 +19,44 @@ class Reseller extends Model
public $incrementing = false; public $incrementing = false;
protected static function boot()
{
parent::boot();
static::addGlobalScope('order', function (Builder $builder) {
$array = Settings::orderByProcess(Session::get('sort_on') ?? 2);//created_at desc if not set
if (!in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$builder->orderBy($array[0], $array[1]);
}
});
}
public static function allResellerHosting() public static function allResellerHosting()
{//All reseller hosting and relationships (no using joins) {//All reseller hosting and relationships (no using joins)
return Cache::remember("all_reseller", now()->addMonth(1), function () { return Cache::remember("all_reseller", now()->addMonth(1), function () {
$query = Reseller::with(['location', 'provider', 'price', 'ips', 'labels']); return Reseller::with(['location', 'provider', 'price', 'ips', 'labels', 'labels.label'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "reseller_hosting.id"), $options[1]);
}
return $query->get();
}); });
} }
public static function resellerHosting(string $reseller_id) public static function resellerHosting(string $shared_id)
{//Single reseller hosting and relationships (no using joins) {//Single reseller hosting and relationships (no using joins)
return Cache::remember("reseller_hosting.$reseller_id", now()->addMonth(1), function () use ($reseller_id) { return Cache::remember("reseller_hosting.$shared_id", now()->addMonth(1), function () use ($shared_id) {
return Reseller::where('id', $reseller_id) return Reseller::where('id', $shared_id)
->with(['location', 'provider', 'price', 'ips', 'labels'])->first(); ->with(['location', 'provider', 'price', 'ips', 'labels', 'labels.label'])->get();
}); });
} }
public function ips(): \Illuminate\Database\Eloquent\Relations\HasMany public function ips()
{ {
return $this->hasMany(IPs::class, 'service_id', 'id'); return $this->hasMany(IPs::class, 'service_id', 'id');
} }
public function location(): \Illuminate\Database\Eloquent\Relations\HasOne public function location()
{ {
return $this->hasOne(Locations::class, 'id', 'location_id'); return $this->hasOne(Locations::class, 'id', 'location_id');
} }
public function provider(): \Illuminate\Database\Eloquent\Relations\HasOne public function provider()
{ {
return $this->hasOne(Providers::class, 'id', 'provider_id'); return $this->hasOne(Providers::class, 'id', 'provider_id');
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }
public function labels(): \Illuminate\Database\Eloquent\Relations\HasMany public function labels()
{ {
return $this->hasMany(LabelsAssigned::class, 'service_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'service_id', 'id');
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
} }

View file

@ -2,11 +2,10 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\DB;
class SeedBoxes extends Model class SeedBoxes extends Model
{ {
@ -20,27 +19,10 @@ class SeedBoxes extends Model
protected $fillable = ['id', 'active', 'title', 'hostname', 'seed_box_type', 'provider_id', 'location_id', 'bandwidth', 'port_speed', 'disk', 'disk_type', 'disk_as_gb', 'was_promo', 'owned_since']; protected $fillable = ['id', 'active', 'title', 'hostname', 'seed_box_type', 'provider_id', 'location_id', 'bandwidth', 'port_speed', 'disk', 'disk_type', 'disk_as_gb', 'was_promo', 'owned_since'];
protected static function boot()
{
parent::boot();
static::addGlobalScope('order', function (Builder $builder) {
$array = Settings::orderByProcess(Session::get('sort_on') ?? 2);//created_at desc if not set
if (!in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$builder->orderBy($array[0], $array[1]);
}
});
}
public static function allSeedboxes() public static function allSeedboxes()
{//All seedboxes and relationships (no using joins) {//All seedboxes and relationships (no using joins)
return Cache::remember("all_seedboxes", now()->addMonth(1), function () { return Cache::remember("all_seedboxes", now()->addMonth(1), function () {
$query = SeedBoxes::with(['location', 'provider', 'price']); return SeedBoxes::with(['location', 'provider', 'price', 'labels.label'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "seedboxes.id"), $options[1]);
}
return $query->get();
}); });
} }
@ -48,26 +30,26 @@ class SeedBoxes extends Model
{//Single seedbox and relationships (no using joins) {//Single seedbox and relationships (no using joins)
return Cache::remember("seedbox.$seedbox_id", now()->addMonth(1), function () use ($seedbox_id) { return Cache::remember("seedbox.$seedbox_id", now()->addMonth(1), function () use ($seedbox_id) {
return SeedBoxes::where('id', $seedbox_id) return SeedBoxes::where('id', $seedbox_id)
->with(['location', 'provider', 'price'])->first(); ->with(['location', 'provider', 'price', 'labels.label'])->get();
}); });
} }
public function location(): \Illuminate\Database\Eloquent\Relations\HasOne public function location()
{ {
return $this->hasOne(Locations::class, 'id', 'location_id'); return $this->hasOne(Locations::class, 'id', 'location_id');
} }
public function provider(): \Illuminate\Database\Eloquent\Relations\HasOne public function provider()
{ {
return $this->hasOne(Providers::class, 'id', 'provider_id'); return $this->hasOne(Providers::class, 'id', 'provider_id');
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }
public function labels(): \Illuminate\Database\Eloquent\Relations\HasMany public function labels()
{ {
return $this->hasMany(LabelsAssigned::class, 'service_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'service_id', 'id');
} }

View file

@ -2,11 +2,11 @@
namespace App\Models; namespace App\Models;
use App\Process;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Builder;
class Server extends Model class Server extends Model
{ {
@ -26,56 +26,35 @@ class Server extends Model
*/ */
private $id; private $id;
protected static function boot()
{
parent::boot();
static::addGlobalScope('order', function (Builder $builder) {
$array = Settings::orderByProcess(Session::get('sort_on') ?? 2);//created_at desc if not set
if (!in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$builder->orderBy($array[0], $array[1]);
}
});
}
public static function allServers() public static function allServers()
{//All servers and relationships (no using joins) {//All servers and relationships (no using joins)
return Cache::remember("all_servers", now()->addMonth(1), function () { return Cache::remember("all_servers", now()->addMonth(1), function () {
$query = Server::with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels']); return Server::with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'labels.label'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "servers.id"), $options[1]);
}
return $query->get();
}); });
} }
public static function server(string $server_id): Server public static function server(string $server_id)
{//Single server and relationships (no using joins) {//Single server and relationships (no using joins)
return Cache::remember("server.$server_id", now()->addMonth(1), function () use ($server_id) { return Cache::remember("server.$server_id", now()->addMonth(1), function () use ($server_id) {
return Server::where('id', $server_id) return Server::where('id', $server_id)
->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels'])->first(); ->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'labels.label'])->get();
}); });
} }
public static function allActiveServers() public static function allActiveServers()
{//All ACTIVE servers and relationships replaces activeServersDataIndexPage() {//All ACTIVE servers and relationships replaces activeServersDataIndexPage()
return Cache::remember("all_active_servers", now()->addMonth(1), function () { return Cache::remember("all_active_servers", now()->addMonth(1), function () {
$query = Server::where('active', 1) return Server::where('active', '=', 1)
->with(['location', 'provider', 'os', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'price']); ->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'labels.label'])
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) { ->get();
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "servers.id"), $options[1]);
}
return $query->get();
}); });
} }
public static function allNonActiveServers() public static function allNonActiveServers()
{//All NON ACTIVE servers and relationships replaces nonActiveServersDataIndexPage() {//All NON ACTIVE servers and relationships replaces nonActiveServersDataIndexPage()
return Cache::remember("non_active_servers", now()->addMonth(1), function () { return Cache::remember("non_active_servers", now()->addMonth(1), function () {
return Server::where('active', 0) return Server::where('active', '=', 0)
->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels']) ->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'labels.label'])
->get(); ->get();
}); });
} }
@ -83,61 +62,116 @@ class Server extends Model
public static function allPublicServers() public static function allPublicServers()
{//server data that will be publicly viewable (values in settings) {//server data that will be publicly viewable (values in settings)
return Cache::remember("public_server_data", now()->addMonth(1), function () { return Cache::remember("public_server_data", now()->addMonth(1), function () {
return Server::where('show_public', 1) return Server::where('show_public', '=', 1)
->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels']) ->with(['location', 'provider', 'os', 'price', 'ips', 'yabs', 'yabs.disk_speed', 'yabs.network_speed', 'labels', 'labels.label'])
->get(); ->get();
}); });
} }
public static function serviceServerType(int $type, bool $short = true): string public static function serviceServerType($type)
{ {
if ($type === 1) { if ($type === 1) {
return "KVM"; return "KVM";
} elseif ($type === 2) { } elseif ($type === 2) {
return "OVZ"; return "OVZ";
} elseif ($type === 3) { } elseif ($type === 3) {
if (!$short) {
return "Dedicated";
}
return "DEDI"; return "DEDI";
} elseif ($type === 4) { } elseif ($type === 4) {
return "LXC"; return "LXC";
} elseif ($type === 6) { } elseif ($type === 6) {
return "VMware"; return "VMware";
} elseif ($type === 7) {
return "NAT";
} else { } else {
if (!$short) {
return "Semi-dedicated";
}
return "SEMI-DEDI"; return "SEMI-DEDI";
} }
} }
public static function osIntToIcon(int $os, string $os_name): string public static function osIntToIcon(int $os, string $os_name)
{ {
if ($os === 1) {//None if ($os === 1) {//None
return "<i class='fas fa-expand' title='{$os_name}'></i>"; return "<i class='fas fa-expand' title='{$os_name}'></i>";
} else if ($os <= 3) {//Centos } else if ($os <= 3) {//Centos
return "<i class='fa-brands fa-centos os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-centos os-icon' title='{$os_name}'></i>";
} elseif (($os > 7 && $os <= 10) || $os === 44) {//Debian } elseif ($os > 3 && $os <= 6) {//Debain
return "<i class='fa-brands fa-linux os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-linux os-icon' title='{$os_name}'></i>";
} elseif (($os > 11 && $os < 15) || $os === 43) {//Fedora } elseif ($os > 6 && $os < 10) {//Fedora
return "<i class='fa-brands fa-fedora os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-fedora os-icon' title='{$os_name}'></i>";
} elseif (($os > 14 && $os < 18) || $os === 46) {//FreeBSD } elseif ($os > 10 && $os < 13) {//FreeBSD
return "<i class='fa-brands fa-linux os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-linux os-icon' title='{$os_name}'></i>";
} elseif (($os > 17 && $os < 21) || $os === 42) {//OpenBSD } elseif ($os > 13 && $os < 16) {//OpenBSD
return "<i class='fa-brands fa-linux os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-linux os-icon' title='{$os_name}'></i>";
} elseif (($os > 25 && $os < 32) || $os === 41) {//Ubuntu } elseif ($os > 15 && $os < 21) {//Ubuntu
return "<i class='fa-brands fa-ubuntu os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-ubuntu os-icon' title='{$os_name}'></i>";
} elseif (($os > 32 && $os < 38) || $os === 40) {//Windows } elseif ($os > 20 && $os < 26) {//Windows
return "<i class='fa-brands fa-windows os-icon' title='{$os_name}'></i>"; return "<i class='fab fa-windows os-icon' title='{$os_name}'></i>";
} else {//OTHER ISO CUSTOM etc } else {//OTHER ISO CUSTOM etc
return "<i class='fa-solid fa-compact-disc os-icon' title='{$os_name}'></i>"; return "<i class='fas fa-compact-disc os-icon' title='{$os_name}'></i>";
} }
} }
public static function tableRowCompare(string $val1, string $val2, string $value_type = '', bool $is_int = true): string public static function osIdAsString($os)
{
if ($os === "0") {
return "None";
} elseif ($os === "1") {
return "CentOS 7";
} elseif ($os === "2") {
return "CentOS 8";
} elseif ($os === "3") {
return "CentOS";
} elseif ($os === "4") {
return "Debian 9";
} elseif ($os === "5") {
return "Debian 10";
} elseif ($os === "6") {
return "Debian";
} elseif ($os === "7") {
return "Fedora 32";
} elseif ($os === "8") {
return "Fedora 33";
} elseif ($os === "9") {
return "Fedora";
} elseif ($os === "10") {
return "FreeBSD 11.4";
} elseif ($os === "11") {
return "FreeBSD 12.1";
} elseif ($os === "12") {
return "FreeBSD";
} elseif ($os === "13") {
return "OpenBSD 6.7";
} elseif ($os === "14") {
return "OpenBSD 6.8";
} elseif ($os === "15") {
return "OpenBSD";
} elseif ($os == "16") {
return "Ubuntu 16.04";
} elseif ($os === "17") {
return "Ubuntu 18.04";
} elseif ($os === "18") {
return "Ubuntu 20.04";
} elseif ($os === "19") {
return "Ubuntu 20.10";
} elseif ($os === "20") {
return "Ubuntu";
} elseif ($os === "21") {
return "Windows Server 2008";
} elseif ($os === "22") {
return "Windows Server 2012";
} elseif ($os === "23") {
return "Windows Server 2016";
} elseif ($os === "24") {
return "Windows Server 2019";
} elseif ($os === "25") {
return "Windows 10";
} elseif ($os === "26") {
return "Custom";
} elseif ($os === "27") {
return "Other";
} else {
return "Unknown";
}
}
public static function tableRowCompare(string $val1, string $val2, string $value_type = '', bool $is_int = true)
{ {
//<td class="td-nowrap plus-td">+303<span class="data-type">MBps</span></td> //<td class="td-nowrap plus-td">+303<span class="data-type">MBps</span></td>
$str = '<td class="td-nowrap '; $str = '<td class="td-nowrap ';
@ -182,7 +216,6 @@ class Server extends Model
Cache::forget('all_pricing');//All pricing Cache::forget('all_pricing');//All pricing
Cache::forget('services_count_all'); Cache::forget('services_count_all');
Cache::forget('pricing_breakdown'); Cache::forget('pricing_breakdown');
Cache::forget('all_active_pricing');
} }
public static function serverSpecificCacheForget(string $server_id): void public static function serverSpecificCacheForget(string $server_id): void
@ -192,48 +225,45 @@ class Server extends Model
} }
public static function serverYabsAmount(string $server_id): int public static function serverYabsAmount(string $server_id): int
{//Returns amount of YABS a server has {//Returns amount of YABs a server has
return Yabs::where('server_id', $server_id)->count(); return DB::table('yabs')
->where('server_id', '=', $server_id)
->get()->count();
} }
public function yabs(): \Illuminate\Database\Eloquent\Relations\HasMany public function yabs()
{ {
return $this->hasMany(Yabs::class, 'server_id', 'id'); return $this->hasMany(Yabs::class, 'server_id', 'id');
} }
public function ips(): \Illuminate\Database\Eloquent\Relations\HasMany public function ips()
{ {
return $this->hasMany(IPs::class, 'service_id', 'id'); return $this->hasMany(IPs::class, 'service_id', 'id');
} }
public function location(): \Illuminate\Database\Eloquent\Relations\HasOne public function location()
{ {
return $this->hasOne(Locations::class, 'id', 'location_id'); return $this->hasOne(Locations::class, 'id', 'location_id');
} }
public function provider(): \Illuminate\Database\Eloquent\Relations\HasOne public function provider()
{ {
return $this->hasOne(Providers::class, 'id', 'provider_id'); return $this->hasOne(Providers::class, 'id', 'provider_id');
} }
public function os(): \Illuminate\Database\Eloquent\Relations\HasOne public function os()
{ {
return $this->hasOne(OS::class, 'id', 'os_id'); return $this->hasOne(OS::class, 'id', 'os_id');
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }
public function labels(): \Illuminate\Database\Eloquent\Relations\HasMany public function labels()
{ {
return $this->hasMany(LabelsAssigned::class, 'service_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'service_id', 'id');
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
} }

View file

@ -5,6 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
class Settings extends Model class Settings extends Model
@ -13,65 +14,36 @@ class Settings extends Model
protected $table = 'settings'; protected $table = 'settings';
protected $fillable = ['id', 'show_versions_footer', 'show_servers_public', 'show_server_value_ip', 'show_server_value_hostname', 'show_server_value_provider', 'show_server_value_location', 'show_server_value_price', 'show_server_value_yabs', 'save_yabs_as_txt', 'default_currency', 'default_server_os', 'due_soon_amount', 'recently_added_amount', 'dark_mode', 'dashboard_currency', 'sort_on', 'favicon']; protected $fillable = ['id', 'show_versions_footer', 'show_servers_public'];
public static function getSettings(): Settings public static function getSettings()
{ {
return Cache::remember('settings', now()->addWeek(1), function () { return Cache::remember('settings', now()->addWeek(1), function () {
$settings = self::where('id', 1)->first(); return DB::table('settings')
if (is_null($settings)){ ->where('id', '=', 1)
$settings = Settings::create(); ->get();
}
return $settings;
}); });
} }
public static function setSettingsToSession($settings): void public static function setSettingsToSession($settings): void
{ {
Session::put('dark_mode', $settings->dark_mode ?? 0); Session::put('dark_mode', $settings[0]->dark_mode ?? 0);
Session::put('timer_version_footer', $settings->show_versions_footer ?? 1); Session::put('timer_version_footer', $settings[0]->show_versions_footer ?? 1);
Session::put('show_servers_public', $settings->show_servers_public ?? 0); Session::put('show_servers_public', $settings[0]->show_servers_public ?? 0);
Session::put('show_server_value_ip', $settings->show_server_value_ip ?? 0); Session::put('show_server_value_ip', $settings[0]->show_server_value_ip ?? 0);
Session::put('show_server_value_hostname', $settings->show_server_value_hostname ?? 0); Session::put('show_server_value_hostname', $settings[0]->show_server_value_hostname ?? 0);
Session::put('show_server_value_price', $settings->show_server_value_price ?? 0); Session::put('show_server_value_price', $settings[0]->show_server_value_price ?? 0);
Session::put('show_server_value_yabs', $settings->show_server_value_yabs ?? 0); Session::put('show_server_value_yabs', $settings[0]->show_server_value_yabs ?? 0);
Session::put('show_server_value_provider', $settings->show_server_value_provider ?? 0); Session::put('show_server_value_provider', $settings[0]->show_server_value_provider ?? 0);
Session::put('show_server_value_location', $settings->show_server_value_location ?? 0); Session::put('show_server_value_location', $settings[0]->show_server_value_location ?? 0);
Session::put('save_yabs_as_txt', $settings->save_yabs_as_txt ?? 0); Session::put('save_yabs_as_txt', $settings[0]->save_yabs_as_txt ?? 0);
Session::put('default_currency', $settings->default_currency ?? 'USD'); Session::put('default_currency', $settings[0]->default_currency ?? 'USD');
Session::put('default_server_os', $settings->default_server_os ?? 1); Session::put('default_server_os', $settings[0]->default_server_os ?? 1);
Session::put('due_soon_amount', $settings->due_soon_amount ?? 6); Session::put('due_soon_amount', $settings[0]->due_soon_amount ?? 6);
Session::put('recently_added_amount', $settings->recently_added_amount ?? 6); Session::put('recently_added_amount', $settings[0]->recently_added_amount ?? 6);
Session::put('dashboard_currency', $settings->dashboard_currency ?? 'USD'); Session::put('dashboard_currency', $settings[0]->dashboard_currency ?? 'USD');
Session::put('sort_on', $settings->sort_on ?? 1);
Session::put('favicon', $settings->favicon ?? 'favicon.ico');
Session::save(); Session::save();
} }
public static function orderByProcess(int $value): array
{
if ($value === 1) {//created_at ASC
return ['created_at', 'asc'];
} elseif ($value === 2) {//created_at DESC
return ['created_at', 'desc'];
} elseif ($value === 3) {//next_due_date ASC
return ['next_due_date', 'asc'];
} elseif ($value === 4) {//next_due_date DESC
return ['next_due_date', 'desc'];
} elseif ($value === 5) {//as_usd ASC
return ['as_usd', 'asc'];
} elseif ($value === 6) {//as_usd DESC
return ['as_usd', 'desc'];
} elseif ($value === 7) {//owned_since ASC
return ['owned_since', 'asc'];
} elseif ($value === 8) {//owned_since DESC
return ['owned_since', 'desc'];
} elseif ($value === 9) {//updated_at ASC
return ['updated_at', 'asc'];
} elseif ($value === 10) {//updated_at DESC
return ['updated_at', 'desc'];
}
return ['created_at', 'desc'];
}
} }

View file

@ -2,11 +2,10 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\DB;
class Shared extends Model class Shared extends Model
{ {
@ -20,27 +19,10 @@ class Shared extends Model
public $incrementing = false; public $incrementing = false;
protected static function boot()
{
parent::boot();
static::addGlobalScope('order', function (Builder $builder) {
$array = Settings::orderByProcess(Session::get('sort_on') ?? 2);//created_at desc if not set
if (!in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$builder->orderBy($array[0], $array[1]);
}
});
}
public static function allSharedHosting() public static function allSharedHosting()
{//All shared hosting and relationships (no using joins) {//All shared hosting and relationships (no using joins)
return Cache::remember("all_shared", now()->addMonth(1), function () { return Cache::remember("all_shared", now()->addMonth(1), function () {
$query = Shared::with(['location', 'provider', 'price', 'ips', 'labels']); return Shared::with(['location', 'provider', 'price', 'ips', 'labels', 'labels.label'])->get();
if (in_array(Session::get('sort_on'), [3, 4, 5, 6], true)) {
$options = Settings::orderByProcess(Session::get('sort_on'));
$query->orderBy(Pricing::select("pricings.$options[0]")->whereColumn("pricings.service_id", "shared_hosting.id"), $options[1]);
}
return $query->get();
}); });
} }
@ -48,38 +30,33 @@ class Shared extends Model
{//Single shared hosting and relationships (no using joins) {//Single shared hosting and relationships (no using joins)
return Cache::remember("shared_hosting.$shared_id", now()->addMonth(1), function () use ($shared_id) { return Cache::remember("shared_hosting.$shared_id", now()->addMonth(1), function () use ($shared_id) {
return Shared::where('id', $shared_id) return Shared::where('id', $shared_id)
->with(['location', 'provider', 'price', 'ips', 'labels'])->first(); ->with(['location', 'provider', 'price', 'ips', 'labels', 'labels.label'])->get();
}); });
} }
public function ips(): \Illuminate\Database\Eloquent\Relations\HasMany public function ips()
{ {
return $this->hasMany(IPs::class, 'service_id', 'id'); return $this->hasMany(IPs::class, 'service_id', 'id');
} }
public function location(): \Illuminate\Database\Eloquent\Relations\HasOne public function location()
{ {
return $this->hasOne(Locations::class, 'id', 'location_id'); return $this->hasOne(Locations::class, 'id', 'location_id');
} }
public function provider(): \Illuminate\Database\Eloquent\Relations\HasOne public function provider()
{ {
return $this->hasOne(Providers::class, 'id', 'provider_id'); return $this->hasOne(Providers::class, 'id', 'provider_id');
} }
public function price(): \Illuminate\Database\Eloquent\Relations\HasOne public function price()
{ {
return $this->hasOne(Pricing::class, 'service_id', 'id'); return $this->hasOne(Pricing::class, 'service_id', 'id');
} }
public function labels(): \Illuminate\Database\Eloquent\Relations\HasMany public function labels()
{ {
return $this->hasMany(LabelsAssigned::class, 'service_id', 'id'); return $this->hasMany(LabelsAssigned::class, 'service_id', 'id');
} }
public function note(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Note::class, 'service_id', 'id');
}
} }

View file

@ -2,13 +2,10 @@
namespace App\Models; namespace App\Models;
use DateTime;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class Yabs extends Model class Yabs extends Model
{ {
@ -20,13 +17,13 @@ class Yabs extends Model
protected $table = 'yabs'; protected $table = 'yabs';
protected $fillable = ['id', 'server_id', 'has_ipv6', 'aes', 'vm', 'output_date', 'cpu_cores', 'cpu_freq', 'cpu_model', 'ram', 'ram_type', 'ram_mb', 'disk', 'disk_type', 'disk_gb', 'gb5_single', 'gb5_multi', 'gb5_id', 'gb6_single', 'gb6_multi', 'gb6_id', '4k', '4k_type', '4k_as_mbps', '64k', '64k_type', '64k_as_mbps', '512k', '512k_type', '512k_as_mbps', '1m', '1m_type', '1m_as_mbps', 'location', 'send', 'send_type', 'send_as_mbps', 'receive', 'receive_type', 'receive_as_mbps', 'uptime', 'distro', 'kernel', 'swap', 'swap_type', 'swap_mb']; protected $fillable = ['id', 'server_id', 'has_ipv6', 'aes', 'vm', 'output_date', 'cpu_cores', 'cpu_freq', 'cpu_model', 'ram', 'ram_type', 'ram_mb', 'disk', 'disk_type', 'disk_gb', 'gb5_single', 'gb5_multi', 'gb5_id', '4k', '4k_type', '4k_as_mbps', '64k', '64k_type', '64k_as_mbps', '512k', '512k_type', '512k_as_mbps', '1m', '1m_type', '1m_as_mbps', 'location', 'send', 'send_type', 'send_as_mbps', 'receive', 'receive_type', 'receive_as_mbps', 'uptime', 'distro', 'kernel', 'swap', 'swap_type', 'swap_mb'];
public static function yabs(string $yabs_id) public static function yabs(string $yabs_id)
{ {
return Cache::remember("yabs.$yabs_id", now()->addMonth(1), function () use ($yabs_id) { return Cache::remember("yabs.$yabs_id", now()->addMonth(1), function () use ($yabs_id) {
return self::where('id', $yabs_id)->with(['server', 'disk_speed', 'network_speed', 'server.location', 'server.provider']) return self::where('id', $yabs_id)->with(['server', 'disk_speed', 'network_speed', 'server.location', 'server.provider'])
->first(); ->get();
}); });
} }
@ -38,17 +35,17 @@ class Yabs extends Model
}); });
} }
public function server(): \Illuminate\Database\Eloquent\Relations\HasOne public function server()
{ {
return $this->hasOne(Server::class, 'id', 'server_id'); return $this->hasOne(Server::class, 'id', 'server_id');
} }
public function disk_speed(): \Illuminate\Database\Eloquent\Relations\HasOne public function disk_speed()
{ {
return $this->hasOne(DiskSpeed::class, 'id', 'id'); return $this->hasOne(DiskSpeed::class, 'id', 'id');
} }
public function network_speed(): \Illuminate\Database\Eloquent\Relations\HasMany public function network_speed()
{ {
return $this->hasMany(NetworkSpeed::class, 'id', 'id'); return $this->hasMany(NetworkSpeed::class, 'id', 'id');
} }
@ -57,20 +54,20 @@ class Yabs extends Model
{ {
$speed_tests = []; $speed_tests = [];
foreach ($data->network_speed as $ns) { foreach ($data->network_speed as $ns) {
$speed_tests[] = [ $speed_tests[] = array(
'location' => $ns->location, 'location' => $ns->location,
'send' => $ns->send . ' ' . $ns->send_type, 'send' => $ns->send . ' ' . $ns->send_type,
'receive' => $ns->receive . ' ' . $ns->receive_type, 'receive' => $ns->receive . ' ' . $ns->receive_type,
]; );
} }
return [ return array(
'date_time' => $data->output_date, 'date_time' => $data->output_date,
'location' => $data->server->location->name, 'location' => $data->server->location->name,
'provider' => $data->server->provider->name, 'provider' => $data->server->provider->name,
'uptime' => $data->uptime, 'uptime' => $data->uptime,
'distro' => $data->distro, 'distro' => $data->distro,
'kernel' => $data->kernel, 'kernel' => $data->kernel,
'cpu' => [ 'cpu' => array(
'cores' => $data->cpu_cores, 'cores' => $data->cpu_cores,
'speed_mhz' => $data->cpu_freq, 'speed_mhz' => $data->cpu_freq,
'model' => $data->cpu_model, 'model' => $data->cpu_model,
@ -78,260 +75,30 @@ class Yabs extends Model
'vm' => $data->vm === 1, 'vm' => $data->vm === 1,
'GB5_single' => $data->gb5_single, 'GB5_single' => $data->gb5_single,
'GB5_multi' => $data->gb5_multi, 'GB5_multi' => $data->gb5_multi,
], ),
'ram' => [ 'ram' => array(
'amount' => $data->ram . ' ' . $data->ram_type, 'amount' => $data->ram . ' ' . $data->ram_type,
'mb' => $data->ram_mb, 'mb' => $data->ram_mb,
'swap' => [ 'swap' => array(
'amount' => $data->swap ?? null . ' ' . $data->swap_type ?? null, 'amount' => $data->swap ?? null . ' ' . $data->swap_type ?? null,
'mb' => $data->swap_mb ?? null, 'mb' => $data->swap_mb ?? null,
], ),
], ),
'disk' => [ 'disk' => array(
'amount' => $data->disk . ' ' . $data->disk_type, 'amount' => $data->disk . ' ' . $data->disk_type,
'gb' => $data->disk_gb, 'gb' => $data->disk_gb,
'speed_tests' => [ 'speed_tests' => array(
'4k' => $data->disk_speed->d_4k . ' ' . $data->disk_speed->d_4k_type, '4k' => $data->disk_speed->d_4k . ' ' . $data->disk_speed->d_4k_type,
'64k' => $data->disk_speed->d_64k . ' ' . $data->disk_speed->d_64k_type, '64k' => $data->disk_speed->d_64k . ' ' . $data->disk_speed->d_64k_type,
'512k' => $data->disk_speed->d_512k . ' ' . $data->disk_speed->d_512k_type, '512k' => $data->disk_speed->d_512k . ' ' . $data->disk_speed->d_512k_type,
'1m' => $data->disk_speed->d_1m . ' ' . $data->disk_speed->d_1m_type, '1m' => $data->disk_speed->d_1m . ' ' . $data->disk_speed->d_1m_type,
], ),
], ),
'network' => [ 'network' => array(
'has_ipv6' => $data->has_ipv6 === 1, 'has_ipv6' => $data->has_ipv6 === 1,
'speed_tests' => $speed_tests 'speed_tests' => $speed_tests
], ),
]; );
}
public static function speedAsMbps(string $string): float
{
$data = explode(" ", $string);
if ($data[0] === 'busy') {
return 0;
}
if ($data[1] === "Gbits/sec") {
return $data[0] * 1000;
} else if ($data[1] === "Mbits/sec") {
return $data[0];
} else {//Kbps
return $data[0] / 1000;
}
}
public static function speedType(string $string): string
{
$data = explode(" ", $string);
if ($data[0] === 'busy') {
return "MBps";
}
if ($data[1] === "Gbits/sec") {
return "GBps";
} else if ($data[1] === "Mbits/sec") {
return "MBps";
} else {//Kbps
return "KBps";
}
}
public static function speedAsFloat(string $string): float
{
$data = explode(" ", $string);
if ($data[0] === 'busy') {
return 0;
}
return (float)$data[0];
}
public static function formatRunTime(string $date): string
{
return DateTime::createFromFormat('Ymd-His', $date)->format('Y-m-d H:i:s');
}
public static function gb5IdFromURL(string $url): int
{
return str_replace("https://browser.geekbench.com/v5/cpu/", "", $url);
}
public static function gb6IdFromURL(string $url): int
{
return str_replace("https://browser.geekbench.com/v6/cpu/", "", $url);
}
public static function KBstoMBs(int $kbs): float
{
return $kbs / 1000;
}
public static function insertFromJson($data, string $server_id): bool
{
$data = (object)$data;
try {
$date_ran = self::formatRunTime($data->time);
$version = $data['version'];
$has_ipv4 = $data['net']['ipv4'];
$has_ipv6 = $data['net']['ipv6'];
//OS
$arch = $data['os']['arch'];
$distro = $data['os']['distro'];
$kernel = $data['os']['kernel'];
$uptime = $data['os']['uptime'];
//CPU
$model = $data['cpu']['model'];
$cores = $data['cpu']['cores'];
$freq = $data['cpu']['freq'];
$aes = $data['cpu']['aes'];
$virt = $data['cpu']['virt'];
//RAM Disk
$ram = $data['mem']['ram'];
$swap = $data['mem']['swap'];
$disk = $data['mem']['disk'];
$gb5_single = $gb5_multi = $gb5_id = $gb6_single = $gb6_multi = $gb6_id = null;
foreach ($data['geekbench'] as $gb) {
if ($gb['version'] === 5) {
$gb5_single = $gb['single'];
$gb5_multi = $gb['multi'];
$gb5_id = self::gb5IdFromURL($gb['url']);
} elseif ($gb['version'] === 6) {
$gb6_single = $gb['single'];
$gb6_multi = $gb['multi'];
$gb6_id = self::gb6IdFromURL($gb['url']);
}
}
$yabs_id = Str::random(8);
if ($ram > 999999) {
$ram_f = ($ram / 1024 / 1024);
$ram_type = 'GB';
} else {
$ram_f = ($ram / 1024);
$ram_type = 'MB';
}
if ($disk > 100000000) {
$disk_f = ($disk / 1024 / 1024 / 1024);
$disk_type = 'TB';
} else {
$disk_f = ($disk / 1024 / 1024);
$disk_type = 'GB';
}
self::create([
'id' => $yabs_id,
'server_id' => $server_id,
'has_ipv6' => $has_ipv6,
'aes' => $aes,
'vm' => $virt,
'distro' => $distro,
'kernel' => $kernel,
'uptime' => $uptime,
'cpu_model' => $model,
'cpu_cores' => $cores,
'cpu_freq' => (float)$freq,
'ram' => $ram_f,
'ram_type' => $ram_type,
'ram_mb' => ($ram / 1024),
'swap' => $swap / 1024,
'swap_mb' => ($swap / 1024),
'swap_type' => 'MB',
'disk' => $disk_f,
'disk_gb' => ($disk / 1024 / 1024),
'disk_type' => $disk_type,
'output_date' => $date_ran,
'gb5_single' => $gb5_single,
'gb5_multi' => $gb5_multi,
'gb5_id' => $gb5_id,
'gb6_single' => $gb6_single,
'gb6_multi' => $gb6_multi,
'gb6_id' => $gb6_id
]);
//fio
foreach ($data['fio'] as $ds) {
if ($ds['bs'] === '4k') {
$d4k = ($ds['speed_rw'] > 999999) ? ($ds['speed_rw'] / 1000 / 1000) : $ds['speed_rw'] / 1000;
$d4k_type = ($ds['speed_rw'] > 999999) ? 'GB/s' : 'MB/s';
$d4k_mbps = self::KBstoMBs($ds['speed_rw']);
}
if ($ds['bs'] === '64k') {
$d64k = ($ds['speed_rw'] > 999999) ? ($ds['speed_rw'] / 1000 / 1000) : $ds['speed_rw'] / 1000;
$d64k_type = ($ds['speed_rw'] > 999999) ? 'GB/s' : 'MB/s';
$d64k_mbps = self::KBstoMBs($ds['speed_rw']);
}
if ($ds['bs'] === '512k') {
$d512k = ($ds['speed_rw'] > 999999) ? ($ds['speed_rw'] / 1000 / 1000) : $ds['speed_rw'] / 1000;
$d512k_type = ($ds['speed_rw'] > 999999) ? 'GB/s' : 'MB/s';
$d512k_mbps = self::KBstoMBs($ds['speed_rw']);
}
if ($ds['bs'] === '1m') {
$d1m = ($ds['speed_rw'] > 999999) ? ($ds['speed_rw'] / 1000 / 1000) : $ds['speed_rw'] / 1000;
$d1m_type = ($ds['speed_rw'] > 999999) ? 'GB/s' : 'MB/s';
$d1m_mbps = self::KBstoMBs($ds['speed_rw']);
}
}
DiskSpeed::create([
'id' => $yabs_id,
'server_id' => $server_id,
'd_4k' => $d4k,
'd_4k_type' => $d4k_type,
'd_4k_as_mbps' => $d4k_mbps,
'd_64k' => $d64k,
'd_64k_type' => $d64k_type,
'd_64k_as_mbps' => $d64k_mbps,
'd_512k' => $d512k,
'd_512k_type' => $d512k_type,
'd_512k_as_mbps' => $d512k_mbps,
'd_1m' => $d1m,
'd_1m_type' => $d1m_type,
'd_1m_as_mbps' => $d1m_mbps
]);
//iperf
foreach ($data['iperf'] as $st) {
($has_ipv4) ? $match = 'IPv4' : $match = 'IPv6';
if ($st['mode'] === $match) {
if ($st['send'] !== "busy " || $st['recv'] !== "busy ") {
NetworkSpeed::create([
'id' => $yabs_id,
'server_id' => $server_id,
'location' => $st['loc'],
'send' => self::speedAsFloat($st['send']),
'send_type' => self::speedType($st['send']),
'send_as_mbps' => self::speedAsMbps($st['send']),
'receive' => self::speedAsFloat($st['recv']),
'receive_type' => self::speedType($st['recv']),
'receive_as_mbps' => self::speedAsMbps($st['recv'])
]);
}
}
}
//Update server
$update_server = DB::table('servers')
->where('id', $server_id)
->update([
'ram' => $ram_f,
'ram_type' => $ram_type,
'ram_as_mb' => ($ram / 1024),
'disk' => $disk_f,
'disk_as_gb' => ($disk / 1024 / 1024),
'disk_type' => $disk_type,
'cpu' => $cores,
'has_yabs' => 1
]);
Cache::forget("yabs.$yabs_id");
Cache::forget("all_yabs");
Cache::forget("server.$server_id");
Cache::forget("all_servers");
} catch (Exception $e) {//Not valid JSON
return false;
}
return true;
} }
} }

View file

@ -2,6 +2,10 @@
namespace App; namespace App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
class Process class Process
{ {
public string $start_time; public string $start_time;
@ -40,4 +44,406 @@ class Process
return "unknown"; return "unknown";
} }
} }
private function floatValue(string $string): float
{//Keeps only numbers and . AKA a float
return preg_replace('/[^0-9,.]/', '', trim($string));
}
private function intValue(string $string): int
{//Keeps only numbers AKA an int
return (int)preg_replace('/[^0-9]/', '', trim($string));
}
private function removeFloat(string $string): string
{//Removes float from a string
return ltrim(preg_replace('/[^A-Za-z\-,.]/', '', $string), '.');
}
private function trimRemoveR(string $string): string
{//Removes \r and does a trim()
return trim(str_replace("\r", '', $string));
}
private function datatype(string $string): string
{//Formats data type (ram and disk)
if (str_contains($string, 'M')) {
return 'MB';//Megabytes
} elseif (str_contains($string, 'G')) {
return 'GB';//Gigabytes
} elseif (str_contains($string, 'K')) {
return 'KB';//Kilobytes
} elseif (str_contains($string, 'T')) {
return 'TB';//TeraBytes
} elseif (str_contains($string, 'B')) {
return 'BT';//Bytes
} else {
return "GB";
}
}
private function GBtoMB(string $gb): float
{//Gigabyte to Megabyte conversion
return ($gb * 1024);
}
private function TBtoGB(string $tb): float
{//Terabyte to Gigabyte conversion
return ($tb * 1024);
}
private function GBpstoMBps(string $gbps, bool $format = false): float
{//Gigabits to Megabits
if ($format) {
return (float)number_format(((float)$gbps * 1024), 3);
}
return (float)$gbps * 1024;
}
private function diskSpeedAsMbps(string $type, string $value): float
{//If value type GB/s convert to MB/s, KB/s to MB/s
if ($type === "GB/s") {
return $this->GBpstoMBps($value);
}
if ($type === "KB/s") {
return (float)($value / 1024);
}
return $value;
}
private function networkSpeedAsMbps(string $type, string $value): float
{//If value type GBps convert to MB/s
if ($type === "GBps") {
return $this->GBpstoMBps($value);
}
return $value;
}
private function yabsSpeedValues(array $data): array
{//Formats YABs speed test for speed value and type as array
$data = explode('|', implode($data));
if ($data[2] === 'busy') {
$send = $send_type = NULL;
} else {
$send = (float)$data[2];
if ($this->removeFloat($data[2]) === 'Mbitssec') {
$send_type = "MBps";
} elseif ($this->removeFloat($data[2]) === 'Gbitssec') {
$send_type = "GBps";
} elseif ($this->removeFloat($data[2]) === 'Kbitssec') {
$send_type = "KBps";
} else {
$send_type = $this->removeFloat($data[2]);
}
}
if ($data[3] === 'busy') {
$receive = $receive_type = NULL;
} else {
$receive = (float)$data[3];
if ($this->removeFloat($data[3]) === 'Mbitssec') {
$receive_type = "MBps";
} elseif ($this->removeFloat($data[3]) === 'Gbitssec') {
$receive_type = "GBps";
} elseif ($this->removeFloat($data[3]) === 'Kbitssec') {
$receive_type = "KBps";
} else {
$receive_type = $this->removeFloat($data[3]);
}
}
return array('send' => $send, 'send_type' => $send_type, 'receive' => $receive, 'receive_type' => $receive_type);
}
private function yabsSpeedLoc(array $data): array
{//Formats YABs speed test provider and location as array
if ($data[1] === '|') {
$provider = $data[0];
} else {
$provider = $data[0] . ' ' . $data[1];
}
if ($data[2] !== '|') {
$location = $data[2] . ' ' . str_replace(',', '', $data[3]);
} else {
$location = $data[3] . ' ' . str_replace(',', '', $data[4]);
}
return array('provider' => $provider, 'location' => $location);
}
public function yabsOutputAsJson(string $server_id, string $data_from_form): array
{
$allowed_versions = ['v2021-12-28', 'v2022-02-18', 'v2022-04-30', 'v2022-05-06', 'v2022-06-11'];
$file_name = date('Y') . '/' . date('m') . '/' . time() . '.txt';
Storage::disk('local')->put($file_name, $data_from_form);
$file = Storage::disk('local')->get($file_name);
if ($file) {
$array = explode("\n", $file);
if (!Session::get('save_yabs_as_txt')) {//Check if we want YABs txt to stay
Storage::disk('local')->delete($file_name);//Delete file
}
} else {
return array('error_id' => 10, 'error_message' => 'Issue writing/reading txt file');
}
//dd($array);//Good for debugging the lines
if (count($array) < 46) {
return array('error_id' => 9, 'error_message' => 'Less than 46 lines');
}
if (str_contains($array[0], "# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #")) {
if (!str_contains($array[1],"# Yet-Another-Bench-Script #")) {
return array('error_id' => 8, 'error_message' => 'Didnt copy output correctly');
}
$version_array = explode(' ', preg_replace('!\s+!', ' ', $this->trimRemoveR($array[2])));
if (in_array($version_array[1], $allowed_versions, true)) {//YABs version is allowed
if ($version_array[1] === 'v2022-05-06' || $version_array[1] === 'v2022-06-11') {//These versions added in more responses
$cpu = $this->trimRemoveR(str_replace(':', '', strstr($array[11], ': ')));
$cpu_spec = explode(' ', strstr($array[12], ': '));//: 2 @ 3792.872 MHz
$ram_line = $this->trimRemoveR(str_replace(':', '', strstr($array[15], ': ')));
$ram = (float)$ram_line;
$ram_type = $this->datatype($ram_line);
$swap_line = $this->trimRemoveR(str_replace(':', '', strstr($array[16], ': ')));
$swap = (float)$swap_line;
$swap_type = $this->datatype($swap_line);
$disk_line = $this->trimRemoveR(str_replace(':', '', strstr($array[17], ': ')));
$disk = (float)$disk_line;
$disk_type = $this->datatype($disk_line);
$io_3 = explode(' ', preg_replace('!\s+!', ' ', $array[27]));
$io_6 = explode(' ', preg_replace('!\s+!', ' ', $array[33]));
(str_contains($array[13], 'Enabled')) ? $aes_ni = true : $aes_ni = false;
(str_contains($array[14], 'Enabled')) ? $vm_amd_v = true : $vm_amd_v = false;
$uptime = str_replace(["Uptime : ", "\r"], '', $array[10]);
$distro = str_replace(["Distro : ", "\r"], '', $array[18]);
$kernel = str_replace(["Kernel : ", "\r"], '', $array[19]);
} else {
$cpu = $this->trimRemoveR(str_replace(':', '', strstr($array[10], ': ')));
$cpu_spec = explode(' ', strstr($array[11], ': '));//: 2 @ 3792.872 MHz
$ram_line = $this->trimRemoveR(str_replace(':', '', strstr($array[14], ': ')));
$ram = (float)$ram_line;
$ram_type = $this->datatype($ram_line);
$swap_line = $this->trimRemoveR(str_replace(':', '', strstr($array[15], ': ')));
$swap = (float)$swap_line;
$swap_type = $this->datatype($swap_line);
$disk_line = $this->trimRemoveR(str_replace(':', '', strstr($array[16], ': ')));
$disk = (float)$disk_line;
$disk_type = $this->datatype($disk_line);
$io_3 = explode(' ', preg_replace('!\s+!', ' ', $array[24]));
$io_6 = explode(' ', preg_replace('!\s+!', ' ', $array[30]));
(str_contains($array[12], 'Enabled')) ? $aes_ni = true : $aes_ni = false;
(str_contains($array[13], 'Enabled')) ? $vm_amd_v = true : $vm_amd_v = false;
}
$cpu_cores = $cpu_spec[1];
$cpu_freq = $cpu_spec[3];
$d4k_as_mbps = $this->diskSpeedAsMbps($io_3[3], $this->floatValue($io_3[2]));
$d64k_as_mbps = $this->diskSpeedAsMbps($io_3[7], $this->floatValue($io_3[6]));
$d512k_as_mbps = $this->diskSpeedAsMbps($io_6[3], $this->floatValue($io_6[2]));
$d1m_as_mbps = $this->diskSpeedAsMbps($io_6[7], $this->floatValue($io_6[6]));
$disk_test_arr = array(
'4k_total' => $this->floatValue($io_3[2]),
'4k_total_type' => $io_3[3],
'4k_total_mbps' => $d4k_as_mbps,
'64k_total' => $this->floatValue($io_3[6]),
'64k_total_type' => $io_3[7],
'64k_total_mbps' => $d64k_as_mbps,
'512k_total' => $this->floatValue($io_6[2]),
'512k_total_type' => $io_6[3],
'512k_total_mbps' => $d512k_as_mbps,
'1m_total' => $this->floatValue($io_6[6]),
'1m_total_type' => $io_6[7],
'1m_total_mbps' => $d1m_as_mbps,
);
if (isset($array[40])) {
if ($version_array[1] === 'v2022-05-06' || $version_array[1] === 'v2022-06-11') {
if (str_contains($array[43], "Geekbench 5 Benchmark Test:")) {
//No ipv6
//Has short ipv4 network speed testing (-r)
$has_ipv6 = false;
$start_st = 39;
$end_st = 41;
$gb_s = 47;
$gb_m = 48;
$gb_url = 49;
} elseif (str_contains($array[45], "Geekbench 4 Benchmark Test:")) {
return array('error_id' => 6, 'error_message' => 'GeekBench 5 only allowed');
} elseif ($array[45] === "Geekbench 5 test failed. Run manually to determine cause.\r") {
return array('error_id' => 7, 'error_message' => 'GeekBench test failed');
} elseif (str_contains($array[46], "Geekbench 5 Benchmark Test:")) {
//No ipv6
//Has full ipv4 network speed testing
$has_ipv6 = false;
$start_st = 39;
$end_st = 44;
$gb_s = 44;
$gb_m = 45;
$gb_url = 46;
} elseif (str_contains($array[47], "Geekbench 5 Benchmark Test:")) {
//No ipv6
//Has full ipv4 network speed testing
$has_ipv6 = false;
$start_st = 39;
$end_st = 45;
$gb_s = 51;
$gb_m = 52;
$gb_url = 53;
} elseif (str_contains($array[43], "iperf3 Network Speed Tests (IPv6):")) {
//HAS ipv6
//Has short ipv4 & ipv6 network speed testing
$has_ipv6 = true;
$start_st = 39;
$end_st = 41;
$gb_s = 55;
$gb_m = 56;
$gb_url = 57;
} elseif (str_contains($array[56], "Geekbench 5 Benchmark Test:")) {
//HAS ipv6
//Has full ipv4 & ipv6 network speed testing
$has_ipv6 = true;
$start_st = 39;
$end_st = 44;
$gb_s = 60;
$gb_m = 61;
$gb_url = 62;
} elseif (str_contains($array[59], "Geekbench 5 Benchmark Test:")) {
//HAS ipv6
//Has full ipv4 & ipv6 network speed testing
$has_ipv6 = true;
$start_st = 39;
$end_st = 45;
$gb_s = 63;
$gb_m = 64;
$gb_url = 65;
} else {
return array('error_id' => 5, 'error_message' => 'Not correct YABs command output');
}
} else {
if (str_contains($array[45], "Geekbench 5 Benchmark Test:")) {
//No ipv6
//Has short ipv4 network speed testing (-r)
$has_ipv6 = false;
$start_st = 36;
$end_st = 43;
$gb_s = 49;
$gb_m = 50;
$gb_url = 51;
} elseif (str_contains($array[45], "Geekbench 4 Benchmark Test:")) {
return array('error_id' => 6, 'error_message' => 'GeekBench 5 only allowed');
} elseif (str_contains($array[45], "Geekbench 5 test failed. Run manually to determine cause.")) {
return array('error_id' => 7, 'error_message' => 'GeekBench test failed');
} elseif (str_contains($array[40], "Geekbench 5 Benchmark Test:")) {
//No ipv6
//Has full ipv4 network speed testing
$has_ipv6 = false;
$start_st = 36;
$end_st = 38;
$gb_s = 44;
$gb_m = 45;
$gb_url = 46;
} elseif (str_contains($array[40], "iperf3 Network Speed Tests (IPv6):")) {
//HAS ipv6
//Has short ipv4 & ipv6 network speed testing
$has_ipv6 = true;
$start_st = 36;
$end_st = 38;
$gb_s = 52;
$gb_m = 53;
$gb_url = 54;
} elseif (str_contains($array[56], "Geekbench 5 Benchmark Test:")) {
//HAS ipv6
//Has full ipv4 & ipv6 network speed testing
$has_ipv6 = true;
$start_st = 36;
$end_st = 43;
$gb_s = 60;
$gb_m = 61;
$gb_url = 62;
} else {
return array('error_id' => 5, 'error_message' => 'Not correct YABs command output');
}
}
} else {
return array('error_id' => 4, 'error_message' => 'Not correct formatting');
}
$geekbench_single = $this->intValue($array[$gb_s]);
$geekbench_multi = $this->intValue($array[$gb_m]);
$geek_full_url = explode(' ', preg_replace('!\s+!', ' ', $array[$gb_url]));
$gb5_id = (int)substr($geek_full_url[3], strrpos($geek_full_url[3], '/') + 1);//
$has_a_speed_test = false;
($ram_type === 'GB') ? $ram_mb = $this->GBtoMB($ram) : $ram_mb = $ram;
($swap_type === 'GB') ? $swap_mb = $this->GBtoMB($swap) : $swap_mb = $swap;
($disk_type === 'TB') ? $disk_gb = $this->TBtoGB($disk) : $disk_gb = $disk;
$date = date_create($array[6]);
$output = [
'id' => $server_id,
'has_ipv6' => $has_ipv6,
'output_date' => date_format($date, 'Y-m-d H:i:s'),
'process_date' => date('Y-m-d H:i:s'),
'cpu_cores' => (int)$cpu_cores,
'cpu_freq' => (float)$cpu_freq,
'cpu' => $cpu,
'ram' => $ram,
'ram_type' => $ram_type,
'ram_mb' => $ram_mb,
'swap' => $swap,
'swap_type' => $swap_type,
'swap_mb' => $swap_mb,
'disk' => $disk,
'disk_type' => $disk_type,
'disk_gb' => $disk_gb,
'aes' => $aes_ni,
'vm' => $vm_amd_v,
'GB5_single' => $geekbench_single,
'GB5_mult' => $geekbench_multi,
'GB5_id' => $gb5_id,
'uptime' => $uptime ?? null,
'distro' => $distro ?? null,
'kernel' => $kernel ?? null,
];
$output['disk_speed'] = $disk_test_arr;
$speed_test_arr = array();
for ($i = $start_st; $i <= $end_st; $i++) {
if (str_contains($array[$i], 'busy')) {
//Has a "busy" result, No insert
} else {
$data = explode(' ', preg_replace('!\s+!', ' ', $array[$i]));
$send_as_mbps = $this->networkSpeedAsMbps($this->yabsSpeedValues($data)['send_type'], $this->yabsSpeedValues($data)['send']);
$recieve_as_mbps = $this->networkSpeedAsMbps($this->yabsSpeedValues($data)['receive_type'], $this->yabsSpeedValues($data)['receive']);
$speed_test_arr[] = array(
'location' => $this->yabsSpeedLoc($data)['location'],
'send' => $this->yabsSpeedValues($data)['send'],
'send_type' => $this->yabsSpeedValues($data)['send_type'],
'send_type_mbps' => $send_as_mbps,
'receive' => $this->yabsSpeedValues($data)['receive'],
'receive_type' => $this->yabsSpeedValues($data)['receive_type'],
'receive_type_mbps' => $recieve_as_mbps
);
$has_a_speed_test = true;
}
}
if ($has_a_speed_test) {
$output['network_speed'] = $speed_test_arr;
}
return $output;
} else {
return array('error_id' => 4, 'error_message' => 'Wrong YABs version');
}
} else {
return array('error_id' => 3, 'error_message' => 'Didnt start at right spot');
}
}
} }

View file

@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
* *
* @var string * @var string
*/ */
public const HOME = '/'; public const HOME = '/dashboard';
/** /**
* The controller namespace for the application. * The controller namespace for the application.

View file

@ -11,7 +11,7 @@ class OsSelect extends Component
public function render() public function render()
{ {
return view('components.os-select', [ return view('components.os-select', [
'os' => OS::allOS()->toArray() 'os' => OS::allOS()
]); ]);
} }
} }

View file

@ -10,23 +10,23 @@
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.3", "php": "^8.0",
"guzzlehttp/guzzle": "^7.9.2", "fruitcake/laravel-cors": "^2.2",
"laravel/framework": "^v11.34.2", "guzzlehttp/guzzle": "^7.4",
"laravel/tinker": "^v2.10.0", "laravel/framework": "^9",
"laravel/ui": "^v4.6.0", "laravel/tinker": "^2.7",
"yajra/laravel-datatables-oracle": "~v11.1.5", "laravel/ui": "^3.4",
"ext-json": "*", "yajra/laravel-datatables-oracle": "~9.20",
"illuminate/view": "^v11.6.0" "ext-json": "*"
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^v1.24.1", "fakerphp/faker": "^1.19.0",
"laravel/breeze": "^v2.2.6", "laravel/breeze": "^1.9",
"laravel/sail": "^v1.39.1", "laravel/sail": "^1.14",
"mockery/mockery": "^1.6.12", "mockery/mockery": "^1.5",
"nunomaduro/collision": "^v8.5.0", "nunomaduro/collision": "^6.2",
"phpunit/phpunit": "^11.5.0", "phpunit/phpunit": "^9.5",
"spatie/laravel-ignition": "^2.9.0" "spatie/laravel-ignition": "^1.2"
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,

4101
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -42,11 +42,6 @@ return [
'visibility' => 'public', 'visibility' => 'public',
], ],
'public_uploads' => [
'driver' => 'local',
'root' => public_path(),
],
's3' => [ 's3' => [
'driver' => 's3', 'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'), 'key' => env('AWS_ACCESS_KEY_ID'),

View file

@ -18,10 +18,10 @@ class CreatePricingTable extends Migration
$table->tinyInteger('service_type'); $table->tinyInteger('service_type');
$table->tinyInteger('active')->default(1); $table->tinyInteger('active')->default(1);
$table->char('currency', 3); $table->char('currency', 3);
$table->decimal('price', 10, 2); $table->decimal('price',10,2);
$table->tinyInteger('term'); $table->tinyInteger('term');
$table->decimal('as_usd', 10, 2); $table->decimal('as_usd',10,2);
$table->decimal('usd_per_month', 10, 2); $table->decimal('usd_per_month',10,2);
$table->date('next_due_date'); $table->date('next_due_date');
$table->timestamps(); $table->timestamps();
}); });

View file

@ -1,18 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('yabs', function($table)
{
$table->integer('gb5_single')->nullable()->change();
$table->integer('gb5_multi')->nullable()->change();
$table->integer('gb5_id')->nullable()->change();
});
}
};

View file

@ -1,22 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->tinyInteger('sort_on')->default(1)->after('dashboard_currency');
});
}
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('sort_on');
});
}
};

View file

@ -1,23 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('notes', function (Blueprint $table) {
$table->char('id', 8)->primary();
$table->char('service_id', 8)->unique();
$table->text('note');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('notes');
}
};

View file

@ -1,22 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->string('favicon')->after('sort_on')->default('favicon.ico');
});
}
public function down(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('favicon');
});
}
};

View file

@ -1,25 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('yabs', function (Blueprint $table) {
$table->integer('gb6_single')->nullable()->default(null)->after('gb5_id');
$table->integer('gb6_multi')->nullable()->default(null)->after('gb5_id');
$table->integer('gb6_id')->nullable()->default(null)->after('gb5_id');
});
}
public function down(): void
{
Schema::table('yabs', function (Blueprint $table) {
$table->dropColumn('gb6_single');
$table->dropColumn('gb6_multi');
$table->dropColumn('gb6_id');
});
}
};

View file

@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('ips', function (Blueprint $table) {
$table->string('continent')->default(null)->nullable()->after('active');
$table->string('country')->default(null)->nullable()->after('active');
$table->string('region')->default(null)->nullable()->after('active');
$table->string('city')->default(null)->nullable()->after('active');
$table->string('org')->default(null)->nullable()->after('active');
$table->string('isp')->default(null)->nullable()->after('active');
$table->string('asn')->default(null)->nullable()->after('active');
$table->string('timezone_gmt')->default(null)->nullable()->after('active');
$table->dateTime('fetched_at')->default(null)->nullable()->after('active');
});
}
public function down(): void
{
Schema::table('ips', function (Blueprint $table) {
$table->dropColumn(['continent', 'country', 'region', 'city', 'org', 'isp', 'asn', 'timezone_gmt', 'fetched_at']);
});
}
};

View file

@ -14,49 +14,42 @@ class OsSeeder extends Seeder
["name" => "None", "created_at" => Carbon::now()], ["name" => "None", "created_at" => Carbon::now()],
["name" => "AlmaLinux 8", "created_at" => Carbon::now()], ["name" => "AlmaLinux 8", "created_at" => Carbon::now()],
["name" => "AlmaLinux", "created_at" => Carbon::now()], ["name" => "AlmaLinux", "created_at" => Carbon::now()],
["name" => "Centos 7", "created_at" => Carbon::now()],//3 ["name" => "Centos 7", "created_at" => Carbon::now()],
["name" => "Centos 8", "created_at" => Carbon::now()], ["name" => "Centos 8", "created_at" => Carbon::now()],
["name" => "Centos 9", "created_at" => Carbon::now()], ["name" => "Centos 9", "created_at" => Carbon::now()],
["name" => "Centos", "created_at" => Carbon::now()], ["name" => "Centos", "created_at" => Carbon::now()],
["name" => "Debian 9", "created_at" => Carbon::now()],//7 ["name" => "Debian 9", "created_at" => Carbon::now()],
["name" => "Debian 10", "created_at" => Carbon::now()], ["name" => "Debian 10", "created_at" => Carbon::now()],
["name" => "Debian", "created_at" => Carbon::now()], ["name" => "Debian", "created_at" => Carbon::now()],
["name" => "Fedora 32", "created_at" => Carbon::now()],//10 ["name" => "Fedora 32", "created_at" => Carbon::now()],
["name" => "Fedora 33", "created_at" => Carbon::now()], ["name" => "Fedora 33", "created_at" => Carbon::now()],
["name" => "Fedora 34", "created_at" => Carbon::now()], ["name" => "Fedora 34", "created_at" => Carbon::now()],
["name" => "Fedora", "created_at" => Carbon::now()],//13 ["name" => "Fedora", "created_at" => Carbon::now()],
["name" => "FreeBSD 11.4", "created_at" => Carbon::now()], ["name" => "FreeBSD 11.4", "created_at" => Carbon::now()],
["name" => "FreeBSD 12.1", "created_at" => Carbon::now()],//15 ["name" => "FreeBSD 12.1", "created_at" => Carbon::now()],
["name" => "FreeBSD", "created_at" => Carbon::now()], ["name" => "FreeBSD", "created_at" => Carbon::now()],
["name" => "OpenBSD 6.7", "created_at" => Carbon::now()], ["name" => "OpenBSD 6.7", "created_at" => Carbon::now()],
["name" => "OpenBSD 6.8", "created_at" => Carbon::now()], ["name" => "OpenBSD 6.8", "created_at" => Carbon::now()],
["name" => "OpenBSD", "created_at" => Carbon::now()], ["name" => "OpenBSD", "created_at" => Carbon::now()],
["name" => "Red Hat Enterprise Linux 8", "created_at" => Carbon::now()],//20 ["name" => "Red Hat Enterprise Linux 8", "created_at" => Carbon::now()],
["name" => "Red Hat Enterprise Linux 9", "created_at" => Carbon::now()], ["name" => "Red Hat Enterprise Linux 9", "created_at" => Carbon::now()],
["name" => "Red Hat Enterprise Linux", "created_at" => Carbon::now()], ["name" => "Red Hat Enterprise Linux", "created_at" => Carbon::now()],
["name" => "Rocky Linux 8", "created_at" => Carbon::now()], ["name" => "Rocky Linux 8", "created_at" => Carbon::now()],
["name" => "Rocky Linux", "created_at" => Carbon::now()], ["name" => "Rocky Linux", "created_at" => Carbon::now()],
["name" => "Ubuntu 16.04", "created_at" => Carbon::now()],//25 ["name" => "Ubuntu 16.04", "created_at" => Carbon::now()],
["name" => "Ubuntu 18.04", "created_at" => Carbon::now()], ["name" => "Ubuntu 18.04", "created_at" => Carbon::now()],
["name" => "Ubuntu 20.04", "created_at" => Carbon::now()], ["name" => "Ubuntu 20.04", "created_at" => Carbon::now()],
["name" => "Ubuntu 20.10", "created_at" => Carbon::now()], ["name" => "Ubuntu 20.10", "created_at" => Carbon::now()],
["name" => "Ubuntu 22.10", "created_at" => Carbon::now()], ["name" => "Ubuntu 22.10", "created_at" => Carbon::now()],
["name" => "Ubuntu", "created_at" => Carbon::now()],//30 ["name" => "Ubuntu", "created_at" => Carbon::now()],
["name" => "Windows Server 2008", "created_at" => Carbon::now()], ["name" => "Windows Server 2008", "created_at" => Carbon::now()],
["name" => "Windows Server 2012", "created_at" => Carbon::now()], ["name" => "Windows Server 2012", "created_at" => Carbon::now()],
["name" => "Windows Server 2016", "created_at" => Carbon::now()], ["name" => "Windows Server 2016", "created_at" => Carbon::now()],
["name" => "Windows Server 2019", "created_at" => Carbon::now()], ["name" => "Windows Server 2019", "created_at" => Carbon::now()],
["name" => "Windows 10", "created_at" => Carbon::now()], ["name" => "Windows 10", "created_at" => Carbon::now()],
["name" => "Windows 11", "created_at" => Carbon::now()],//38 ["name" => "Windows 11", "created_at" => Carbon::now()],
["name" => "Custom", "created_at" => Carbon::now()],//39 ["name" => "Custom", "created_at" => Carbon::now()],
["name" => "Other", "created_at" => Carbon::now()],//40 ["name" => "Other", "created_at" => Carbon::now()]
["name" => "Windows Server 2022", "created_at" => Carbon::now()],//41
["name" => "Ubuntu 24.04", "created_at" => Carbon::now()],//42
["name" => "OpenBSD 7.5", "created_at" => Carbon::now()],//43
["name" => "Fedora 41", "created_at" => Carbon::now()],//44
["name" => "Debian 11", "created_at" => Carbon::now()],//45
["name" => "AlmaLinux 9", "created_at" => Carbon::now()],//46
["name" => "FreeBSD 14.1", "created_at" => Carbon::now()],//47
]; ];
DB::table('os')->insert($os); DB::table('os')->insert($os);

16608
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,29 +7,26 @@
"watch-poll": "mix watch -- --watch-options-poll=1000", "watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot", "hot": "mix watch --hot",
"prod": "npm run production", "prod": "npm run production",
"production": "mix --production", "production": "mix --production"
"build": "webpack --config webpack.config.js"
}, },
"devDependencies": { "devDependencies": {
"axios": "^1.7.9", "@popperjs/core": "^2.10.2",
"bootstrap": "^5.3.3", "@tailwindcss/forms": "^0.4.0",
"bootstrap-dark-5": "^1.1.3", "alpinejs": "^3.4.2",
"bootstrap-data-table": "^1.0.0", "autoprefixer": "^10.1.0",
"datatables": "^1.10.18", "axios": "^0.21.4",
"datatables.net-bs": "^2.1.8", "bootstrap": "^5.1.3",
"font-awesome": "^4.7.0", "laravel-mix": "^6.0.41",
"jquery": "^3.7.1", "lodash": "^4.17.21",
"laravel-mix": "^6.0.49", "postcss": "^8.2.1",
"resolve-url-loader": "^5.0.0", "postcss-import": "^14.0.1",
"sass": "^1.82.0", "resolve-url-loader": "^3.1.2",
"sass-loader": "^12.6.0", "sass": "^1.32.11",
"vue": "^2.7.16", "sass-loader": "^11.0.1",
"vue-loader": "^17.4.2", "tailwindcss": "^3.0.0",
"vue": "^2.6.12",
"vue-loader": "^15.9.5",
"vue-resource": "^1.5.3", "vue-resource": "^1.5.3",
"vue-template-compiler": "^2.7.16" "vue-template-compiler": "^2.6.12"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.7.1",
"datatables.net-bs5": "^1.13.11"
} }
} }

14363
public/css/app.css vendored

File diff suppressed because it is too large Load diff

10
public/css/bootstrap-dark.min.css vendored Normal file

File diff suppressed because one or more lines are too long

7
public/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

13116
public/css/dark.css vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

5
public/css/fa.min.css vendored Normal file

File diff suppressed because one or more lines are too long

11969
public/css/light.css vendored

File diff suppressed because it is too large Load diff

10
public/js/addService.js vendored Normal file
View file

@ -0,0 +1,10 @@
var vm = new Vue({
data: {
key: ""
},
methods: {
onChange(event) {
console.log(event.target.value)
}
}
});

89245
public/js/app.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
/*!
* Bootstrap v5.3.3 (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <http://feross.org>
* @license MIT
*/
/*!
* Vue.js v2.7.16
* (c) 2014-2023 Evan You
* Released under the MIT License.
*/
/*!
* jQuery JavaScript Library v3.7.1
* https://jquery.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2023-08-28T13:37Z
*/
/*! DataTables 1.10.18
* ©2008-2018 SpryMedia Ltd - datatables.net/license
*/
/*! DataTables Bootstrap 5 integration
* 2020 SpryMedia Ltd - datatables.net/license
*/
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */

2
public/js/axios.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
public/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

14
public/js/datatables.bootstrap5.min.js vendored Normal file
View file

@ -0,0 +1,14 @@
/*!
DataTables Bootstrap 5 integration
2020 SpryMedia Ltd - datatables.net/license
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,b,c){a instanceof String&&(a=String(a));for(var e=a.length,d=0;d<e;d++){var f=a[d];if(b.call(c,f,d,a))return{i:d,v:f}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};$jscomp.getGlobal=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(a,b){var c=$jscomp.propertyToPolyfillSymbol[b];if(null==c)return a[b];c=a[c];return void 0!==c?c:a[b]};
$jscomp.polyfill=function(a,b,c,e){b&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(a,b,c,e):$jscomp.polyfillUnisolated(a,b,c,e))};$jscomp.polyfillUnisolated=function(a,b,c,e){c=$jscomp.global;a=a.split(".");for(e=0;e<a.length-1;e++){var d=a[e];if(!(d in c))return;c=c[d]}a=a[a.length-1];e=c[a];b=b(e);b!=e&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})};
$jscomp.polyfillIsolated=function(a,b,c,e){var d=a.split(".");a=1===d.length;e=d[0];e=!a&&e in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var f=0;f<d.length-1;f++){var l=d[f];if(!(l in e))return;e=e[l]}d=d[d.length-1];c=$jscomp.IS_SYMBOL_NATIVE&&"es6"===c?e[d]:null;b=b(c);null!=b&&(a?$jscomp.defineProperty($jscomp.polyfills,d,{configurable:!0,writable:!0,value:b}):b!==c&&($jscomp.propertyToPolyfillSymbol[d]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(d):$jscomp.POLYFILL_PREFIX+d,d=
$jscomp.propertyToPolyfillSymbol[d],$jscomp.defineProperty(e,d,{configurable:!0,writable:!0,value:b})))};$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(b,c){return $jscomp.findInternal(this,b,c).v}},"es6","es3");
(function(a){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(b){return a(b,window,document)}):"object"===typeof exports?module.exports=function(b,c){b||(b=window);c&&c.fn.dataTable||(c=require("datatables.net")(b,c).$);return a(c,b,b.document)}:a(jQuery,window,document)})(function(a,b,c,e){var d=a.fn.dataTable;a.extend(!0,d.defaults,{dom:"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
renderer:"bootstrap"});a.extend(d.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap5",sFilterInput:"form-control form-control-sm",sLengthSelect:"form-select form-select-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"});d.ext.renderer.pageButton.bootstrap=function(f,l,A,B,m,t){var u=new d.Api(f),C=f.oClasses,n=f.oLanguage.oPaginate,D=f.oLanguage.oAria.paginate||{},h,k,v=0,y=function(q,w){var x,E=function(p){p.preventDefault();a(p.currentTarget).hasClass("disabled")||
u.page()==p.data.action||u.page(p.data.action).draw("page")};var r=0;for(x=w.length;r<x;r++){var g=w[r];if(Array.isArray(g))y(q,g);else{k=h="";switch(g){case "ellipsis":h="&#x2026;";k="disabled";break;case "first":h=n.sFirst;k=g+(0<m?"":" disabled");break;case "previous":h=n.sPrevious;k=g+(0<m?"":" disabled");break;case "next":h=n.sNext;k=g+(m<t-1?"":" disabled");break;case "last":h=n.sLast;k=g+(m<t-1?"":" disabled");break;default:h=g+1,k=m===g?"active":""}if(h){var F=a("<li>",{"class":C.sPageButton+
" "+k,id:0===A&&"string"===typeof g?f.sTableId+"_"+g:null}).append(a("<a>",{href:"#","aria-controls":f.sTableId,"aria-label":D[g],"data-dt-idx":v,tabindex:f.iTabIndex,"class":"page-link"}).html(h)).appendTo(q);f.oApi._fnBindAction(F,{action:g},E);v++}}}};try{var z=a(l).find(c.activeElement).data("dt-idx")}catch(q){}y(a(l).empty().html('<ul class="pagination"/>').children("ul"),B);z!==e&&a(l).find("[data-dt-idx="+z+"]").trigger("focus")};return d});

181
public/js/datatables.min.js vendored Normal file
View file

@ -0,0 +1,181 @@
/*!
Copyright 2008-2020 SpryMedia Ltd.
This source file is free software, available under the following license:
MIT license - http://datatables.net/license
This source file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
For details please refer to: http://www.datatables.net
DataTables 1.10.21
©2008-2020 SpryMedia Ltd - datatables.net/license
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(f,y,w){f instanceof String&&(f=String(f));for(var n=f.length,H=0;H<n;H++){var L=f[H];if(y.call(w,L,H,f))return{i:H,v:L}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(f,y,w){f!=Array.prototype&&f!=Object.prototype&&(f[y]=w.value)};$jscomp.getGlobal=function(f){f=["object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global,f];for(var y=0;y<f.length;++y){var w=f[y];if(w&&w.Math==Math)return w}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(f,y,w,n){if(y){w=$jscomp.global;f=f.split(".");for(n=0;n<f.length-1;n++){var H=f[n];H in w||(w[H]={});w=w[H]}f=f[f.length-1];n=w[f];y=y(n);y!=n&&null!=y&&$jscomp.defineProperty(w,f,{configurable:!0,writable:!0,value:y})}};$jscomp.polyfill("Array.prototype.find",function(f){return f?f:function(f,w){return $jscomp.findInternal(this,f,w).v}},"es6","es3");
(function(f){"function"===typeof define&&define.amd?define(["jquery"],function(y){return f(y,window,document)}):"object"===typeof exports?module.exports=function(y,w){y||(y=window);w||(w="undefined"!==typeof window?require("jquery"):require("jquery")(y));return f(w,y,y.document)}:f(jQuery,window,document)})(function(f,y,w,n){function H(a){var b,c,d={};f.each(a,function(e,h){(b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" ")&&(c=e.replace(b[0],b[2].toLowerCase()),
d[c]=e,"o"===b[1]&&H(a[e]))});a._hungarianMap=d}function L(a,b,c){a._hungarianMap||H(a);var d;f.each(b,function(e,h){d=a._hungarianMap[e];d===n||!c&&b[d]!==n||("o"===d.charAt(0)?(b[d]||(b[d]={}),f.extend(!0,b[d],b[e]),L(a[d],b[d],c)):b[d]=b[e])})}function Fa(a){var b=q.defaults.oLanguage,c=b.sDecimal;c&&Ga(c);if(a){var d=a.sZeroRecords;!a.sEmptyTable&&d&&"No data available in table"===b.sEmptyTable&&M(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&d&&"Loading..."===b.sLoadingRecords&&M(a,a,
"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&c!==a&&Ga(a)}}function ib(a){E(a,"ordering","bSort");E(a,"orderMulti","bSortMulti");E(a,"orderClasses","bSortClasses");E(a,"orderCellsTop","bSortCellsTop");E(a,"order","aaSorting");E(a,"orderFixed","aaSortingFixed");E(a,"paging","bPaginate");E(a,"pagingType","sPaginationType");E(a,"pageLength","iDisplayLength");E(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":
"");"boolean"===typeof a.scrollX&&(a.scrollX=a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&L(q.models.oSearch,a[b])}function jb(a){E(a,"orderable","bSortable");E(a,"orderData","aDataSort");E(a,"orderSequence","asSorting");E(a,"orderDataType","sortDataType");var b=a.aDataSort;"number"!==typeof b||f.isArray(b)||(a.aDataSort=[b])}function kb(a){if(!q.__browser){var b={};q.__browser=b;var c=f("<div/>").css({position:"fixed",top:0,left:-1*f(y).scrollLeft(),height:1,width:1,
overflow:"hidden"}).append(f("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(f("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}f.extend(a.oBrowser,q.__browser);a.oScroll.iBarWidth=q.__browser.barWidth}
function lb(a,b,c,d,e,h){var g=!1;if(c!==n){var k=c;g=!0}for(;d!==e;)a.hasOwnProperty(d)&&(k=g?b(k,a[d],d,a):a[d],g=!0,d+=h);return k}function Ha(a,b){var c=q.defaults.column,d=a.aoColumns.length;c=f.extend({},q.models.oColumn,c,{nTh:b?b:w.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=f.extend({},q.models.oSearch,c[d]);la(a,d,f(b).data())}function la(a,b,c){b=a.aoColumns[b];
var d=a.oClasses,e=f(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var h=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);h&&(b.sWidthOrig=h[1])}c!==n&&null!==c&&(jb(c),L(q.defaults.column,c,!0),c.mDataProp===n||c.mData||(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),f.extend(b,c),M(b,c,"sWidth","sWidthOrig"),c.iDataSort!==n&&(b.aDataSort=[c.iDataSort]),M(b,c,"aDataSort"));var g=b.mData,k=T(g),
l=b.mRender?T(b.mRender):null;c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=f.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=k(a,b,n,c);return l&&b?l(d,b,a,c):d};b.fnSetData=function(a,b,c){return Q(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==f.inArray("asc",b.asSorting);c=-1!==f.inArray("desc",b.asSorting);b.bSortable&&(a||c)?a&&!c?(b.sSortingClass=
d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI):(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI="")}function Z(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ia(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;""===b.sY&&""===b.sX||ma(a);A(a,null,"column-sizing",[a])}function aa(a,b){a=na(a,"bVisible");return"number"===
typeof a[b]?a[b]:null}function ba(a,b){a=na(a,"bVisible");b=f.inArray(b,a);return-1!==b?b:null}function V(a){var b=0;f.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==f(d.nTh).css("display")&&b++});return b}function na(a,b){var c=[];f.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ja(a){var b=a.aoColumns,c=a.aoData,d=q.ext.type.detect,e,h,g;var k=0;for(e=b.length;k<e;k++){var f=b[k];var m=[];if(!f.sType&&f._sManualType)f.sType=f._sManualType;else if(!f.sType){var p=0;for(h=
d.length;p<h;p++){var v=0;for(g=c.length;v<g;v++){m[v]===n&&(m[v]=F(a,v,k,"type"));var u=d[p](m[v],a);if(!u&&p!==d.length-1)break;if("html"===u)break}if(u){f.sType=u;break}}f.sType||(f.sType="string")}}}function mb(a,b,c,d){var e,h,g,k=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){var l=b[e];var m=l.targets!==n?l.targets:l.aTargets;f.isArray(m)||(m=[m]);var p=0;for(h=m.length;p<h;p++)if("number"===typeof m[p]&&0<=m[p]){for(;k.length<=m[p];)Ha(a);d(m[p],l)}else if("number"===typeof m[p]&&0>m[p])d(k.length+
m[p],l);else if("string"===typeof m[p]){var v=0;for(g=k.length;v<g;v++)("_all"==m[p]||f(k[v].nTh).hasClass(m[p]))&&d(v,l)}}if(c)for(e=0,a=c.length;e<a;e++)d(e,c[e])}function R(a,b,c,d){var e=a.aoData.length,h=f.extend(!0,{},q.models.oRow,{src:c?"dom":"data",idx:e});h._aData=b;a.aoData.push(h);for(var g=a.aoColumns,k=0,l=g.length;k<l;k++)g[k].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==n&&(a.aIds[b]=h);!c&&a.oFeatures.bDeferRender||Ka(a,e,c,d);return e}function oa(a,b){var c;b instanceof
f||(b=f(b));return b.map(function(b,e){c=La(a,e);return R(a,c.data,e,c.cells)})}function F(a,b,c,d){var e=a.iDraw,h=a.aoColumns[c],g=a.aoData[b]._aData,k=h.sDefaultContent,f=h.fnGetData(g,d,{settings:a,row:b,col:c});if(f===n)return a.iDrawError!=e&&null===k&&(O(a,0,"Requested unknown parameter "+("function"==typeof h.mData?"{function}":"'"+h.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),k;if((f===g||null===f)&&null!==k&&d!==n)f=k;else if("function"===typeof f)return f.call(g);return null===
f&&"display"==d?"":f}function nb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}function Ma(a){return f.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function T(a){if(f.isPlainObject(a)){var b={};f.each(a,function(a,c){c&&(b[a]=T(c))});return function(a,c,h,g){var d=b[c]||b._;return d!==n?d(a,c,h,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,h,g){return a(b,c,h,g)};if("string"!==typeof a||
-1===a.indexOf(".")&&-1===a.indexOf("[")&&-1===a.indexOf("("))return function(b,c){return b[a]};var c=function(a,b,h){if(""!==h){var d=Ma(h);for(var e=0,l=d.length;e<l;e++){h=d[e].match(ca);var m=d[e].match(W);if(h){d[e]=d[e].replace(ca,"");""!==d[e]&&(a=a[d[e]]);m=[];d.splice(0,e+1);d=d.join(".");if(f.isArray(a))for(e=0,l=a.length;e<l;e++)m.push(c(a[e],b,d));a=h[0].substring(1,h[0].length-1);a=""===a?m:m.join(a);break}else if(m){d[e]=d[e].replace(W,"");a=a[d[e]]();continue}if(null===a||a[d[e]]===
n)return n;a=a[d[e]]}}return a};return function(b,e){return c(b,e,a)}}function Q(a){if(f.isPlainObject(a))return Q(a._);if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"!==typeof a||-1===a.indexOf(".")&&-1===a.indexOf("[")&&-1===a.indexOf("("))return function(b,d){b[a]=d};var b=function(a,d,e){e=Ma(e);var c=e[e.length-1];for(var g,k,l=0,m=e.length-1;l<m;l++){g=e[l].match(ca);k=e[l].match(W);if(g){e[l]=e[l].replace(ca,"");a[e[l]]=[];c=e.slice();
c.splice(0,l+1);g=c.join(".");if(f.isArray(d))for(k=0,m=d.length;k<m;k++)c={},b(c,d[k],g),a[e[l]].push(c);else a[e[l]]=d;return}k&&(e[l]=e[l].replace(W,""),a=a[e[l]](d));if(null===a[e[l]]||a[e[l]]===n)a[e[l]]={};a=a[e[l]]}if(c.match(W))a[c.replace(W,"")](d);else a[c.replace(ca,"")]=d};return function(c,d){return b(c,d,a)}}function Na(a){return K(a.aoData,"_aData")}function pa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function qa(a,b,c){for(var d=-1,e=0,h=a.length;e<
h;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===n&&a.splice(d,1)}function da(a,b,c,d){var e=a.aoData[b],h,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=F(a,b,d,"display")};if("dom"!==c&&(c&&"auto"!==c||"dom"!==e.src)){var k=e.anCells;if(k)if(d!==n)g(k[d],d);else for(c=0,h=k.length;c<h;c++)g(k[c],c)}else e._aData=La(a,e,d,d===n?n:e._aData).data;e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==n)g[d].sType=null;else{c=0;for(h=g.length;c<h;c++)g[c].sType=null;
Oa(a,e)}}function La(a,b,c,d){var e=[],h=b.firstChild,g,k=0,l,m=a.aoColumns,p=a._rowReadObject;d=d!==n?d:p?{}:[];var v=function(a,b){if("string"===typeof a){var c=a.indexOf("@");-1!==c&&(c=a.substring(c+1),Q(a)(d,b.getAttribute(c)))}},u=function(a){if(c===n||c===k)g=m[k],l=f.trim(a.innerHTML),g&&g._bAttrSrc?(Q(g.mData._)(d,l),v(g.mData.sort,a),v(g.mData.type,a),v(g.mData.filter,a)):p?(g._setter||(g._setter=Q(g.mData)),g._setter(d,l)):d[k]=l;k++};if(h)for(;h;){var q=h.nodeName.toUpperCase();if("TD"==
q||"TH"==q)u(h),e.push(h);h=h.nextSibling}else for(e=b.anCells,h=0,q=e.length;h<q;h++)u(e[h]);(b=b.firstChild?b:b.nTr)&&(b=b.getAttribute("id"))&&Q(a.rowId)(d,b);return{data:d,cells:e}}function Ka(a,b,c,d){var e=a.aoData[b],h=e._aData,g=[],k,l;if(null===e.nTr){var m=c||w.createElement("tr");e.nTr=m;e.anCells=g;m._DT_RowIndex=b;Oa(a,e);var p=0;for(k=a.aoColumns.length;p<k;p++){var v=a.aoColumns[p];var n=(l=c?!1:!0)?w.createElement(v.sCellType):d[p];n._DT_CellIndex={row:b,column:p};g.push(n);if(l||
!(c&&!v.mRender&&v.mData===p||f.isPlainObject(v.mData)&&v.mData._===p+".display"))n.innerHTML=F(a,b,p,"display");v.sClass&&(n.className+=" "+v.sClass);v.bVisible&&!c?m.appendChild(n):!v.bVisible&&c&&n.parentNode.removeChild(n);v.fnCreatedCell&&v.fnCreatedCell.call(a.oInstance,n,F(a,b,p),h,b,p)}A(a,"aoRowCreatedCallback",null,[m,h,b,g])}e.nTr.setAttribute("role","row")}function Oa(a,b){var c=b.nTr,d=b._aData;if(c){if(a=a.rowIdFn(d))c.id=a;d.DT_RowClass&&(a=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?
sa(b.__rowc.concat(a)):a,f(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&f(c).attr(d.DT_RowAttr);d.DT_RowData&&f(c).data(d.DT_RowData)}}function ob(a){var b,c,d=a.nTHead,e=a.nTFoot,h=0===f("th, td",d).length,g=a.oClasses,k=a.aoColumns;h&&(c=f("<tr/>").appendTo(d));var l=0;for(b=k.length;l<b;l++){var m=k[l];var p=f(m.nTh).addClass(m.sClass);h&&p.appendTo(c);a.oFeatures.bSort&&(p.addClass(m.sSortingClass),!1!==m.bSortable&&(p.attr("tabindex",a.iTabIndex).attr("aria-controls",
a.sTableId),Pa(a,m.nTh,l)));m.sTitle!=p[0].innerHTML&&p.html(m.sTitle);Qa(a,"header")(a,p,m,g)}h&&ea(a.aoHeader,d);f(d).find(">tr").attr("role","row");f(d).find(">tr>th, >tr>td").addClass(g.sHeaderTH);f(e).find(">tr>th, >tr>td").addClass(g.sFooterTH);if(null!==e)for(a=a.aoFooter[0],l=0,b=a.length;l<b;l++)m=k[l],m.nTf=a[l].cell,m.sClass&&f(m.nTf).addClass(m.sClass)}function fa(a,b,c){var d,e,h=[],g=[],k=a.aoColumns.length;if(b){c===n&&(c=!1);var l=0;for(d=b.length;l<d;l++){h[l]=b[l].slice();h[l].nTr=
b[l].nTr;for(e=k-1;0<=e;e--)a.aoColumns[e].bVisible||c||h[l].splice(e,1);g.push([])}l=0;for(d=h.length;l<d;l++){if(a=h[l].nTr)for(;e=a.firstChild;)a.removeChild(e);e=0;for(b=h[l].length;e<b;e++){var m=k=1;if(g[l][e]===n){a.appendChild(h[l][e].cell);for(g[l][e]=1;h[l+k]!==n&&h[l][e].cell==h[l+k][e].cell;)g[l+k][e]=1,k++;for(;h[l][e+m]!==n&&h[l][e].cell==h[l][e+m].cell;){for(c=0;c<k;c++)g[l+c][e+m]=1;m++}f(h[l][e].cell).attr("rowspan",k).attr("colspan",m)}}}}}function S(a){var b=A(a,"aoPreDrawCallback",
"preDraw",[a]);if(-1!==f.inArray(!1,b))J(a,!1);else{b=[];var c=0,d=a.asStripeClasses,e=d.length,h=a.oLanguage,g=a.iInitDisplayStart,k="ssp"==I(a),l=a.aiDisplay;a.bDrawing=!0;g!==n&&-1!==g&&(a._iDisplayStart=k?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);g=a._iDisplayStart;var m=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,J(a,!1);else if(!k)a.iDraw++;else if(!a.bDestroying&&!pb(a))return;if(0!==l.length)for(h=k?a.aoData.length:m,k=k?0:g;k<h;k++){var p=l[k],v=a.aoData[p];
null===v.nTr&&Ka(a,p);var u=v.nTr;if(0!==e){var q=d[c%e];v._sRowStripe!=q&&(f(u).removeClass(v._sRowStripe).addClass(q),v._sRowStripe=q)}A(a,"aoRowCallback",null,[u,v._aData,c,k,p]);b.push(u);c++}else c=h.sZeroRecords,1==a.iDraw&&"ajax"==I(a)?c=h.sLoadingRecords:h.sEmptyTable&&0===a.fnRecordsTotal()&&(c=h.sEmptyTable),b[0]=f("<tr/>",{"class":e?d[0]:""}).append(f("<td />",{valign:"top",colSpan:V(a),"class":a.oClasses.sRowEmpty}).html(c))[0];A(a,"aoHeaderCallback","header",[f(a.nTHead).children("tr")[0],
Na(a),g,m,l]);A(a,"aoFooterCallback","footer",[f(a.nTFoot).children("tr")[0],Na(a),g,m,l]);d=f(a.nTBody);d.children().detach();d.append(f(b));A(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function U(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&qb(a);d?ha(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;S(a);a._drawHold=!1}function rb(a){var b=a.oClasses,c=f(a.nTable);c=f("<div/>").insertBefore(c);var d=a.oFeatures,e=
f("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var h=a.sDom.split(""),g,k,l,m,p,n,u=0;u<h.length;u++){g=null;k=h[u];if("<"==k){l=f("<div/>")[0];m=h[u+1];if("'"==m||'"'==m){p="";for(n=2;h[u+n]!=m;)p+=h[u+n],n++;"H"==p?p=b.sJUIHeader:"F"==p&&(p=b.sJUIFooter);-1!=p.indexOf(".")?(m=p.split("."),l.id=m[0].substr(1,m[0].length-1),l.className=m[1]):"#"==p.charAt(0)?l.id=p.substr(1,
p.length-1):l.className=p;u+=n}e.append(l);e=f(l)}else if(">"==k)e=e.parent();else if("l"==k&&d.bPaginate&&d.bLengthChange)g=sb(a);else if("f"==k&&d.bFilter)g=tb(a);else if("r"==k&&d.bProcessing)g=ub(a);else if("t"==k)g=vb(a);else if("i"==k&&d.bInfo)g=wb(a);else if("p"==k&&d.bPaginate)g=xb(a);else if(0!==q.ext.feature.length)for(l=q.ext.feature,n=0,m=l.length;n<m;n++)if(k==l[n].cFeature){g=l[n].fnInit(a);break}g&&(l=a.aanFeatures,l[k]||(l[k]=[]),l[k].push(g),e.append(g))}c.replaceWith(e);a.nHolding=
null}function ea(a,b){b=f(b).children("tr");var c,d,e;a.splice(0,a.length);var h=0;for(e=b.length;h<e;h++)a.push([]);h=0;for(e=b.length;h<e;h++){var g=b[h];for(c=g.firstChild;c;){if("TD"==c.nodeName.toUpperCase()||"TH"==c.nodeName.toUpperCase()){var k=1*c.getAttribute("colspan");var l=1*c.getAttribute("rowspan");k=k&&0!==k&&1!==k?k:1;l=l&&0!==l&&1!==l?l:1;var m=0;for(d=a[h];d[m];)m++;var p=m;var n=1===k?!0:!1;for(d=0;d<k;d++)for(m=0;m<l;m++)a[h+m][p+d]={cell:c,unique:n},a[h+m].nTr=g}c=c.nextSibling}}}
function ta(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],ea(c,b)));b=0;for(var e=c.length;b<e;b++)for(var h=0,g=c[b].length;h<g;h++)!c[b][h].unique||d[h]&&a.bSortCellsTop||(d[h]=c[b][h].cell);return d}function ua(a,b,c){A(a,"aoServerParams","serverParams",[b]);if(b&&f.isArray(b)){var d={},e=/(.*?)\[\]$/;f.each(b,function(a,b){(a=b.name.match(e))?(a=a[0],d[a]||(d[a]=[]),d[a].push(b.value)):d[b.name]=b.value});b=d}var h=a.ajax,g=a.oInstance,k=function(b){A(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(f.isPlainObject(h)&&
h.data){var l=h.data;var m="function"===typeof l?l(b,a):l;b="function"===typeof l&&m?m:f.extend(!0,b,m);delete h.data}m={data:b,success:function(b){var c=b.error||b.sError;c&&O(a,0,c);a.json=b;k(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c,d){d=A(a,null,"xhr",[a,null,a.jqXHR]);-1===f.inArray(!0,d)&&("parsererror"==c?O(a,0,"Invalid JSON response",1):4===b.readyState&&O(a,0,"Ajax error",7));J(a,!1)}};a.oAjaxData=b;A(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(g,
a.sAjaxSource,f.map(b,function(a,b){return{name:b,value:a}}),k,a):a.sAjaxSource||"string"===typeof h?a.jqXHR=f.ajax(f.extend(m,{url:h||a.sAjaxSource})):"function"===typeof h?a.jqXHR=h.call(g,b,k,a):(a.jqXHR=f.ajax(f.extend(m,h)),h.data=l)}function pb(a){return a.bAjaxDataGet?(a.iDraw++,J(a,!0),ua(a,yb(a),function(b){zb(a,b)}),!1):!0}function yb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,h=a.aoPreSearchCols,g=[],k=X(a);var l=a._iDisplayStart;var m=!1!==d.bPaginate?a._iDisplayLength:
-1;var p=function(a,b){g.push({name:a,value:b})};p("sEcho",a.iDraw);p("iColumns",c);p("sColumns",K(b,"sName").join(","));p("iDisplayStart",l);p("iDisplayLength",m);var n={draw:a.iDraw,columns:[],order:[],start:l,length:m,search:{value:e.sSearch,regex:e.bRegex}};for(l=0;l<c;l++){var u=b[l];var ra=h[l];m="function"==typeof u.mData?"function":u.mData;n.columns.push({data:m,name:u.sName,searchable:u.bSearchable,orderable:u.bSortable,search:{value:ra.sSearch,regex:ra.bRegex}});p("mDataProp_"+l,m);d.bFilter&&
(p("sSearch_"+l,ra.sSearch),p("bRegex_"+l,ra.bRegex),p("bSearchable_"+l,u.bSearchable));d.bSort&&p("bSortable_"+l,u.bSortable)}d.bFilter&&(p("sSearch",e.sSearch),p("bRegex",e.bRegex));d.bSort&&(f.each(k,function(a,b){n.order.push({column:b.col,dir:b.dir});p("iSortCol_"+a,b.col);p("sSortDir_"+a,b.dir)}),p("iSortingCols",k.length));b=q.ext.legacy.ajax;return null===b?a.sAjaxSource?g:n:b?g:n}function zb(a,b){var c=function(a,c){return b[a]!==n?b[a]:b[c]},d=va(a,b),e=c("sEcho","draw"),h=c("iTotalRecords",
"recordsTotal");c=c("iTotalDisplayRecords","recordsFiltered");if(e!==n){if(1*e<a.iDraw)return;a.iDraw=1*e}pa(a);a._iRecordsTotal=parseInt(h,10);a._iRecordsDisplay=parseInt(c,10);e=0;for(h=d.length;e<h;e++)R(a,d[e]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;S(a);a._bInitComplete||wa(a,b);a.bAjaxDataGet=!0;J(a,!1)}function va(a,b){a=f.isPlainObject(a.ajax)&&a.ajax.dataSrc!==n?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===a?b.aaData||b[a]:""!==a?T(a)(b):b}function tb(a){var b=a.oClasses,
c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,h=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',k=d.sSearch;k=k.match(/_INPUT_/)?k.replace("_INPUT_",g):k+g;b=f("<div/>",{id:h.f?null:c+"_filter","class":b.sFilter}).append(f("<label/>").append(k));var l=function(){var b=this.value?this.value:"";b!=e.sSearch&&(ha(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,S(a))};h=null!==a.searchDelay?a.searchDelay:"ssp"===I(a)?400:0;var m=
f("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",h?Ra(l,h):l).on("mouseup",function(a){setTimeout(function(){l.call(m[0])},10)}).on("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);f(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{m[0]!==w.activeElement&&m.val(e.sSearch)}catch(u){}});return b[0]}function ha(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,h=function(a){d.sSearch=a.sSearch;d.bRegex=
a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive},g=function(a){return a.bEscapeRegex!==n?!a.bEscapeRegex:a.bRegex};Ja(a);if("ssp"!=I(a)){Ab(a,b.sSearch,c,g(b),b.bSmart,b.bCaseInsensitive);h(b);for(b=0;b<e.length;b++)Bb(a,e[b].sSearch,b,g(e[b]),e[b].bSmart,e[b].bCaseInsensitive);Cb(a)}else h(b);a.bFiltered=!0;A(a,null,"search",[a])}function Cb(a){for(var b=q.ext.search,c=a.aiDisplay,d,e,h=0,g=b.length;h<g;h++){for(var k=[],l=0,m=c.length;l<m;l++)e=c[l],d=a.aoData[e],b[h](a,d._aFilterData,
e,d._aData,l)&&k.push(e);c.length=0;f.merge(c,k)}}function Bb(a,b,c,d,e,h){if(""!==b){var g=[],k=a.aiDisplay;d=Sa(b,d,e,h);for(e=0;e<k.length;e++)b=a.aoData[k[e]]._aFilterData[c],d.test(b)&&g.push(k[e]);a.aiDisplay=g}}function Ab(a,b,c,d,e,h){e=Sa(b,d,e,h);var g=a.oPreviousSearch.sSearch,k=a.aiDisplayMaster;h=[];0!==q.ext.search.length&&(c=!0);var f=Db(a);if(0>=b.length)a.aiDisplay=k.slice();else{if(f||c||d||g.length>b.length||0!==b.indexOf(g)||a.bSorted)a.aiDisplay=k.slice();b=a.aiDisplay;for(c=
0;c<b.length;c++)e.test(a.aoData[b[c]]._sFilterRow)&&h.push(b[c]);a.aiDisplay=h}}function Sa(a,b,c,d){a=b?a:Ta(a);c&&(a="^(?=.*?"+f.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0)){var b=a.match(/^"(.*)"$/);a=b?b[1]:a}return a.replace('"',"")}).join(")(?=.*?")+").*$");return new RegExp(a,d?"i":"")}function Db(a){var b=a.aoColumns,c,d,e=q.ext.type.search;var h=!1;var g=0;for(c=a.aoData.length;g<c;g++){var k=a.aoData[g];if(!k._aFilterData){var f=[];var m=0;for(d=b.length;m<d;m++){h=
b[m];if(h.bSearchable){var p=F(a,g,m,"filter");e[h.sType]&&(p=e[h.sType](p));null===p&&(p="");"string"!==typeof p&&p.toString&&(p=p.toString())}else p="";p.indexOf&&-1!==p.indexOf("&")&&(xa.innerHTML=p,p=$b?xa.textContent:xa.innerText);p.replace&&(p=p.replace(/[\r\n\u2028]/g,""));f.push(p)}k._aFilterData=f;k._sFilterRow=f.join(" ");h=!0}}return h}function Eb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}function Fb(a){return{sSearch:a.search,bSmart:a.smart,
bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function wb(a){var b=a.sTableId,c=a.aanFeatures.i,d=f("<div/>",{"class":a.oClasses.sInfo,id:c?null:b+"_info"});c||(a.aoDrawCallback.push({fn:Gb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),f(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Gb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),h=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),k=g?c.sInfo:c.sInfoEmpty;
g!==h&&(k+=" "+c.sInfoFiltered);k+=c.sInfoPostFix;k=Hb(a,k);c=c.fnInfoCallback;null!==c&&(k=c.call(a.oInstance,a,d,e,h,g,k));f(b).html(k)}}function Hb(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,h=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,h)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(h/
e)))}function ia(a){var b=a.iInitDisplayStart,c=a.aoColumns;var d=a.oFeatures;var e=a.bDeferLoading;if(a.bInitialised){rb(a);ob(a);fa(a,a.aoHeader);fa(a,a.aoFooter);J(a,!0);d.bAutoWidth&&Ia(a);var h=0;for(d=c.length;h<d;h++){var g=c[h];g.sWidth&&(g.nTh.style.width=B(g.sWidth))}A(a,null,"preInit",[a]);U(a);c=I(a);if("ssp"!=c||e)"ajax"==c?ua(a,[],function(c){var d=va(a,c);for(h=0;h<d.length;h++)R(a,d[h]);a.iInitDisplayStart=b;U(a);J(a,!1);wa(a,c)},a):(J(a,!1),wa(a))}else setTimeout(function(){ia(a)},
200)}function wa(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Z(a);A(a,null,"plugin-init",[a,b]);A(a,"aoInitComplete","init",[a,b])}function Ua(a,b){b=parseInt(b,10);a._iDisplayLength=b;Va(a);A(a,null,"length",[a,b])}function sb(a){var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=f.isArray(d[0]),h=e?d[0]:d;d=e?d[1]:d;e=f("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect});for(var g=0,k=h.length;g<k;g++)e[0][g]=new Option("number"===typeof d[g]?a.fnFormatNumber(d[g]):d[g],h[g]);
var l=f("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(l[0].id=c+"_length");l.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));f("select",l).val(a._iDisplayLength).on("change.DT",function(b){Ua(a,f(this).val());S(a)});f(a.nTable).on("length.dt.DT",function(b,c,d){a===c&&f("select",l).val(d)});return l[0]}function xb(a){var b=a.sPaginationType,c=q.ext.pager[b],d="function"===typeof c,e=function(a){S(a)};b=f("<div/>").addClass(a.oClasses.sPaging+b)[0];var h=
a.aanFeatures;d||c.fnInit(a,b,e);h.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,g=a._iDisplayLength,f=a.fnRecordsDisplay(),p=-1===g;b=p?0:Math.ceil(b/g);g=p?1:Math.ceil(f/g);f=c(b,g);var n;p=0;for(n=h.p.length;p<n;p++)Qa(a,"pageButton")(a,h.p[p],p,f,b,g)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Wa(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,h=a.fnRecordsDisplay();0===h||-1===e?d=0:"number"===typeof b?(d=b*e,d>h&&(d=0)):
"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<h&&(d+=e):"last"==b?d=Math.floor((h-1)/e)*e:O(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(A(a,null,"page",[a]),c&&S(a));return b}function ub(a){return f("<div/>",{id:a.aanFeatures.r?null:a.sTableId+"_processing","class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function J(a,b){a.oFeatures.bProcessing&&f(a.aanFeatures.r).css("display",b?"block":"none");A(a,
null,"processing",[a,b])}function vb(a){var b=f(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,h=a.oClasses,g=b.children("caption"),k=g.length?g[0]._captionSide:null,l=f(b[0].cloneNode(!1)),m=f(b[0].cloneNode(!1)),p=b.children("tfoot");p.length||(p=null);l=f("<div/>",{"class":h.sScrollWrapper}).append(f("<div/>",{"class":h.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?d?B(d):null:"100%"}).append(f("<div/>",{"class":h.sScrollHeadInner}).css({"box-sizing":"content-box",
width:c.sXInner||"100%"}).append(l.removeAttr("id").css("margin-left",0).append("top"===k?g:null).append(b.children("thead"))))).append(f("<div/>",{"class":h.sScrollBody}).css({position:"relative",overflow:"auto",width:d?B(d):null}).append(b));p&&l.append(f("<div/>",{"class":h.sScrollFoot}).css({overflow:"hidden",border:0,width:d?d?B(d):null:"100%"}).append(f("<div/>",{"class":h.sScrollFootInner}).append(m.removeAttr("id").css("margin-left",0).append("bottom"===k?g:null).append(b.children("tfoot")))));
b=l.children();var n=b[0];h=b[1];var u=p?b[2]:null;if(d)f(h).on("scroll.DT",function(a){a=this.scrollLeft;n.scrollLeft=a;p&&(u.scrollLeft=a)});f(h).css("max-height",e);c.bCollapse||f(h).css("height",e);a.nScrollHead=n;a.nScrollBody=h;a.nScrollFoot=u;a.aoDrawCallback.push({fn:ma,sName:"scrolling"});return l[0]}function ma(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY;b=b.iBarWidth;var h=f(a.nScrollHead),g=h[0].style,k=h.children("div"),l=k[0].style,m=k.children("table");k=a.nScrollBody;var p=f(k),v=
k.style,u=f(a.nScrollFoot).children("div"),q=u.children("table"),t=f(a.nTHead),r=f(a.nTable),x=r[0],ya=x.style,w=a.nTFoot?f(a.nTFoot):null,y=a.oBrowser,A=y.bScrollOversize,ac=K(a.aoColumns,"nTh"),Xa=[],z=[],C=[],G=[],H,I=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};var D=k.scrollHeight>k.clientHeight;if(a.scrollBarVis!==D&&a.scrollBarVis!==n)a.scrollBarVis=D,Z(a);else{a.scrollBarVis=D;r.children("thead, tfoot").remove();if(w){var E=
w.clone().prependTo(r);var F=w.find("tr");E=E.find("tr")}var J=t.clone().prependTo(r);t=t.find("tr");D=J.find("tr");J.find("th, td").removeAttr("tabindex");c||(v.width="100%",h[0].style.width="100%");f.each(ta(a,J),function(b,c){H=aa(a,b);c.style.width=a.aoColumns[H].sWidth});w&&N(function(a){a.style.width=""},E);h=r.outerWidth();""===c?(ya.width="100%",A&&(r.find("tbody").height()>k.offsetHeight||"scroll"==p.css("overflow-y"))&&(ya.width=B(r.outerWidth()-b)),h=r.outerWidth()):""!==d&&(ya.width=B(d),
h=r.outerWidth());N(I,D);N(function(a){C.push(a.innerHTML);Xa.push(B(f(a).css("width")))},D);N(function(a,b){-1!==f.inArray(a,ac)&&(a.style.width=Xa[b])},t);f(D).height(0);w&&(N(I,E),N(function(a){G.push(a.innerHTML);z.push(B(f(a).css("width")))},E),N(function(a,b){a.style.width=z[b]},F),f(E).height(0));N(function(a,b){a.innerHTML='<div class="dataTables_sizing">'+C[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=Xa[b]},D);w&&N(function(a,b){a.innerHTML=
'<div class="dataTables_sizing">'+G[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=z[b]},E);r.outerWidth()<h?(F=k.scrollHeight>k.offsetHeight||"scroll"==p.css("overflow-y")?h+b:h,A&&(k.scrollHeight>k.offsetHeight||"scroll"==p.css("overflow-y"))&&(ya.width=B(F-b)),""!==c&&""===d||O(a,1,"Possible column misalignment",6)):F="100%";v.width=B(F);g.width=B(F);w&&(a.nScrollFoot.style.width=B(F));!e&&A&&(v.height=B(x.offsetHeight+b));c=r.outerWidth();m[0].style.width=
B(c);l.width=B(c);d=r.height()>k.clientHeight||"scroll"==p.css("overflow-y");e="padding"+(y.bScrollbarLeft?"Left":"Right");l[e]=d?b+"px":"0px";w&&(q[0].style.width=B(c),u[0].style.width=B(c),u[0].style[e]=d?b+"px":"0px");r.children("colgroup").insertBefore(r.children("thead"));p.trigger("scroll");!a.bSorted&&!a.bFiltered||a._drawHold||(k.scrollTop=0)}}function N(a,b,c){for(var d=0,e=0,h=b.length,g,k;e<h;){g=b[e].firstChild;for(k=c?c[e].firstChild:null;g;)1===g.nodeType&&(c?a(g,k,d):a(g,d),d++),g=
g.nextSibling,k=c?k.nextSibling:null;e++}}function Ia(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,h=d.sX,g=d.sXInner,k=c.length,l=na(a,"bVisible"),m=f("th",a.nTHead),p=b.getAttribute("width"),n=b.parentNode,u=!1,q,t=a.oBrowser;d=t.bScrollOversize;(q=b.style.width)&&-1!==q.indexOf("%")&&(p=q);for(q=0;q<l.length;q++){var r=c[l[q]];null!==r.sWidth&&(r.sWidth=Ib(r.sWidthOrig,n),u=!0)}if(d||!u&&!h&&!e&&k==V(a)&&k==m.length)for(q=0;q<k;q++)l=aa(a,q),null!==l&&(c[l].sWidth=B(m.eq(q).width()));else{k=
f(b).clone().css("visibility","hidden").removeAttr("id");k.find("tbody tr").remove();var w=f("<tr/>").appendTo(k.find("tbody"));k.find("thead, tfoot").remove();k.append(f(a.nTHead).clone()).append(f(a.nTFoot).clone());k.find("tfoot th, tfoot td").css("width","");m=ta(a,k.find("thead")[0]);for(q=0;q<l.length;q++)r=c[l[q]],m[q].style.width=null!==r.sWidthOrig&&""!==r.sWidthOrig?B(r.sWidthOrig):"",r.sWidthOrig&&h&&f(m[q]).append(f("<div/>").css({width:r.sWidthOrig,margin:0,padding:0,border:0,height:1}));
if(a.aoData.length)for(q=0;q<l.length;q++)u=l[q],r=c[u],f(Jb(a,u)).clone(!1).append(r.sContentPadding).appendTo(w);f("[name]",k).removeAttr("name");r=f("<div/>").css(h||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(k).appendTo(n);h&&g?k.width(g):h?(k.css("width","auto"),k.removeAttr("width"),k.width()<n.clientWidth&&p&&k.width(n.clientWidth)):e?k.width(n.clientWidth):p&&k.width(p);for(q=e=0;q<l.length;q++)n=f(m[q]),g=n.outerWidth()-n.width(),n=t.bBounding?Math.ceil(m[q].getBoundingClientRect().width):
n.outerWidth(),e+=n,c[l[q]].sWidth=B(n-g);b.style.width=B(e);r.remove()}p&&(b.style.width=B(p));!p&&!h||a._reszEvt||(b=function(){f(y).on("resize.DT-"+a.sInstance,Ra(function(){Z(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0)}function Ib(a,b){if(!a)return 0;a=f("<div/>").css("width",B(a)).appendTo(b||w.body);b=a[0].offsetWidth;a.remove();return b}function Jb(a,b){var c=Kb(a,b);if(0>c)return null;var d=a.aoData[c];return d.nTr?d.anCells[b]:f("<td/>").html(F(a,c,b,"display"))[0]}function Kb(a,b){for(var c,
d=-1,e=-1,h=0,g=a.aoData.length;h<g;h++)c=F(a,h,b,"display")+"",c=c.replace(bc,""),c=c.replace(/&nbsp;/g," "),c.length>d&&(d=c.length,e=h);return e}function B(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function X(a){var b=[],c=a.aoColumns;var d=a.aaSortingFixed;var e=f.isPlainObject(d);var h=[];var g=function(a){a.length&&!f.isArray(a[0])?h.push(a):f.merge(h,a)};f.isArray(d)&&g(d);e&&d.pre&&g(d.pre);g(a.aaSorting);e&&d.post&&g(d.post);for(a=0;a<h.length;a++){var k=
h[a][0];g=c[k].aDataSort;d=0;for(e=g.length;d<e;d++){var l=g[d];var m=c[l].sType||"string";h[a]._idx===n&&(h[a]._idx=f.inArray(h[a][1],c[l].asSorting));b.push({src:k,col:l,dir:h[a][1],index:h[a]._idx,type:m,formatter:q.ext.type.order[m+"-pre"]})}}return b}function qb(a){var b,c=[],d=q.ext.type.order,e=a.aoData,h=0,g=a.aiDisplayMaster;Ja(a);var k=X(a);var f=0;for(b=k.length;f<b;f++){var m=k[f];m.formatter&&h++;Lb(a,m.col)}if("ssp"!=I(a)&&0!==k.length){f=0;for(b=g.length;f<b;f++)c[g[f]]=f;h===k.length?
g.sort(function(a,b){var d,h=k.length,g=e[a]._aSortData,f=e[b]._aSortData;for(d=0;d<h;d++){var l=k[d];var m=g[l.col];var p=f[l.col];m=m<p?-1:m>p?1:0;if(0!==m)return"asc"===l.dir?m:-m}m=c[a];p=c[b];return m<p?-1:m>p?1:0}):g.sort(function(a,b){var h,g=k.length,f=e[a]._aSortData,l=e[b]._aSortData;for(h=0;h<g;h++){var m=k[h];var p=f[m.col];var n=l[m.col];m=d[m.type+"-"+m.dir]||d["string-"+m.dir];p=m(p,n);if(0!==p)return p}p=c[a];n=c[b];return p<n?-1:p>n?1:0})}a.bSorted=!0}function Mb(a){var b=a.aoColumns,
c=X(a);a=a.oLanguage.oAria;for(var d=0,e=b.length;d<e;d++){var h=b[d];var g=h.asSorting;var k=h.sTitle.replace(/<.*?>/g,"");var f=h.nTh;f.removeAttribute("aria-sort");h.bSortable&&(0<c.length&&c[0].col==d?(f.setAttribute("aria-sort","asc"==c[0].dir?"ascending":"descending"),h=g[c[0].index+1]||g[0]):h=g[0],k+="asc"===h?a.sSortAscending:a.sSortDescending);f.setAttribute("aria-label",k)}}function Ya(a,b,c,d){var e=a.aaSorting,h=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===n&&(c=f.inArray(a[1],
h));return c+1<h.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=f.inArray(b,K(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=h[b],e[c]._idx=b)):(e.push([b,h[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=h[b],e[0]._idx=b):(e.length=0,e.push([b,h[0]]),e[0]._idx=0);U(a);"function"==typeof d&&d(a)}function Pa(a,b,c,d){var e=a.aoColumns[c];Za(b,{},function(b){!1!==e.bSortable&&
(a.oFeatures.bProcessing?(J(a,!0),setTimeout(function(){Ya(a,c,b.shiftKey,d);"ssp"!==I(a)&&J(a,!1)},0)):Ya(a,c,b.shiftKey,d))})}function za(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=X(a),e=a.oFeatures,h;if(e.bSort&&e.bSortClasses){e=0;for(h=b.length;e<h;e++){var g=b[e].src;f(K(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3))}e=0;for(h=d.length;e<h;e++)g=d[e].src,f(K(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Lb(a,b){var c=a.aoColumns[b],d=q.ext.order[c.sSortDataType],
e;d&&(e=d.call(a.oInstance,a,b,ba(a,b)));for(var h,g=q.ext.type.order[c.sType+"-pre"],f=0,l=a.aoData.length;f<l;f++)if(c=a.aoData[f],c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)h=d?e[f]:F(a,f,b,"sort"),c._aSortData[b]=g?g(h):h}function Aa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:f.extend(!0,[],a.aaSorting),search:Eb(a.oPreviousSearch),columns:f.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Eb(a.aoPreSearchCols[d])}})};
A(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Nb(a,b,c){var d,e,h=a.aoColumns;b=function(b){if(b&&b.time){var g=A(a,"aoStateLoadParams","stateLoadParams",[a,b]);if(-1===f.inArray(!1,g)&&(g=a.iStateDuration,!(0<g&&b.time<+new Date-1E3*g||b.columns&&h.length!==b.columns.length))){a.oLoadedState=f.extend(!0,{},b);b.start!==n&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==n&&(a._iDisplayLength=b.length);b.order!==
n&&(a.aaSorting=[],f.each(b.order,function(b,c){a.aaSorting.push(c[0]>=h.length?[0,c[1]]:c)}));b.search!==n&&f.extend(a.oPreviousSearch,Fb(b.search));if(b.columns)for(d=0,e=b.columns.length;d<e;d++)g=b.columns[d],g.visible!==n&&(h[d].bVisible=g.visible),g.search!==n&&f.extend(a.aoPreSearchCols[d],Fb(g.search));A(a,"aoStateLoaded","stateLoaded",[a,b])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==n&&b(g)}else c()}function Ba(a){var b=q.settings;a=f.inArray(a,
K(b,"nTable"));return-1!==a?b[a]:null}function O(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)y.console&&console.log&&console.log(c);else if(b=q.ext,b=b.sErrMode||b.errMode,a&&A(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function M(a,b,c,d){f.isArray(c)?f.each(c,function(c,d){f.isArray(d)?M(a,b,d[0],d[1]):M(a,b,
d)}):(d===n&&(d=c),b[c]!==n&&(a[d]=b[c]))}function $a(a,b,c){var d;for(d in b)if(b.hasOwnProperty(d)){var e=b[d];f.isPlainObject(e)?(f.isPlainObject(a[d])||(a[d]={}),f.extend(!0,a[d],e)):c&&"data"!==d&&"aaData"!==d&&f.isArray(e)?a[d]=e.slice():a[d]=e}return a}function Za(a,b,c){f(a).on("click.DT",b,function(b){f(a).trigger("blur");c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function D(a,b,c,d){c&&a[b].push({fn:c,sName:d})}
function A(a,b,c,d){var e=[];b&&(e=f.map(a[b].slice().reverse(),function(b,c){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=f.Event(c+".dt"),f(a.nTable).trigger(b,d),e.push(b.result));return e}function Va(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Qa(a,b){a=a.renderer;var c=q.ext.renderer[b];return f.isPlainObject(a)&&a[b]?c[a[b]]||c._:"string"===typeof a?c[a]||c._:c._}function I(a){return a.oFeatures.bServerSide?
"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ja(a,b){var c=Ob.numbers_length,d=Math.floor(c/2);b<=c?a=Y(0,b):a<=d?(a=Y(0,c-2),a.push("ellipsis"),a.push(b-1)):(a>=b-1-d?a=Y(b-(c-2),b):(a=Y(a-d+2,a+d-1),a.push("ellipsis"),a.push(b-1)),a.splice(0,0,"ellipsis"),a.splice(0,0,0));a.DT_el="span";return a}function Ga(a){f.each({num:function(b){return Ca(b,a)},"num-fmt":function(b){return Ca(b,a,ab)},"html-num":function(b){return Ca(b,a,Da)},"html-num-fmt":function(b){return Ca(b,a,Da,ab)}},function(b,
c){C.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(C.type.search[b+a]=C.type.search.html)})}function Pb(a){return function(){var b=[Ba(this[q.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return q.ext.internal[a].apply(this,b)}}var q=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new x(Ba(this[C.iApiIndex])):new x(this)};this.fnAddData=function(a,b){var c=this.api(!0);a=f.isArray(a)&&
(f.isArray(a[0])||f.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===n||b)&&c.draw();return a.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===n||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&ma(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===n||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0);a=d.rows(a);var e=a.settings()[0],h=e.aoData[a[0][0]];
a.remove();b&&b.call(this,e,h);(c===n||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,f){e=this.api(!0);null===b||b===n?e.search(a,c,d,f):e.column(b).search(a,c,d,f);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==n){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==n||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=
function(a){var b=this.api(!0);return a!==n?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){a=this.api(!0).page(a);(b===n||
b)&&a.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===n||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Ba(this[C.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===n||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===n||e)&&h.columns.adjust();(d===n||d)&&h.draw();return 0};this.fnVersionCheck=C.fnVersionCheck;
var b=this,c=a===n,d=this.length;c&&(a={});this.oApi=this.internal=C.internal;for(var e in q.ext.internal)e&&(this[e]=Pb(e));this.each(function(){var e={},g=1<d?$a(e,a,!0):a,k=0,l;e=this.getAttribute("id");var m=!1,p=q.defaults,v=f(this);if("table"!=this.nodeName.toLowerCase())O(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{ib(p);jb(p.column);L(p,p,!0);L(p.column,p.column,!0);L(p,f.extend(g,v.data()),!0);var u=q.settings;k=0;for(l=u.length;k<l;k++){var t=u[k];if(t.nTable==this||
t.nTHead&&t.nTHead.parentNode==this||t.nTFoot&&t.nTFoot.parentNode==this){var w=g.bRetrieve!==n?g.bRetrieve:p.bRetrieve;if(c||w)return t.oInstance;if(g.bDestroy!==n?g.bDestroy:p.bDestroy){t.oInstance.fnDestroy();break}else{O(t,0,"Cannot reinitialise DataTable",3);return}}if(t.sTableId==this.id){u.splice(k,1);break}}if(null===e||""===e)this.id=e="DataTables_Table_"+q.ext._unique++;var r=f.extend(!0,{},q.models.oSettings,{sDestroyWidth:v[0].style.width,sInstance:e,sTableId:e});r.nTable=this;r.oApi=
b.internal;r.oInit=g;u.push(r);r.oInstance=1===b.length?b:v.dataTable();ib(g);Fa(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=f.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);g=$a(f.extend(!0,{},p),g);M(r.oFeatures,g,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));M(r,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu",
"sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"]]);M(r.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);M(r.oLanguage,g,"fnInfoCallback");D(r,"aoDrawCallback",g.fnDrawCallback,
"user");D(r,"aoServerParams",g.fnServerParams,"user");D(r,"aoStateSaveParams",g.fnStateSaveParams,"user");D(r,"aoStateLoadParams",g.fnStateLoadParams,"user");D(r,"aoStateLoaded",g.fnStateLoaded,"user");D(r,"aoRowCallback",g.fnRowCallback,"user");D(r,"aoRowCreatedCallback",g.fnCreatedRow,"user");D(r,"aoHeaderCallback",g.fnHeaderCallback,"user");D(r,"aoFooterCallback",g.fnFooterCallback,"user");D(r,"aoInitComplete",g.fnInitComplete,"user");D(r,"aoPreDrawCallback",g.fnPreDrawCallback,"user");r.rowIdFn=
T(g.rowId);kb(r);var x=r.oClasses;f.extend(x,q.ext.classes,g.oClasses);v.addClass(x.sTable);r.iInitDisplayStart===n&&(r.iInitDisplayStart=g.iDisplayStart,r._iDisplayStart=g.iDisplayStart);null!==g.iDeferLoading&&(r.bDeferLoading=!0,e=f.isArray(g.iDeferLoading),r._iRecordsDisplay=e?g.iDeferLoading[0]:g.iDeferLoading,r._iRecordsTotal=e?g.iDeferLoading[1]:g.iDeferLoading);var y=r.oLanguage;f.extend(!0,y,g.oLanguage);y.sUrl&&(f.ajax({dataType:"json",url:y.sUrl,success:function(a){Fa(a);L(p.oLanguage,
a);f.extend(!0,y,a);ia(r)},error:function(){ia(r)}}),m=!0);null===g.asStripeClasses&&(r.asStripeClasses=[x.sStripeOdd,x.sStripeEven]);e=r.asStripeClasses;var z=v.children("tbody").find("tr").eq(0);-1!==f.inArray(!0,f.map(e,function(a,b){return z.hasClass(a)}))&&(f("tbody tr",this).removeClass(e.join(" ")),r.asDestroyStripes=e.slice());e=[];u=this.getElementsByTagName("thead");0!==u.length&&(ea(r.aoHeader,u[0]),e=ta(r));if(null===g.aoColumns)for(u=[],k=0,l=e.length;k<l;k++)u.push(null);else u=g.aoColumns;
k=0;for(l=u.length;k<l;k++)Ha(r,e?e[k]:null);mb(r,g.aoColumnDefs,u,function(a,b){la(r,a,b)});if(z.length){var B=function(a,b){return null!==a.getAttribute("data-"+b)?b:null};f(z[0]).children("th, td").each(function(a,b){var c=r.aoColumns[a];if(c.mData===a){var d=B(b,"sort")||B(b,"order");b=B(b,"filter")||B(b,"search");if(null!==d||null!==b)c.mData={_:a+".display",sort:null!==d?a+".@data-"+d:n,type:null!==d?a+".@data-"+d:n,filter:null!==b?a+".@data-"+b:n},la(r,a)}})}var C=r.oFeatures;e=function(){if(g.aaSorting===
n){var a=r.aaSorting;k=0;for(l=a.length;k<l;k++)a[k][1]=r.aoColumns[k].asSorting[0]}za(r);C.bSort&&D(r,"aoDrawCallback",function(){if(r.bSorted){var a=X(r),b={};f.each(a,function(a,c){b[c.src]=c.dir});A(r,null,"order",[r,a,b]);Mb(r)}});D(r,"aoDrawCallback",function(){(r.bSorted||"ssp"===I(r)||C.bDeferRender)&&za(r)},"sc");a=v.children("caption").each(function(){this._captionSide=f(this).css("caption-side")});var b=v.children("thead");0===b.length&&(b=f("<thead/>").appendTo(v));r.nTHead=b[0];b=v.children("tbody");
0===b.length&&(b=f("<tbody/>").appendTo(v));r.nTBody=b[0];b=v.children("tfoot");0===b.length&&0<a.length&&(""!==r.oScroll.sX||""!==r.oScroll.sY)&&(b=f("<tfoot/>").appendTo(v));0===b.length||0===b.children().length?v.addClass(x.sNoFooter):0<b.length&&(r.nTFoot=b[0],ea(r.aoFooter,r.nTFoot));if(g.aaData)for(k=0;k<g.aaData.length;k++)R(r,g.aaData[k]);else(r.bDeferLoading||"dom"==I(r))&&oa(r,f(r.nTBody).children("tr"));r.aiDisplay=r.aiDisplayMaster.slice();r.bInitialised=!0;!1===m&&ia(r)};g.bStateSave?
(C.bStateSave=!0,D(r,"aoDrawCallback",Aa,"state_save"),Nb(r,g,e)):e()}});b=null;return this},C,t,z,bb={},Qb=/[\r\n\u2028]/g,Da=/<.*?>/g,cc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,dc=/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\|\$|\^|\-)/g,ab=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,P=function(a){return a&&!0!==a&&"-"!==a?!1:!0},Rb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Sb=function(a,b){bb[b]||(bb[b]=new RegExp(Ta(b),"g"));
return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(bb[b],"."):a},cb=function(a,b,c){var d="string"===typeof a;if(P(a))return!0;b&&d&&(a=Sb(a,b));c&&d&&(a=a.replace(ab,""));return!isNaN(parseFloat(a))&&isFinite(a)},Tb=function(a,b,c){return P(a)?!0:P(a)||"string"===typeof a?cb(a.replace(Da,""),b,c)?!0:null:null},K=function(a,b,c){var d=[],e=0,h=a.length;if(c!==n)for(;e<h;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<h;e++)a[e]&&d.push(a[e][b]);return d},ka=function(a,b,c,d){var e=[],
h=0,g=b.length;if(d!==n)for(;h<g;h++)a[b[h]][c]&&e.push(a[b[h]][c][d]);else for(;h<g;h++)e.push(a[b[h]][c]);return e},Y=function(a,b){var c=[];if(b===n){b=0;var d=a}else d=b,b=a;for(a=b;a<d;a++)c.push(a);return c},Ub=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},sa=function(a){a:{if(!(2>a.length)){var b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d<e;d++){if(b[d]===c){b=!1;break a}c=b[d]}}b=!0}if(b)return a.slice();b=[];e=a.length;var h,g=0;d=0;a:for(;d<e;d++){c=
a[d];for(h=0;h<g;h++)if(b[h]===c)continue a;b.push(c);g++}return b};q.util={throttle:function(a,b){var c=b!==n?b:200,d,e;return function(){var b=this,g=+new Date,f=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=n;a.apply(b,f)},c)):(d=g,a.apply(b,f))}},escapeRegex:function(a){return a.replace(dc,"\\$1")}};var E=function(a,b,c){a[b]!==n&&(a[c]=a[b])},ca=/\[.*?\]$/,W=/\(\)$/,Ta=q.util.escapeRegex,xa=f("<div>")[0],$b=xa.textContent!==n,bc=/<.*?>/g,Ra=q.util.throttle,Vb=[],G=Array.prototype,
ec=function(a){var b,c=q.settings,d=f.map(c,function(a,b){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase()){var e=f.inArray(a,d);return-1!==e?[c[e]]:null}if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?b=f(a):a instanceof f&&(b=a)}else return[];if(b)return b.map(function(a){e=f.inArray(this,d);return-1!==e?c[e]:null}).toArray()};var x=function(a,b){if(!(this instanceof x))return new x(a,b);var c=[],d=function(a){(a=
ec(a))&&c.push.apply(c,a)};if(f.isArray(a))for(var e=0,h=a.length;e<h;e++)d(a[e]);else d(a);this.context=sa(c);b&&f.merge(this,b);this.selector={rows:null,cols:null,opts:null};x.extend(this,this,Vb)};q.Api=x;f.extend(x.prototype,{any:function(){return 0!==this.count()},concat:G.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new x(b[a],this[a]):
null},filter:function(a){var b=[];if(G.filter)b=G.filter.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new x(this.context,b)},flatten:function(){var a=[];return new x(this.context,a.concat.apply(a,this.toArray()))},join:G.join,indexOf:G.indexOf||function(a,b){b=b||0;for(var c=this.length;b<c;b++)if(this[b]===a)return b;return-1},iterator:function(a,b,c,d){var e=[],h,g,f=this.context,l,m=this.selector;"string"===typeof a&&(d=c,c=b,b=a,
a=!1);var p=0;for(h=f.length;p<h;p++){var q=new x(f[p]);if("table"===b){var u=c.call(q,f[p],p);u!==n&&e.push(u)}else if("columns"===b||"rows"===b)u=c.call(q,f[p],this[p],p),u!==n&&e.push(u);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){var t=this[p];"column-rows"===b&&(l=Ea(f[p],m.opts));var w=0;for(g=t.length;w<g;w++)u=t[w],u="cell"===b?c.call(q,f[p],u.row,u.column,p,w):c.call(q,f[p],u,p,w,l),u!==n&&e.push(u)}}return e.length||d?(a=new x(f,a?e.concat.apply([],e):e),b=a.selector,
b.rows=m.rows,b.cols=m.cols,b.opts=m.opts,a):this},lastIndexOf:G.lastIndexOf||function(a,b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(G.map)b=G.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new x(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:G.pop,push:G.push,reduce:G.reduce||function(a,b){return lb(this,a,b,0,this.length,1)},reduceRight:G.reduceRight||function(a,
b){return lb(this,a,b,this.length-1,-1,-1)},reverse:G.reverse,selector:null,shift:G.shift,slice:function(){return new x(this.context,this)},sort:G.sort,splice:G.splice,toArray:function(){return G.slice.call(this)},to$:function(){return f(this)},toJQuery:function(){return f(this)},unique:function(){return new x(this.context,sa(this))},unshift:G.unshift});x.extend=function(a,b,c){if(c.length&&b&&(b instanceof x||b.__dt_wrapper)){var d,e=function(a,b,c){return function(){var d=b.apply(a,arguments);x.extend(d,
d,c.methodExt);return d}};var h=0;for(d=c.length;h<d;h++){var f=c[h];b[f.name]="function"===f.type?e(a,f.val,f):"object"===f.type?{}:f.val;b[f.name].__dt_wrapper=!0;x.extend(a,b[f.name],f.propExt)}}};x.register=t=function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)x.register(a[c],b);else{d=a.split(".");var e=Vb,h;a=0;for(c=d.length;a<c;a++){var g=(h=-1!==d[a].indexOf("()"))?d[a].replace("()",""):d[a];a:{var k=0;for(var l=e.length;k<l;k++)if(e[k].name===g){k=e[k];break a}k=null}k||(k={name:g,
val:{},methodExt:[],propExt:[],type:"object"},e.push(k));a===c-1?(k.val=b,k.type="function"===typeof b?"function":f.isPlainObject(b)?"object":"other"):e=h?k.methodExt:k.propExt}}};x.registerPlural=z=function(a,b,c){x.register(a,c);x.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof x?a.length?f.isArray(a[0])?new x(a.context,a[0]):a[0]:n:a})};var Wb=function(a,b){if(f.isArray(a))return f.map(a,function(a){return Wb(a,b)});if("number"===typeof a)return[b[a]];var c=
f.map(b,function(a,b){return a.nTable});return f(c).filter(a).map(function(a){a=f.inArray(this,c);return b[a]}).toArray()};t("tables()",function(a){return a!==n&&null!==a?new x(Wb(a,this.context)):this});t("table()",function(a){a=this.tables(a);var b=a.context;return b.length?new x(b[0]):a});z("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});z("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},
1)});z("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});z("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});z("tables().containers()","table().container()",function(){return this.iterator("table",function(a){return a.nTableWrapper},1)});t("draw()",function(a){return this.iterator("table",function(b){"page"===a?S(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),U(b,!1===
a))})});t("page()",function(a){return a===n?this.page.info().page:this.iterator("table",function(b){Wa(b,a)})});t("page.info()",function(a){if(0===this.context.length)return n;a=this.context[0];var b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:"ssp"===I(a)}});t("page.len()",function(a){return a===
n?0!==this.context.length?this.context[0]._iDisplayLength:n:this.iterator("table",function(b){Ua(b,a)})});var Xb=function(a,b,c){if(c){var d=new x(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==I(a))U(a,b);else{J(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ua(a,[],function(c){pa(a);c=va(a,c);for(var d=0,e=c.length;d<e;d++)R(a,c[d]);U(a,b);J(a,!1)})}};t("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});t("ajax.params()",function(){var a=this.context;if(0<
a.length)return a[0].oAjaxData});t("ajax.reload()",function(a,b){return this.iterator("table",function(c){Xb(c,!1===b,a)})});t("ajax.url()",function(a){var b=this.context;if(a===n){if(0===b.length)return n;b=b[0];return b.ajax?f.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){f.isPlainObject(b.ajax)?b.ajax.url=a:b.ajax=a})});t("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Xb(c,!1===b,a)})});var db=function(a,b,c,d,e){var h=
[],g,k,l;var m=typeof b;b&&"string"!==m&&"function"!==m&&b.length!==n||(b=[b]);m=0;for(k=b.length;m<k;m++){var p=b[m]&&b[m].split&&!b[m].match(/[\[\(:]/)?b[m].split(","):[b[m]];var q=0;for(l=p.length;q<l;q++)(g=c("string"===typeof p[q]?f.trim(p[q]):p[q]))&&g.length&&(h=h.concat(g))}a=C.selector[a];if(a.length)for(m=0,k=a.length;m<k;m++)h=a[m](d,e,h);return sa(h)},eb=function(a){a||(a={});a.filter&&a.search===n&&(a.search=a.filter);return f.extend({search:"none",order:"current",page:"all"},a)},fb=
function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Ea=function(a,b){var c=[],d=a.aiDisplay;var e=a.aiDisplayMaster;var h=b.search;var g=b.order;b=b.page;if("ssp"==I(a))return"removed"===h?[]:Y(0,e.length);if("current"==b)for(g=a._iDisplayStart,a=a.fnDisplayEnd();g<a;g++)c.push(d[g]);else if("current"==g||"applied"==g)if("none"==h)c=e.slice();else if("applied"==h)c=d.slice();else{if("removed"==h){var k=
{};g=0;for(a=d.length;g<a;g++)k[d[g]]=null;c=f.map(e,function(a){return k.hasOwnProperty(a)?null:a})}}else if("index"==g||"original"==g)for(g=0,a=a.aoData.length;g<a;g++)"none"==h?c.push(g):(e=f.inArray(g,d),(-1===e&&"removed"==h||0<=e&&"applied"==h)&&c.push(g));return c},fc=function(a,b,c){var d;return db("row",b,function(b){var e=Rb(b),g=a.aoData;if(null!==e&&!c)return[e];d||(d=Ea(a,c));if(null!==e&&-1!==f.inArray(e,d))return[e];if(null===b||b===n||""===b)return d;if("function"===typeof b)return f.map(d,
function(a){var c=g[a];return b(a,c._aData,c.nTr)?a:null});if(b.nodeName){e=b._DT_RowIndex;var k=b._DT_CellIndex;if(e!==n)return g[e]&&g[e].nTr===b?[e]:[];if(k)return g[k.row]&&g[k.row].nTr===b.parentNode?[k.row]:[];e=f(b).closest("*[data-dt-row]");return e.length?[e.data("dt-row")]:[]}if("string"===typeof b&&"#"===b.charAt(0)&&(e=a.aIds[b.replace(/^#/,"")],e!==n))return[e.idx];e=Ub(ka(a.aoData,d,"nTr"));return f(e).filter(b).map(function(){return this._DT_RowIndex}).toArray()},a,c)};t("rows()",function(a,
b){a===n?a="":f.isPlainObject(a)&&(b=a,a="");b=eb(b);var c=this.iterator("table",function(c){return fc(c,a,b)},1);c.selector.rows=a;c.selector.opts=b;return c});t("rows().nodes()",function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||n},1)});t("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ka(a.aoData,b,"_aData")},1)});z("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){b=b.aoData[c];return"search"===a?b._aFilterData:
b._aSortData},1)});z("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",function(b,c){da(b,c,a)})});z("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});z("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var k=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+k)}return new x(c,b)});z("rows().remove()","row().remove()",function(){var a=
this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,k;e.splice(c,1);var l=0;for(g=e.length;l<g;l++){var m=e[l];var p=m.anCells;null!==m.nTr&&(m.nTr._DT_RowIndex=l);if(null!==p)for(m=0,k=p.length;m<k;m++)p[m]._DT_CellIndex.row=l}qa(b.aiDisplayMaster,c);qa(b.aiDisplay,c);qa(a[d],c,!1);0<b._iRecordsDisplay&&b._iRecordsDisplay--;Va(b);c=b.rowIdFn(f._aData);c!==n&&delete b.aIds[c]});this.iterator("table",function(a){for(var b=0,d=a.aoData.length;b<d;b++)a.aoData[b].idx=b});return this});t("rows.add()",
function(a){var b=this.iterator("table",function(b){var c,d=[];var f=0;for(c=a.length;f<c;f++){var k=a[f];k.nodeName&&"TR"===k.nodeName.toUpperCase()?d.push(oa(b,k)[0]):d.push(R(b,k))}return d},1),c=this.rows(-1);c.pop();f.merge(c,b);return c});t("row()",function(a,b){return fb(this.rows(a,b))});t("row().data()",function(a){var b=this.context;if(a===n)return b.length&&this.length?b[0].aoData[this[0]]._aData:n;var c=b[0].aoData[this[0]];c._aData=a;f.isArray(a)&&c.nTr&&c.nTr.id&&Q(b[0].rowId)(a,c.nTr.id);
da(b[0],this[0],"data");return this});t("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});t("row.add()",function(a){a instanceof f&&a.length&&(a=a[0]);var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?oa(b,a)[0]:R(b,a)});return this.row(b[0])});var gc=function(a,b,c,d){var e=[],h=function(b,c){if(f.isArray(b)||b instanceof f)for(var d=0,g=b.length;d<g;d++)h(b[d],c);else b.nodeName&&"tr"===b.nodeName.toLowerCase()?
e.push(b):(d=f("<tr><td/></tr>").addClass(c),f("td",d).addClass(c).html(b)[0].colSpan=V(a),e.push(d[0]))};h(c,d);b._details&&b._details.detach();b._details=f(e);b._detailsShow&&b._details.insertAfter(b.nTr)},gb=function(a,b){var c=a.context;c.length&&(a=c[0].aoData[b!==n?b:a[0]])&&a._details&&(a._details.remove(),a._detailsShow=n,a._details=n)},Yb=function(a,b){var c=a.context;c.length&&a.length&&(a=c[0].aoData[a[0]],a._details&&((a._detailsShow=b)?a._details.insertAfter(a.nTr):a._details.detach(),
hc(c[0])))},hc=function(a){var b=new x(a),c=a.aoData;b.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");0<K(c,"_details").length&&(b.on("draw.dt.DT_details",function(d,e){a===e&&b.rows({page:"current"}).eq(0).each(function(a){a=c[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),b.on("column-visibility.dt.DT_details",function(b,e,f,g){if(a===e)for(e=V(e),f=0,g=c.length;f<g;f++)b=c[f],b._details&&b._details.children("td[colspan]").attr("colspan",e)}),b.on("destroy.dt.DT_details",
function(d,e){if(a===e)for(d=0,e=c.length;d<e;d++)c[d]._details&&gb(b,d)}))};t("row().child()",function(a,b){var c=this.context;if(a===n)return c.length&&this.length?c[0].aoData[this[0]]._details:n;!0===a?this.child.show():!1===a?gb(this):c.length&&this.length&&gc(c[0],c[0].aoData[this[0]],a,b);return this});t(["row().child.show()","row().child().show()"],function(a){Yb(this,!0);return this});t(["row().child.hide()","row().child().hide()"],function(){Yb(this,!1);return this});t(["row().child.remove()",
"row().child().remove()"],function(){gb(this);return this});t("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var ic=/^([^:]+):(name|visIdx|visible)$/,Zb=function(a,b,c,d,e){c=[];d=0;for(var f=e.length;d<f;d++)c.push(F(a,e[d],b));return c},jc=function(a,b,c){var d=a.aoColumns,e=K(d,"sName"),h=K(d,"nTh");return db("column",b,function(b){var g=Rb(b);if(""===b)return Y(d.length);if(null!==g)return[0<=g?g:d.length+g];if("function"===
typeof b){var l=Ea(a,c);return f.map(d,function(c,d){return b(d,Zb(a,d,0,0,l),h[d])?d:null})}var m="string"===typeof b?b.match(ic):"";if(m)switch(m[2]){case "visIdx":case "visible":g=parseInt(m[1],10);if(0>g){var p=f.map(d,function(a,b){return a.bVisible?b:null});return[p[p.length+g]]}return[aa(a,g)];case "name":return f.map(e,function(a,b){return a===m[1]?b:null});default:return[]}if(b.nodeName&&b._DT_CellIndex)return[b._DT_CellIndex.column];g=f(h).filter(b).map(function(){return f.inArray(this,
h)}).toArray();if(g.length||!b.nodeName)return g;g=f(b).closest("*[data-dt-column]");return g.length?[g.data("dt-column")]:[]},a,c)};t("columns()",function(a,b){a===n?a="":f.isPlainObject(a)&&(b=a,a="");b=eb(b);var c=this.iterator("table",function(c){return jc(c,a,b)},1);c.selector.cols=a;c.selector.opts=b;return c});z("columns().header()","column().header()",function(a,b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});z("columns().footer()","column().footer()",function(a,
b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});z("columns().data()","column().data()",function(){return this.iterator("column-rows",Zb,1)});z("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});z("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ka(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});z("columns().nodes()",
"column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ka(a.aoData,e,"anCells",b)},1)});z("columns().visible()","column().visible()",function(a,b){var c=this,d=this.iterator("column",function(b,c){if(a===n)return b.aoColumns[c].bVisible;var d=b.aoColumns,e=d[c],h=b.aoData,m;if(a!==n&&e.bVisible!==a){if(a){var p=f.inArray(!0,K(d,"bVisible"),c+1);d=0;for(m=h.length;d<m;d++){var q=h[d].nTr;b=h[d].anCells;q&&q.insertBefore(b[c],b[p]||null)}}else f(K(b.aoData,"anCells",
c)).detach();e.bVisible=a}});a!==n&&this.iterator("table",function(d){fa(d,d.aoHeader);fa(d,d.aoFooter);d.aiDisplay.length||f(d.nTBody).find("td[colspan]").attr("colspan",V(d));Aa(d);c.iterator("column",function(c,d){A(c,null,"column-visibility",[c,d,a,b])});(b===n||b)&&c.columns.adjust()});return d});z("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===a?ba(b,c):c},1)});t("columns.adjust()",function(){return this.iterator("table",function(a){Z(a)},
1)});t("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return aa(c,b);if("fromData"===a||"toVisible"===a)return ba(c,b)}});t("column()",function(a,b){return fb(this.columns(a,b))});var kc=function(a,b,c){var d=a.aoData,e=Ea(a,c),h=Ub(ka(d,e,"anCells")),g=f([].concat.apply([],h)),k,l=a.aoColumns.length,m,p,q,u,t,w;return db("cell",b,function(b){var c="function"===typeof b;if(null===b||b===n||c){m=[];p=0;for(q=e.length;p<q;p++)for(k=
e[p],u=0;u<l;u++)t={row:k,column:u},c?(w=d[k],b(t,F(a,k,u),w.anCells?w.anCells[u]:null)&&m.push(t)):m.push(t);return m}if(f.isPlainObject(b))return b.column!==n&&b.row!==n&&-1!==f.inArray(b.row,e)?[b]:[];c=g.filter(b).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();if(c.length||!b.nodeName)return c;w=f(b).closest("*[data-dt-row]");return w.length?[{row:w.data("dt-row"),column:w.data("dt-column")}]:[]},a,c)};t("cells()",function(a,b,c){f.isPlainObject(a)&&
(a.row===n?(c=a,a=null):(c=b,b=null));f.isPlainObject(b)&&(c=b,b=null);if(null===b||b===n)return this.iterator("table",function(b){return kc(b,a,eb(c))});var d=c?{page:c.page,order:c.order,search:c.search}:{},e=this.columns(b,d),h=this.rows(a,d),g,k,l,m;d=this.iterator("table",function(a,b){a=[];g=0;for(k=h[b].length;g<k;g++)for(l=0,m=e[b].length;l<m;l++)a.push({row:h[b][g],column:e[b][l]});return a},1);d=c&&c.selected?this.cells(d,c):d;f.extend(d.selector,{cols:b,rows:a,opts:c});return d});z("cells().nodes()",
"cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b])&&a.anCells?a.anCells[c]:n},1)});t("cells().data()",function(){return this.iterator("cell",function(a,b,c){return F(a,b,c)},1)});z("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});z("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return F(b,c,d,a)},
1)});z("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,b,c){return{row:b,column:c,columnVisible:ba(a,c)}},1)});z("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){da(b,c,a,d)})});t("cell()",function(a,b,c){return fb(this.cells(a,b,c))});t("cell().data()",function(a){var b=this.context,c=this[0];if(a===n)return b.length&&c.length?F(b[0],c[0].row,c[0].column):n;nb(b[0],c[0].row,c[0].column,a);da(b[0],c[0].row,
"data",c[0].column);return this});t("order()",function(a,b){var c=this.context;if(a===n)return 0!==c.length?c[0].aaSorting:n;"number"===typeof a?a=[[a,b]]:a.length&&!f.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});t("order.listener()",function(a,b,c){return this.iterator("table",function(d){Pa(d,a,b,c)})});t("order.fixed()",function(a){if(!a){var b=this.context;b=b.length?b[0].aaSortingFixed:n;return f.isArray(b)?{pre:b}:
b}return this.iterator("table",function(b){b.aaSortingFixed=f.extend(!0,{},a)})});t(["columns().order()","column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];f.each(b[d],function(b,c){e.push([c,a])});c.aaSorting=e})});t("search()",function(a,b,c,d){var e=this.context;return a===n?0!==e.length?e[0].oPreviousSearch.sSearch:n:this.iterator("table",function(e){e.oFeatures.bFilter&&ha(e,f.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===
c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});z("columns().search()","column().search()",function(a,b,c,d){return this.iterator("column",function(e,h){var g=e.aoPreSearchCols;if(a===n)return g[h].sSearch;e.oFeatures.bFilter&&(f.extend(g[h],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),ha(e,e.oPreviousSearch,1))})});t("state()",function(){return this.context.length?this.context[0].oSavedState:null});t("state.clear()",function(){return this.iterator("table",
function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});t("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null});t("state.save()",function(){return this.iterator("table",function(a){Aa(a)})});q.versionCheck=q.fnVersionCheck=function(a){var b=q.version.split(".");a=a.split(".");for(var c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};q.isDataTable=q.fnIsDataTable=function(a){var b=f(a).get(0),c=!1;if(a instanceof
q.Api)return!0;f.each(q.settings,function(a,e){a=e.nScrollHead?f("table",e.nScrollHead)[0]:null;var d=e.nScrollFoot?f("table",e.nScrollFoot)[0]:null;if(e.nTable===b||a===b||d===b)c=!0});return c};q.tables=q.fnTables=function(a){var b=!1;f.isPlainObject(a)&&(b=a.api,a=a.visible);var c=f.map(q.settings,function(b){if(!a||a&&f(b.nTable).is(":visible"))return b.nTable});return b?new x(c):c};q.camelToHungarian=L;t("$()",function(a,b){b=this.rows(b).nodes();b=f(b);return f([].concat(b.filter(a).toArray(),
b.find(a).toArray()))});f.each(["on","one","off"],function(a,b){t(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0]=f.map(a[0].split(/\s/),function(a){return a.match(/\.dt\b/)?a:a+".dt"}).join(" ");var d=f(this.tables().nodes());d[b].apply(d,a);return this})});t("clear()",function(){return this.iterator("table",function(a){pa(a)})});t("settings()",function(){return new x(this.context,this.context)});t("init()",function(){var a=this.context;return a.length?a[0].oInit:null});t("data()",
function(){return this.iterator("table",function(a){return K(a.aoData,"_aData")}).flatten()});t("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,h=b.nTBody,g=b.nTHead,k=b.nTFoot,l=f(e);h=f(h);var m=f(b.nTableWrapper),p=f.map(b.aoData,function(a){return a.nTr}),n;b.bDestroying=!0;A(b,"aoDestroyCallback","destroy",[b]);a||(new x(b)).columns().visible(!0);m.off(".DT").find(":not(tbody *)").off(".DT");f(y).off(".DT-"+b.sInstance);
e!=g.parentNode&&(l.children("thead").detach(),l.append(g));k&&e!=k.parentNode&&(l.children("tfoot").detach(),l.append(k));b.aaSorting=[];b.aaSortingFixed=[];za(b);f(p).removeClass(b.asStripeClasses.join(" "));f("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);h.children().detach();h.append(p);g=a?"remove":"detach";l[g]();m[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),l.css("width",b.sDestroyWidth).removeClass(d.sTable),(n=b.asDestroyStripes.length)&&
h.children().each(function(a){f(this).addClass(b.asDestroyStripes[a%n])}));c=f.inArray(b,q.settings);-1!==c&&q.settings.splice(c,1)})});f.each(["column","row","cell"],function(a,b){t(b+"s().every()",function(a){var c=this.selector.opts,e=this;return this.iterator(b,function(d,f,k,l,m){a.call(e[b](f,"cell"===b?k:c,"cell"===b?c:n),f,k,l,m)})})});t("i18n()",function(a,b,c){var d=this.context[0];a=T(a)(d.oLanguage);a===n&&(a=b);c!==n&&f.isPlainObject(a)&&(a=a[c]!==n?a[c]:a._);return a.replace("%d",c)});
q.version="1.10.21";q.settings=[];q.models={};q.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};q.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};q.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,
sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};q.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,
bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){return{}}},
fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",
sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:f.extend({},q.models.oSearch),sAjaxDataProp:"data",
sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};H(q.defaults);q.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};H(q.defaults.column);q.models.oSettings=
{oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},
aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,
aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:n,oAjaxData:n,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==I(this)?1*this._iRecordsTotal:
this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==I(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};q.ext=C={buttons:{},
classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:q.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:q.version};f.extend(C,{afnFiltering:C.search,aTypes:C.type.detect,ofnSearch:C.type.search,oSort:C.type.order,afnSortData:C.order,aoFeatures:C.feature,oApi:C.internal,oStdClasses:C.classes,oPagination:C.pager});
f.extend(q.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",
sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",
sJUIHeader:"",sJUIFooter:""});var Ob=q.ext.pager;f.extend(Ob,{simple:function(a,b){return["previous","next"]},full:function(a,b){return["first","previous","next","last"]},numbers:function(a,b){return[ja(a,b)]},simple_numbers:function(a,b){return["previous",ja(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ja(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ja(a,b),"last"]},_numbers:ja,numbers_length:7});f.extend(!0,q.ext.renderer,{pageButton:{_:function(a,b,
c,d,e,h){var g=a.oClasses,k=a.oLanguage.oPaginate,l=a.oLanguage.oAria.paginate||{},m,p,q=0,t=function(b,d){var n,r=g.sPageButtonDisabled,u=function(b){Wa(a,b.data.action,!0)};var w=0;for(n=d.length;w<n;w++){var v=d[w];if(f.isArray(v)){var x=f("<"+(v.DT_el||"div")+"/>").appendTo(b);t(x,v)}else{m=null;p=v;x=a.iTabIndex;switch(v){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":m=k.sFirst;0===e&&(x=-1,p+=" "+r);break;case "previous":m=k.sPrevious;0===e&&(x=-1,p+=
" "+r);break;case "next":m=k.sNext;if(0===h||e===h-1)x=-1,p+=" "+r;break;case "last":m=k.sLast;e===h-1&&(x=-1,p+=" "+r);break;default:m=v+1,p=e===v?g.sPageButtonActive:""}null!==m&&(x=f("<a>",{"class":g.sPageButton+" "+p,"aria-controls":a.sTableId,"aria-label":l[v],"data-dt-idx":q,tabindex:x,id:0===c&&"string"===typeof v?a.sTableId+"_"+v:null}).html(m).appendTo(b),Za(x,{action:v},u),q++)}}};try{var x=f(b).find(w.activeElement).data("dt-idx")}catch(lc){}t(f(b).empty(),d);x!==n&&f(b).find("[data-dt-idx="+
x+"]").trigger("focus")}}});f.extend(q.ext.type.detect,[function(a,b){b=b.oLanguage.sDecimal;return cb(a,b)?"num"+b:null},function(a,b){if(a&&!(a instanceof Date)&&!cc.test(a))return null;b=Date.parse(a);return null!==b&&!isNaN(b)||P(a)?"date":null},function(a,b){b=b.oLanguage.sDecimal;return cb(a,b,!0)?"num-fmt"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Tb(a,b)?"html-num"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Tb(a,b,!0)?"html-num-fmt"+b:null},function(a,b){return P(a)||"string"===
typeof a&&-1!==a.indexOf("<")?"html":null}]);f.extend(q.ext.type.search,{html:function(a){return P(a)?a:"string"===typeof a?a.replace(Qb," ").replace(Da,""):""},string:function(a){return P(a)?a:"string"===typeof a?a.replace(Qb," "):a}});var Ca=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Sb(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};f.extend(C.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return P(a)?
"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return P(a)?"":"string"===typeof a?a.toLowerCase():a.toString?a.toString():""},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,b){return a<b?1:a>b?-1:0}});Ga("");f.extend(!0,q.ext.renderer,{header:{_:function(a,b,c,d){f(a.nTable).on("order.dt.DT",function(e,f,g,k){a===f&&(e=c.idx,b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass("asc"==k[e]?d.sSortAsc:"desc"==k[e]?d.sSortDesc:
c.sSortingClass))})},jqueryui:function(a,b,c,d){f("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(f("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);f(a.nTable).on("order.dt.DT",function(e,f,g,k){a===f&&(e=c.idx,b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass("asc"==k[e]?d.sSortAsc:"desc"==k[e]?d.sSortDesc:c.sSortingClass),b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass("asc"==
k[e]?d.sSortJUIAsc:"desc"==k[e]?d.sSortJUIDesc:c.sSortingClassJUI))})}}});var hb=function(a){return"string"===typeof a?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):a};q.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return hb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,
a)+f+(e||"")}}},text:function(){return{display:hb,filter:hb}}};f.extend(q.ext.internal,{_fnExternApiFunc:Pb,_fnBuildAjax:ua,_fnAjaxUpdate:pb,_fnAjaxParameters:yb,_fnAjaxUpdateDraw:zb,_fnAjaxDataSrc:va,_fnAddColumn:Ha,_fnColumnOptions:la,_fnAdjustColumnSizing:Z,_fnVisibleToColumnIndex:aa,_fnColumnIndexToVisible:ba,_fnVisbleColumns:V,_fnGetColumns:na,_fnColumnTypes:Ja,_fnApplyColumnDefs:mb,_fnHungarianMap:H,_fnCamelToHungarian:L,_fnLanguageCompat:Fa,_fnBrowserDetect:kb,_fnAddData:R,_fnAddTr:oa,_fnNodeToDataIndex:function(a,
b){return b._DT_RowIndex!==n?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return f.inArray(c,a.aoData[b].anCells)},_fnGetCellData:F,_fnSetCellData:nb,_fnSplitObjNotation:Ma,_fnGetObjectDataFn:T,_fnSetObjectDataFn:Q,_fnGetDataMaster:Na,_fnClearTable:pa,_fnDeleteIndex:qa,_fnInvalidate:da,_fnGetRowElements:La,_fnCreateTr:Ka,_fnBuildHead:ob,_fnDrawHead:fa,_fnDraw:S,_fnReDraw:U,_fnAddOptionsHtml:rb,_fnDetectHeader:ea,_fnGetUniqueThs:ta,_fnFeatureHtmlFilter:tb,_fnFilterComplete:ha,_fnFilterCustom:Cb,
_fnFilterColumn:Bb,_fnFilter:Ab,_fnFilterCreateSearch:Sa,_fnEscapeRegex:Ta,_fnFilterData:Db,_fnFeatureHtmlInfo:wb,_fnUpdateInfo:Gb,_fnInfoMacros:Hb,_fnInitialise:ia,_fnInitComplete:wa,_fnLengthChange:Ua,_fnFeatureHtmlLength:sb,_fnFeatureHtmlPaginate:xb,_fnPageChange:Wa,_fnFeatureHtmlProcessing:ub,_fnProcessingDisplay:J,_fnFeatureHtmlTable:vb,_fnScrollDraw:ma,_fnApplyToChildren:N,_fnCalculateColumnWidths:Ia,_fnThrottle:Ra,_fnConvertToWidth:Ib,_fnGetWidestNode:Jb,_fnGetMaxLenString:Kb,_fnStringToCss:B,
_fnSortFlatten:X,_fnSort:qb,_fnSortAria:Mb,_fnSortListener:Ya,_fnSortAttachListener:Pa,_fnSortingClasses:za,_fnSortData:Lb,_fnSaveState:Aa,_fnLoadState:Nb,_fnSettingsFromNode:Ba,_fnLog:O,_fnMap:M,_fnBindAction:Za,_fnCallbackReg:D,_fnCallbackFire:A,_fnLengthOverflow:Va,_fnRenderer:Qa,_fnDataSource:I,_fnRowAttributes:Oa,_fnExtend:$a,_fnCalculateEnd:function(){}});f.fn.dataTable=q;q.$=f;f.fn.dataTableSettings=q.settings;f.fn.dataTableExt=q.ext;f.fn.DataTable=function(a){return f(this).dataTable(a).api()};
f.each(q,function(a,b){f.fn.DataTable[a]=b});return f.fn.dataTable});

2
public/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/js/vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,11 +1,4 @@
{ {
"/js/app.js": "/js/app.js", "/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css", "/css/app.css": "/css/app.css"
"/css/dark.css": "/css/dark.css",
"/css/light.css": "/css/light.css",
"/webfonts/fa-regular-400.ttf": "/webfonts/fa-regular-400.ttf",
"/webfonts/fa-regular-400.woff2": "/webfonts/fa-regular-400.woff2",
"/webfonts/fa-solid-900.ttf": "/webfonts/fa-solid-900.ttf",
"/webfonts/fa-solid-900.woff2": "/webfonts/fa-solid-900.woff2",
"/webfonts/fa-brands-400.ttf": "/webfonts/fa-brands-400.ttf"
} }

Binary file not shown.

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 896 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

63
public/yabsFromForm.txt Normal file
View file

@ -0,0 +1,63 @@
# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #
# Yet-Another-Bench-Script #
# v2021-12-28 #
# https://github.com/masonr/yet-another-bench-script #
# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #
Sat 05 Feb 2022 02:54:48 AM CET
Basic System Information:
---------------------------------
Processor : AMD Ryzen 9 3900X 12-Core Processor
CPU cores : 2 @ 3792.874 MHz
AES-NI : ✔ Enabled
VM-x/AMD-V : ✔ Enabled
RAM : 3.8 GiB
Swap : 0.0 KiB
Disk : 39.3 GiB
fio Disk Speed Tests (Mixed R/W 50/50):
---------------------------------
Block Size | 4k (IOPS) | 64k (IOPS)
------ | --- ---- | ---- ----
Read | 174.73 MB/s (43.6k) | 979.69 MB/s (15.3k)
Write | 175.19 MB/s (43.7k) | 984.85 MB/s (15.3k)
Total | 349.93 MB/s (87.4k) | 1.96 GB/s (30.6k)
| |
Block Size | 512k (IOPS) | 1m (IOPS)
------ | --- ---- | ---- ----
Read | 571.27 MB/s (1.1k) | 590.50 MB/s (576)
Write | 601.62 MB/s (1.1k) | 629.83 MB/s (615)
Total | 1.17 GB/s (2.2k) | 1.22 GB/s (1.1k)
iperf3 Network Speed Tests (IPv4):
---------------------------------
Provider | Location (Link) | Send Speed | Recv Speed
| | |
Clouvider | London, UK (10G) | 709 Mbits/sec | 882 Mbits/sec
Online.net | Paris, FR (10G) | 570 Mbits/sec | 786 Mbits/sec
WorldStream | The Netherlands (10G) | 886 Mbits/sec | 933 Mbits/sec
WebHorizon | Singapore (400M) | 278 Mbits/sec | 478 Mbits/sec
Clouvider | NYC, NY, US (10G) | 260 Mbits/sec | 243 Mbits/sec
Velocity Online | Tallahassee, FL, US (10G) | 227 Mbits/sec | 317 Mbits/sec
Clouvider | Los Angeles, CA, US (10G) | 255 Mbits/sec | 288 Mbits/sec
Iveloz Telecom | Sao Paulo, BR (2G) | 110 Mbits/sec | 281 Mbits/sec
iperf3 Network Speed Tests (IPv6):
---------------------------------
Provider | Location (Link) | Send Speed | Recv Speed
| | |
Clouvider | London, UK (10G) | 706 Mbits/sec | 854 Mbits/sec
Online.net | Paris, FR (10G) | 591 Mbits/sec | 760 Mbits/sec
WorldStream | The Netherlands (10G) | 867 Mbits/sec | 904 Mbits/sec
WebHorizon | Singapore (400M) | 207 Mbits/sec | 502 Mbits/sec
Clouvider | NYC, NY, US (10G) | 302 Mbits/sec | 201 Mbits/sec
Clouvider | Los Angeles, CA, US (10G) | 169 Mbits/sec | 450 Mbits/sec
Geekbench 5 Benchmark Test:
---------------------------------
Test | Value
|
Single Core | 1276
Multi Core | 2394
Full Test | https://browser.geekbench.com/v5/cpu/12590829

View file

@ -1,2 +1,3 @@
@import "datatables.net-bs5"; @import 'tailwindcss/base';
@import "style.css"; @import 'tailwindcss/components';
@import 'tailwindcss/utilities';

View file

@ -1 +0,0 @@
@import 'bootstrap-dark-5';

View file

@ -1 +0,0 @@
@import 'bootstrap';

View file

@ -1,33 +0,0 @@
/*
Custom styles go in here
*/
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
transition: opacity .3s ease;
}
.modal-body {
margin: 10px 0;
}
.modal {
display: contents !important;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-radius: var(--bs-border-radius) !important;
}
@media (min-width: 1400px) {
.container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {
max-width: 1520px;
}
}

14
resources/js/app.js vendored
View file

@ -1,8 +1,6 @@
require('bootstrap') require('./bootstrap');
require('datatables') import Alpine from 'alpinejs';
window.Vue = require('vue/dist/vue');
window.axios = require('axios'); window.Alpine = Alpine;
import $ from 'jquery';
window.jQuery = $; Alpine.start();
window.$ = $;
require('datatables.net-bs5');

View file

@ -0,0 +1,23 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>

View file

@ -1,2 +1,7 @@
// FontAwesome // Body
$fa-font-path: "webfonts"; $body-bg: #f8fafc;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;

Some files were not shown because too many files have changed in this diff Show more