Merge branch 'devel' into new/mac_clients

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-06-05 22:22:07 +02:00
258 changed files with 4930 additions and 13929 deletions
+1
View File
@@ -0,0 +1 @@
* text=auto
+10 -9
View File
@@ -1,7 +1,7 @@
**In raising this issue, I confirm the following:** `{please fill the checkboxes, e.g: [X]}`
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/AdminLTE/blob/master/CONTRIBUTING.md).
- [] The issue I am reporting can be *replicated*.
- [] The issue I am reporting can be _replicated_.
- [] The issue I am reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/AdminLTE/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/AdminLTE/issues)).
**How familiar are you with the the source code relevant to this issue?:**
@@ -9,11 +9,12 @@
`{Replace this with a number from 1 to 10. 1 being not familiar, and 10 being very familiar}`
---
**Expected behaviour:**
**Expected behavior:**
`{A detailed description of what you expect to see}`
**Actual behaviour:**
**Actual behavior:**
`{A detailed description and/or screenshots of what you do see}`
@@ -29,9 +30,9 @@
`{Steps of what you have done to fix this}`
> * `{Please delete this quoted section when opening your issue}`
> * You must follow the template instructions. Failure to do so will result in your issue being closed.
> * Please [submit any feature requests here](https://discourse.pi-hole.net/c/feature-requests), so it is votable and trackable by the community.
> * Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
> * Detail helps us understand and resolve an issue quicker, but please ensure it's relevant.
> * _This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
> - `{Please delete this quoted section when opening your issue}`
> - You must follow the template instructions. Failure to do so will result in your issue being closed.
> - Please [submit any feature requests here](https://discourse.pi-hole.net/c/feature-requests), so it is votable and trackable by the community.
> - Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
> - Detail helps us understand and resolve an issue quicker, but please ensure it's relevant.
> - _This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
+4 -4
View File
@@ -26,7 +26,7 @@
`{A detailed list of any necessary changes}`
> * `{Please delete this quoted section when opening your pull request}`
> * You must follow the template instructions. Failure to do so will result in your issue being closed.
> * Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
> * Detail helps us understand an issue quicker, but please ensure it's relevant.
> - `{Please delete this quoted section when opening your pull request}`
> - You must follow the template instructions. Failure to do so will result in your issue being closed.
> - Please respect that Pi-hole is developed by volunteers, who can only reply in their spare time.
> - Detail helps us understand an issue quicker, but please ensure it's relevant.
+11 -7
View File
@@ -1,5 +1,14 @@
name: Tests
on: [push, pull_request]
on:
push:
branches:
- devel
- master
pull_request:
branches:
- "**"
env:
CI: true
@@ -8,11 +17,6 @@ jobs:
name: Node ${{ matrix.node }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [12]
steps:
- name: Clone repository
uses: actions/checkout@v2
@@ -20,7 +24,7 @@ jobs:
- name: Set Node.js version
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
node-version: "12.x"
- name: Install npm dependencies
run: npm ci
+2 -2
View File
@@ -6,8 +6,8 @@ Please read and understand the contribution guide before creating an issue or pu
## Etiquette
- Our goal for Pi-hole is **stability before features**. This means we focus on squashing critical bugs before adding new features. Often, we can do both in tandem, but bugs will take priority over a new feature.
- Pi-hole is open source and [powered by donations](https://pi-hole.net/donate/), and as such, we give our **free time** to build, maintain, and **provide user support** for this project. It would be extremely unfair for us to suffer abuse or anger for our hard work, so please take a moment to consider that.
- Our goal for Pi-hole is **stability before features**. This means we focus on squashing critical bugs before adding new features. Often, we can do both in tandem, but bugs will take priority over a new feature.
- Pi-hole is open source and [powered by donations](https://pi-hole.net/donate/), and as such, we give our **free time** to build, maintain, and **provide user support** for this project. It would be extremely unfair for us to suffer abuse or anger for our hard work, so please take a moment to consider that.
- Please be considerate towards the developers and other users when raising issues or presenting pull requests.
- Respect our decision(s), and do not be upset or abusive if your submission is not used.
+66 -41
View File
@@ -1,8 +1,14 @@
<p align="center">
<a href="https://pi-hole.net"><img src="https://pi-hole.github.io/graphics/Vortex/Vortex_with_text.png" width="150" height="255" alt="Pi-hole"></a><br/></br>
<b>Network-wide ad blocking via your own Linux hardware</b><br/>
</br>
<a href="https://pi-hole.net"><img src="https://pi-hole.github.io/graphics/Screenshots/pihole-dashboard.png" alt="Pi-hole Web interface"></a><br/>
<a href="https://pi-hole.net/">
<img src="https://pi-hole.github.io/graphics/Vortex/Vortex_with_Wordmark.svg" width="150" height="260" alt="Pi-hole">
</a>
<br>
<strong>Network-wide ad blocking via your own Linux hardware</strong>
<br>
<br>
<a href="https://pi-hole.net/">
<img src="https://pi-hole.github.io/graphics/Screenshots/pihole-dashboard.png" alt="Pi-hole Web interface">
</a>
</p>
Pi-hole[®](https://pi-hole.net/trademark-rules-and-brand-guidelines/)'s Web interface (based off of [AdminLTE](https://github.com/ColorlibHQ/AdminLTE)) provides a central location to manage your Pi-hole and review the statistics generated by FTLDNS[](https://pi-hole.net/trademark-rules-and-brand-guidelines/).
@@ -13,6 +19,7 @@ Pi-hole[®](https://pi-hole.net/trademark-rules-and-brand-guidelines/)'s Web int
- **Insightful**: use the query log, audit log, or long-term stats to gain insight into your networks activity
---
<img src="https://pi-hole.github.io/graphics/Badges/browserstack-badge.png" height="80"><br>
# Installation
@@ -20,6 +27,7 @@ Pi-hole[®](https://pi-hole.net/trademark-rules-and-brand-guidelines/)'s Web int
The Web interface is enabled by default when you install Pi-hole.
## Post-installation: access the Web interface and gain insight into your network's activity
There are several ways to [access the dashboard](https://discourse.pi-hole.net/t/how-do-i-access-pi-holes-dashboard-admin-interface/3168):
1. `http://<IP_ADDPRESS_OF_YOUR_PI_HOLE>/admin/`
@@ -33,123 +41,140 @@ Once logged in (forgot your password?), you can view your network stats to see t
- the amount of domains that were blocked
- the upstream server queries were sent to
- the type of queries (`A`, `AAAA`, `CNAME`, `SRV`, `TXT`, etc.)
---
## Pi-hole is free, but powered by your support
There are many reoccurring costs involved with maintaining free, open source, and privacy respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software, as well as the importance of keeping it maintained.
Make no mistake: **your support is absolutely vital to help keep us innovating!**
### Donations
Sending a donation using our links below is **extremely helpful** in offsetting a portion of our monthly expenses:
- <img src="https://pi-hole.github.io/graphics/Badges/paypal-badge-black.svg" width="24" height="24" alt="PP"/> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY">Donate via PayPal</a><br/>
- <img src="https://pi-hole.github.io/graphics/Badges/bitcoin-badge-black.svg" width="24" height="24" alt="BTC"/> [Bitcoin, Bitcoin Cash, Ethereum, Litecoin](https://commerce.coinbase.com/checkout/dd304d04-f324-4a77-931b-0db61c77a41b)
- <img src="https://pi-hole.github.io/graphics/Badges/paypal-badge-black.svg" width="24" height="24" alt="PP"> [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
- <img src="https://pi-hole.github.io/graphics/Badges/bitcoin-badge-black.svg" width="24" height="24" alt="BTC"> [Bitcoin, Bitcoin Cash, Ethereum, Litecoin](https://commerce.coinbase.com/checkout/dd304d04-f324-4a77-931b-0db61c77a41b)
### Alternative support
If you'd rather not [donate](https://pi-hole.net/donate/) (_which is okay!_), there are other ways you can help support us:
- [Patreon](https://patreon.com/pihole) _Become a patron for rewards_
- [Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
- [Stickermule](https://www.stickermule.com/unlock?ref_id=6055890701&utm_medium=link&utm_source=invite) _earn a $10 credit after your first purchase_
- [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
- [Stickermule](https://www.stickermule.com/unlock?ref_id=6055890701&utm_medium=link&utm_source=invite) _earn a \$10 credit after your first purchase_
- [Pi-hole Swag Store](https://pi-hole.net/shop/) _affiliate link_
- [Amazon](http://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
- [Amazon](https://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
- [DNS Made Easy](https://cp.dnsmadeeasy.com/u/133706) _affiliate link_
- [Vultr](http://www.vultr.com/?ref=7190426) _affiliate link_
- Spreading the word about our software, and how you have benefited from it
### Contributing via GitHub
We welcome _everyone_ to contribute to issue reports, suggest new features, and create pull requests.
If you have something to add - anything from a typo through to a whole new feature, we're happy to check it out! Just make sure to fill out our template when submitting your request; the questions that it asks will help the volunteers quickly understand what you're aiming to achieve.
### Presentations about Pi-hole
Word-of-mouth continues to help our project grow immensely, and so we are helping make this easier for people.
If you are going to be presenting Pi-hole at a conference, meetup or even a school project, [get in touch with us](https://pi-hole.net/2017/05/17/giving-a-presentation-on-pi-hole-contact-us-first-for-some-goodies-and-support/) so we can hook you up with free swag to hand out to your audience!
-----
---
## Getting in touch with us
While we are primarily reachable on our <a href="https://discourse.pi-hole.net/">Discourse User Forum</a>, we can also be found on a variety of social media outlets. **Please be sure to check the FAQ's** before starting a new discussion, as we do not have the spare time to reply to every request for assistance.
<ul>
<li><b><a href="https://discourse.pi-hole.net/c/faqs">Frequently Asked Questions</a></b></li>
<li><b><a href="https://github.com/pi-hole/pi-hole/wiki">Pi-hole Wiki</a></b></li>
<li><b><a href="https://discourse.pi-hole.net/c/feature-requests?order=votes">Feature Requests</a></b></li>
<li><a href="https://discourse.pi-hole.net/">Discourse User Forum</a></li>
<li><a href="https://www.reddit.com/r/pihole/">Reddit</a></li>
<li><a href="https://twitter.com/The_Pi_Hole">Twitter</a></li>
<li><a href="https://www.facebook.com/ThePiHole/">Facebook</a></li>
<li><a href="https://gitter.im/pi-hole/pi-hole">Gitter</a> (Real-time chat)</li>
<li><a href="https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w">YouTube</a></li>
</ul>
* **[Frequently Asked Questions](https://discourse.pi-hole.net/c/faqs)**
* **[Pi-hole Wiki](https://github.com/pi-hole/pi-hole/wiki)**
* **[Feature Requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)**
* [Discourse User Forum](https://discourse.pi-hole.net/)
* [Reddit](https://www.reddit.com/r/pihole/)
* [Twitter](https://twitter.com/The_Pi_Hole)
* [Facebook](https://www.facebook.com/ThePiHole/)
* [Gitter](https://gitter.im/pi-hole/pi-hole) (Real-time chat)
* [YouTube](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
# Features
## Mobile friendly interface
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/mobile-friendly.png" height="300" alt="Mobile friendly"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/mobile-friendly.png" height="300" alt="Mobile friendly">
</p>
## Password protection
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/password-protection.png" height="400" alt="Password protection"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/password-protection.png" height="400" alt="Password protection">
</p>
## Detailed graphs and doughnut charts
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/piecharts.png" alt="Pie charts"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/piecharts.png" alt="Pie charts">
</p>
## Top lists of domains and clients
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/topdomains-clients.png" alt="Top domains/top clients"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/topdomains-clients.png" alt="Top domains/top clients">
</p>
## A filterable and sortable query log
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/query-log-sorted.png" alt="Query log"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/query-log-sorted.png" alt="Query log">
</p>
## An audit log
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/audit-log.png" alt="Pi-hole Web interface"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/audit-log.png" alt="Pi-hole Web interface">
</p>
## Long Term Statistics to view data over user defined time ranges
## Long-term statistics to view data over user defined time ranges
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/long-term-stats.png" alt="Long-term stats"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/long-term-stats.png" alt="Long-term stats">
</p>
## A built-in debugger
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/debug.png" alt="Debugger"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/debug.png" alt="Debugger">
</p>
## Black and white lists
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/blacklist.png" alt="Blacklist"></a>
</br></br>
<img src="https://pi-hole.github.io/graphics/Screenshots/whitelist.png" alt="Whitelist"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/blacklist.png" alt="Blacklist">
<br><br>
<img src="https://pi-hole.github.io/graphics/Screenshots/whitelist.png" alt="Whitelist">
</p>
## The ability to easily manage and configure Pi-hole features
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/dashboard-settings.gif" alt="Settings"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/dashboard-settings.gif" alt="Settings">
</p>
## ... and all the main features of the Command Line Interface!
<p align="center">
<img src="https://pi-hole.github.io/graphics/Screenshots/pihole-t.png" alt="Tail the log"></a>
</br></br>
<img src="https://pi-hole.github.io/graphics/Screenshots/pihole-q.png" alt="Query ad lists"></a>
<img src="https://pi-hole.github.io/graphics/Screenshots/pihole-t.png" alt="Tail the log">
<br><br>
<img src="https://pi-hole.github.io/graphics/Screenshots/pihole-q.png" alt="Query ad lists">
</p>
## API
Full usage available [here](https://discourse.pi-hole.net/t/pi-hole-api/1863). can be accessed at `/admin/api.php`. With either no parameters or `/admin/api.php?summary` it returns the following JSON:
```JSON
{
Full usage available [here](https://discourse.pi-hole.net/t/pi-hole-api/1863). Can be accessed at `/admin/api.php`. With either no parameters or `/admin/api.php?summary` it returns the following JSON:
```json
{
"domains_being_blocked":243038,
"dns_queries_today":2385,
"ads_blocked_today":414,
+36 -15
View File
@@ -7,10 +7,10 @@
* Please see LICENSE file for your rights under this license */
$api = true;
header('Content-type: application/json');
require("scripts/pi-hole/php/FTL.php");
require("scripts/pi-hole/php/password.php");
require("scripts/pi-hole/php/auth.php");
require_once("scripts/pi-hole/php/FTL.php");
require_once("scripts/pi-hole/php/password.php");
require_once("scripts/pi-hole/php/database.php");
require_once("scripts/pi-hole/php/auth.php");
check_cors();
$FTL_IP = "127.0.0.1";
@@ -107,29 +107,49 @@ elseif (isset($_GET['versions']))
}
elseif (isset($_GET['list']))
{
if (!$auth)
die("Not authorized!");
if(!isset($_GET["list"]))
die("List has not been specified.");
switch ($_GET["list"]) {
case 'black':
$_POST['type'] = ListType::blacklist;
break;
case 'regex_black':
$_POST['type'] = ListType::regex_blacklist;
break;
case 'white':
$_POST['type'] = ListType::whitelist;
break;
case 'regex_white':
$_POST['type'] = ListType::regex_whitelist;
break;
default:
die("Invalid list [supported: black, regex_black, white, regex_white]");
}
if (isset($_GET['add']))
{
if (!$auth)
die("Not authorized!");
// Set POST parameters and invoke script to add domain to list
$_POST['domain'] = $_GET['add'];
$_POST['list'] = $_GET['list'];
require("scripts/pi-hole/php/add.php");
$_POST['action'] = 'add_domain';
require("scripts/pi-hole/php/groups.php");
}
elseif (isset($_GET['sub']))
{
if (!$auth)
die("Not authorized!");
// Set POST parameters and invoke script to remove domain from list
$_POST['domain'] = $_GET['sub'];
$_POST['list'] = $_GET['list'];
require("scripts/pi-hole/php/sub.php");
$_POST['action'] = 'delete_domain_string';
require("scripts/pi-hole/php/groups.php");
}
else
{
require("scripts/pi-hole/php/get.php");
// Set POST parameters and invoke script to get all domains
$_POST['action'] = 'get_domains';
require("scripts/pi-hole/php/groups.php");
}
return;
@@ -138,6 +158,7 @@ elseif (isset($_GET['list']))
// Other API functions
require("api_FTL.php");
header('Content-type: application/json');
if(isset($_GET["jsonForceObject"]))
{
echo json_encode($data, JSON_FORCE_OBJECT);
+1 -1
View File
@@ -320,7 +320,7 @@ else
// UTF-8 encode domain
$tmp[2] = utf8_encode($tmp[2]);
// UTF-8 encode client host name
$tmp[3] = utf8_encode($tmp[3]);;
$tmp[3] = utf8_encode($tmp[3]);
array_push($allQueries,$tmp);
}
+33 -2
View File
@@ -278,7 +278,7 @@ if (isset($_GET['topAds']) && $auth)
{
$limit = " AND timestamp <= :until";
}
$stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE (STATUS == 1 OR STATUS == 4)'.$limit.' GROUP by domain order by count(domain) desc limit 10');
$stmt = $db->prepare('SELECT domain,count(domain) FROM queries WHERE (STATUS == 1 OR STATUS > 3)'.$limit.' GROUP by domain order by count(domain) desc limit 10');
$stmt->bindValue(":from", intval($_GET['from']), SQLITE3_INTEGER);
$stmt->bindValue(":until", intval($_GET['until']), SQLITE3_INTEGER);
$results = $stmt->execute();
@@ -410,7 +410,7 @@ if (isset($_GET['getGraphData']) && $auth)
$data = array_merge($data, $result);
// Count blocked queries in intervals
$stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE (status == 1 OR status == 4 OR status == 5)'.$limit.' GROUP by interval ORDER by interval');
$stmt = $db->prepare('SELECT (timestamp/:interval)*:interval interval, COUNT(*) FROM queries WHERE (status == 1 OR status > 3)'.$limit.' GROUP by interval ORDER by interval');
$stmt->bindValue(":from", $from, SQLITE3_INTEGER);
$stmt->bindValue(":until", $until, SQLITE3_INTEGER);
$stmt->bindValue(":interval", $interval, SQLITE3_INTEGER);
@@ -422,6 +422,37 @@ if (isset($_GET['getGraphData']) && $auth)
$data = array_merge($data, $result);
}
if (isset($_GET['status']))
{
$results = $db->query('SELECT COUNT(*) FROM message;');
if(!is_bool($results))
$result = array('message_count' => $results->fetchArray()[0]);
else
$result = array();
$data = array_merge($data, $result);
}
if(isset($_GET["messages"]) && $auth)
{
$messages = array();
$results = $db->query('SELECT * FROM message');
while($results !== false && $res = $results->fetchArray(SQLITE3_ASSOC))
{
// Convert string to to UTF-8 encoding to ensure php-json can handle it.
// Furthermore, convert special characters to HTML entities to prevent XSS attacks.
foreach ($res as $key => $value) {
if (is_string($value))
$res[$key] = htmlspecialchars(utf8_encode($value));
}
array_push($messages, $res);
}
$data = array_merge($data, array('messages' => $messages));
}
if(isset($_GET["jsonForceObject"]))
{
echo json_encode($data, JSON_FORCE_OBJECT);
+5 -4
View File
@@ -7,15 +7,14 @@
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
?>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<!-- Title -->
<div class="page-header">
<h1>Audit log (showing live data)</h1>
</div>
<div class="row">
<div class="col-md-6">
<div class="col-xs-12 col-lg-6">
<div class="box" id="domain-frequency">
<div class="box-header with-border">
<h3 class="box-title">Allowed queries</h3>
@@ -42,7 +41,8 @@
<!-- /.box -->
</div>
<!-- /.col -->
<div class="col-md-6">
<div class="col-xs-12 col-lg-6">
<div class="box" id="ad-frequency">
<div class="box-header with-border">
<h3 class="box-title">Blocked queries</h3>
@@ -72,6 +72,7 @@
</div>
<!-- /.row -->
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/auditlog.js"></script>
<?php
+4 -12
View File
@@ -6,16 +6,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
// Generate CSRF token
if(empty($_SESSION['token'])) {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
$token = $_SESSION['token'];
?>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<div class="page-header">
<h1>Compute graphical statistics from the Pi-hole query database</h1>
@@ -46,7 +37,7 @@ $token = $_SESSION['token'];
<div class="row">
<div class="col-md-12">
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden="true">
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
Depending on how large of a range you specified, the request may time out while Pi-hole tries to retrieve all the data.<br/><span id="err"></span>
</div>
</div>
@@ -69,14 +60,15 @@ $token = $_SESSION['token'];
</div>
</div>
</div>
<div class="overlay" hidden="true">
<div class="overlay" hidden>
<i class="fa fa-sync fa-spin"></i>
</div>
</div>
</div>
</div>
<script src="scripts/vendor/daterangepicker.js"></script>
<script src="scripts/vendor/daterangepicker.min.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/db_graph.js"></script>
<?php
+4 -11
View File
@@ -6,19 +6,11 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
// Generate CSRF token
if(empty($_SESSION['token'])) {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
$token = $_SESSION['token'];
?>
<!-- Sourceing CSS colors from stylesheet to be used in JS code -->
<span class="queries-permitted"></span>
<span class="queries-blocked"></span>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<!-- Title -->
<div class="page-header">
@@ -49,7 +41,7 @@ $token = $_SESSION['token'];
</div>
</div>
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden="true">
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
Depending on how large of a range you specified, the request may time out while Pi-hole tries to retrieve all the data.<br/><span id="err"></span>
</div>
@@ -147,7 +139,8 @@ else
<!-- /.col -->
</div>
<script src="scripts/vendor/daterangepicker.js"></script>
<script src="scripts/vendor/daterangepicker.min.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/db_lists.js"></script>
<?php
+16 -25
View File
@@ -6,16 +6,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
// Generate CSRF token
if(empty($_SESSION['token'])) {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
$token = $_SESSION['token'];
?>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<!-- Title -->
<div class="page-header">
@@ -52,26 +43,26 @@ $token = $_SESSION['token'];
</div>
<div class="form-group">
<div class="col-md-3">
<input type="checkbox" id="type_forwarded" checked><label for="type_forwarded">Permitted: forwarded</label><br>
<input type="checkbox" id="type_cached" checked><label for="type_cached">Permitted: cached</label>
<div><input type="checkbox" id="type_forwarded" checked><label for="type_forwarded">Permitted: forwarded</label><br></div>
<div><input type="checkbox" id="type_cached" checked><label for="type_cached">Permitted: cached</label></div>
</div>
<div class="col-md-3">
<input type="checkbox" id="type_gravity" checked><label for="type_gravity">Blocked: gravity</label><br>
<input type="checkbox" id="type_external" checked><label for="type_external">Blocked: external</label>
<div><input type="checkbox" id="type_gravity" checked><label for="type_gravity">Blocked: gravity</label><br></div>
<div><input type="checkbox" id="type_external" checked><label for="type_external">Blocked: external</label></div>
</div>
<div class="col-md-3">
<input type="checkbox" id="type_blacklist" checked><label for="type_blacklist">Blocked: exact blacklist</label><br>
<input type="checkbox" id="type_regex" checked><label for="type_regex">Blocked: regex blacklist</label>
<div><input type="checkbox" id="type_blacklist" checked><label for="type_blacklist">Blocked: exact blacklist</label><br></div>
<div><input type="checkbox" id="type_regex" checked><label for="type_regex">Blocked: regex blacklist</label></div>
</div>
<div class="col-md-3">
<input type="checkbox" id="type_gravity_CNAME" checked><label for="type_gravity_CNAME">Blocked: gravity (CNAME)</label><br>
<input type="checkbox" id="type_blacklist_CNAME" checked><label for="type_blacklist_CNAME">Blocked: exact blacklist (CNAME)</label><br>
<input type="checkbox" id="type_regex_CNAME" checked><label for="type_regex_CNAME">Blocked: regex blacklist (CNAME)</label>
<div><input type="checkbox" id="type_gravity_CNAME" checked><label for="type_gravity_CNAME">Blocked: gravity (CNAME)</label><br></div>
<div><input type="checkbox" id="type_blacklist_CNAME" checked><label for="type_blacklist_CNAME">Blocked: exact blacklist (CNAME)</label><br></div>
<div><input type="checkbox" id="type_regex_CNAME" checked><label for="type_regex_CNAME">Blocked: regex blacklist (CNAME)</label></div>
</div>
</div>
</div>
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden="true">
<div id="timeoutWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
Depending on how large of a range you specified, the request may time out while Pi-hole tries to retrieve all the data.<br/><span id="err"></span>
</div>
@@ -79,7 +70,7 @@ $token = $_SESSION['token'];
<div class="row">
<div class="col-lg-3 col-xs-12">
<!-- small box -->
<div class="small-box bg-aqua">
<div class="small-box bg-aqua no-user-select">
<div class="inner">
<h3 class="statistic" id="ads_blocked_exact">---</h3>
<p>Queries Blocked</p>
@@ -92,7 +83,7 @@ $token = $_SESSION['token'];
<!-- ./col -->
<div class="col-lg-3 col-xs-12">
<!-- small box -->
<div class="small-box bg-aqua">
<div class="small-box bg-aqua no-user-select">
<div class="inner">
<h3 class="statistic" id="ads_wildcard_blocked">---</h3>
<p>Queries Blocked (Wildcards)</p>
@@ -105,7 +96,7 @@ $token = $_SESSION['token'];
<!-- ./col -->
<div class="col-lg-3 col-xs-12">
<!-- small box -->
<div class="small-box bg-green">
<div class="small-box bg-green no-user-select">
<div class="inner">
<h3 class="statistic" id="dns_queries">---</h3>
<p>Queries Total</p>
@@ -118,7 +109,7 @@ $token = $_SESSION['token'];
<!-- ./col -->
<div class="col-lg-3 col-xs-12">
<!-- small box -->
<div class="small-box bg-yellow">
<div class="small-box bg-yellow no-user-select">
<div class="inner">
<h3 class="statistic" id="ads_percentage_today">---</h3>
<p>Queries Blocked</p>
@@ -139,7 +130,7 @@ $token = $_SESSION['token'];
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="all-queries" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
@@ -169,7 +160,7 @@ $token = $_SESSION['token'];
</div>
<!-- /.row -->
<script src="scripts/vendor/daterangepicker.js"></script>
<script src="scripts/vendor/daterangepicker.min.js"></script>
<script src="scripts/pi-hole/js/db_queries.js"></script>
<?php
+5 -3
View File
@@ -11,11 +11,13 @@
<div class="page-header">
<h1>Generate debug log</h1>
</div>
<input type="checkbox" id="upload"><label for="upload">Upload debug log and provide token once finished</label>
<div>
<input type="checkbox" id="upload">
<label for="upload">Upload debug log and provide token once finished</label>
</div>
<p>Once you click this button a debug log will be generated and can automatically be uploaded if we detect a working internet connection.</p>
<button type="button" id="debugBtn" class="btn btn-lg btn-primary btn-block">Generate debug log</button>
<pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre>
<pre id="output" style="width: 100%; height: 100%;" hidden></pre>
<script src="scripts/pi-hole/js/debug.js"></script>
+6 -6
View File
@@ -46,19 +46,19 @@
</div>
<!-- Alerts -->
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert" hidden="true">
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Updating the custom DNS entries...
</div>
<div id="alSuccess" class="alert alert-success alert-dismissible fade in" role="alert" hidden="true">
<div id="alSuccess" class="alert alert-success alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Success! The list will refresh.
</div>
<div id="alFailure" class="alert alert-danger alert-dismissible fade in" role="alert" hidden="true">
<div id="alFailure" class="alert alert-danger alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Failure! Something went wrong, see output below:<br/><br/><pre><span id="err"></span></pre>
</div>
<div id="alWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden="true">
<div id="alWarning" class="alert alert-warning alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
At least one domain was already present, see output below:<br/><br/><pre><span id="warn"></span></pre>
</div>
@@ -72,7 +72,7 @@
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="customDNSTable" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="customDNSTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Domain</th>
@@ -81,7 +81,7 @@
</tr>
</thead>
</table>
<button type="button" id="resetButton" hidden="true" class="btn btn-default btn-sm text-red">Clear Filters</button>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear Filters</button>
</div>
<!-- /.box-body -->
</div>
+4 -4
View File
@@ -13,17 +13,17 @@
</div>
<!-- Alerts -->
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert" hidden="true">
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Updating...this may take a while. <strong>Please do not navigate away from or close this page.</strong>
Updating... this may take a while. <strong>Please do not navigate away from or close this page.</strong>
</div>
<div id="alSuccess" class="alert alert-success alert-dismissible fade in" role="alert" hidden="true">
<div id="alSuccess" class="alert alert-success alert-dismissible fade in" role="alert" hidden>
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Success!
</div>
<button type="button" id="gravityBtn" class="btn btn-lg btn-primary btn-block">Update</button>
<pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre>
<pre id="output" style="width: 100%; height: 100%;" hidden></pre>
<script src="scripts/pi-hole/js/gravity.js"></script>
+11 -5
View File
@@ -28,7 +28,7 @@
<div class="row">
<div class="form-group col-md-6">
<label for="new_address">Address:</label>
<input id="new_address" type="text" class="form-control" placeholder="http://..., https://..., file://..." autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off">
<input id="new_address" type="text" class="form-control" placeholder="URL or space-separated URLs" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off">
</div>
<div class="form-group col-md-6">
<label for="new_comment">Comment:</label>
@@ -37,7 +37,11 @@
</div>
</div>
<div class="box-footer clearfix">
<strong>Hint:</strong>&nbsp;Please run <code>pihole -g</code> or update your gravity list <a href="gravity.php">online</a> after modifying your adlists.
<strong>Hints:</strong>
<ol>
<li>Please run <code>pihole -g</code> or update your gravity list <a href="gravity.php">online</a> after modifying your adlists.</li>
<li>Multiple adlists can be added by separating each <i>unique</i> URL with a space</li>
</ol>
<button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button>
</div>
</div>
@@ -53,7 +57,7 @@
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="adlistsTable" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="adlistsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
@@ -65,7 +69,7 @@
</tr>
</thead>
</table>
<button type="button" id="resetButton" hidden="true" class="btn btn-default btn-sm text-red">Reset sorting</button>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
</div>
<!-- /.box-body -->
</div>
@@ -73,7 +77,9 @@
</div>
</div>
<script src="scripts/pi-hole/js/groups-common.js"></script>
<script src="scripts/vendor/bootstrap-select.min.js"></script>
<script src="scripts/vendor/bootstrap-toggle.min.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/groups-adlists.js"></script>
<?php
+6 -3
View File
@@ -66,7 +66,7 @@
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="clientsTable" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="clientsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
@@ -77,7 +77,7 @@
</tr>
</thead>
</table>
<button type="button" id="resetButton" hidden="true" class="btn btn-default btn-sm text-red">Reset sorting</button>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
</div>
<!-- /.box-body -->
</div>
@@ -85,7 +85,10 @@
</div>
</div>
<script src="scripts/pi-hole/js/groups-common.js"></script>
<script src="scripts/vendor/bootstrap-select.min.js"></script>
<script src="scripts/vendor/bootstrap-toggle.min.js"></script>
<script src="scripts/pi-hole/js/ip-address-sorting.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/groups-clients.js"></script>
<?php
+24 -19
View File
@@ -33,28 +33,22 @@
<!-- /.box-header -->
<div class="box-body">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a aria-expanded="true" href="#tab_domain" data-toggle="tab">Domain</a></li>
<li class=""><a aria-expanded="false" href="#tab_regex" data-toggle="tab">RegEx filter</a></li>
</ul>
<ul class="nav nav-tabs" role="tablist">
<li class="active" role="presentation">
<a href="#tab_domain" aria-controls="tab_domain" aria-expanded="true" role="tab" data-toggle="tab">Domain</a>
</li>
<li role="presentation">
<a href="#tab_regex" aria-controls="tab_regex" aria-expanded="false" role="tab" data-toggle="tab">RegEx filter</a>
</li>
</ul>
<div class="tab-content">
<!-- Domain tab -->
<div id="tab_domain" class="tab-pane active in">
<div id="tab_domain" class="tab-pane active fade in">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="new_domain">Domain:</label>
<div class="input-group">
<input id="new_domain" type="url" class="form-control active" placeholder="Domain to be added" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off">
<span class="input-group-addon">
<input type="checkbox" id="wildcard_checkbox">
<label for="wildcard_checkbox">wildcard</label></span>
</span>
</div>
</div>
<div class="form-group">
<strong><i class="fa fa-question-circle"></i> Checkbox "wildcard":</span></strong> Check this box if you want to involve
all subdomains. The entered domain will be converted to a RegEx filter while adding.
</div>
</div>
<div class="col-md-6 form-group">
@@ -62,9 +56,18 @@
<input id="new_domain_comment" type="text" class="form-control" placeholder="Description (optional)">
</div>
</div>
<div class="row">
<div class="col-md-12">
<div>
<input type="checkbox" id="wildcard_checkbox">
<label for="wildcard_checkbox"><strong>Add domain as wildcard</strong></label>
<p>Check this box if you want to involve all subdomains. The entered domain will be converted to a RegEx filter while adding.</p>
</div>
</div>
</div>
</div>
<!-- RegEx tab -->
<div id="tab_regex" class="tab-pane">
<div id="tab_regex" class="tab-pane fade">
<div class="row">
<div class="col-md-6">
<div class="form-group">
@@ -114,7 +117,7 @@
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="domainsTable" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="domainsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
@@ -127,7 +130,7 @@
</tr>
</thead>
</table>
<button type="button" id="resetButton" hidden="true" class="btn btn-default btn-sm text-red">Reset sorting</button>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
</div>
<!-- /.box-body -->
</div>
@@ -135,7 +138,9 @@
</div>
</div>
<script src="scripts/pi-hole/js/groups-common.js"></script>
<script src="scripts/vendor/bootstrap-select.min.js"></script>
<script src="scripts/vendor/bootstrap-toggle.min.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/groups-domains.js"></script>
<?php
+11 -4
View File
@@ -28,7 +28,7 @@
<div class="row">
<div class="form-group col-md-6">
<label for="new_name">Name:</label>
<input id="new_name" type="text" class="form-control" placeholder="Group name">
<input id="new_name" type="text" class="form-control" placeholder="Group name or space-separated group names">
</div>
<div class="form-group col-md-6">
<label for="new_desc">Description:</label>
@@ -37,6 +37,11 @@
</div>
</div>
<div class="box-footer clearfix">
<strong>Hints:</strong>
<ol>
<li>Multiple groups can be added by separating each group name with a space</li>
<li>Group names can have spaces if entered in quotes. e.g "My New Group"</li>
</ol>
<button type="button" id="btnAdd" class="btn btn-primary pull-right">Add</button>
</div>
</div>
@@ -52,7 +57,7 @@
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="groupsTable" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="groupsTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
@@ -63,7 +68,7 @@
</tr>
</thead>
</table>
<button type="button" id="resetButton" hidden="true" class="btn btn-default btn-sm text-red">Reset sorting</button>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Reset sorting</button>
</div>
<!-- /.box-body -->
</div>
@@ -71,7 +76,9 @@
</div>
</div>
<script src="scripts/pi-hole/js/groups-common.js"></script>
<script src="scripts/vendor/bootstrap-select.min.js"></script>
<script src="scripts/vendor/bootstrap-toggle.min.js"></script>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/groups.js"></script>
<?php
-156
View File
@@ -1,156 +0,0 @@
<?php /*
* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
if(strlen($pwhash) > 0)
{
$authenticationsystem = true;
}
else
{
$authenticationsystem = false;
}
?>
<div class="row">
<div class="col-md-12">
<h1>Help center</h1>
<h2>Header</h2>
<h4>Top left: Status display</h4>
<p>Shows different status messages:</p>
<ul>
<li>Status: Current status of the Pi-hole - Active (<i class="fa fa-circle text-green-light"></i>), Offline (<i class="fa fa-circle text-red"></i>), or Starting (<i class="fa fa-circle text-orange"></i>)</li>
<li>Temp: Current CPU temperature</li>
<li>Load: load averages for the last minute, 5 minutes and 15 minutes, respectively. A load average of 1 reflects the full workload of a single processor on the system. We show a red icon if the current load exceeds the number of available processors on this machine (which is <?php echo $nproc; ?>)</li>
<li>Memory usage: Shows the percentage of memory actually blocked by applications. We show a red icon if the memory usage exceeds 75%</li>
</ul>
<h4>Top right: About</h4>
<ul>
<li>GitHub: Link to the Pi-hole repository</li>
<li>Details: Link to Jacob Salmela's blog with some more details, describing also the concept of the Pi-hole</li>
<li>Updates: Link to list of releases</li>
<li>Update notifications: If updates are available, a link will be shown here.</li>
<?php if($authenticationsystem){ ?>
<li>Session timer: Shows the time remaining until the current login session expires.</li>
<?php } ?>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Dashboard</h2>
<p>On the dashboard, you can see various Pi-hole statistics:</p>
<ul>
<li>Summary: A summary of statistics showing how many total DNS queries have been blocked today, what percentage of DNS queries have been blocked, and how many domains are in the compiled ad list. This summary is updated every 10 seconds.</li>
<li>Queries over time: Graph showing DNS queries (total and blocked) over 10 minute time intervals. More information can be acquired by hovering over the lines. This graph is updated every 10 minutes.</li>
<li>Query Types: Identifies the types of processed queries</li>
<li>Forward Destinations: Shows to which upstream DNS the permitted requests have been forwarded to.</li>
<li>Top Domains: Ranking of requested sites by number of DNS lookups.</li>
<li>Top Advertisers: Ranking of requested advertisements by number of DNS lookups.</li>
<li>Top Clients: Ranking of how many DNS requests each client has made on the local network.</li>
</ul>
<p>The Top Domains and Top Advertisers lists may be hidden depending on the privacy Settings on the settings page</p>
<?php if($authenticationsystem){ ?>
<p>Note that the login session does <em>not</em> expire on the dashboard, as the summary is updated every 10 seconds which refreshes the session.</p>
<?php } ?>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Query Log</h2>
<p>Shows the recent queries by parsing Pi-hole's log. It is possible to search through the whole list by using the "Search" input field. If the status is reported as "OK", then the DNS request has been permitted. Otherwise ("Pi-holed") it has been blocked. By clicking on the buttons under "Action" the corresponding domains can quickly be added to the white-/blacklist. The status of the action will be reported on this page. By default, only the recent 10 minutes are shown to enhance the loading speed of the query log page. All domains can be requested by clicking on the corresponding link in the header of the page. Note that the result heavily depends on your privacy settings (see Settings page).</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>White- / Blacklist</h2>
<p>Add or remove domains (or subdomains) from the white-/blacklist. If a domain is added to e.g. the whitelist, any possible entry of the same domain will be automatically removed from the blacklist and vice versa.</p>
<p>Regex blacklisting is supported (entering <code>^example</code> will block any domain starting with <code>example</code>, see also our <a href="https://docs.pi-hole.net/ftldns/regex/" rel="noopener" target="_blank">Regex documentation</a>). You can still whitelist specific domains even if they fall under a regex pattern.</p>
<p>You can white-/blacklist multiple entries at a time if you separate the domains by spaces.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Disable / Enable</h2>
Disables/enables Pi-hole blocking completely. You may have to wait a few minutes for the changes to reach all of your devices. The change will be reflected by a changed status (top left)
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Tools &rarr; Update Gravity</h2>
<p>Will download any updates from the third-party blocklists that we source. By default, this command runs once a week via cron (Sunday).</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Tools &rarr; Query Lists</h2>
This function is useful to find out what list a domain appears on. Since we don't control what the third-parties put on the blocklists, you may find that a domain you normally visit stops working. If this is the case, you could run this command to scan for strings in the list of blocked domains and it will return the list the domain is found on. This proved useful a while back when the Mahakala list was adding <code>apple.com</code> and <code>microsoft.com</code> to their block list.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Tools &rarr; Tail pihole.log</h2>
Live tailing of the raw Pi-hole log.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Settings</h2>
Change settings for the Pi-hole
<h4>System</h4>
Displays network and other system information of Pi-hole. At the bottom there is a "Danger Zone" with actions such as disable query logging and reboot.
<h4>Blocklists</h4>
View and edit the blocklists sourced for blocked domains.
<h4>DNS</h4>
Customize used upstream DNS servers + advanced settings for DNS servers. Note that any number of DNS servers may be enabled at a time.
<h4>DHCP</h4>
Using this setting you can enable/disable the DHCP server of the Pi-hole. Note that you should disable any other DHCP server on your network to avoid IP addresses being used more than once. You have to give the range of IPs that DHCP will serve and the IP of the local router (gateway). If the DHCP server is active, the current leases are shown on the settings page. IPv4 DHCP will always be activated, IPv6 (stateless + statefull) can be enabled.
<h4>API / Web Interface</h4>
Change settings which apply to the API as well as the web interface
<h4>Privacy</h4>
Set the privacy level for queries. Note that decreasing the privacy level will not disclose previously hidden query data.
<h4>Teleporter</h4>
Import and export Pi-hole settings.
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Authentication system (currently <?php if($authenticationsystem) { ?>enabled<?php } else { ?>disabled<?php } ?>)</h2>
<p>Using the command<pre>sudo pihole -a -p</pre> and entering a password to be set, one can enable the authentication system of this web interface. Thereafter, a login is required for most pages (the dashboard will show a limited amount of statistics). Note that the authentication system may be disabled again, by setting an empty password using the command shown above. The Help center will show more details concerning the authentication system only if it is enabled</p>
</div>
</div>
<?php if($authenticationsystem) { ?>
<div class="row">
<div class="col-md-12">
<h2>Login / Logout</h2>
<p>Using the Login / Logout function, a user can initiate / terminate a login session. The login page will also always be shown if a user tries to access a protected page directly without having a valid login session</p>
</div>
</div>
<?php } ?>
<div class="row">
<div class="col-md-12">
<h2>Donate</h2>
Keep in mind that Pi-hole is free. If you like Pi-hole, please consider a small donation to help support its development
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Help (this page)</h2>
Shows information about what is happening behind the scenes and what can be done with this web user interface (web UI). The Help center will show details concerning the authentication system only if it is enabled
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Footer</h2>
Shows the currently installed Pi-hole and Web Interface version. If an update is available, this will be indicated here
</div>
</div>
<?php
require "scripts/pi-hole/php/footer.php";
?>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+12 -11
View File
@@ -31,7 +31,7 @@
<div class="row">
<div class="col-lg-3 col-sm-6">
<!-- small box -->
<div class="small-box bg-green" id="total_queries" title="only A + AAAA queries">
<div class="small-box bg-green no-user-select" id="total_queries" title="only A + AAAA queries">
<div class="inner">
<p>Total queries (<span id="unique_clients">-</span> clients)</p>
<h3 class="statistic"><span id="dns_queries_today">---</span></h3>
@@ -44,10 +44,10 @@
<!-- ./col -->
<div class="col-lg-3 col-sm-6">
<!-- small box -->
<div class="small-box bg-aqua">
<div class="small-box bg-aqua no-user-select">
<div class="inner">
<p>Queries Blocked</p>
<h3 class="statistic"><span id="ads_blocked_today">---</span></h3>
<h3 class="statistic"><span id="queries_blocked_today">---</span></h3>
</div>
<div class="icon">
<i class="fas fa-hand-paper"></i>
@@ -57,10 +57,10 @@
<!-- ./col -->
<div class="col-lg-3 col-sm-6">
<!-- small box -->
<div class="small-box bg-yellow">
<div class="small-box bg-yellow no-user-select">
<div class="inner">
<p>Percent Blocked</p>
<h3 class="statistic"><span id="ads_percentage_today">---</span></h3>
<h3 class="statistic"><span id="percentage_blocked_today">---</span></h3>
</div>
<div class="icon">
<i class="fas fa-chart-pie"></i>
@@ -70,7 +70,7 @@
<!-- ./col -->
<div class="col-lg-3 col-sm-6">
<!-- small box -->
<div class="small-box bg-red" title="<?php echo gravity_last_update(); ?>">
<div class="small-box bg-red no-user-select" title="<?php echo gravity_last_update(); ?>">
<div class="inner">
<p>Domains on Blocklist</p>
<h3 class="statistic"><span id="domains_being_blocked">---</span></h3>
@@ -116,7 +116,7 @@
</div>
<div class="box-body">
<div class="chart">
<canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas"></canvas>
<canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas>
</div>
</div>
<div class="overlay">
@@ -128,7 +128,7 @@
</div>
<div class="row">
<div class="col-md-12 col-lg-6">
<div class="col-md-6">
<div class="box" id="query-types-pie">
<div class="box-header with-border">
<h3 class="box-title">Query Types</h3>
@@ -147,17 +147,17 @@
<!-- /.box-body -->
</div>
</div>
<div class="col-md-12 col-lg-6">
<div class="col-md-6">
<div class="box" id="forward-destinations-pie">
<div class="box-header with-border">
<h3 class="box-title">Queries answered by</h3>
</div>
<div class="box-body">
<div class="pull-left" style="width:50%">
<canvas id="forwardDestinationPieChart" width="120" height="120" class="extratooltipcanvas"></canvas>
<canvas id="forwardDestinationPieChart" width="120" height="120" class="extratooltipcanvas no-user-select"></canvas>
</div>
<div class="pull-left" style="width:50%">
<div id="forward-destinations-legend" class="chart-legend" class="extratooltipcanvas"></div>
<div id="forward-destinations-legend" class="chart-legend extratooltipcanvas no-user-select"></div>
</div>
</div>
<div class="overlay">
@@ -294,6 +294,7 @@ else
<!-- /.row -->
<?php } ?>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/index.js"></script>
<?php
+49
View File
@@ -0,0 +1,49 @@
<?php /*
* Pi-hole: A black hole for Internet advertisements
* (c) 2020 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
?>
<!-- Title -->
<div class="page-header">
<h1>Pi-hole diagnosis</h1>
<small>On this page, you can see messages from your Pi-hole concerning possible issues.</small>
</div>
<div class="row">
<div class="col-md-12">
<div class="box" id="messages-list">
<!-- /.box-header -->
<div class="box-body">
<table id="messagesTable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>ID</th>
<th>Time</th>
<th>Type</th>
<th>Message</th>
<th>Data1</th>
<th>Data2</th>
<th>Data3</th>
<th>Data4</th>
<th>Data5</th>
</tr>
</thead>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
</div>
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/messages.js"></script>
<?php
require "scripts/pi-hole/php/footer.php";
?>
+6 -12
View File
@@ -6,15 +6,8 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
// Generate CSRF token
if(empty($_SESSION['token'])) {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
$token = $_SESSION['token'];
?>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<!-- Sourceing CSS colors from stylesheet to be used in JS code -->
<span class="queries-permitted"></span>
<span class="queries-blocked"></span>
@@ -29,7 +22,7 @@ $token = $_SESSION['token'];
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="network-entries" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="network-entries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>IP address</th>
@@ -73,9 +66,10 @@ $token = $_SESSION['token'];
</div>
<!-- /.row -->
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/ip-address-sorting.js"></script>
<script src="scripts/pi-hole/js/network.js"></script>
<?php
require "scripts/pi-hole/php/footer.php";
?>
<script src="scripts/pi-hole/js/ip-address-sorting.js"></script>
<script src="scripts/pi-hole/js/network.js"></script>
+1662 -754
View File
File diff suppressed because it is too large Load Diff
+31 -6
View File
@@ -15,13 +15,26 @@
},
"homepage": "https://github.com/pi-hole/AdminLTE#readme",
"scripts": {
"prefix": "postcss \"style/*.css\" \"style/themes/*.css\" --use autoprefixer --no-map --replace",
"prettier:check": "prettier -l \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**/*.js\"",
"prettier:fix": "prettier --write \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**/*.js\"",
"xo": "xo",
"xo:fix": "npm run xo -- --fix",
"test": "npm run xo"
"test": "npm run prettier:check && npm run xo"
},
"devDependencies": {
"xo": "^0.30.0"
"autoprefixer": "^9.8.0",
"eslint-plugin-compat": "^3.7.0",
"postcss-cli": "^7.1.1",
"prettier": "2.0.4",
"xo": "^0.32.0"
},
"browserslist": [
"defaults",
"Explorer >= 11",
"not ExplorerMobile <= 11",
"not Safari 5.1"
],
"prettier": {
"arrowParens": "avoid",
"bracketSpacing": true,
@@ -35,6 +48,9 @@
"browser",
"jquery"
],
"extends": [
"plugin:compat/recommended"
],
"parserOptions": {
"ecmaVersion": 5,
"sourceType": "script"
@@ -46,13 +62,23 @@
"**/vendor/**"
],
"rules": {
"camelcase": "off",
"camelcase": [
"error",
{
"properties": "never"
}
],
"capitalized-comments": "off",
"new-cap": "off",
"new-cap": [
"error",
{
"properties": false
}
],
"no-alert": "off",
"no-console": "error",
"no-negated-condition": "off",
"one-var": "off",
"radix": "off",
"spaced-comment": "off",
"unicorn/explicit-length-check": [
"error",
@@ -63,7 +89,6 @@
"unicorn/filename-case": "off",
"unicorn/no-fn-reference-in-iterator": "off",
"unicorn/no-for-loop": "off",
"unicorn/no-zero-fractions": "off",
"unicorn/prefer-includes": "off",
"unicorn/prefer-node-append": "off",
"unicorn/prefer-number-properties": "off",
+7 -11
View File
@@ -7,12 +7,6 @@
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/header.php";
// Generate CSRF token
if(empty($_SESSION['token'])) {
$_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));
}
$token = $_SESSION['token'];
$showing = "";
if(isset($setupVars["API_QUERY_LOG_SHOW"]))
@@ -80,8 +74,6 @@ if(strlen($showing) > 0)
$showing .= ", <a href=\"?all\">show all</a>";
}
?>
<!-- Send PHP info to JS -->
<div id="token" hidden><?php echo $token ?></div>
<!-- Alert Modal -->
<div id="alertModal" class="modal fade" role="dialog" data-backdrop="static" data-keyboard="false">
@@ -122,7 +114,7 @@ if(strlen($showing) > 0)
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="all-queries" class="display table table-striped table-bordered" cellspacing="0" width="100%">
<table id="all-queries" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>Time</th>
@@ -146,8 +138,11 @@ if(strlen($showing) > 0)
</tr>
</tfoot>
</table>
<label><input type="checkbox" id="autofilter">&nbsp;Apply filtering on click on Type, Domain, and Clients</label><br/>
<button type="button" id="resetButton" hidden="true">Clear Filters</button>
<div>
<input type="checkbox" id="autofilter">
<label for="autofilter">Apply filtering on click on Type, Domain, and Clients</label>
</div>
<button type="button" id="resetButton" class="btn btn-default btn-sm text-red hidden">Clear Filters</button>
</div>
<!-- /.box-body -->
</div>
@@ -156,6 +151,7 @@ if(strlen($showing) > 0)
</div>
<!-- /.row -->
<script src="scripts/pi-hole/js/utils.js"></script>
<script src="scripts/pi-hole/js/queries.js"></script>
<?php
+9 -11
View File
@@ -15,16 +15,14 @@
<div class="col-md-12">
<div class="box">
<div class="box-body">
<div class="row">
<div class="form-group col-md-12">
<div class="form-group input-group">
<input id="domain" type="text" class="form-control" placeholder="Domain to look for (example.com or sub.example.com)">
<input id="quiet" type="hidden" value="no">
<span class="input-group-btn">
<button type="button" id="btnSearch" class="btn btn-default">Search partial match</button>
<button type="button" id="btnSearchExact" class="btn btn-default">Search exact match</button>
</span>
</div>
<div class="form-group">
<div class="input-group">
<input id="domain" type="text" class="form-control" placeholder="Domain to look for (example.com or sub.example.com)">
<input id="quiet" type="hidden" value="no">
<span class="input-group-btn">
<button type="button" id="btnSearch" class="btn btn-default">Search partial match</button>
<button type="button" id="btnSearchExact" class="btn btn-default">Search exact match</button>
</span>
</div>
</div>
</div>
@@ -32,7 +30,7 @@
</div>
</div>
<pre id="output" style="width: 100%; height: 100%;" hidden="true"></pre>
<pre id="output" style="width: 100%; height: 100%;" hidden></pre>
<script src="scripts/pi-hole/js/queryads.js"></script>
+24 -29
View File
@@ -5,24 +5,11 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global utils:false */
// Define global variables
var auditTimeout = null;
// Credit: http://stackoverflow.com/questions/1787322/htmlspecialchars-equivalent-in-javascript/4835406#4835406
function escapeHtml(text) {
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#039;"
};
return text.replace(/[&<>"']/g, function (m) {
return map[m];
});
}
function updateTopLists() {
$.getJSON("api.php?topItems=audit", function (data) {
if ("FTLnotrunning" in data) {
@@ -38,7 +25,7 @@ function updateTopLists() {
for (domain in data.top_queries) {
if (Object.prototype.hasOwnProperty.call(data.top_queries, domain)) {
// Sanitize domain
domain = escapeHtml(domain);
domain = utils.escapeHtml(domain);
url = '<a href="queries.php?domain=' + domain + '">' + domain + "</a>";
domaintable.append(
"<tr><td>" +
@@ -46,8 +33,8 @@ function updateTopLists() {
"</td> <td>" +
data.top_queries[domain] +
"</td> <td>" +
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>' +
'<button type="button" class="btn btn-default btn-sm text-orange"><i class="fa fa-balance-scale"></i> Audit</button>' +
'<button type="button" class="btn btn-default btn-xs text-red"><i class="fa fa-ban"></i> Blacklist</button>' +
'<button type="button" class="btn btn-default btn-xs text-orange"><i class="fa fa-balance-scale"></i> Audit</button>' +
"</td> </tr> "
);
}
@@ -57,7 +44,7 @@ function updateTopLists() {
if (Object.prototype.hasOwnProperty.call(data.top_ads, domain)) {
var input = domain.split(" ");
// Sanitize domain
var printdomain = escapeHtml(input[0]);
var printdomain = utils.escapeHtml(input[0]);
if (input.length > 1) {
url =
'<a href="queries.php?domain=' +
@@ -82,8 +69,8 @@ function updateTopLists() {
"</td> <td>" +
data.top_ads[domain] +
"</td> <td>" +
'<button type="button" class="btn btn-default btn-sm text-green"><i class="fas fa-check"></i> Whitelist</button>' +
'<button type="button" class="btn btn-default btn-sm text-orange"><i class="fa fa-balance-scale"></i> Audit</button>' +
'<button type="button" class="btn btn-default btn-xs text-green"><i class="fas fa-check"></i> Whitelist</button>' +
'<button type="button" class="btn btn-default btn-xs text-orange"><i class="fa fa-balance-scale"></i> Audit</button>' +
"</td> </tr> "
);
}
@@ -106,14 +93,20 @@ function updateTopLists() {
function add(domain, list) {
var token = $("#token").text();
$.ajax({
url: "scripts/pi-hole/php/add.php",
url: "scripts/pi-hole/php/groups.php",
method: "post",
data: { domain: domain, list: list, token: token },
data: {
domain: domain,
list: list,
token: token,
action: "add_domain",
comment: "Added from Audit Log"
},
success: function () {
updateTopLists();
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -134,22 +127,24 @@ function auditUrl(url) {
add(url, "audit");
}
$(document).ready(function () {
$(function () {
// Pull in data via AJAX
updateTopLists();
$("#domain-frequency tbody").on("click", "button", function () {
$("#domain-frequency tbody").on("click", "button", function (event) {
var url = $(this).parents("tr")[0].textContent.split(" ")[0];
if ($(this).context.textContent === " Blacklist") {
if (event.target.textContent.trim() === "Blacklist") {
blacklistUrl(url);
} else {
auditUrl(url);
}
});
$("#ad-frequency tbody").on("click", "button", function () {
$("#ad-frequency tbody").on("click", "button", function (event) {
var url = $(this).parents("tr")[0].textContent.split(" ")[0];
if ($(this).context.textContent === " Whitelist") {
if (event.target.textContent.trim() === "Whitelist") {
whitelistUrl(url);
} else {
auditUrl(url);
+10 -5
View File
@@ -6,6 +6,7 @@
* Please see LICENSE file for your rights under this license. */
var table;
var token = $("#token").text();
function showAlert(type, message) {
var alertElement = null;
@@ -36,11 +37,15 @@ function showAlert(type, message) {
alertElement.delay(8000).fadeOut(2000);
}
$(document).ready(function () {
$(function () {
$("#btnAdd").on("click", addCustomDNS);
table = $("#customDNSTable").DataTable({
ajax: "scripts/pi-hole/php/customdns.php?action=get",
ajax: {
url: "scripts/pi-hole/php/customdns.php",
data: { action: "get", token: token },
type: "POST"
},
columns: [{}, { type: "ip-address" }, { orderable: false, searchable: false }],
columnDefs: [
{
@@ -79,7 +84,7 @@ function addCustomDNS() {
url: "scripts/pi-hole/php/customdns.php",
method: "post",
dataType: "json",
data: { action: "add", ip: ip, domain: domain },
data: { action: "add", ip: ip, domain: domain, token: token },
success: function (response) {
if (response.success) {
showAlert("success");
@@ -101,7 +106,7 @@ function deleteCustomDNS() {
url: "scripts/pi-hole/php/customdns.php",
method: "post",
dataType: "json",
data: { action: "delete", domain: domain, ip: ip },
data: { action: "delete", domain: domain, ip: ip, token: token },
success: function (response) {
if (response.success) {
showAlert("success");
@@ -110,7 +115,7 @@ function deleteCustomDNS() {
},
error: function (jqXHR, exception) {
showAlert("error", "Error while deleting this custom DNS entry");
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
+36 -58
View File
@@ -5,7 +5,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global Chart:false, moment:false */
/* global utils:false, Chart:false, moment:false */
var start__ = moment().subtract(6, "days");
var from = moment(start__).utc().valueOf() / 1000;
@@ -13,8 +13,6 @@ var end__ = moment();
var until = moment(end__).utc().valueOf() / 1000;
var interval = 0;
var timeoutWarning = $("#timeoutWarning");
var dateformat = "MMMM Do YYYY, HH:mm";
$(function () {
@@ -52,28 +50,6 @@ $(function () {
);
});
function padNumber(num) {
return ("00" + num).substr(-2, 2);
}
// Helper function needed for converting the Objects to Arrays
function objectToArray(p) {
var keys = Object.keys(p);
keys.sort(function (a, b) {
return a - b;
});
var arr = [],
idx = [];
for (var i = 0; i < keys.length; i++) {
arr.push(p[keys[i]]);
idx.push(keys[i]);
}
return [idx, arr];
}
var timeLineChart;
function compareNumbers(a, b) {
@@ -81,6 +57,8 @@ function compareNumbers(a, b) {
}
function updateQueriesOverTime() {
var timeoutWarning = $("#timeoutWarning");
$("#queries-over-time .overlay").show();
timeoutWarning.show();
@@ -110,8 +88,8 @@ function updateQueriesOverTime() {
"api_db.php?getGraphData&from=" + from + "&until=" + until + "&interval=" + interval,
function (data) {
// convert received objects to arrays
data.domains_over_time = objectToArray(data.domains_over_time);
data.ads_over_time = objectToArray(data.ads_over_time);
data.domains_over_time = utils.objectToArray(data.domains_over_time);
data.ads_over_time = utils.objectToArray(data.ads_over_time);
// Remove possibly already existing data
timeLineChart.data.labels = [];
timeLineChart.data.datasets[0].data = [];
@@ -122,14 +100,14 @@ function updateQueriesOverTime() {
for (hour in data.domains_over_time[0]) {
if (Object.prototype.hasOwnProperty.call(data.domains_over_time[0], hour)) {
dates.push(parseInt(data.domains_over_time[0][hour]));
dates.push(parseInt(data.domains_over_time[0][hour], 10));
}
}
for (hour in data.ads_over_time[0]) {
if (Object.prototype.hasOwnProperty.call(data.ads_over_time[0], hour)) {
if (dates.indexOf(parseInt(data.ads_over_time[0][hour])) === -1) {
dates.push(parseInt(data.ads_over_time[0][hour]));
if (dates.indexOf(parseInt(data.ads_over_time[0][hour], 10)) === -1) {
dates.push(parseInt(data.ads_over_time[0][hour], 10));
}
}
}
@@ -168,12 +146,12 @@ function updateQueriesOverTime() {
);
}
$(document).ready(function () {
$(function () {
var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
var blockedColor = "#999";
var permittedColor = "#00a65a";
timeLineChart = new Chart(ctx, {
type: "bar",
type: utils.getGraphType(),
data: {
labels: [],
datasets: [
@@ -212,40 +190,40 @@ $(document).ready(function () {
title: function (tooltipItem) {
var label = tooltipItem[0].xLabel;
var time = new Date(label);
var from_date =
var fromDate =
time.getFullYear() +
"-" +
padNumber(time.getMonth() + 1) +
utils.padNumber(time.getMonth() + 1) +
"-" +
padNumber(time.getDate());
var from_time =
padNumber(time.getHours()) +
utils.padNumber(time.getDate());
var fromTime =
utils.padNumber(time.getHours()) +
":" +
padNumber(time.getMinutes()) +
utils.padNumber(time.getMinutes()) +
":" +
padNumber(time.getSeconds());
utils.padNumber(time.getSeconds());
time = new Date(time.valueOf() + 1000 * interval);
var until_date =
var untilDate =
time.getFullYear() +
"-" +
padNumber(time.getMonth() + 1) +
utils.padNumber(time.getMonth() + 1) +
"-" +
padNumber(time.getDate());
var until_time =
padNumber(time.getHours()) +
utils.padNumber(time.getDate());
var untilTime =
utils.padNumber(time.getHours()) +
":" +
padNumber(time.getMinutes()) +
utils.padNumber(time.getMinutes()) +
":" +
padNumber(time.getSeconds());
utils.padNumber(time.getSeconds());
if (from_date === until_date) {
if (fromDate === untilDate) {
// Abbreviated form for intervals on the same day
// We split title in two lines on small screens
if ($(window).width() < 992) {
until_time += "\n";
untilTime += "\n";
}
return ("Queries from " + from_time + " to " + until_time + " on " + from_date).split(
return ("Queries from " + fromTime + " to " + untilTime + " on " + fromDate).split(
"\n "
);
}
@@ -253,27 +231,27 @@ $(document).ready(function () {
// Full tooltip for intervals spanning more than one day
// We split title in two lines on small screens
if ($(window).width() < 992) {
from_date += "\n";
fromDate += "\n";
}
return (
"Queries from " +
from_date +
fromDate +
" " +
from_time +
fromTime +
" to " +
until_date +
untilDate +
" " +
until_time
untilTime
).split("\n ");
},
label: function (tooltipItems, data) {
if (tooltipItems.datasetIndex === 0) {
var percentage = 0.0;
var permitted = parseInt(data.datasets[1].data[tooltipItems.index]);
var blocked = parseInt(data.datasets[0].data[tooltipItems.index]);
var percentage = 0;
var permitted = parseInt(data.datasets[1].data[tooltipItems.index], 10);
var blocked = parseInt(data.datasets[0].data[tooltipItems.index], 10);
if (permitted + blocked > 0) {
percentage = (100.0 * blocked) / (permitted + blocked);
percentage = (100 * blocked) / (permitted + blocked);
}
return (
+14 -29
View File
@@ -5,7 +5,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global moment:false */
/* global utils:false, moment:false */
var start__ = moment().subtract(6, "days");
var from = moment(start__).utc().valueOf() / 1000;
@@ -52,21 +52,6 @@ $(function () {
);
});
// Credit: http://stackoverflow.com/questions/1787322/htmlspecialchars-equivalent-in-javascript/4835406#4835406
function escapeHtml(text) {
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#039;"
};
return text.replace(/[&<>"']/g, function (m) {
return map[m];
});
}
function updateTopClientsChart() {
$("#client-frequency .overlay").show();
$.getJSON("api_db.php?topClients&from=" + from + "&until=" + until, function (data) {
@@ -84,20 +69,20 @@ function updateTopClientsChart() {
for (client in data.top_sources) {
if (Object.prototype.hasOwnProperty.call(data.top_sources, client)) {
// Sanitize client
client = escapeHtml(client);
if (escapeHtml(client) !== client) {
client = utils.escapeHtml(client);
if (utils.escapeHtml(client) !== client) {
// Make a copy with the escaped index if necessary
data.top_sources[escapeHtml(client)] = data.top_sources[client];
data.top_sources[utils.escapeHtml(client)] = data.top_sources[client];
}
if (client.indexOf("|") > -1) {
if (client.indexOf("|") !== -1) {
var idx = client.indexOf("|");
clientname = client.substr(0, idx);
} else {
clientname = client;
}
percentage = (data.top_sources[client] / sum) * 100.0;
percentage = (data.top_sources[client] / sum) * 100;
clienttable.append(
"<tr> <td>" +
clientname +
@@ -138,13 +123,13 @@ function updateTopDomainsChart() {
for (domain in data.top_domains) {
if (Object.prototype.hasOwnProperty.call(data.top_domains, domain)) {
// Sanitize domain
domain = escapeHtml(domain);
if (escapeHtml(domain) !== domain) {
domain = utils.escapeHtml(domain);
if (utils.escapeHtml(domain) !== domain) {
// Make a copy with the escaped index if necessary
data.top_domains[escapeHtml(domain)] = data.top_domains[domain];
data.top_domains[utils.escapeHtml(domain)] = data.top_domains[domain];
}
percentage = (data.top_domains[domain] / sum) * 100.0;
percentage = (data.top_domains[domain] / sum) * 100;
domaintable.append(
"<tr> <td>" +
domain +
@@ -185,13 +170,13 @@ function updateTopAdsChart() {
for (ad in data.top_ads) {
if (Object.prototype.hasOwnProperty.call(data.top_ads, ad)) {
// Sanitize ad
ad = escapeHtml(ad);
if (escapeHtml(ad) !== ad) {
ad = utils.escapeHtml(ad);
if (utils.escapeHtml(ad) !== ad) {
// Make a copy with the escaped index if necessary
data.top_ads[escapeHtml(ad)] = data.top_ads[ad];
data.top_ads[utils.escapeHtml(ad)] = data.top_ads[ad];
}
percentage = (data.top_ads[ad] / sum) * 100.0;
percentage = (data.top_ads[ad] / sum) * 100;
adtable.append(
"<tr> <td>" +
ad +
+27 -20
View File
@@ -28,8 +28,8 @@ window.location.search
});
if ("from" in GETDict && "until" in GETDict) {
from = parseInt(GETDict.from);
until = parseInt(GETDict.until);
from = parseInt(GETDict.from, 10);
until = parseInt(GETDict.until, 10);
start__ = moment(1000 * from);
end__ = moment(1000 * until);
instantquery = true;
@@ -92,16 +92,19 @@ function add(domain, list) {
alSuccess.hide();
alFailure.hide();
$.ajax({
url: "scripts/pi-hole/php/add.php",
url: "scripts/pi-hole/php/groups.php",
method: "post",
data: { domain: domain, list: list, token: token },
data: {
domain: domain,
list: list,
token: token,
action: "add_domain",
comment: "Added from Long-Term-Data Query Log"
},
success: function (response) {
if (
response.indexOf("not a valid argument") >= 0 ||
response.indexOf("is not a valid domain") >= 0
) {
if (!response.success) {
alFailure.show();
err.html(response);
err.html(response.message);
alFailure.delay(4000).fadeOut(2000, function () {
alFailure.hide();
});
@@ -136,10 +139,14 @@ function add(domain, list) {
function handleAjaxError(xhr, textStatus) {
if (textStatus === "timeout") {
alert("The server took too long to send the data.");
} else if (xhr.responseText.indexOf("Connection refused") >= 0) {
} else if (xhr.responseText.indexOf("Connection refused") !== -1) {
alert("An error occurred while loading the data: Connection refused. Is FTL running?");
} else {
alert("An unknown error occurred while loading the data.\n" + xhr.responseText);
alert(
"An unknown error occurred while loading the data.\n" +
xhr.responseText +
"\nCheck the server's log files (/var/log/lighttpd/error.log when you're using the default Pi-hole web server) for details. You may need to increase the memory available for Pi-hole in case you requested a lot of data."
);
}
$("#all-queries_processing").hide();
@@ -195,13 +202,13 @@ var reloadCallback = function () {
statistics = [0, 0, 0, 0];
var data = tableApi.rows().data();
for (var i = 0; i < data.length; i++) {
statistics[0]++;
if (data[i][4] === 1) {
statistics[2]++;
statistics[0]++; // TOTAL query
if (data[i][4] === 1 || (data[i][4] > 4 && data[i][4] !== 10)) {
statistics[2]++; // EXACT blocked
} else if (data[i][4] === 3) {
statistics[1]++;
} else if (data[i][4] === 4) {
statistics[3]++;
statistics[1]++; // CACHE query
} else if (data[i][4] === 4 || data[i][4] === 10) {
statistics[3]++; // REGEX blocked
}
}
@@ -209,9 +216,9 @@ var reloadCallback = function () {
$("h3#ads_blocked_exact").text(statistics[2].toLocaleString());
$("h3#ads_wildcard_blocked").text(statistics[3].toLocaleString());
var percent = 0.0;
var percent = 0;
if (statistics[2] + statistics[3] > 0) {
percent = (100.0 * (statistics[2] + statistics[3])) / statistics[0];
percent = (100 * (statistics[2] + statistics[3])) / statistics[0];
}
$("h3#ads_percentage_today").text(parseFloat(percent).toFixed(1).toLocaleString() + " %");
@@ -230,7 +237,7 @@ function refreshTableData() {
tableApi.ajax.url(APIstring).load(reloadCallback);
}
$(document).ready(function () {
$(function () {
var APIstring;
if (instantquery) {
+12 -28
View File
@@ -5,31 +5,6 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global ActiveXObject: false */
// Credit: http://stackoverflow.com/a/10642418/2087442
function httpGet(ta, theUrl) {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
ta.show();
ta.empty();
ta.append(xmlhttp.responseText);
}
};
xmlhttp.open("GET", theUrl, false);
xmlhttp.send();
}
function eventsource() {
var ta = $("#output");
var upload = $("#upload");
@@ -42,10 +17,19 @@ function eventsource() {
// IE does not support EventSource - load whole content at once
if (typeof EventSource !== "function") {
httpGet(ta, "scripts/pi-hole/php/debug.php?IE&token=" + token + "&" + checked);
$.ajax({
method: "GET",
url: "scripts/pi-hole/php/debug.php?IE&token=" + token + "&" + checked,
async: false
}).done(function (data) {
ta.show();
ta.empty();
ta.append(data);
});
return;
}
// eslint-disable-next-line compat/compat
var source = new EventSource("scripts/pi-hole/php/debug.php?&token=" + token + "&" + checked);
// Reset and show field
@@ -71,7 +55,7 @@ function eventsource() {
}
$("#debugBtn").on("click", function () {
$("#debugBtn").attr("disabled", true);
$("#upload").attr("disabled", true);
$("#debugBtn").prop("disabled", true);
$("#upload").prop("disabled", true);
eventsource();
});
+129 -32
View File
@@ -4,6 +4,7 @@
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global initpage:false */
//The following functions allow us to display time until pi-hole is enabled after disabling.
//Works between all pages
@@ -43,7 +44,7 @@ function piholeChanged(action) {
function countDown() {
var ena = $("#enableLabel");
var enaT = $("#enableTimer");
var target = new Date(parseInt(enaT.html()));
var target = new Date(parseInt(enaT.html(), 10));
var seconds = Math.round((target.getTime() - new Date().getTime()) / 1000);
if (seconds > 0) {
@@ -93,9 +94,120 @@ function piholeChange(action, duration) {
}
}
$(document).ready(function () {
function checkMessages() {
$.getJSON("api_db.php?status", function (data) {
if ("message_count" in data && data.message_count > 0) {
var title;
if (data.message_count > 1) {
title = "There are " + data.message_count + " warnings. Click for further details.";
} else {
title = "There is one warning. Click for further details.";
}
$("#pihole-diagnosis").prop("title", title);
$("#pihole-diagnosis-count").text(data.message_count);
$("#pihole-diagnosis").removeClass("hidden");
}
});
}
function testCookies() {
if (navigator.cookieEnabled) {
return true;
}
// set and read cookie
document.cookie = "cookietest=1";
var ret = document.cookie.indexOf("cookietest=") !== -1;
// delete cookie
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
return ret;
}
function initCheckboxRadioStyle() {
function getCheckboxURL(style) {
var extra = style.startsWith("material-") ? "material" : "bootstrap";
return "style/vendor/icheck-" + extra + ".min.css";
}
function applyCheckboxRadioStyle(style) {
boxsheet.attr("href", getCheckboxURL(style));
var sel = $("input[type='radio'],input[type='checkbox']");
sel.parent().removeClass();
sel.parent().addClass("icheck-" + style);
}
// Read from local storage, initialize if needed
var chkboxStyle = localStorage.getItem("theme_icheck");
if (chkboxStyle === null) {
chkboxStyle = "primary";
}
var boxsheet = $('<link href="' + getCheckboxURL(chkboxStyle) + '" rel="stylesheet" />');
boxsheet.appendTo("head");
applyCheckboxRadioStyle(chkboxStyle);
// Add handler when on settings page
var iCheckStyle = $("#iCheckStyle");
if (iCheckStyle !== null) {
iCheckStyle.val(chkboxStyle);
iCheckStyle.change(function () {
var themename = $(this).val();
localStorage.setItem("theme_icheck", themename);
applyCheckboxRadioStyle(themename);
});
}
}
function initCPUtemp() {
function setCPUtemp(unit) {
localStorage.setItem("tempunit", tempunit);
var temperature = parseFloat($("#rawtemp").text());
var displaytemp = $("#tempdisplay");
if (!isNaN(temperature)) {
switch (unit) {
case "K":
temperature += 273.15;
displaytemp.html(temperature.toFixed(1) + "&nbsp;&deg;K");
break;
case "F":
temperature = (temperature * 9) / 5 + 32;
displaytemp.html(temperature.toFixed(1) + "&nbsp;&deg;F");
break;
default:
displaytemp.html(temperature.toFixed(1) + "&nbsp;&deg;C");
break;
}
}
}
// Read from local storage, initialize if needed
var tempunit = localStorage.getItem("tempunit");
if (tempunit === null) {
tempunit = "C";
}
setCPUtemp(tempunit);
// Add handler when on settings page
var tempunitSelector = $("#tempunit-selector");
if (tempunitSelector !== null) {
tempunitSelector.val(tempunit);
tempunitSelector.change(function () {
tempunit = $(this).val();
setCPUtemp(tempunit);
});
}
}
$(function () {
var enaT = $("#enableTimer");
var target = new Date(parseInt(enaT.html()));
var target = new Date(parseInt(enaT.html(), 10));
var seconds = Math.round((target.getTime() - new Date().getTime()) / 1000);
if (seconds > 0) {
setTimeout(countDown, 100);
@@ -105,12 +217,18 @@ $(document).ready(function () {
$("#cookieInfo").show();
}
var checkbox_theme = $("#checkbox_theme").text();
$("input").icheck({
checkboxClass: "icheckbox_" + checkbox_theme,
radioClass: "iradio_" + checkbox_theme,
increaseArea: "20%"
});
// Apply per-browser styling settings
initCheckboxRadioStyle();
initCPUtemp();
if (typeof initpage === "function") {
setTimeout(initpage, 100);
}
// Run check immediately after page loading ...
checkMessages();
// ... and once again with five seconds delay
setTimeout(checkMessages, 5000);
});
// Handle Enable/Disable
@@ -119,7 +237,7 @@ $("#pihole-enable").on("click", function (e) {
localStorage.removeItem("countDownTarget");
piholeChange("enable", "");
});
$("#pihole-disable-permanently").on("click", function (e) {
$("#pihole-disable-indefinitely").on("click", function (e) {
e.preventDefault();
piholeChange("disable", "0");
});
@@ -144,7 +262,7 @@ $("#pihole-disable-custom").on("click", function (e) {
// Session timer
var sessionTimerCounter = document.getElementById("sessiontimercounter");
var sessionvalidity = parseInt(sessionTimerCounter.textContent);
var sessionvalidity = parseInt(sessionTimerCounter.textContent, 10);
var start = new Date();
function updateSessionTimer() {
@@ -186,24 +304,3 @@ $(document).keypress(function (e) {
$("#loginform").submit();
}
});
function testCookies() {
if (navigator.cookieEnabled) {
return true;
}
// set and read cookie
document.cookie = "cookietest=1";
var ret = document.cookie.indexOf("cookietest=") !== -1;
// delete cookie
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
return ret;
}
$(function () {
if (!testCookies() && $("#cookieInfo").length > 0) {
$("#cookieInfo").show();
}
});
+8 -6
View File
@@ -17,6 +17,7 @@ function eventsource() {
return;
}
// eslint-disable-next-line compat/compat
var source = new EventSource("scripts/pi-hole/php/gravity.sh.php");
ta.html("");
@@ -32,10 +33,11 @@ function eventsource() {
}
// Detect ${OVER}
if (e.data.indexOf("<------") !== -1) {
var newString = "<------";
if (e.data.indexOf(newString) !== -1) {
ta.text(ta.text().substring(0, ta.text().lastIndexOf("\n")) + "\n");
var new_string = e.data.replace("<------", "");
ta.append(new_string);
ta.append(e.data.replace(newString, ""));
} else {
ta.append(e.data);
}
@@ -51,14 +53,14 @@ function eventsource() {
alInfo.hide();
});
source.close();
$("#gravityBtn").removeAttr("disabled");
$("#gravityBtn").prop("disabled", false);
},
false
);
}
$("#gravityBtn").on("click", function () {
$("#gravityBtn").attr("disabled", true);
$("#gravityBtn").prop("disabled", true);
eventsource();
});
@@ -74,7 +76,7 @@ $(function () {
// gravity.php?go
var searchString = window.location.search.substring(1);
if (searchString.indexOf("go") !== -1) {
$("#gravityBtn").attr("disabled", true);
$("#gravityBtn").prop("disabled", true);
eventsource();
}
});
+29 -46
View File
@@ -11,7 +11,7 @@ var table;
var groups = [];
var token = $("#token").text();
function get_groups() {
function getGroups() {
$.post(
"scripts/pi-hole/php/groups.php",
{ action: "get_groups", token: token },
@@ -23,11 +23,11 @@ function get_groups() {
);
}
$(document).ready(function () {
$(function () {
$("#btnAdd").on("click", addAdlist);
utils.bsSelect_defaults();
get_groups();
utils.setBsSelectDefaults();
getGroups();
});
function initTable() {
@@ -96,13 +96,13 @@ function initTable() {
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var data_sub = "";
var dataSub = "";
if (!groups[i].enabled) {
data_sub = 'data-subtext="(disabled)"';
dataSub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option " + data_sub + "/>")
$("<option " + dataSub + "/>")
.val(groups[i].id)
.text(groups[i].name)
);
@@ -127,8 +127,8 @@ function initTable() {
})
.on("changed.bs.select", function () {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
if ($(applyBtn).prop("disabled")) {
$(applyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function () {
@@ -138,9 +138,9 @@ function initTable() {
})
.on("hide.bs.select", function () {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
if (!$(applyBtn).prop("disabled")) {
$(this).val(data.groups).selectpicker("refresh");
$(ApplyBtn).removeClass("btn-success").prop("disabled", true).off("click");
$(applyBtn).removeClass("btn-success").prop("disabled", true).off("click");
}
})
.selectpicker()
@@ -152,7 +152,7 @@ function initTable() {
' class="btn btn-block btn-sm" disabled>Apply</button>'
);
var ApplyBtn = "#btn_apply_" + data.id;
var applyBtn = "#btn_apply_" + data.id;
var button =
'<button type="button" class="btn btn-danger btn-xs" id="deleteAdlist_' +
@@ -172,22 +172,15 @@ function initTable() {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("groups-adlists-table", JSON.stringify(data));
utils.stateSaveCallback("groups-adlists-table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("groups-adlists-table");
var data = utils.stateLoadCallback("groups-adlists-table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Reset visibility of ID column
data.columns[0].visible = false;
// Apply loaded state to table
@@ -198,14 +191,14 @@ function initTable() {
table.on("order.dt", function () {
var order = table.order();
if (order[0][0] !== 0 || order[0][1] !== "asc") {
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
} else {
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
}
});
$("#resetButton").on("click", function () {
table.order([[0, "asc"]]).draw();
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
});
// Disable autocorrect in the search box
@@ -243,12 +236,7 @@ function addAdlist() {
success: function (response) {
utils.enableAll();
if (response.success) {
utils.showAlert(
"success",
"glyphicon glyphicon-plus",
"Successfully added adlist",
address
);
utils.showAlert("success", "fas fa-plus", "Successfully added adlist", address);
table.ajax.reload(null, false);
$("#new_address").val("");
$("#new_comment").val("");
@@ -260,7 +248,7 @@ function addAdlist() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while adding new adlist: ", jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -275,25 +263,25 @@ function editAdlist() {
var address = tr.find("#address_" + id).text();
var done = "edited";
var not_done = "editing";
var notDone = "editing";
switch (elem) {
case "status_" + id:
if (status === 0) {
done = "disabled";
not_done = "disabling";
notDone = "disabling";
} else if (status === 1) {
done = "enabled";
not_done = "enabling";
notDone = "enabling";
}
break;
case "comment_" + id:
done = "edited comment of";
not_done = "editing comment of";
notDone = "editing comment of";
break;
case "multiselect_" + id:
done = "edited groups of";
not_done = "editing groups of";
notDone = "editing groups of";
break;
default:
alert("bad element or invalid data-id!");
@@ -329,7 +317,7 @@ function editAdlist() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " adlist with ID " + id,
"Error while " + notDone + " adlist with ID " + id,
Number(response.message)
);
}
@@ -339,10 +327,10 @@ function editAdlist() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " adlist with ID " + id,
"Error while " + notDone + " adlist with ID " + id,
jqXHR.responseText
);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -362,12 +350,7 @@ function deleteAdlist() {
success: function (response) {
utils.enableAll();
if (response.success) {
utils.showAlert(
"success",
"glyphicon glyphicon-trash",
"Successfully deleted adlist ",
address
);
utils.showAlert("success", "far fa-trash-alt", "Successfully deleted adlist ", address);
table.row(tr).remove().draw(false).ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while deleting adlist with ID " + id, response.message);
@@ -376,7 +359,7 @@ function deleteAdlist() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while deleting adlist with ID " + id, jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
+44 -64
View File
@@ -11,7 +11,7 @@ var table;
var groups = [];
var token = $("#token").text();
function reload_client_suggestions() {
function reloadClientSuggestions() {
$.post(
"scripts/pi-hole/php/groups.php",
{ action: "get_unconfigured_clients", token: token },
@@ -32,12 +32,12 @@ function reload_client_suggestions() {
continue;
}
var text = key,
key_plain = key;
var text = key;
var keyPlain = key;
if (key.startsWith("IP-")) {
// Mock MAC address for address-only devices
key_plain = key.substring(3);
text = key_plain;
keyPlain = key.substring(3);
text = keyPlain;
}
// Append host name if available
@@ -45,14 +45,14 @@ function reload_client_suggestions() {
text += " (" + data[key] + ")";
}
sel.append($("<option />").val(key_plain).text(text));
sel.append($("<option />").val(keyPlain).text(text));
}
},
"json"
);
}
function get_groups() {
function getGroups() {
$.post(
"scripts/pi-hole/php/groups.php",
{ action: "get_groups", token: token },
@@ -64,18 +64,17 @@ function get_groups() {
);
}
$(document).ready(function () {
$(function () {
$("#btnAdd").on("click", addClient);
reload_client_suggestions();
$("select").select2({
tags: true,
placeholder: "Select client...",
allowClear: true
});
utils.bsSelect_defaults();
get_groups();
reloadClientSuggestions();
utils.setBsSelectDefaults();
getGroups();
$("#select").on("change", function () {
$("#ip-custom").val("");
@@ -93,7 +92,7 @@ function initTable() {
order: [[0, "asc"]],
columns: [
{ data: "id", visible: false },
{ data: "ip" },
{ data: "ip", type: "ip-address" },
{ data: "comment" },
{ data: "groups", searchable: false },
{ data: "name", width: "80px", orderable: false }
@@ -112,7 +111,7 @@ function initTable() {
utils.datetime(data.date_modified) +
"\nDatabase ID: " +
data.id;
var ip_name =
var ipName =
'<code id="ip_' +
data.id +
'" title="' +
@@ -121,7 +120,7 @@ function initTable() {
data.ip +
"</code>";
if (data.name !== null && data.name.length > 0)
ip_name +=
ipName +=
'<br><code id="name_' +
data.id +
'" title="' +
@@ -129,7 +128,7 @@ function initTable() {
'" class="breakall">' +
data.name +
"</code>";
$("td:eq(0)", row).html(ip_name);
$("td:eq(0)", row).html(ipName);
$("td:eq(1)", row).html('<input id="comment_' + data.id + '" class="form-control">');
var commentEl = $("#comment_" + data.id, row);
@@ -143,13 +142,13 @@ function initTable() {
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var data_sub = "";
var dataSub = "";
if (!groups[i].enabled) {
data_sub = 'data-subtext="(disabled)"';
dataSub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option " + data_sub + "/>")
$("<option " + dataSub + "/>")
.val(groups[i].id)
.text(groups[i].name)
);
@@ -174,8 +173,8 @@ function initTable() {
})
.on("changed.bs.select", function () {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
if ($(applyBtn).prop("disabled")) {
$(applyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function () {
@@ -185,9 +184,9 @@ function initTable() {
})
.on("hide.bs.select", function () {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
if (!$(applyBtn).prop("disabled")) {
$(this).val(data.groups).selectpicker("refresh");
$(ApplyBtn).removeClass("btn-success").prop("disabled", true).off("click");
$(applyBtn).removeClass("btn-success").prop("disabled", true).off("click");
}
})
.selectpicker()
@@ -199,7 +198,7 @@ function initTable() {
' class="btn btn-block btn-sm" disabled>Apply</button>'
);
var ApplyBtn = "#btn_apply_" + data.id;
var applyBtn = "#btn_apply_" + data.id;
var button =
'<button type="button" class="btn btn-danger btn-xs" id="deleteClient_' +
@@ -219,22 +218,15 @@ function initTable() {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("groups-clients-table", JSON.stringify(data));
utils.stateSaveCallback("groups-clients-table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("groups-clients-table");
var data = utils.stateLoadCallback("groups-clients-table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Reset visibility of ID column
data.columns[0].visible = false;
// Apply loaded state to table
@@ -254,15 +246,15 @@ function initTable() {
table.on("order.dt", function () {
var order = table.order();
if (order[0][0] !== 0 || order[0][1] !== "asc") {
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
} else {
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
}
});
$("#resetButton").on("click", function () {
table.order([[0, "asc"]]).draw();
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
});
}
@@ -307,7 +299,7 @@ function addClient() {
utils.enableAll();
if (response.success) {
utils.showAlert("success", "fas fa-plus", "Successfully added client", ip);
reload_client_suggestions();
reloadClientSuggestions();
table.ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while adding new client", response.message);
@@ -316,7 +308,7 @@ function addClient() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while adding new client", jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -331,28 +323,27 @@ function editClient() {
var comment = tr.find("#comment_" + id).val();
var done = "edited";
var not_done = "editing";
var notDone = "editing";
switch (elem) {
case "multiselect_" + id:
done = "edited groups of";
not_done = "editing groups of";
notDone = "editing groups of";
break;
case "comment_" + id:
done = "edited comment of";
not_done = "editing comment of";
notDone = "editing comment of";
break;
default:
alert("bad element or invalid data-id!");
return;
}
var ip_name = ip;
if (name.length > 0) {
ip_name += " (" + name + ")";
ip += " (" + name + ")";
}
utils.disableAll();
utils.showAlert("info", "", "Editing client...", ip_name);
utils.showAlert("info", "", "Editing client...", ip);
$.ajax({
url: "scripts/pi-hole/php/groups.php",
method: "post",
@@ -367,17 +358,12 @@ function editClient() {
success: function (response) {
utils.enableAll();
if (response.success) {
utils.showAlert(
"success",
"glyphicon glyphicon-pencil",
"Successfully " + done + " client",
ip_name
);
utils.showAlert("success", "fas fa-pencil-alt", "Successfully " + done + " client", ip);
table.ajax.reload(null, false);
} else {
utils.showAlert(
"error",
"Error while " + not_done + " client with ID " + id,
"Error while " + notDone + " client with ID " + id,
response.message
);
}
@@ -387,10 +373,10 @@ function editClient() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " client with ID " + id,
"Error while " + notDone + " client with ID " + id,
jqXHR.responseText
);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -401,13 +387,12 @@ function deleteClient() {
var ip = tr.find("#ip_" + id).text();
var name = tr.find("#name_" + id).text();
var ip_name = ip;
if (name.length > 0) {
ip_name += " (" + name + ")";
ip += " (" + name + ")";
}
utils.disableAll();
utils.showAlert("info", "", "Deleting client...", ip_name);
utils.showAlert("info", "", "Deleting client...", ip);
$.ajax({
url: "scripts/pi-hole/php/groups.php",
method: "post",
@@ -416,14 +401,9 @@ function deleteClient() {
success: function (response) {
utils.enableAll();
if (response.success) {
utils.showAlert(
"success",
"glyphicon glyphicon-trash",
"Successfully deleted client ",
ip_name
);
utils.showAlert("success", "far fa-trash-alt", "Successfully deleted client ", ip);
table.row(tr).remove().draw(false).ajax.reload(null, false);
reload_client_suggestions();
reloadClientSuggestions();
} else {
utils.showAlert("error", "", "Error while deleting client with ID " + id, response.message);
}
@@ -431,7 +411,7 @@ function deleteClient() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while deleting client with ID " + id, jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
+68 -72
View File
@@ -13,7 +13,7 @@ var token = $("#token").text();
var GETDict = {};
var showtype = "all";
function get_groups() {
function getGroups() {
$.post(
"scripts/pi-hole/php/groups.php",
{ action: "get_groups", token: token },
@@ -25,7 +25,7 @@ function get_groups() {
);
}
$(document).ready(function () {
$(function () {
window.location.search
.substr(1)
.split("&")
@@ -55,8 +55,8 @@ $(document).ready(function () {
$("#add2black, #add2white").on("click", addDomain);
utils.bsSelect_defaults();
get_groups();
utils.setBsSelectDefaults();
getGroups();
});
function initTable() {
@@ -100,9 +100,9 @@ function initTable() {
"</code>"
);
var whitelist_options = "";
var whitelistOptions = "";
if (showtype === "all" || showtype === "white") {
whitelist_options =
whitelistOptions =
'<option value="0"' +
(data.type === 0 ? " selected" : "") +
">Exact whitelist</option>" +
@@ -111,9 +111,9 @@ function initTable() {
">Regex whitelist</option>";
}
var blacklist_options = "";
var blacklistOptions = "";
if (showtype === "all" || showtype === "black") {
blacklist_options =
blacklistOptions =
'<option value="1"' +
(data.type === 1 ? " selected " : " ") +
">Exact blacklist</option>" +
@@ -126,8 +126,8 @@ function initTable() {
'<select id="type_' +
data.id +
'" class="form-control">' +
whitelist_options +
blacklist_options +
whitelistOptions +
blacklistOptions +
"</select>"
);
var typeEl = $("#type_" + data.id, row);
@@ -161,13 +161,13 @@ function initTable() {
var selectEl = $("#multiselect_" + data.id, row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var data_sub = "";
var dataSub = "";
if (!groups[i].enabled) {
data_sub = 'data-subtext="(disabled)"';
dataSub = 'data-subtext="(disabled)"';
}
selectEl.append(
$("<option " + data_sub + "/>")
$("<option " + dataSub + "/>")
.val(groups[i].id)
.text(groups[i].name)
);
@@ -192,8 +192,8 @@ function initTable() {
})
.on("changed.bs.select", function () {
// enable Apply button
if ($(ApplyBtn).prop("disabled")) {
$(ApplyBtn)
if ($(applyBtn).prop("disabled")) {
$(applyBtn)
.addClass("btn-success")
.prop("disabled", false)
.on("click", function () {
@@ -203,9 +203,9 @@ function initTable() {
})
.on("hide.bs.select", function () {
// Restore values if drop-down menu is closed without clicking the Apply button
if (!$(ApplyBtn).prop("disabled")) {
if (!$(applyBtn).prop("disabled")) {
$(this).val(data.groups).selectpicker("refresh");
$(ApplyBtn).removeClass("btn-success").prop("disabled", true).off("click");
$(applyBtn).removeClass("btn-success").prop("disabled", true).off("click");
}
})
.selectpicker()
@@ -218,10 +218,10 @@ function initTable() {
);
}
var ApplyBtn = "#btn_apply_" + data.id;
var applyBtn = "#btn_apply_" + data.id;
// Highlight row (if url parameter "domainid=" is used)
if ("domainid" in GETDict && data.id === parseInt(GETDict.domainid)) {
if ("domainid" in GETDict && data.id === parseInt(GETDict.domainid, 10)) {
$(row).find("td").addClass("highlight");
}
@@ -247,22 +247,15 @@ function initTable() {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("groups-domains-table", JSON.stringify(data));
utils.stateSaveCallback("groups-domains-table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("groups-domains-table");
var data = utils.stateLoadCallback("groups-domains-table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Reset visibility of ID column
data.columns[0].visible = false;
// Show group assignment column only on full page
@@ -272,7 +265,10 @@ function initTable() {
},
initComplete: function () {
if ("domainid" in GETDict) {
var pos = table.column(0, { order: "current" }).data().indexOf(parseInt(GETDict.domainid));
var pos = table
.column(0, { order: "current" })
.data()
.indexOf(parseInt(GETDict.domainid, 10));
if (pos >= 0) {
var page = Math.floor(pos / table.page.info().length);
table.page(page).draw(false);
@@ -292,14 +288,14 @@ function initTable() {
table.on("order.dt", function () {
var order = table.order();
if (order[0][0] !== 0 || order[0][1] !== "asc") {
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
} else {
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
}
});
$("#resetButton").on("click", function () {
table.order([[0, "asc"]]).draw();
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
});
}
@@ -307,17 +303,17 @@ function addDomain() {
var action = this.id;
var tabHref = $('a[data-toggle="tab"][aria-expanded="true"]').attr("href");
var wildcardEl = $("#wildcard_checkbox");
var wildcard_checked = wildcardEl.prop("checked");
var wildcardChecked = wildcardEl.prop("checked");
var type;
// current tab's inputs
var domain_regex, domainEl, commentEl;
var domainRegex, domainEl, commentEl;
if (tabHref === "#tab_domain") {
domain_regex = "domain";
domainRegex = "domain";
domainEl = $("#new_domain");
commentEl = $("#new_domain_comment");
} else if (tabHref === "#tab_regex") {
domain_regex = "regex";
domainRegex = "regex";
domainEl = $("#new_regex");
commentEl = $("#new_regex_comment");
}
@@ -326,31 +322,31 @@ function addDomain() {
var comment = commentEl.val();
utils.disableAll();
utils.showAlert("info", "", "Adding " + domain_regex + "...", domain);
utils.showAlert("info", "", "Adding " + domainRegex + "...", domain);
if (domain.length > 0) {
// strip "*." if specified by user in wildcard mode
if (domain_regex === "domain" && wildcard_checked && domain.startsWith("*.")) {
if (domainRegex === "domain" && wildcardChecked && domain.startsWith("*.")) {
domain = domain.substr(2);
}
// determine list type
if (domain_regex === "domain" && action === "add2black" && wildcard_checked) {
if (domainRegex === "domain" && action === "add2black" && wildcardChecked) {
type = "3W";
} else if (domain_regex === "domain" && action === "add2black" && !wildcard_checked) {
} else if (domainRegex === "domain" && action === "add2black" && !wildcardChecked) {
type = "1";
} else if (domain_regex === "domain" && action === "add2white" && wildcard_checked) {
} else if (domainRegex === "domain" && action === "add2white" && wildcardChecked) {
type = "2W";
} else if (domain_regex === "domain" && action === "add2white" && !wildcard_checked) {
} else if (domainRegex === "domain" && action === "add2white" && !wildcardChecked) {
type = "0";
} else if (domain_regex === "regex" && action === "add2black") {
} else if (domainRegex === "regex" && action === "add2black") {
type = "3";
} else if (domain_regex === "regex" && action === "add2white") {
} else if (domainRegex === "regex" && action === "add2white") {
type = "2";
}
} else {
utils.enableAll();
utils.showAlert("warning", "", "Warning", "Please specify a " + domain_regex);
utils.showAlert("warning", "", "Warning", "Please specify a " + domainRegex);
return;
}
@@ -368,19 +364,19 @@ function addDomain() {
success: function (response) {
utils.enableAll();
if (response.success) {
utils.showAlert("success", "fas fa-plus", "Successfully added " + domain_regex, domain);
utils.showAlert("success", "fas fa-plus", "Success!", response.message);
domainEl.val("");
commentEl.val("");
wildcardEl.prop("checked", false);
table.ajax.reload(null, false);
} else {
utils.showAlert("error", "", "Error while adding new " + domain_regex, response.message);
utils.showAlert("error", "", "Error while adding new " + domainRegex, response.message);
}
},
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while adding new " + domain_regex, jqXHR.responseText);
console.log(exception);
utils.showAlert("error", "", "Error while adding new " + domainRegex, jqXHR.responseText);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -399,41 +395,41 @@ function editDomain() {
var rowData = table.row(tr).data();
var groups = table.column(5).visible() ? tr.find("#multiselect_" + id).val() : rowData.groups;
var domain_regex;
var domainRegex;
if (type === "0" || type === "1") {
domain_regex = "domain";
domainRegex = "domain";
} else if (type === "2" || type === "3") {
domain_regex = "regex";
domainRegex = "regex";
}
var done = "edited";
var not_done = "editing";
var notDone = "editing";
switch (elem) {
case "status_" + id:
if (status === 0) {
done = "disabled";
not_done = "disabling";
notDone = "disabling";
} else if (status === 1) {
done = "enabled";
not_done = "enabling";
notDone = "enabling";
}
break;
case "name_" + id:
done = "edited name of";
not_done = "editing name of";
notDone = "editing name of";
break;
case "comment_" + id:
done = "edited comment of";
not_done = "editing comment of";
notDone = "editing comment of";
break;
case "type_" + id:
done = "edited type of";
not_done = "editing type of";
notDone = "editing type of";
break;
case "multiselect_" + id:
done = "edited groups of";
not_done = "editing groups of";
notDone = "editing groups of";
break;
default:
alert("bad element or invalid data-id!");
@@ -441,7 +437,7 @@ function editDomain() {
}
utils.disableAll();
utils.showAlert("info", "", "Editing " + domain_regex + "...", name);
utils.showAlert("info", "", "Editing " + domainRegex + "...", name);
$.ajax({
url: "scripts/pi-hole/php/groups.php",
method: "post",
@@ -461,7 +457,7 @@ function editDomain() {
utils.showAlert(
"success",
"fas fa-pencil-alt",
"Successfully " + done + " " + domain_regex,
"Successfully " + done + " " + domainRegex,
domain
);
table.ajax.reload(null, false);
@@ -469,7 +465,7 @@ function editDomain() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " " + domain_regex + " with ID " + id,
"Error while " + notDone + " " + domainRegex + " with ID " + id,
response.message
);
},
@@ -478,10 +474,10 @@ function editDomain() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " " + domain_regex + " with ID " + id,
"Error while " + notDone + " " + domainRegex + " with ID " + id,
jqXHR.responseText
);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -492,15 +488,15 @@ function deleteDomain() {
var domain = tr.find("#domain_" + id).text();
var type = tr.find("#type_" + id).val();
var domain_regex;
var domainRegex;
if (type === "0" || type === "1") {
domain_regex = "domain";
domainRegex = "domain";
} else if (type === "2" || type === "3") {
domain_regex = "regex";
domainRegex = "regex";
}
utils.disableAll();
utils.showAlert("info", "", "Deleting " + domain_regex + "...", domain);
utils.showAlert("info", "", "Deleting " + domainRegex + "...", domain);
$.ajax({
url: "scripts/pi-hole/php/groups.php",
method: "post",
@@ -512,7 +508,7 @@ function deleteDomain() {
utils.showAlert(
"success",
"far fa-trash-alt",
"Successfully deleted " + domain_regex,
"Successfully deleted " + domainRegex,
domain
);
table.row(tr).remove().draw(false).ajax.reload(null, false);
@@ -520,7 +516,7 @@ function deleteDomain() {
utils.showAlert(
"error",
"",
"Error while deleting " + domain_regex + " with ID " + id,
"Error while deleting " + domainRegex + " with ID " + id,
response.message
);
}
@@ -530,10 +526,10 @@ function deleteDomain() {
utils.showAlert(
"error",
"",
"Error while deleting " + domain_regex + " with ID " + id,
"Error while deleting " + domainRegex + " with ID " + id,
jqXHR.responseText
);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
+16 -23
View File
@@ -10,7 +10,7 @@
var table;
var token = $("#token").text();
$(document).ready(function () {
$(function () {
$("#btnAdd").on("click", addGroup);
table = $("#groupsTable").DataTable({
@@ -87,22 +87,15 @@ $(document).ready(function () {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("groups-table", JSON.stringify(data));
utils.stateSaveCallback("groups-table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("groups-table");
var data = utils.stateLoadCallback("groups-table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Reset visibility of ID column
data.columns[0].visible = false;
// Apply loaded state to table
@@ -122,14 +115,14 @@ $(document).ready(function () {
table.on("order.dt", function () {
var order = table.order();
if (order[0][0] !== 0 || order[0][1] !== "asc") {
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
} else {
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
}
});
$("#resetButton").on("click", function () {
table.order([[0, "asc"]]).draw();
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
});
});
@@ -164,7 +157,7 @@ function addGroup() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while adding new group", jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -178,25 +171,25 @@ function editGroup() {
var desc = tr.find("#desc_" + id).val();
var done = "edited";
var not_done = "editing";
var notDone = "editing";
switch (elem) {
case "status_" + id:
if (status === 0) {
done = "disabled";
not_done = "disabling";
notDone = "disabling";
} else if (status === 1) {
done = "enabled";
not_done = "enabling";
notDone = "enabling";
}
break;
case "name_" + id:
done = "edited name of";
not_done = "editing name of";
notDone = "editing name of";
break;
case "desc_" + id:
done = "edited description of";
not_done = "editing description of";
notDone = "editing description of";
break;
default:
alert("bad element or invalid data-id!");
@@ -225,7 +218,7 @@ function editGroup() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " group with ID " + id,
"Error while " + notDone + " group with ID " + id,
response.message
);
}
@@ -235,10 +228,10 @@ function editGroup() {
utils.showAlert(
"error",
"",
"Error while " + not_done + " group with ID " + id,
"Error while " + notDone + " group with ID " + id,
jqXHR.responseText
);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
@@ -267,7 +260,7 @@ function deleteGroup() {
error: function (jqXHR, exception) {
utils.enableAll();
utils.showAlert("error", "", "Error while deleting group with ID " + id, jqXHR.responseText);
console.log(exception);
console.log(exception); // eslint-disable-line no-console
}
});
}
+105 -164
View File
@@ -5,12 +5,13 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global utils:false, Chart:false, updateSessionTimer:false */
// Define global variables
/* global Chart:false, updateSessionTimer:false */
var timeLineChart, clientsChart;
var queryTypePieChart, forwardDestinationPieChart;
var colors = [
var THEME_COLORS = [
"#3c8dbc",
"#f56954",
"#00a65a",
@@ -29,28 +30,6 @@ var colors = [
"#d2d6de"
];
function padNumber(num) {
return ("00" + num).substr(-2, 2);
}
// Helper function needed for converting the Objects to Arrays
function objectToArray(p) {
var keys = Object.keys(p);
keys.sort(function (a, b) {
return a - b;
});
var arr = [],
idx = [];
for (var i = 0; i < keys.length; i++) {
arr.push(p[keys[i]]);
idx.push(keys[i]);
}
return [idx, arr];
}
var customTooltips = function (tooltip) {
var tooltipEl = document.getElementById(this._chart.canvas.id + "-customTooltip");
if (!tooltipEl) {
@@ -83,14 +62,12 @@ var customTooltips = function (tooltip) {
tooltipEl.classList.remove("left", "right", "center", "top", "bottom");
tooltipEl.classList.add(tooltip.xAlign, tooltip.yAlign);
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltip.body) {
var titleLines = tooltip.title || [];
var bodyLines = tooltip.body.map(getBody);
var bodyLines = tooltip.body.map(function (bodyItem) {
return bodyItem.lines;
});
var innerHtml = "<thead>";
titleLines.forEach(function (title) {
@@ -101,9 +78,9 @@ var customTooltips = function (tooltip) {
var devicePixel = (1 / window.devicePixelRatio).toFixed(1);
bodyLines.forEach(function (body, i) {
var colors = tooltip.labelColors[i];
var style = "background: " + colors.backgroundColor;
style += "; outline: 1px solid " + colors.backgroundColor;
var labelColors = tooltip.labelColors[i];
var style = "background-color: " + labelColors.backgroundColor;
style += "; outline: 1px solid " + labelColors.backgroundColor;
style += "; border: " + devicePixel + "px solid #fff";
var span = "<span class='chartjs-tooltip-key' style='" + style + "'></span>";
@@ -244,21 +221,39 @@ function updateQueriesOverTime() {
}
// convert received objects to arrays
data.domains_over_time = objectToArray(data.domains_over_time);
data.ads_over_time = objectToArray(data.ads_over_time);
data.domains_over_time = utils.objectToArray(data.domains_over_time);
data.ads_over_time = utils.objectToArray(data.ads_over_time);
// remove last data point since it not representative
data.ads_over_time[0].splice(-1, 1);
// Remove possibly already existing data
timeLineChart.data.labels = [];
timeLineChart.data.datasets[0].data = [];
timeLineChart.data.datasets[1].data = [];
timeLineChart.data.datasets = [];
var labels = ["Blocked DNS Queries", "Permitted DNS Queries"];
var blockedColor = $(".queries-blocked").css("background-color");
var permittedColor = $(".queries-permitted").css("background-color");
var colors = [blockedColor, permittedColor];
// Collect values and colors, and labels
for (var i = 0; i < labels.length; i++) {
timeLineChart.data.datasets.push({
data: [],
// If we ran out of colors, make a random one
backgroundColor: colors[i],
pointRadius: 0,
pointHitRadius: 5,
pointHoverRadius: 5,
label: labels[i],
cubicInterpolationMode: "monotone"
});
}
// Add data for each hour that is available
for (var hour in data.ads_over_time[0]) {
if (Object.prototype.hasOwnProperty.call(data.ads_over_time[0], hour)) {
var d, h;
h = parseInt(data.domains_over_time[0][hour]);
if (parseInt(data.ads_over_time[0][0]) < 1200) {
h = parseInt(data.domains_over_time[0][hour], 10);
if (parseInt(data.ads_over_time[0][0], 10) < 1200) {
// Fallback - old style
d = new Date().setHours(Math.floor(h / 6), 10 * (h % 6), 0, 0);
} else {
@@ -310,18 +305,18 @@ function updateQueryTypesPie() {
iter = data;
}
$.each(iter, function (key, value) {
v.push(value);
c.push(colors[i++ % colors.length]);
Object.keys(iter).forEach(function (key) {
v.push(iter[key]);
c.push(THEME_COLORS[i++ % THEME_COLORS.length]);
k.push(key);
});
// Build a single dataset with the data to be pushed
var dd = { data: v, backgroundColor: c };
// and push it at once
queryTypePieChart.data.datasets[0] = dd;
queryTypePieChart.data.labels = k;
$("#query-types-pie .overlay").hide();
queryTypePieChart.update();
queryTypePieChart.chart.config.options.cutoutPercentage = 50;
queryTypePieChart.update();
// Don't use rotation animation for further updates
@@ -367,50 +362,39 @@ function updateClientsOverTime() {
}
// convert received objects to arrays
data.over_time = objectToArray(data.over_time);
data.over_time = utils.objectToArray(data.over_time);
// remove last data point since it not representative
data.over_time[0].splice(-1, 1);
var timestamps = data.over_time[0];
var plotdata = data.over_time[1];
var labels = [];
var key, i, j;
var key;
for (key in data.clients) {
if (!Object.prototype.hasOwnProperty.call(data.clients, key)) {
continue;
if (Object.prototype.hasOwnProperty.call(data.clients, key)) {
var client = data.clients[key];
labels.push(client.name.length > 0 ? client.name : client.ip);
}
var clientname;
if (data.clients[key].name.length > 0) {
clientname = data.clients[key].name;
} else {
clientname = data.clients[key].ip;
}
labels.push(clientname);
}
// Remove possibly already existing data
clientsChart.data.labels = [];
clientsChart.data.datasets[0].data = [];
for (i = 1; i < clientsChart.data.datasets.length; i++) {
clientsChart.data.datasets[i].data = [];
}
clientsChart.data.datasets = [];
// Collect values and colors, and labels
clientsChart.data.datasets[0].backgroundColor = colors[0];
clientsChart.data.datasets[0].pointRadius = 0;
clientsChart.data.datasets[0].pointHitRadius = 5;
clientsChart.data.datasets[0].pointHoverRadius = 5;
clientsChart.data.datasets[0].label = labels[0];
var numClients = 0;
if (plotdata.length > 0) {
numClients = plotdata[0].length;
}
for (i = clientsChart.data.datasets.length; plotdata.length && i < plotdata[0].length; i++) {
for (var i = 0; i < numClients; i++) {
clientsChart.data.datasets.push({
data: [],
// If we ran out of colors, make a random one
backgroundColor:
i < colors.length
? colors[i]
i < THEME_COLORS.length
? THEME_COLORS[i]
: "#" + (0x1000000 + Math.random() * 0xffffff).toString(16).substr(1, 6),
pointRadius: 0,
pointHitRadius: 5,
@@ -421,20 +405,18 @@ function updateClientsOverTime() {
}
// Add data for each dataset that is available
for (j in timestamps) {
for (var j in timestamps) {
if (!Object.prototype.hasOwnProperty.call(timestamps, j)) {
continue;
}
for (key in plotdata[j]) {
if (!Object.prototype.hasOwnProperty.call(plotdata[j], key)) {
continue;
if (Object.prototype.hasOwnProperty.call(plotdata[j], key)) {
clientsChart.data.datasets[key].data.push(plotdata[j][key]);
}
clientsChart.data.datasets[key].data.push(plotdata[j][key]);
}
var d = new Date(1000 * parseInt(timestamps[j]));
var d = new Date(1000 * parseInt(timestamps[j], 10));
clientsChart.data.labels.push(d);
}
@@ -469,16 +451,18 @@ function updateForwardDestinationsPie() {
values = [];
// Collect values and colors
$.each(data.forward_destinations, function (key, value) {
if (key.indexOf("|") > -1) {
Object.keys(data.forward_destinations).forEach(function (key) {
var value = data.forward_destinations[key];
if (key.indexOf("|") !== -1) {
key = key.substr(0, key.indexOf("|"));
}
values.push([key, value, colors[i++ % colors.length]]);
values.push([key, value, THEME_COLORS[i++ % THEME_COLORS.length]]);
});
// Split data into individual arrays for the graphs
$.each(values, function (key, value) {
values.forEach(function (value) {
k.push(value[0]);
v.push(value[1]);
c.push(value[2]);
@@ -491,7 +475,6 @@ function updateForwardDestinationsPie() {
forwardDestinationPieChart.data.datasets[0] = dd;
// and push it at once
$("#forward-destinations-pie .overlay").hide();
forwardDestinationPieChart.update();
forwardDestinationPieChart.chart.config.options.cutoutPercentage = 50;
forwardDestinationPieChart.update();
// Don't use rotation animation for further updates
@@ -525,21 +508,6 @@ function updateForwardDestinationsPie() {
});
}
// Credit: http://stackoverflow.com/questions/1787322/htmlspecialchars-equivalent-in-javascript/4835406#4835406
function escapeHtml(text) {
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#039;"
};
return text.replace(/[&<>"']/g, function (m) {
return map[m];
});
}
function updateTopClientsChart() {
$.getJSON("api.php?summaryRaw&getQuerySources&topClientsBlocked", function (data) {
if ("FTLnotrunning" in data) {
@@ -553,13 +521,13 @@ function updateTopClientsChart() {
for (client in data.top_sources) {
if (Object.prototype.hasOwnProperty.call(data.top_sources, client)) {
// Sanitize client
if (escapeHtml(client) !== client) {
if (utils.escapeHtml(client) !== client) {
// Make a copy with the escaped index if necessary
data.top_sources[escapeHtml(client)] = data.top_sources[client];
data.top_sources[utils.escapeHtml(client)] = data.top_sources[client];
}
client = escapeHtml(client);
if (client.indexOf("|") > -1) {
client = utils.escapeHtml(client);
if (client.indexOf("|") !== -1) {
idx = client.indexOf("|");
clientname = client.substr(0, idx);
clientip = client.substr(idx + 1, client.length - idx);
@@ -599,13 +567,13 @@ function updateTopClientsChart() {
for (client in data.top_sources_blocked) {
if (Object.prototype.hasOwnProperty.call(data.top_sources_blocked, client)) {
// Sanitize client
if (escapeHtml(client) !== client) {
if (utils.escapeHtml(client) !== client) {
// Make a copy with the escaped index if necessary
data.top_sources_blocked[escapeHtml(client)] = data.top_sources_blocked[client];
data.top_sources_blocked[utils.escapeHtml(client)] = data.top_sources_blocked[client];
}
client = escapeHtml(client);
if (client.indexOf("|") > -1) {
client = utils.escapeHtml(client);
if (client.indexOf("|") !== -1) {
idx = client.indexOf("|");
clientname = client.substr(0, idx);
clientip = client.substr(idx + 1, client.length - idx);
@@ -671,12 +639,12 @@ function updateTopLists() {
for (domain in data.top_queries) {
if (Object.prototype.hasOwnProperty.call(data.top_queries, domain)) {
// Sanitize domain
if (escapeHtml(domain) !== domain) {
if (utils.escapeHtml(domain) !== domain) {
// Make a copy with the escaped index if necessary
data.top_queries[escapeHtml(domain)] = data.top_queries[domain];
data.top_queries[utils.escapeHtml(domain)] = data.top_queries[domain];
}
domain = escapeHtml(domain);
domain = utils.escapeHtml(domain);
urlText = domain === "" ? "." : domain;
url = '<a href="queries.php?domain=' + domain + '">' + urlText + "</a>";
percentage = (data.top_queries[domain] / data.dns_queries_today) * 100;
@@ -704,12 +672,12 @@ function updateTopLists() {
for (domain in data.top_ads) {
if (Object.prototype.hasOwnProperty.call(data.top_ads, domain)) {
// Sanitize domain
if (escapeHtml(domain) !== domain) {
if (utils.escapeHtml(domain) !== domain) {
// Make a copy with the escaped index if necessary
data.top_ads[escapeHtml(domain)] = data.top_ads[domain];
data.top_ads[utils.escapeHtml(domain)] = data.top_ads[domain];
}
domain = escapeHtml(domain);
domain = utils.escapeHtml(domain);
urlText = domain === "" ? "." : domain;
url = '<a href="queries.php?domain=' + domain + '">' + urlText + "</a>";
percentage = (data.top_ads[domain] / data.ads_blocked_today) * 100;
@@ -777,15 +745,24 @@ function updateSummaryData(runOnce) {
updateTopLists();
}
["ads_blocked_today", "dns_queries_today", "ads_percentage_today", "unique_clients"].forEach(
function (today) {
var $todayElement = $("span#" + today);
if ($todayElement.text() !== data[today] && $todayElement.text() !== data[today] + "%") {
$todayElement.addClass("glow");
}
//Element name might have a different name to the property of the API so we split it at |
[
"ads_blocked_today|queries_blocked_today",
"dns_queries_today",
"ads_percentage_today|percentage_blocked_today",
"unique_clients",
"domains_being_blocked"
].forEach(function (arrayItem, idx) {
var apiElName = arrayItem.split("|");
var apiName = apiElName[0];
var elName = apiElName[1];
var $todayElement = elName ? $("span#" + elName) : $("span#" + apiName);
var textData = idx === 2 && data[apiName] !== "to" ? data[apiName] + "%" : data[apiName];
if ($todayElement.text() !== textData && $todayElement.text() !== textData + "%") {
$todayElement.addClass("glow");
$todayElement.text(textData);
}
);
});
if (Object.prototype.hasOwnProperty.call(data, "dns_queries_all_types")) {
$("#total_queries").prop(
@@ -794,17 +771,7 @@ function updateSummaryData(runOnce) {
);
}
window.setTimeout(function () {
[
"ads_blocked_today",
"dns_queries_today",
"domains_being_blocked",
"ads_percentage_today",
"unique_clients"
].forEach(function (header, idx) {
var textData = idx === 3 && data[header] !== "to" ? data[header] + "%" : data[header];
$("span#" + header).text(textData);
});
setTimeout(function () {
$("span.glow").removeClass("glow");
}, 500);
})
@@ -820,44 +787,18 @@ function updateSummaryData(runOnce) {
});
}
$(document).ready(function () {
$(function () {
// Pull in data via AJAX
updateSummaryData();
var blockedColor = $(".queries-blocked").css("background-color");
var permittedColor = $(".queries-permitted").css("background-color");
var gridColor = $(".graphs-grid").css("background-color");
var ticksColor = $(".graphs-ticks").css("color");
var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
timeLineChart = new Chart(ctx, {
type: "bar",
type: utils.getGraphType(),
data: {
labels: [],
datasets: [
{
label: "Blocked DNS Queries",
fill: true,
backgroundColor: blockedColor,
borderColor: blockedColor,
pointBorderColor: blockedColor,
pointRadius: 1,
pointHoverRadius: 5,
data: [],
pointHitRadius: 5
},
{
label: "Permitted DNS Queries",
fill: true,
backgroundColor: permittedColor,
borderColor: permittedColor,
pointBorderColor: permittedColor,
pointRadius: 1,
pointHoverRadius: 5,
data: [],
pointHitRadius: 5
}
]
datasets: [{ data: [] }]
},
options: {
tooltips: {
@@ -872,18 +813,18 @@ $(document).ready(function () {
var time = label.match(/(\d?\d):?(\d?\d?)/);
var h = parseInt(time[1], 10);
var m = parseInt(time[2], 10) || 0;
var from = padNumber(h) + ":" + padNumber(m - 5) + ":00";
var to = padNumber(h) + ":" + padNumber(m + 4) + ":59";
var from = utils.padNumber(h) + ":" + utils.padNumber(m - 5) + ":00";
var to = utils.padNumber(h) + ":" + utils.padNumber(m + 4) + ":59";
return "Queries from " + from + " to " + to;
},
label: function (tooltipItems, data) {
if (tooltipItems.datasetIndex === 0) {
var percentage = 0.0;
var permitted = parseInt(data.datasets[1].data[tooltipItems.index]);
var blocked = parseInt(data.datasets[0].data[tooltipItems.index]);
var percentage = 0;
var permitted = parseInt(data.datasets[1].data[tooltipItems.index], 10);
var blocked = parseInt(data.datasets[0].data[tooltipItems.index], 10);
var total = permitted + blocked;
if (total > 0) {
percentage = (100.0 * blocked) / total;
percentage = (100 * blocked) / total;
}
return (
@@ -949,7 +890,7 @@ $(document).ready(function () {
if (clientsChartEl) {
ctx = clientsChartEl.getContext("2d");
clientsChart = new Chart(ctx, {
type: "bar",
type: utils.getGraphType(),
data: {
labels: [],
datasets: [{ data: [] }]
@@ -969,8 +910,8 @@ $(document).ready(function () {
var time = label.match(/(\d?\d):?(\d?\d?)/);
var h = parseInt(time[1], 10);
var m = parseInt(time[2], 10) || 0;
var from = padNumber(h) + ":" + padNumber(m - 5) + ":00";
var to = padNumber(h) + ":" + padNumber(m + 4) + ":59";
var from = utils.padNumber(h) + ":" + utils.padNumber(m - 5) + ":00";
var to = utils.padNumber(h) + ":" + utils.padNumber(m + 4) + ":59";
return "Client activity from " + from + " to " + to;
},
label: function (tooltipItems, data) {
+25 -6
View File
@@ -5,13 +5,12 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
// The original ip-sorting code has been taken from
// This code has been taken from
// https://datatables.net/plug-ins/sorting/ip-address
// and was modified by the Pi-hole team to support
// CIDR notation and be more robust against invalid
// input data (like empty IP addresses)
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
$.extend($.fn.dataTableExt.oSort, {
"ip-address-pre": function (a) {
// Skip empty fields (IP address might have expired or
// reassigned to a differenct device)
@@ -29,9 +28,16 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
var m = a.split("."),
n = a.split(":"),
x = "",
xa = "";
xa = "",
cidr = [];
if (m.length === 4) {
// IPV4
// IPV4 (possibly with CIDR)
cidr = m[3].split("/");
if (cidr.length === 2) {
m.pop();
m = m.concat(cidr);
}
for (i = 0; i < m.length; i++) {
item = m[i];
@@ -44,7 +50,7 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
}
}
} else if (n.length > 0) {
// IPV6
// IPV6 (possibly with CIDR)
var count = 0;
for (i = 0; i < n.length; i++) {
item = n[i];
@@ -85,6 +91,19 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
x += item;
}
}
cidr = x.split("/");
x = cidr[0];
if (cidr.length === 2) {
item = cidr[1];
if (item.length === 1) {
x += "00" + item;
} else if (item.length === 2) {
x += "0" + item;
} else {
x += item;
}
}
}
return x;
+135
View File
@@ -0,0 +1,135 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global utils:false */
var token = $("#token").text();
function renderTimestamp(data, type) {
// Display and search content
if (type === "display" || type === "filter") {
return utils.datetime(data);
}
// Sorting content
return data;
}
function multline(input) {
return input.split(",").join("\n");
}
function renderMessage(data, type, row) {
// Display and search content
switch (row.type) {
case "REGEX":
return (
'Encountered an error when processing <a href="groups-domains.php?domainid=' +
row.blob3 +
'">' +
row.blob1 +
" regex filter with ID " +
row.blob3 +
"</a>:<pre>" +
row.blob2 +
"</pre>Error message: <pre>" +
row.message +
"</pre>"
);
case "SUBNET":
return (
"Client <code>" +
row.message +
"</code> is managed by " +
row.blob1 +
" groups (database IDs [" +
row.blob3 +
"]):<pre>" +
multline(row.blob2) +
"</pre>" +
"FTL chose the most recent entry <pre>" +
row.blob4 +
"</pre> to get the group configuration for this client."
);
case "HOSTNAME":
var hint = new Array(row.blob2 + row.message.length + 3).join(" ");
return (
"Hostname contains invalid character <code>" +
decodeURIComponent(escape(row.blob1))[row.blob2] +
"</code>:<pre>" +
hint +
"&darr;\n" +
row.message +
": " +
decodeURIComponent(escape(row.blob1)) +
"\n" +
hint +
"&uarr;</pre>"
);
default:
return "Unknown message type<pre>" + JSON.stringify(row) + "</pre>";
}
}
$(function () {
$("#messagesTable").DataTable({
ajax: {
url: "api_db.php?messages",
data: { token: token },
type: "POST",
dataSrc: "messages"
},
order: [[0, "asc"]],
columns: [
{ data: "id", visible: false },
{ data: "timestamp", width: "8%", render: renderTimestamp },
{ data: "type", width: "8%" },
{ data: "message", orderable: false, render: renderMessage },
{ data: "blob1", visible: false },
{ data: "blob2", visible: false },
{ data: "blob3", visible: false },
{ data: "blob4", visible: false },
{ data: "blob5", visible: false }
],
dom:
"<'row'<'col-sm-4'l><'col-sm-8'f>>" +
"<'row'<'col-sm-12'<'table-responsive'tr>>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>",
lengthMenu: [
[10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"]
],
language: {
emptyTable: "No issues found."
},
stateSave: true,
stateSaveCallback: function (settings, data) {
utils.stateSaveCallback("messages-table", data);
},
stateLoadCallback: function () {
var data = utils.stateLoadCallback("messages-table");
// Return if not available
if (data === null) {
return null;
}
// Reset visibility of ID and blob columns
var hiddenCols = [0, 4, 5, 6, 7, 8];
for (var key in hiddenCols) {
if (Object.prototype.hasOwnProperty.call(hiddenCols, key)) {
data.columns[hiddenCols[key]].visible = false;
}
}
// Apply loaded state to table
return data;
}
});
});
+37 -50
View File
@@ -5,19 +5,21 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global moment:false */
/* global moment:false, utils:false */
var tableApi;
var APIstring = "api_db.php?network";
var API_STRING = "api_db.php?network";
// How many IPs do we show at most per device?
var MAXIPDISPLAY = 3;
var DAY_IN_SECONDS = 24 * 60 * 60;
function handleAjaxError(xhr, textStatus) {
if (textStatus === "timeout") {
alert("The server took too long to send the data.");
} else if (xhr.responseText.indexOf("Connection refused") >= 0) {
} else if (xhr.responseText.indexOf("Connection refused") !== -1) {
alert("An error occured while loading the data: Connection refused. Is FTL running?");
} else {
alert("An unknown error occured while loading the data.\n" + xhr.responseText);
@@ -49,57 +51,56 @@ function rgbToHex(values) {
function mixColors(ratio, rgb1, rgb2) {
return [
(1.0 - ratio) * rgb1[0] + ratio * rgb2[0],
(1.0 - ratio) * rgb1[1] + ratio * rgb2[1],
(1.0 - ratio) * rgb1[2] + ratio * rgb2[2]
(1 - ratio) * rgb1[0] + ratio * rgb2[0],
(1 - ratio) * rgb1[1] + ratio * rgb2[1],
(1 - ratio) * rgb1[2] + ratio * rgb2[2]
];
}
function parseColor(input) {
var m;
m = input.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
if (m) {
return [m[1], m[2], m[3]];
var match = input.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
if (match) {
return [match[1], match[2], match[3]];
}
}
$(document).ready(function () {
$(function () {
tableApi = $("#network-entries").DataTable({
rowCallback: function (row, data) {
var color,
mark,
maxiter,
index,
lastQuery = parseInt(data.lastQuery);
var network_recent = $(".network-recent").css("background-color");
var network_old = $(".network-old").css("background-color");
var network_older = $(".network-older").css("background-color");
var network_never = $(".network-never").css("background-color");
var color;
var index;
var maxiter;
var iconClasses;
var lastQuery = parseInt(data.lastQuery, 10);
var diff = getTimestamp() - lastQuery;
var networkRecent = $(".network-recent").css("background-color");
var networkOld = $(".network-old").css("background-color");
var networkOlder = $(".network-older").css("background-color");
var networkNever = $(".network-never").css("background-color");
if (lastQuery > 0) {
var diff = getTimestamp() - lastQuery;
if (diff <= 86400) {
// Last query came in within the last 24 hours (24*60*60 = 86400)
if (diff <= DAY_IN_SECONDS) {
// Last query came in within the last 24 hours
// Color: light-green to light-yellow
var ratio = Number(diff) / 86400;
var lightgreen = parseColor(network_recent);
var lightyellow = parseColor(network_old);
color = rgbToHex(mixColors(ratio, lightgreen, lightyellow));
mark = "&#x2714;";
var ratio = Number(diff) / DAY_IN_SECONDS;
color = rgbToHex(mixColors(ratio, parseColor(networkRecent), parseColor(networkOld)));
iconClasses = "fas fa-check";
} else {
// Last query was longer than 24 hours ago
// Color: light-orange
color = network_older;
mark = "<strong>?</strong>";
color = networkOlder;
iconClasses = "fas fa-question";
}
} else {
// This client has never sent a query to Pi-hole, color light-red
color = network_never;
mark = "&#x2718;";
color = networkNever;
iconClasses = "fas fa-check";
}
// Set determined background color
$(row).css("background-color", color);
$("td:eq(7)", row).html(mark);
$("td:eq(7)", row).html('<i class="' + iconClasses + '"></i>');
// Insert "Never" into Last Query field when we have
// never seen a query from this device
@@ -181,7 +182,7 @@ $(document).ready(function () {
"<'row'<'col-sm-4'l><'col-sm-8'p>>" +
"<'row'<'col-sm-12'<'table-responsive'tr>>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>",
ajax: { url: APIstring, error: handleAjaxError, dataSrc: "network" },
ajax: { url: API_STRING, error: handleAjaxError, dataSrc: "network" },
autoWidth: false,
processing: true,
order: [[5, "desc"]],
@@ -221,24 +222,10 @@ $(document).ready(function () {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("network_table", JSON.stringify(data));
utils.stateSaveCallback("network_table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("network_table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Apply loaded state to table
return data;
return utils.stateLoadCallback("network_table");
},
columnDefs: [
{
+39 -51
View File
@@ -5,7 +5,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global moment:false */
/* global moment:false, utils:false */
var tableApi;
@@ -39,19 +39,21 @@ function add(domain, list) {
// add Domain to List after Modal has faded in
alertModal.one("shown.bs.modal", function () {
$.ajax({
url: "scripts/pi-hole/php/add.php",
url: "scripts/pi-hole/php/groups.php",
method: "post",
data: { domain: domain, list: list, token: token },
data: {
domain: domain,
list: list,
token: token,
action: "add_domain",
comment: "Added from Query Log"
},
success: function (response) {
alProcessing.hide();
if (
response.indexOf("not a valid argument") >= 0 ||
response.indexOf("is not a valid domain") >= 0 ||
response.indexOf("Wrong token") >= 0
) {
if (!response.success) {
// Failure
alNetworkErr.hide();
alCustomErr.html(response.replace("[✗]", ""));
alCustomErr.html(response.message);
alFailure.fadeIn(1000);
setTimeout(function () {
alertModal.modal("hide");
@@ -90,7 +92,7 @@ function add(domain, list) {
function handleAjaxError(xhr, textStatus) {
if (textStatus === "timeout") {
alert("The server took too long to send the data.");
} else if (xhr.responseText.indexOf("Connection refused") >= 0) {
} else if (xhr.responseText.indexOf("Connection refused") !== -1) {
alert("An error occured while loading the data: Connection refused. Is FTL running?");
} else {
alert("An unknown error occured while loading the data.\n" + xhr.responseText);
@@ -105,7 +107,7 @@ function autofilter() {
return $("#autofilter").prop("checked");
}
$(document).ready(function () {
$(function () {
// Do we want to filter queries?
var GETDict = {};
window.location.search
@@ -137,26 +139,26 @@ $(document).ready(function () {
tableApi = $("#all-queries").DataTable({
rowCallback: function (row, data) {
// DNSSEC status
var dnssec_status;
var dnssecStatus;
switch (data[5]) {
case "1":
dnssec_status = '<br><span class="text-green">SECURE</span>';
dnssecStatus = '<br><span class="text-green">SECURE</span>';
break;
case "2":
dnssec_status = '<br><span class="text-orange">INSECURE</span>';
dnssecStatus = '<br><span class="text-orange">INSECURE</span>';
break;
case "3":
dnssec_status = '<br><span class="text-red">BOGUS</span>';
dnssecStatus = '<br><span class="text-red">BOGUS</span>';
break;
case "4":
dnssec_status = '<br><span class="text-red">ABANDONED</span>';
dnssecStatus = '<br><span class="text-red">ABANDONED</span>';
break;
case "5":
dnssec_status = '<br><span class="text-orange">UNKNOWN</span>';
dnssecStatus = '<br><span class="text-orange">UNKNOWN</span>';
break;
default:
// No DNSSEC
dnssec_status = "";
dnssecStatus = "";
}
// Query status
@@ -178,14 +180,14 @@ $(document).ready(function () {
case "2":
blocked = false;
colorClass = "text-green";
fieldtext = "OK <br class='hidden-lg'>(forwarded)" + dnssec_status;
fieldtext = "OK <br class='hidden-lg'>(forwarded)" + dnssecStatus;
buttontext =
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>';
break;
case "3":
blocked = false;
colorClass = "text-green";
fieldtext = "OK <br class='hidden-lg'>(cached)" + dnssec_status;
fieldtext = "OK <br class='hidden-lg'>(cached)" + dnssecStatus;
buttontext =
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>';
break;
@@ -258,7 +260,7 @@ $(document).ready(function () {
default:
blocked = false;
colorClass = false;
fieldtext = "Unknown (" + parseInt(data[4]) + ")";
fieldtext = "Unknown (" + parseInt(data[4], 10) + ")";
buttontext = "";
}
@@ -281,9 +283,9 @@ $(document).ready(function () {
);
$("td:eq(4)", row).off(); // Release any possible previous onClick event handlers
$("td:eq(4)", row).click(function () {
var new_tab = window.open("groups-domains.php?domainid=" + data[9], "_blank");
if (new_tab) {
new_tab.focus();
var newTab = window.open("groups-domains.php?domainid=" + data[9], "_blank");
if (newTab) {
newTab.focus();
}
});
$("td:eq(4)", row).addClass("text-underline pointer");
@@ -296,9 +298,9 @@ $(document).ready(function () {
}
if (isCNAME) {
var CNAME_domain = data[8];
var CNAMEDomain = data[8];
// Add domain in CNAME chain causing the query to have been blocked
$("td:eq(2)", row).text(domain + "\n(blocked " + CNAME_domain + ")");
$("td:eq(2)", row).text(domain + "\n(blocked " + CNAMEDomain + ")");
} else {
$("td:eq(2)", row).text(domain);
}
@@ -341,7 +343,7 @@ $(document).ready(function () {
replytext = "upstream error";
break;
default:
replytext = "? (" + parseInt(data[6]) + ")";
replytext = "? (" + parseInt(data[6], 10) + ")";
}
} else {
replytext = "-";
@@ -349,7 +351,7 @@ $(document).ready(function () {
$("td:eq(5)", row).html(replytext);
if (data.length > 7 && data[7] > 0) {
if (data.length > 7) {
var content = $("td:eq(5)", row).html();
$("td:eq(5)", row).html(content + " (" + (0.1 * data[7]).toFixed(1) + "ms)");
}
@@ -399,24 +401,10 @@ $(document).ready(function () {
],
stateSave: true,
stateSaveCallback: function (settings, data) {
// Store current state in client's local storage area
localStorage.setItem("query_log_table", JSON.stringify(data));
utils.stateSaveCallback("query_log_table", data);
},
stateLoadCallback: function () {
// Receive previous state from client's local storage area
var data = localStorage.getItem("query_log_table");
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Apply loaded state to table
return data;
return utils.stateLoadCallback("query_log_table");
},
columnDefs: [
{
@@ -431,7 +419,7 @@ $(document).ready(function () {
api.$("td:eq(1)").click(function () {
if (autofilter()) {
api.search(this.textContent).draw();
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
}
});
api.$("td:eq(1)").hover(
@@ -454,7 +442,7 @@ $(document).ready(function () {
if (autofilter()) {
var domain = this.textContent.split("\n")[0];
api.search(domain).draw();
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
}
});
api.$("td:eq(2)").hover(
@@ -477,7 +465,7 @@ $(document).ready(function () {
api.$("td:eq(3)").click(function () {
if (autofilter()) {
api.search(this.textContent).draw();
$("#resetButton").show();
$("#resetButton").removeClass("hidden");
}
});
api.$("td:eq(3)").hover(
@@ -509,7 +497,7 @@ $(document).ready(function () {
$("#resetButton").click(function () {
tableApi.search("").draw();
$("#resetButton").hide();
$("#resetButton").addClass("hidden");
});
// Disable autocorrect in the search box
@@ -519,10 +507,10 @@ $(document).ready(function () {
input.setAttribute("autocapitalize", "off");
input.setAttribute("spellcheck", false);
var chkbox_data = localStorage.getItem("query_log_filter_chkbox");
if (chkbox_data !== null) {
var chkboxData = localStorage.getItem("query_log_filter_chkbox");
if (chkboxData !== null) {
// Restore checkbox state
$("#autofilter").prop("checked", chkbox_data === "true");
$("#autofilter").prop("checked", chkboxData === "true");
} else {
// Initialize checkbox
$("#autofilter").prop("checked", true);
+16 -36
View File
@@ -5,8 +5,6 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global ActiveXObject: false */
var exact = "";
function quietfilter(ta, data) {
@@ -21,33 +19,6 @@ function quietfilter(ta, data) {
}
}
// Credit: http://stackoverflow.com/a/10642418/2087442
function httpGet(ta, quiet, theUrl) {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
ta.show();
ta.empty();
if (!quiet) {
ta.append(xmlhttp.responseText);
} else {
quietfilter(ta, xmlhttp.responseText);
}
}
};
xmlhttp.open("GET", theUrl, false);
xmlhttp.send();
}
function eventsource() {
var ta = $("#output");
var domain = $("#domain").val().trim();
@@ -65,14 +36,23 @@ function eventsource() {
// IE does not support EventSource - load whole content at once
if (typeof EventSource !== "function") {
httpGet(
ta,
quiet,
"scripts/pi-hole/php/queryads.php?domain=" + domain.toLowerCase() + exact + "&IE"
);
$.ajax({
method: "GET",
url: "scripts/pi-hole/php/queryads.php?domain=" + domain.toLowerCase() + exact + "&IE",
async: false
}).done(function (data) {
ta.show();
ta.empty();
if (!quiet) {
ta.append(data);
} else {
quietfilter(ta, data);
}
});
return;
}
// eslint-disable-next-line compat/compat
var source = new EventSource(
"scripts/pi-hole/php/queryads.php?domain=" + domain.toLowerCase() + "&" + exact
);
@@ -127,7 +107,7 @@ $("#btnSearchExact").on("click", function () {
// Wrap form-group's buttons to next line when viewed on a small screen
$(window).on("resize", function () {
if ($(window).width() < 991) {
if ($(window).width() < 992) {
$(".form-group.input-group").removeClass("input-group").addClass("input-group-block");
$(".form-group.input-group-block > input").css("margin-bottom", "5px");
$(".form-group.input-group-block > .input-group-btn")
@@ -141,6 +121,6 @@ $(window).on("resize", function () {
.addClass("input-group-btn");
}
});
$(document).ready(function () {
$(function () {
$(window).trigger("resize");
});
+54 -17
View File
@@ -5,6 +5,8 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global utils:false */
$(function () {
$("[data-static]").on("click", function () {
var row = $(this).closest("tr");
@@ -17,7 +19,7 @@ $(function () {
});
});
$(".confirm-poweroff").confirm({
text: "Are you sure you want to send a poweroff command to your Pi-Hole?",
text: "Are you sure you want to send a poweroff command to your Pi-hole?",
title: "Confirmation required",
confirm: function () {
$("#poweroffform").submit();
@@ -30,10 +32,10 @@ $(".confirm-poweroff").confirm({
post: true,
confirmButtonClass: "btn-danger",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg" // Bootstrap classes for mid-size modal
dialogClass: "modal-dialog"
});
$(".confirm-reboot").confirm({
text: "Are you sure you want to send a reboot command to your Pi-Hole?",
text: "Are you sure you want to send a reboot command to your Pi-hole?",
title: "Confirmation required",
confirm: function () {
$("#rebootform").submit();
@@ -46,7 +48,7 @@ $(".confirm-reboot").confirm({
post: true,
confirmButtonClass: "btn-danger",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg" // Bootstrap classes for mid-size modal
dialogClass: "modal-dialog"
});
$(".confirm-restartdns").confirm({
@@ -63,7 +65,7 @@ $(".confirm-restartdns").confirm({
post: true,
confirmButtonClass: "btn-danger",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg"
dialogClass: "modal-dialog"
});
$(".confirm-flushlogs").confirm({
@@ -80,7 +82,7 @@ $(".confirm-flushlogs").confirm({
post: true,
confirmButtonClass: "btn-danger",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg"
dialogClass: "modal-dialog"
});
$(".confirm-flusharp").confirm({
@@ -97,7 +99,7 @@ $(".confirm-flusharp").confirm({
post: true,
confirmButtonClass: "btn-warning",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg"
dialogClass: "modal-dialog"
});
$(".confirm-disablelogging-noflush").confirm({
@@ -114,7 +116,7 @@ $(".confirm-disablelogging-noflush").confirm({
post: true,
confirmButtonClass: "btn-warning",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg"
dialogClass: "modal-dialog"
});
$(".api-token").confirm({
@@ -132,7 +134,7 @@ $(".api-token").confirm({
post: true,
confirmButtonClass: "btn-danger",
cancelButtonClass: "btn-success",
dialogClass: "modal-dialog modal-mg"
dialogClass: "modal-dialog"
});
$("#DHCPchk").click(function () {
@@ -147,11 +149,11 @@ function loadCacheInfo() {
}
// Fill table with obtained values
$("#cache-size").text(parseInt(data.cacheinfo["cache-size"]));
$("#cache-inserted").text(parseInt(data.cacheinfo["cache-inserted"]));
$("#cache-size").text(parseInt(data.cacheinfo["cache-size"], 10));
$("#cache-inserted").text(parseInt(data.cacheinfo["cache-inserted"], 10));
// Highlight early cache removals when present
var cachelivefreed = parseInt(data.cacheinfo["cache-live-freed"]);
var cachelivefreed = parseInt(data.cacheinfo["cache-live-freed"], 10);
$("#cache-live-freed").text(cachelivefreed);
if (cachelivefreed > 0) {
$("#cache-live-freed").parent("tr").addClass("lookatme");
@@ -165,7 +167,7 @@ function loadCacheInfo() {
}
var leasetable, staticleasetable;
$(document).ready(function () {
$(function () {
if (document.getElementById("DHCPLeasesTable")) {
leasetable = $("#DHCPLeasesTable").DataTable({
dom: "<'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'f>>",
@@ -173,7 +175,15 @@ $(document).ready(function () {
paging: false,
scrollCollapse: true,
scrollY: "200px",
scrollX: true
scrollX: true,
order: [[2, "asc"]],
stateSave: true,
stateSaveCallback: function (settings, data) {
utils.stateSaveCallback("activeDhcpLeaseTable", data);
},
stateLoadCallback: function () {
return utils.stateLoadCallback("activeDhcpLeaseTable");
}
});
}
@@ -184,7 +194,15 @@ $(document).ready(function () {
paging: false,
scrollCollapse: true,
scrollY: "200px",
scrollX: true
scrollX: true,
order: [[2, "asc"]],
stateSave: true,
stateSaveCallback: function (settings, data) {
utils.stateSaveCallback("staticDhcpLeaseTable", data);
},
stateLoadCallback: function () {
return utils.stateLoadCallback("staticDhcpLeaseTable");
}
});
}
@@ -207,7 +225,7 @@ $(function () {
});
// DHCP leases tooltips
$(document).ready(function () {
$(function () {
$('[data-toggle="tooltip"]').tooltip({ html: true, container: "body" });
});
@@ -223,7 +241,7 @@ $(".nav-tabs a").on("shown.bs.tab", function (e) {
});
// Auto dismissal for info notifications
$(document).ready(function () {
$(function () {
var alInfo = $("#alInfo");
if (alInfo.length > 0) {
alInfo.delay(3000).fadeOut(2000, function () {
@@ -238,3 +256,22 @@ $(document).ready(function () {
input.setAttribute("autocapitalize", "off");
input.setAttribute("spellcheck", false);
});
// Bar/Smooth chart toggle
$(function () {
var bargraphs = $("#bargraphs");
var chkboxData = localStorage.getItem("barchart_chkbox");
if (chkboxData !== null) {
// Restore checkbox state
bargraphs.prop("checked", chkboxData === "true");
} else {
// Initialize checkbox
bargraphs.prop("checked", true);
localStorage.setItem("barchart_chkbox", true);
}
bargraphs.click(function () {
localStorage.setItem("barchart_chkbox", bargraphs.prop("checked"));
});
});
@@ -7,7 +7,44 @@
/* global moment:false */
var info = null;
// Credit: https://stackoverflow.com/a/4835406
function escapeHtml(text) {
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#039;"
};
return text.replace(/[&<>"']/g, function (m) {
return map[m];
});
}
// Helper function for converting Objects to Arrays after sorting the keys
function objectToArray(obj) {
var arr = [];
var idx = [];
var keys = Object.keys(obj);
keys.sort(function (a, b) {
return a - b;
});
for (var i = 0; i < keys.length; i++) {
arr.push(obj[keys[i]]);
idx.push(keys[i]);
}
return [idx, arr];
}
function padNumber(num) {
return ("00" + num).substr(-2, 2);
}
var info = null; // TODO clear this up; there shouldn't be a global var here
function showAlert(type, icon, title, message) {
var opts = {};
title = "&nbsp;<strong>" + title + "</strong><br>";
@@ -68,26 +105,26 @@ function showAlert(type, icon, title, message) {
}
function datetime(date) {
return moment.unix(Math.floor(date)).format("Y-MM-DD HH:mm:ss z");
return moment.unix(Math.floor(date)).format("Y-MM-DD [<br class='hidden-lg'>]HH:mm:ss z");
}
function disableAll() {
$("input").attr("disabled", true);
$("select").attr("disabled", true);
$("button").attr("disabled", true);
$("textarea").attr("disabled", true);
$("input").prop("disabled", true);
$("select").prop("disabled", true);
$("button").prop("disabled", true);
$("textarea").prop("disabled", true);
}
function enableAll() {
$("input").attr("disabled", false);
$("select").attr("disabled", false);
$("button").attr("disabled", false);
$("textarea").attr("disabled", false);
$("input").prop("disabled", false);
$("select").prop("disabled", false);
$("button").prop("disabled", false);
$("textarea").prop("disabled", false);
// Enable custom input field only if applicable
var ip = $("#select") ? $("#select").val() : null;
if (ip !== null && ip !== "custom") {
$("#ip-custom").attr("disabled", true);
$("#ip-custom").prop("disabled", true);
}
}
@@ -139,18 +176,18 @@ function validateHostname(name) {
return namevalidator.test(name);
}
function bsSelect_defaults() {
// set bootstrap-select defaults
var pickerDEFAULTS = $.fn.selectpicker.Constructor.DEFAULTS;
pickerDEFAULTS.noneSelectedText = "none selected";
pickerDEFAULTS.selectedTextFormat = "count > 1";
pickerDEFAULTS.actionsBox = true;
pickerDEFAULTS.width = "fit";
pickerDEFAULTS.container = "body";
pickerDEFAULTS.dropdownAlignRight = "auto";
pickerDEFAULTS.selectAllText = "All";
pickerDEFAULTS.deselectAllText = "None";
pickerDEFAULTS.countSelectedText = function (num, total) {
// set bootstrap-select defaults
function setBsSelectDefaults() {
var bsSelectDefaults = $.fn.selectpicker.Constructor.DEFAULTS;
bsSelectDefaults.noneSelectedText = "none selected";
bsSelectDefaults.selectedTextFormat = "count > 1";
bsSelectDefaults.actionsBox = true;
bsSelectDefaults.width = "fit";
bsSelectDefaults.container = "body";
bsSelectDefaults.dropdownAlignRight = "auto";
bsSelectDefaults.selectAllText = "All";
bsSelectDefaults.deselectAllText = "None";
bsSelectDefaults.countSelectedText = function (num, total) {
if (num === total) {
return "All selected (" + num + ")";
}
@@ -159,16 +196,48 @@ function bsSelect_defaults() {
};
}
function stateSaveCallback(itemName, data) {
localStorage.setItem(itemName, JSON.stringify(data));
}
function stateLoadCallback(itemName) {
// Receive previous state from client's local storage area
var data = localStorage.getItem(itemName);
// Return if not available
if (data === null) {
return null;
}
data = JSON.parse(data);
// Always start on the first page to show most recent queries
data.start = 0;
// Always start with empty search field
data.search.search = "";
// Apply loaded state to table
return data;
}
function getGraphType() {
// Only return line if `barchart_chkbox` is explicitly set to false. Else return bar
return localStorage.getItem("barchart_chkbox") === "false" ? "line" : "bar";
}
window.utils = (function () {
return {
escapeHtml: escapeHtml,
objectToArray: objectToArray,
padNumber: padNumber,
showAlert: showAlert,
datetime: datetime,
disableAll: disableAll,
enableAll: enableAll,
validateIPv4CIDR: validateIPv4CIDR,
validateIPv6CIDR: validateIPv6CIDR,
setBsSelectDefaults: setBsSelectDefaults,
stateSaveCallback: stateSaveCallback,
stateLoadCallback: stateLoadCallback,
getGraphType: getGraphType,
validateMAC: validateMAC,
validateHostname: validateHostname,
bsSelect_defaults: bsSelect_defaults
validateHostname: validateHostname
};
})();
+8 -3
View File
@@ -36,9 +36,13 @@ function connectFTL($address, $port=4711)
{
$config = piholeFTLConfig();
// Read port
$portfile = file_get_contents($config["PORTFILE"]);
if(is_numeric($portfile))
$port = intval($portfile);
$portfileName = isset($config['PORTFILE']) ? $config['PORTFILE'] : '';
if ($portfileName != '')
{
$portfileContents = file_get_contents($portfileName);
if(is_numeric($portfileContents))
$port = intval($portfileContents);
}
}
// Open Internet socket connection
@@ -46,6 +50,7 @@ function connectFTL($address, $port=4711)
return $socket;
}
function sendRequestFTL($requestin)
{
global $socket;
-93
View File
@@ -1,93 +0,0 @@
<?php
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require_once('auth.php');
$list = $_POST['list'];
// Perform all of the authentication for list editing
// when NOT invoked and authenticated from API
if (empty($api)) {
list_verify($list);
}
// Split individual domains into array
$domains = preg_split('/\s+/', trim($_POST['domain']));
// Get comment if available
$comment = null;
if(isset($_POST['comment'])) {
$comment = trim($_POST['comment']);
}
// Convert domain name to IDNA ASCII form for international domains
// Do this only for exact domains, not for regex filters
// Only do it when the php-intl extension is available
if (extension_loaded("intl") && ($list === "white" || $list === "black")) {
foreach($domains as &$domain)
{
$domain = idn_to_ascii($domain);
}
}
// Only check domains we add to the exact lists.
// Regex are validated by FTL during import
$check_lists = ["white","black","audit"];
if(in_array($list, $check_lists)) {
check_domain($domains);
}
require_once("func.php");
require_once("database.php");
$GRAVITYDB = getGravityDBFilename();
$db = SQLite3_connect($GRAVITYDB, SQLITE3_OPEN_READWRITE);
$reload = true;
switch($list) {
case "white":
$domains = array_map('strtolower', $domains);
echo add_to_table($db, "domainlist", $domains, $comment, false, false, ListType::whitelist);
break;
case "black":
$domains = array_map('strtolower', $domains);
echo add_to_table($db, "domainlist", $domains, $comment, false, false, ListType::blacklist);
break;
case "white_regex":
echo add_to_table($db, "domainlist", $domains, $comment, false, false, ListType::regex_whitelist);
break;
case "white_wild":
echo add_to_table($db, "domainlist", $domains, $comment, true, false, ListType::regex_whitelist);
break;
case "black_regex":
echo add_to_table($db, "domainlist", $domains, $comment, false, false, ListType::regex_blacklist);
break;
case "black_wild":
echo add_to_table($db, "domainlist", $domains, $comment, true, false, ListType::regex_blacklist);
break;
case "audit":
$reload = false;
echo add_to_table($db, "domain_audit", $domains);
break;
default:
die("Invalid list!");
}
// Reload lists in pihole-FTL after having added something
if ($reload) {
$output = pihole_execute("restartdns reload-lists");
echo implode("\n", $output);
}
?>
+14 -1
View File
@@ -4,7 +4,18 @@
$customDNSFile = "/etc/pihole/custom.list";
switch ($_REQUEST['action'])
require_once('auth.php');
// Authentication checks
if (isset($_POST['token'])) {
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
switch ($_POST['action'])
{
case 'get': echo json_encode(echoCustomDNSEntries()); break;
case 'add': echo json_encode(addCustomDNSEntry()); break;
@@ -12,4 +23,6 @@
default:
die("Wrong action");
}
?>
+9 -7
View File
@@ -136,7 +136,7 @@ function add_to_table($db, $table, $domains, $comment=null, $wildcardstyle=false
$querystr = "INSERT OR IGNORE INTO $table ($field,comment) VALUES (:$field, :comment);";
$bindcomment = true;
} else {
$querystr = "INSERT OR IGNORE INTO $table ($field,comment,type) VALUES (:$field, :comment, $type);";
$querystr = "REPLACE INTO $table ($field,comment,type) VALUES (:$field, :comment, $type);";
$bindcomment = true;
}
$stmt = $db->prepare($querystr);
@@ -311,9 +311,11 @@ function remove_from_table($db, $table, $domains, $returnnum=false, $type=-1)
}
}
class ListType{
const whitelist = 0;
const blacklist = 1;
const regex_whitelist = 2;
const regex_blacklist = 3;
}
if (!class_exists("ListType")) {
class ListType{
const whitelist = 0;
const blacklist = 1;
const regex_whitelist = 2;
const regex_blacklist = 3;
}
}
+56 -23
View File
@@ -36,34 +36,67 @@
</div>
</div>
</div>
</div>
</div> <!-- /.content-wrapper -->
<?php
// Flushes the system write buffers of PHP. This attempts to push everything we have so far all the way to the client's browser.
flush();
// Run update checker
// - determines local branch each time,
// - determines local and remote version every 30 minutes
require "scripts/pi-hole/php/update_checker.php";
// Flushes the system write buffers of PHP. This attempts to push everything we have so far all the way to the client's browser.
flush();
// Run update checker
// - determines local branch each time,
// - determines local and remote version every 30 minutes
require "scripts/pi-hole/php/update_checker.php";
$coreVersionStr = $core_current . (isset($core_commit) ? " (" . $core_branch . ", " . $core_commit . ")" : "");
$webVersionStr = $web_current . (isset($web_commit) ? " (" . $web_branch . ", " . $web_commit . ")" : "");
$ftlVersionStr = $FTL_current . (isset($FTL_commit) ? " (" . $FTL_branch . ", " . $FTL_commit . ")" : "");
$githubBaseUrl = "https://github.com/pi-hole";
$coreUrl = $githubBaseUrl . "/pi-hole";
$webUrl = $githubBaseUrl . "/AdminLTE";
$ftlUrl = $githubBaseUrl . "/FTL";
$coreReleasesUrl = $coreUrl . "/releases";
$webReleasesUrl = $webUrl . "/releases";
$ftlReleasesUrl = $ftlUrl . "/releases";
?>
<!-- /.content-wrapper -->
<footer class="main-footer">
<!-- Version Infos -->
<div class="pull-right hidden-xs hidden-sm<?php if(isset($core_commit) || isset($web_commit) || isset($FTL_commit)) { ?> hidden-md<?php } ?>">
<b>Pi-hole Version </b> <?php
echo $core_current;
if(isset($core_commit)) { echo " (".$core_branch.", ".$core_commit.")"; }
if($core_update){ ?> <a class="alert-link lookatme" href="https://github.com/pi-hole/pi-hole/releases" rel="noopener" target="_blank">(Update available!)</a><?php } ?>
<b>Web Interface Version </b><?php
echo $web_current;
if(isset($web_commit)) { echo " (".$web_branch.", ".$web_commit.")"; }
if($web_update){ ?> <a class="alert-link lookatme" href="https://github.com/pi-hole/AdminLTE/releases" rel="noopener" target="_blank">(Update available!)</a><?php } ?>
<b>FTL Version </b> <?php
echo $FTL_current;
if(isset($FTL_commit)) { echo " (".$FTL_branch.", ".$FTL_commit.")"; }
if($FTL_update){ ?> <a class="alert-link lookatme" href="https://github.com/pi-hole/FTL/releases" rel="noopener" target="_blank">(Update available!)</a><?php } ?>
<div class="row row-centered text-center">
<div class="col-xs-12 col-sm-6">
<strong><a href="https://pi-hole.net/donate/" rel="noopener" target="_blank"><i class="fa fa-heart text-red"></i> Donate</a></strong> if you found this useful.
</div>
</div>
<div class="row row-centered text-center version-info">
<div class="col-xs-12 col-sm-8 col-md-6">
<?php if (isset($core_commit) || isset($web_commit) || isset($FTL_commit)) { ?>
<ul class="list-unstyled">
<li><strong>Pi-hole</strong> <?php echo $coreVersionStr; ?></li>
<li><strong>Web Interface</strong> <?php echo $webVersionStr; ?></li>
<li><strong>FTL</strong> <?php echo $ftlVersionStr; ?></li>
</ul>
<?php } else { ?>
<ul class="list-inline">
<li>
<strong>Pi-hole</strong>
<a href="<?php echo $coreReleasesUrl . "/" . $core_current; ?>" rel="noopener" target="_blank"><?php echo $core_current; ?></a>
<?php if ($core_update) { ?> &middot; <a class="lookatme" href="<?php echo $coreReleasesUrl . "/latest"; ?>" rel="noopener" target="_blank">Update available!</a><?php } ?>
</li>
<li>
<strong>Web Interface</strong>
<a href="<?php echo $webReleasesUrl . "/" . $web_current; ?>" rel="noopener" target="_blank"><?php echo $web_current; ?></a>
<?php if ($web_update) { ?> &middot; <a class="lookatme" href="<?php echo $webReleasesUrl . "/latest"; ?>" rel="noopener" target="_blank">Update available!</a><?php } ?>
</li>
<li>
<strong>FTL</strong>
<a href="<?php echo $ftlReleasesUrl . "/" . $FTL_current; ?>" rel="noopener" target="_blank"><?php echo $FTL_current; ?></a>
<?php if ($FTL_update) { ?> &middot; <a class="lookatme" href="<?php echo $ftlReleasesUrl . "/latest"; ?>" rel="noopener" target="_blank">Update available!</a><?php } ?>
</li>
</ul>
<?php } ?>
</div>
</div>
<div style="display: inline-block"><strong><a href="https://pi-hole.net/donate/" rel="noopener" target="_blank"><i class="fa fa-heart"></i> Donate</a></strong> if you found this useful.</div>
</footer>
</div>
<!-- ./wrapper -->
<script src="scripts/pi-hole/js/footer.js"></script>
+1 -1
View File
@@ -6,7 +6,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
require "scripts/pi-hole/php/database.php";
require_once("scripts/pi-hole/php/database.php");
function gravity_last_update($raw = false)
{
+106 -20
View File
@@ -9,11 +9,13 @@
require_once('auth.php');
// Authentication checks
if (isset($_POST['token'])) {
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
if (!isset($api)) {
if (isset($_POST['token'])) {
check_cors();
check_csrf($_POST['token']);
} else {
log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!');
}
}
$reload = false;
@@ -47,6 +49,8 @@ if ($_POST['action'] == 'get_groups') {
while (($res = $query->fetchArray(SQLITE3_ASSOC)) !== false) {
array_push($data, $res);
}
header('Content-type: application/json');
echo json_encode(array('data' => $data));
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
@@ -54,7 +58,7 @@ if ($_POST['action'] == 'get_groups') {
} elseif ($_POST['action'] == 'add_group') {
// Add new group
try {
$names = explode(' ', trim($_POST['name']));
$names = str_getcsv(trim($_POST['name']), ' ');
$total = count($names);
$added = 0;
$stmt = $db->prepare('INSERT INTO "group" (name,description) VALUES (:name,:desc)');
@@ -62,7 +66,12 @@ if ($_POST['action'] == 'get_groups') {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':desc', $_POST['desc'], SQLITE3_TEXT)) {
$desc = $_POST['desc'];
if (strlen($desc) === 0) {
// Store NULL in database for empty descriptions
$desc = null;
}
if (!$stmt->bindValue(':desc', $desc, SQLITE3_TEXT)) {
throw new Exception('While binding desc: ' . $db->lastErrorMsg());
}
@@ -102,7 +111,7 @@ if ($_POST['action'] == 'get_groups') {
}
$desc = $_POST['desc'];
if (strlen($desc) == 0) {
if (strlen($desc) === 0) {
// Store NULL in database for empty descriptions
$desc = null;
}
@@ -199,6 +208,7 @@ if ($_POST['action'] == 'get_groups') {
array_push($data, $res);
}
header('Content-type: application/json');
echo json_encode(array('data' => $data));
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
@@ -276,6 +286,7 @@ if ($_POST['action'] == 'get_groups') {
}
}
header('Content-type: application/json');
echo json_encode($ips);
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
@@ -297,7 +308,7 @@ if ($_POST['action'] == 'get_groups') {
}
$comment = $_POST['comment'];
if (strlen($comment) == 0) {
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
@@ -327,7 +338,7 @@ if ($_POST['action'] == 'get_groups') {
}
$comment = $_POST['comment'];
if (strlen($comment) == 0) {
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
@@ -424,6 +435,8 @@ if ($_POST['action'] == 'get_groups') {
$limit = " WHERE type = 0 OR type = 2";
} elseif (isset($_POST["showtype"]) && $_POST["showtype"] === "black"){
$limit = " WHERE type = 1 OR type = 3";
} elseif (isset($_POST["type"]) && is_numeric($_POST["type"])){
$limit = " WHERE type = " . $_POST["type"];
}
$query = $db->query('SELECT * FROM domainlist'.$limit);
if (!$query) {
@@ -476,7 +489,7 @@ if ($_POST['action'] == 'get_groups') {
array_push($data, $res);
}
header('Content-type: application/json');
echo json_encode(array('data' => $data));
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
@@ -485,6 +498,7 @@ if ($_POST['action'] == 'get_groups') {
// Add new domain
try {
$domains = explode(' ', trim($_POST['domain']));
$before = intval($db->querySingle("SELECT COUNT(*) FROM domainlist;"));
$total = count($domains);
$added = 0;
$stmt = $db->prepare('REPLACE INTO domainlist (domain,type,comment) VALUES (:domain,:type,:comment)');
@@ -492,13 +506,24 @@ if ($_POST['action'] == 'get_groups') {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}
$type = intval($_POST['type']);
if (isset($_POST['type'])) {
$type = intval($_POST['type']);
} else if (isset($_POST['list']) && $_POST['list'] === "white") {
$type = ListType::whitelist;
} else if (isset($_POST['list']) && $_POST['list'] === "black") {
$type = ListType::blacklist;
}
if (!$stmt->bindValue(':type', $type, SQLITE3_TEXT)) {
throw new Exception('While binding type: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':comment', $_POST['comment'], SQLITE3_TEXT)) {
$comment = $_POST['comment'];
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}
@@ -555,8 +580,23 @@ if ($_POST['action'] == 'get_groups') {
$added++;
}
$after = intval($db->querySingle("SELECT COUNT(*) FROM domainlist;"));
$difference = $after - $before;
if($total === 1) {
if($difference !== 1) {
$msg = "Not adding ". htmlentities(utf8_encode($domain)) . " as it is already on the list";
} else {
$msg = "Added " . htmlentities(utf8_encode($domain));
}
} else {
if($difference !== $total) {
$msg = "Added " . ($after-$before) . " out of ". $total . " domains (skipped duplicates)";
} else {
$msg = "Added " . $total . " domains";
}
}
$reload = true;
JSON_success();
JSON_success($msg);
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
}
@@ -578,7 +618,7 @@ if ($_POST['action'] == 'get_groups') {
}
$comment = $_POST['comment'];
if (strlen($comment) == 0) {
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
@@ -668,6 +708,48 @@ if ($_POST['action'] == 'get_groups') {
throw new Exception('While executing domainlist statement: ' . $db->lastErrorMsg());
}
$reload = true;
JSON_success();
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
}
} elseif ($_POST['action'] == 'delete_domain_string') {
// Delete domain identified by the domain string itself
try {
$stmt = $db->prepare('DELETE FROM domainlist_by_group WHERE domainlist_id=(SELECT id FROM domainlist WHERE domain=:domain AND type=:type);');
if (!$stmt) {
throw new Exception('While preparing domainlist_by_group statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':domain', $_POST['domain'], SQLITE3_TEXT)) {
throw new Exception('While binding domain to domainlist_by_group statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':type', intval($_POST['type']), SQLITE3_INTEGER)) {
throw new Exception('While binding type to domainlist_by_group statement: ' . $db->lastErrorMsg());
}
if (!$stmt->execute()) {
throw new Exception('While executing domainlist_by_group statement: ' . $db->lastErrorMsg());
}
$stmt = $db->prepare('DELETE FROM domainlist WHERE domain=:domain AND type=:type');
if (!$stmt) {
throw new Exception('While preparing domainlist statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':domain', $_POST['domain'], SQLITE3_TEXT)) {
throw new Exception('While binding domain to domainlist statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':type', intval($_POST['type']), SQLITE3_INTEGER)) {
throw new Exception('While binding type to domainlist statement: ' . $db->lastErrorMsg());
}
if (!$stmt->execute()) {
throw new Exception('While executing domainlist statement: ' . $db->lastErrorMsg());
}
$reload = true;
JSON_success();
} catch (\Exception $ex) {
@@ -696,7 +778,7 @@ if ($_POST['action'] == 'get_groups') {
array_push($data, $res);
}
header('Content-type: application/json');
echo json_encode(array('data' => $data));
} catch (\Exception $ex) {
JSON_error($ex->getMessage());
@@ -713,12 +795,17 @@ if ($_POST['action'] == 'get_groups') {
throw new Exception('While preparing statement: ' . $db->lastErrorMsg());
}
if (!$stmt->bindValue(':comment', $_POST['comment'], SQLITE3_TEXT)) {
$comment = $_POST['comment'];
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
if (!$stmt->bindValue(':comment', $comment, SQLITE3_TEXT)) {
throw new Exception('While binding comment: ' . $db->lastErrorMsg());
}
foreach ($addresses as $address) {
if(preg_match("/[^a-zA-Z0-9:\/?&%=~._()-]/", $address) !== 0) {
if(preg_match("/[^a-zA-Z0-9:\/?&%=~._()-;]/", $address) !== 0) {
throw new Exception('<strong>Invalid adlist URL ' . htmlentities($address) . '</strong><br>'.
'Added ' . $added . " out of ". $total . " adlists");
}
@@ -758,7 +845,7 @@ if ($_POST['action'] == 'get_groups') {
}
$comment = $_POST['comment'];
if (strlen($comment) == 0) {
if (strlen($comment) === 0) {
// Store NULL in database for empty comments
$comment = null;
}
@@ -853,5 +940,4 @@ if ($_POST['action'] == 'get_groups') {
// Reload lists in pihole-FTL after having added something
if ($reload) {
$output = pihole_execute('restartdns reload-lists');
echo implode("\n", $output);
}
+136 -157
View File
@@ -11,6 +11,7 @@
require_once "scripts/pi-hole/php/FTL.php";
require "scripts/pi-hole/php/theme.php";
$scriptname = basename($_SERVER['SCRIPT_FILENAME']);
$hostname = gethostname() ? gethostname() : "";
check_cors();
@@ -39,7 +40,7 @@
{
// $output could be either 4-5 digits or 2-3, and we only divide by 1000 if it's 4-5
// ex. 39007 vs 39
$celsius = intVal($output);
$celsius = intval($output);
// If celsius is greater than 1 degree and is in the 4-5 digit format
if($celsius > 1000) {
@@ -47,22 +48,6 @@
$celsius *= 1e-3;
}
$kelvin = $celsius + 273.15;
$fahrenheit = ($celsius*9./5)+32.0;
if(isset($setupVars['TEMPERATUREUNIT']))
{
$temperatureunit = $setupVars['TEMPERATUREUNIT'];
}
else
{
$temperatureunit = "C";
}
// Override temperature unit setting if it is changed via Settings page
if(isset($_POST["tempunit"]))
{
$temperatureunit = $_POST["tempunit"];
}
// Get user-defined temperature limit if set
if(isset($setupVars['TEMPERATURE_LIMIT']))
{
@@ -105,7 +90,7 @@
if(count($expl) == 2)
{
// remove " kB" from the end of the string and make it an integer
$meminfo[$expl[0]] = intVal(substr($expl[1],0, -3));
$meminfo[$expl[0]] = intval(substr($expl[1],0, -3));
}
}
$memory_used = $meminfo["MemTotal"]-$meminfo["MemFree"]-$meminfo["Buffers"]-$meminfo["Cached"];
@@ -175,19 +160,15 @@
* Please see LICENSE file for your rights under this license. -->
<html lang="en">
<head>
<?php if ($darkmode) { ?>
<style>
html { background-color: black; }
</style>
<?php } ?>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://api.github.com; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'">
<title>Pi-hole<?php if (gethostname()) {echo " - ", gethostname();} ?></title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; base-uri 'none'; child-src 'self'; form-action 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'">
<!-- Usually browsers proactively perform domain name resolution on links that the user may choose to follow. We disable DNS prefetching here -->
<meta http-equiv="x-dns-prefetch-control" content="off">
<meta http-equiv="cache-control" content="max-age=60,private">
<!-- Tell the browser to be responsive to screen width -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pi-hole<?php echo $hostname ? " - " . $hostname : "" ?></title>
<link rel="apple-touch-icon" href="img/favicons/apple-touch-icon.png" sizes="180x180">
<link rel="icon" href="img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
@@ -199,53 +180,48 @@
<meta name="msapplication-TileImage" content="img/favicons/mstile-150x150.png">
<meta name="theme-color" content="#367fa9">
<?php if ($darkmode) { ?>
<style>
html { background-color: #000; }
</style>
<?php } ?>
<link rel="stylesheet" href="style/vendor/SourceSansPro/SourceSansPro.css">
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="style/vendor/font-awesome-5.11.2/css/all.min.css">
<link rel="stylesheet" href="style/vendor/dataTables.bootstrap.min.css">
<link rel="stylesheet" href="style/vendor/daterangepicker.css">
<link rel="stylesheet" href="style/vendor/font-awesome/css/all.min.css">
<link rel="stylesheet" href="style/vendor/datatables.min.css">
<link rel="stylesheet" href="style/vendor/daterangepicker.min.css">
<link rel="stylesheet" href="style/vendor/AdminLTE.min.css">
<link rel="stylesheet" href="style/vendor/animate.css">
<link rel="stylesheet" href="style/vendor/select2.min.css">
<?php if (in_array($scriptname, array("groups.php", "groups-adlists.php", "groups-clients.php", "groups-domains.php"))){ ?>
<link rel="stylesheet" href="style/vendor/animate.min.css">
<link rel="stylesheet" href="style/vendor/bootstrap-select.min.css">
<link rel="stylesheet" href="style/vendor/bootstrap-toggle.min.css">
<?php } ?>
<link rel="stylesheet" href="style/pi-hole.css">
<link rel="stylesheet" href="style/themes/<?php echo $theme; ?>.css">
<noscript><link rel="stylesheet" href="style/vendor/js-warn.css"></noscript>
<script src="scripts/vendor/jquery.min.js"></script>
<script src="scripts/vendor/jquery-ui.min.js"></script>
<script src="style/vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="scripts/vendor/adminlte.min.js"></script>
<script src="scripts/vendor/bootstrap-notify.min.js"></script>
<script src="scripts/vendor/select2.min.js"></script>
<?php if(in_array($scriptname, array("groups.php", "groups-clients.php", "groups-domains.php", "groups-adlists.php"))){ ?>
<script src="style/vendor/bootstrap/js/bootstrap-select.min.js"></script>
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap-select.min.css">
<script src="style/vendor/bootstrap/js/bootstrap-toggle.min.js"></script>
<link rel="stylesheet" href="style/vendor/bootstrap/css/bootstrap-toggle.min.css">
<?php } ?>
<script src="scripts/vendor/jquery.dataTables.min.js"></script>
<script src="scripts/vendor/dataTables.bootstrap.min.js"></script>
<script src="scripts/vendor/datatables.min.js"></script>
<script src="scripts/vendor/moment.min.js"></script>
<script src="scripts/vendor/Chart.min.js"></script>
<script src="scripts/vendor/iCheck.min.js"></script>
<link rel="stylesheet" type="text/css" href="style/vendor/iCheck/<?php echo $checkbox_theme_name;?>/<?php echo $checkbox_theme_variant;?>.css">
<link rel="stylesheet" href="style/pi-hole.css">
<link rel="stylesheet" href="style/themes/<?php echo $theme; ?>.css">
</head>
<body class="hold-transition sidebar-mini <?php if($boxedlayout){ ?>layout-boxed<?php } ?>">
<noscript>
<!-- JS Warning -->
<div>
<input type="checkbox" id="js-hide">
<div class="js-warn" id="js-warn-exit"><h1>JavaScript Is Disabled</h1><p>JavaScript is required for the site to function.</p>
<p>To learn how to enable JavaScript click <a href="https://www.enable-javascript.com/" rel="noopener" target="_blank">here</a></p><label for="js-hide">Close</label>
<noscript>
<!-- JS Warning -->
<div>
<input type="checkbox" id="js-hide">
<div class="js-warn" id="js-warn-exit"><h1>JavaScript Is Disabled</h1><p>JavaScript is required for the site to function.</p>
<p>To learn how to enable JavaScript click <a href="https://www.enable-javascript.com/" rel="noopener" target="_blank">here</a></p><label for="js-hide">Close</label>
</div>
</div>
</div>
<!-- /JS Warning -->
</noscript>
<!-- /JS Warning -->
</noscript>
<?php
if($auth) {
echo "<div id=\"token\" hidden>$token</div>";
@@ -253,37 +229,42 @@ if($auth) {
?>
<!-- Send token to JS -->
<div id="checkbox_theme" hidden><?php echo $checkbox_theme_name; ?><?php if($checkbox_theme_name !== $checkbox_theme_variant){ echo "-$checkbox_theme_variant"; } ?></div>
<div id="enableTimer" hidden><?php if(file_exists("../custom_disable_timer")){ echo file_get_contents("../custom_disable_timer"); } ?></div>
<div class="wrapper">
<header class="main-header">
<!-- Logo -->
<a href="index.php" class="logo">
<!-- mini logo for sidebar mini 50x50 pixels -->
<span class="logo-mini">P<b>h</b></span>
<span class="logo-mini">P<strong>h</strong></span>
<!-- logo for regular state and mobile devices -->
<span class="logo-lg">Pi-<b>hole</b></span>
<span class="logo-lg">Pi-<strong>hole</strong></span>
</a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top">
<!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
<a href="#" class="sidebar-toggle fa5" data-toggle="push-menu" role="button">
<span class="sr-only">Toggle navigation</span>
</a>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li>
<a style="pointer-events:none;">
<span class="hidden-xs hidden-sm">hostname:</span>
<code><?php echo gethostname(); ?></code>
<li id="pihole-diagnosis" class="hidden">
<a href="messages.php">
<i class="fa fa-exclamation-triangle"></i>
<span class="label label-warning" id="pihole-diagnosis-count"></span>
</a>
</li>
<li<?php echo !$hostname ? ' class="hidden"' : "" ?>>
<p class="navbar-text">
<span class="hidden-xs hidden-sm">hostname:</span>
<code><?php echo $hostname; ?></code>
</p>
</li>
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<img src="img/logo.svg" class="user-image" alt="Pi-hole logo" style="border-radius: 0" width="25" height="25">
<span class="hidden-xs">Pi-hole</span>
</a>
<ul class="dropdown-menu" style="right:0">
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header">
<img src="img/logo.svg" alt="Pi-hole Logo" style="border: 0" width="90" height="90">
@@ -294,17 +275,19 @@ if($auth) {
</li>
<!-- Menu Body -->
<li class="user-body">
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://github.com/pi-hole" rel="noopener" target="_blank">GitHub</a>
</div>
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://pi-hole.net/" rel="noopener" target="_blank">Website</a>
</div>
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://github.com/pi-hole/pi-hole/releases" rel="noopener" target="_blank">Updates</a>
</div>
<div class="col-xs-12 text-center" id="sessiontimer">
<b>Session is valid for <span id="sessiontimercounter"><?php if($auth && strlen($pwhash) > 0){echo $maxlifetime;}else{echo "0";} ?></span></b>
<div class="row">
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://github.com/pi-hole" rel="noopener" target="_blank">GitHub</a>
</div>
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://pi-hole.net/" rel="noopener" target="_blank">Website</a>
</div>
<div class="col-xs-4 text-center">
<a class="btn-link" href="https://github.com/pi-hole/pi-hole/releases" rel="noopener" target="_blank">Updates</a>
</div>
<div id="sessiontimer" class="col-xs-12 text-center">
<strong>Session is valid for <span id="sessiontimercounter"><?php if($auth && strlen($pwhash) > 0){echo $maxlifetime;}else{echo "0";} ?></span></strong>
</div>
</div>
</li>
<!-- Menu Footer -->
@@ -329,32 +312,32 @@ if($auth) {
<!-- Sidebar user panel -->
<div class="user-panel">
<div class="pull-left image">
<img src="img/logo.svg" class="img-responsive" alt="Pi-hole logo" style="display: table; table-layout: fixed; height: 67px;">
<img src="img/logo.svg" alt="Pi-hole logo" width="45" height="67" style="height: 67px;">
</div>
<div class="pull-left info">
<p>Status</p>
<?php
$pistatus = pihole_execute('status web');
if(isset($pistatus[0])) {
if (isset($pistatus[0])) {
$pistatus = $pistatus[0];
} else {
$pistatus = null;
}
if ($pistatus === "1") {
echo '<a id="status"><i class="fa fa-circle text-green-light"></i> Active</a>';
echo '<span id="status"><i class="fa fa-circle text-green-light"></i> Active</span>';
} elseif ($pistatus === "0") {
echo '<a id="status"><i class="fa fa-circle text-red"></i> Offline</a>';
echo '<span id="status"><i class="fa fa-circle text-red"></i> Offline</span>';
} elseif ($pistatus === "-1") {
echo '<a id="status"><i class="fa fa-circle text-red"></i> DNS service not running</a>';
echo '<span id="status"><i class="fa fa-circle text-red"></i> DNS service not running</span>';
} else {
echo '<a id="status"><i class="fa fa-circle text-orange"></i> Unknown</a>';
echo '<span id="status"><i class="fa fa-circle text-orange"></i> Unknown</span>';
}
// CPU Temp
if($FTL)
{
if ($celsius >= -273.15) {
echo "<a id=\"temperature\"><i class=\"fa fa-fire ";
echo "<span id=\"temperature\"><i class=\"fa fa-fire ";
if ($celsius > $temperaturelimit) {
echo "text-red";
}
@@ -362,30 +345,17 @@ if($auth) {
{
echo "text-vivid-blue";
}
echo "\"></i> Temp:&nbsp;";
if($temperatureunit === "F")
{
echo round($fahrenheit,1) . "&nbsp;&deg;F";
}
elseif($temperatureunit === "K")
{
echo round($kelvin,1) . "&nbsp;K";
}
else
{
echo round($celsius,1) . "&nbsp;&deg;C";
}
echo "</a>";
?>"\"></i> Temp:&nbsp;<span id="rawtemp" hidden><?php echo $celsius;?></span><span id="tempdisplay"></span><?php
}
}
else
{
echo '<a id=\"temperature\"><i class="fa fa-circle text-red"></i> FTL offline</a>';
echo '<span id=\"temperature\"><i class="fa fa-circle text-red"></i> FTL offline</span>';
}
?>
<br/>
<?php
echo "<a title=\"Detected $nproc cores\"><i class=\"fa fa-circle ";
echo "<span title=\"Detected $nproc cores\"><i class=\"fa fa-circle ";
if ($loaddata[0] > $nproc) {
echo "text-red";
}
@@ -393,11 +363,11 @@ if($auth) {
{
echo "text-green-light";
}
echo "\"></i> Load:&nbsp;&nbsp;" . $loaddata[0] . "&nbsp;&nbsp;" . $loaddata[1] . "&nbsp;&nbsp;". $loaddata[2] . "</a>";
echo "\"></i> Load:&nbsp;&nbsp;" . $loaddata[0] . "&nbsp;&nbsp;" . $loaddata[1] . "&nbsp;&nbsp;". $loaddata[2] . "</span>";
?>
<br/>
<?php
echo "<a><i class=\"fa fa-circle ";
echo "<span><i class=\"fa fa-circle ";
if ($memory_usage > 0.75 || $memory_usage < 0.0) {
echo "text-red";
}
@@ -407,11 +377,11 @@ if($auth) {
}
if($memory_usage > 0.0)
{
echo "\"></i> Memory usage:&nbsp;&nbsp;" . sprintf("%.1f",100.0*$memory_usage) . "&thinsp;%</a>";
echo "\"></i> Memory usage:&nbsp;&nbsp;" . sprintf("%.1f",100.0*$memory_usage) . "&thinsp;%</span>";
}
else
{
echo "\"></i> Memory usage:&nbsp;&nbsp; N/A</a>";
echo "\"></i> Memory usage:&nbsp;&nbsp; N/A</span>";
}
?>
</div>
@@ -435,7 +405,7 @@ if($auth) {
}
?>
<ul class="sidebar-menu" data-widget="tree">
<li class="header">MAIN NAVIGATION</li>
<li class="header text-uppercase">Main navigation</li>
<!-- Home Page -->
<li<?php if($scriptname === "index.php"){ ?> class="active"<?php } ?>>
<a href="index.php">
@@ -451,25 +421,25 @@ if($auth) {
</li>
<li class="treeview<?php if($scriptname === "db_queries.php" || $scriptname === "db_lists.php" || $scriptname === "db_graph.php"){ ?> active<?php } ?>">
<a href="#">
<i class="fa fa-clock"></i> <span>Long-term data</span>
<span class="pull-right-container">
<i class="fa fa-angle-down pull-right" style="padding-right: 5px;"></i>
<i class="fa fa-angle-left pull-right"></i>
</span>
<i class="fa fa-clock"></i> <span>Long term data</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "db_graph.php"){ ?> class="active"<?php } ?>>
<a href="db_graph.php">
<i class="fa fa-file-alt"></i> <span>Graphics</span>
<i class="fa fa-file-alt"></i> Graphics
</a>
</li>
<li<?php if($scriptname === "db_queries.php"){ ?> class="active"<?php } ?>>
<a href="db_queries.php">
<i class="fa fa-file-alt"></i> <span>Query Log</span>
<i class="fa fa-file-alt"></i> Query Log
</a>
</li>
<li<?php if($scriptname === "db_lists.php"){ ?> class="active"<?php } ?>>
<a href="db_lists.php">
<i class="fa fa-file-alt"></i> <span>Top Lists</span>
<i class="fa fa-file-alt"></i> Top Lists
</a>
</li>
</ul>
@@ -486,64 +456,70 @@ if($auth) {
<i class="fa fa-ban"></i> <span>Blacklist</span>
</a>
</li>
<!-- Local DNS Records -->
<li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>>
<a href="dns_records.php">
<i class="fa fa-address-book"></i> <span>Local DNS Records</span>
</a>
</li>
<!-- Group Management -->
<li class="treeview <?php if(in_array($scriptname, array("groups.php", "groups-clients.php", "groups-domains.php", "groups-adlists.php"))){ ?>active<?php } ?>">
<li class="treeview<?php if (in_array($scriptname, array("groups.php", "groups-adlists.php", "groups-clients.php", "groups-domains.php"))){ ?> active<?php } ?>">
<a href="#">
<span class="pull-right-container">
<i class="fa fa-angle-down pull-right" style="padding-right: 5px;"></i>
</span>
<i class="fa fa-users-cog"></i> <span>Group Management</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li<?php if($scriptname === "groups.php"){ ?> class="active"<?php } ?>>
<a href="groups.php">
<i class="fa fa-user-friends"></i> <span>Groups</span>
<i class="fa fa-user-friends"></i> Groups
</a>
</li>
<li<?php if($scriptname === "groups-clients.php"){ ?> class="active"<?php } ?>>
<a href="groups-clients.php">
<i class="fa fa-laptop"></i> <span>Clients</span>
<i class="fa fa-laptop"></i> Clients
</a>
</li>
<li<?php if($scriptname === "groups-domains.php"){ ?> class="active"<?php } ?>>
<a href="groups-domains.php">
<i class="fa fa-list"></i> <span>Domains</span>
<i class="fa fa-list"></i> Domains
</a>
</li>
<li<?php if($scriptname === "groups-adlists.php"){ ?> class="active"<?php } ?>>
<a href="groups-adlists.php">
<i class="fa fa-shield-alt"></i> <span>Adlists</span>
<i class="fa fa-shield-alt"></i> Adlists
</a>
</li>
</ul>
</li>
<!-- Toggle -->
<li id="pihole-disable" class="treeview"<?php if ($pistatus == "0") { ?> hidden="true"<?php } ?>>
<li id="pihole-disable" class="treeview"<?php if ($pistatus == "0") { ?> hidden<?php } ?>>
<a href="#">
<span class="pull-right-container">
<i class="fa fa-angle-down pull-right" style="padding-right: 5px;"></i>
<i class="fa fa-angle-left pull-right"></i>
</span>
<i class="fa fa-stop"></i> <span>Disable&nbsp;&nbsp;&nbsp;<span id="flip-status-disable"></span></span>
</a>
<ul class="treeview-menu">
<li>
<a href="#" id="pihole-disable-permanently">
<i class="fa fa-stop"></i> <span>Permanently</span>
<a href="#" id="pihole-disable-indefinitely">
<i class="fa fa-stop"></i> Indefinitely
</a>
</li>
<li>
<a href="#" id="pihole-disable-10s">
<i class="fa fa-clock"></i> <span>For 10 seconds</span>
<i class="fa fa-clock"></i> For 10 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-30s">
<i class="fa fa-clock"></i> <span>For 30 seconds</span>
<i class="fa fa-clock"></i> For 30 seconds
</a>
</li>
<li>
<a href="#" id="pihole-disable-5m">
<i class="fa fas fa-clock"></i> <span>For 5 minutes</span>
<i class="fa fas fa-clock"></i> For 5 minutes
</a>
</li>
<li>
@@ -554,74 +530,79 @@ if($auth) {
</ul>
<!-- <a href="#" id="flip-status"><i class="fa fa-stop"></i> <span>Disable</span></a> -->
</li>
<li id="pihole-enable" class="treeview"<?php if ($pistatus == "1") { ?> hidden="true"<?php } ?>>
<a href="#"><i class="fa fa-play"></i> <span id="enableLabel">Enable&nbsp;&nbsp;&nbsp;<span id="flip-status-enable"></span></span></a>
<li id="pihole-enable" class="treeview"<?php if ($pistatus == "1") { ?> hidden<?php } ?>>
<a href="#">
<i class="fa fa-play"></i>
<span id="enableLabel">Enable&nbsp;&nbsp;&nbsp;
<span id="flip-status-enable"></span>
</span>
</a>
</li>
<!-- Tools -->
<li class="treeview <?php if(in_array($scriptname, array("gravity.php", "queryads.php", "auditlog.php", "taillog.php", "taillog-FTL.php", "debug.php"))){ ?>active<?php } ?>">
<li class="treeview<?php if (in_array($scriptname, array("messages.php", "gravity.php", "queryads.php", "auditlog.php", "taillog.php", "taillog-FTL.php", "debug.php", "network.php"))){ ?> active<?php } ?>">
<a href="#">
<span class="pull-right-container">
<i class="fa fa-angle-down pull-right" style="padding-right: 5px;"></i>
</span>
<i class="fa fa-folder"></i> <span>Tools</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<!-- Pi-hole diagnosis -->
<li<?php if($scriptname === "messages.php"){ ?> class="active"<?php } ?>>
<a href="messages.php">
<i class="fa fa-stethoscope"></i> Pi-hole diagnosis
</a>
</li>
<!-- Run gravity.sh -->
<li<?php if($scriptname === "gravity.php"){ ?> class="active"<?php } ?>>
<a href="gravity.php">
<i class="fa fa-arrow-circle-down"></i> <span>Update Gravity</span>
<i class="fa fa-arrow-circle-down"></i> Update Gravity
</a>
</li>
<!-- Query Lists -->
<li<?php if($scriptname === "queryads.php"){ ?> class="active"<?php } ?>>
<a href="queryads.php">
<i class="fa fa-search"></i> <span>Query Lists</span>
<i class="fa fa-search"></i> Query Lists
</a>
</li>
<!-- Audit log -->
<li<?php if($scriptname === "auditlog.php"){ ?> class="active"<?php } ?>>
<a href="auditlog.php">
<i class="fa fa-balance-scale"></i> <span>Audit log</span>
<i class="fa fa-balance-scale"></i> Audit log
</a>
</li>
<!-- Tail pihole.log -->
<li<?php if($scriptname === "taillog.php"){ ?> class="active"<?php } ?>>
<a href="taillog.php">
<i class="fa fa-list-ul"></i> <span>Tail pihole.log</span>
<i class="fa fa-list-ul"></i> Tail pihole.log
</a>
</li>
<!-- Tail pihole-FTL.log -->
<li<?php if($scriptname === "taillog-FTL.php"){ ?> class="active"<?php } ?>>
<a href="taillog-FTL.php">
<i class="fa fa-list-ul"></i> <span>Tail pihole-FTL.log</span>
<i class="fa fa-list-ul"></i> Tail pihole-FTL.log
</a>
</li>
<!-- Generate debug log -->
<li<?php if($scriptname === "debug.php"){ ?> class="active"<?php } ?>>
<a href="debug.php">
<i class="fa fa-ambulance"></i> <span>Generate debug log</span>
<i class="fa fa-ambulance"></i> Generate debug log
</a>
</li>
<!-- Network -->
<li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>>
<a href="network.php">
<i class="fa fa-network-wired"></i> Network
</a>
</li>
</ul>
</li>
<!-- Network -->
<li<?php if($scriptname === "network.php"){ ?> class="active"<?php } ?>>
<a href="network.php">
<i class="fa fa-network-wired"></i> <span>Network</span>
</a>
</li>
<!-- Settings -->
<li<?php if($scriptname === "settings.php"){ ?> class="active"<?php } ?>>
<a href="settings.php">
<i class="fa fa-cogs"></i> <span>Settings</span>
</a>
</li>
<!-- Local DNS Records -->
<li<?php if($scriptname === "dns_records.php"){ ?> class="active"<?php } ?>>
<a href="dns_records.php">
<i class="fa fa-address-book"></i> <span>Local DNS Records</span>
</a>
</li>
<!-- Logout -->
<?php
// Show Logout button if $auth is set and authorization is required
@@ -639,24 +620,22 @@ if($auth) {
if(strlen($pwhash) > 0 && !$auth) { ?>
<li<?php if($scriptname === "login"){ ?> class="active"<?php } ?>>
<a href="index.php?login">
<i class="fa far fa-user"></i> <span>Login</span>
<i class="fa fa-user"></i> <span>Login</span>
</a>
</li>
<?php } ?>
<!-- Donate -->
<li>
<a href="https://pi-hole.net/donate/" rel="noopener" target="_blank">
<i class="fa-paypal-icon fab fa-paypal"></i> <span>Donate</span>
<i class="fab fa-paypal"></i> <span>Donate</span>
</a>
</li>
<?php if($auth){ ?>
<!-- Help -->
<li<?php if($scriptname === "help.php"){ ?> class="active"<?php } ?>>
<a href="help.php">
<i class="fa fa-question-circle"></i> <span>Help</span>
<!-- Docs -->
<li>
<a href="https://docs.pi-hole.net/" rel="noopener" target="_blank">
<i class="fa fa-question-circle"></i> <span>Documentation</span>
</a>
</li>
<?php } ?>
</ul>
</section>
<!-- /.sidebar -->
+5 -2
View File
@@ -38,8 +38,11 @@
</ul>
</div>
<div class="col-xs-12 col-md-4">
<div class="form-group pull-left">
<div class="checkbox pull-right"><label><input type="checkbox" id="logincookie" name="persistentlogin">Remember me for 7 days</label></div>
<div class="pull-right">
<div>
<input type="checkbox" id="logincookie" name="persistentlogin">
<label for="logincookie">Remember me for 7 days</label>
</div>
</div>
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-sign-in-alt"></i>&nbsp;&nbsp;&nbsp;Log in</button>
</div>
+2 -2
View File
@@ -28,7 +28,7 @@
if(isset($_GET["logout"]))
{
session_unset();
setcookie('persistentlogin', '');
setcookie('persistentlogin', '', 1);
header('Location: index.php');
exit();
}
@@ -52,7 +52,7 @@
{
// Invalid cookie
$auth = false;
setcookie('persistentlogin', '');
setcookie('persistentlogin', '', 1);
}
}
// Compare doubly hashes password input with saved hash
-12
View File
@@ -525,18 +525,6 @@ function addStaticDHCPLease($mac, $ip, $hostname) {
break;
case "webUI":
if($_POST["tempunit"] == "F")
{
pihole_execute('-a -f');
}
elseif($_POST["tempunit"] == "K")
{
pihole_execute('-a -k');
}
else
{
pihole_execute('-a -c');
}
$adminemail = trim($_POST["adminemail"]);
if(strlen($adminemail) == 0 || !isset($adminemail))
{
+2 -1
View File
@@ -540,7 +540,8 @@ if(isset($_POST["action"]))
}
else
{
$tarname = "pi-hole-teleporter_".date("Y-m-d_h-i-s").".tar";
$hostname = gethostname() ? gethostname()."-" : "";
$tarname = "pi-hole-".$hostname."teleporter_".date("Y-m-d_H-i-s").".tar";
$filename = $tarname.".gz";
$archive_file_name = sys_get_temp_dir() ."/". $tarname;
$archive = new PharData($archive_file_name);
+5 -11
View File
@@ -7,17 +7,14 @@
* Please see LICENSE file for your rights under this license. */
// Array of available themes and their description
$available_themes = [];
$available_themes = array();
/* Array key = name used internally, not shown to the user
* Array[0] = Description
* Array[1] = Is this a dark mode theme? (Sets background to black during page reloading to avoid white "flashing")
* Array[2] = Style sheet name
* Array[3] = Radio/checkbox theme name
* Array[4] = Radio/checkbox theme variant
*/
$available_themes["default-light"] = ["Pi-hole default theme (light, default)", false, "default-light", "minimal", "blue"];
$available_themes["default-dark"] = ["Pi-hole midnight theme (dark)", true, "default-dark", "polaris", "polaris"];
$available_themes["default-dark2"] = ["Pi-hole afternoon theme (dark)", true, "default-dark", "futurico", "futurico"];
$available_themes["default-light"] = array("Pi-hole default theme (light, default)", false, "default-light");
$available_themes["default-dark"] = array("Pi-hole midnight theme (dark)", true, "default-dark");
$webtheme = "";
// Try to load theme settings from setupVars.conf
@@ -39,15 +36,12 @@ if(!array_key_exists($webtheme,$available_themes)) {
$darkmode = $available_themes[$webtheme][1];
$theme = $available_themes[$webtheme][2];
$checkbox_theme_name = $available_themes[$webtheme][3];
$checkbox_theme_variant = $available_themes[$webtheme][4];
error_log(print_r($available_themes,true));
function theme_selection() {
global $available_themes, $webtheme;
foreach ($available_themes as $key => $value) {
?><input type="radio" name="webtheme" value="<?php echo $key; ?>" id="webtheme_<?php echo $key; ?>" <?php if ($key === $webtheme){ ?>checked<?php } ?>>
<label for="webtheme_<?php echo $key; ?>"><?php echo $value[0]; ?></label><br><?php
?><div><input type="radio" name="webtheme" value="<?php echo $key; ?>" id="webtheme_<?php echo $key; ?>" <?php if ($key === $webtheme){ ?>checked<?php } ?>>
<label for="webtheme_<?php echo $key; ?>"><strong><?php echo $value[0]; ?></strong></label></div><?php
}
}
?>
+5 -8
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bootstrap-toggle.min.js","sources":["bootstrap-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","outerHeight","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,SAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,SACV,SAAtBjB,KAAKI,QAAQa,KAAkB,SAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUa,aAAcV,EAAWU,cAAeT,EAAcS,aAAa,EACpHlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUc,cAAeX,EAAWW,cACjFd,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQQ,KAAMrB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUe,IAAI,cAAef,EAAUL,SAAW,MAClDQ,EAAWY,IAAI,cAAeZ,EAAWR,SAAW,OAErDpB,KAAKyC,QAAO,GACZzC,KAAK0C,SAAQ,IAGdrC,EAAOgB,UAAUsB,OAAS,WACrB3C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU+B,GAC/B,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUP,IAAM,SAAU8B,GAChC,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUyB,OAAS,WACzB9C,KAAKgC,QAAQe,WAAW,YACxB/C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU2B,QAAU,WAC1BhD,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUoB,OAAS,SAAUG,GAC/B5C,KAAKO,SAAS0B,KAAK,YAAajC,KAAKgD,UACpChD,KAAK8C,SACN9C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG+B,GACtC5C,KAAKc,IAAI8B,IAGfvC,EAAOgB,UAAUqB,QAAU,SAAUE,GACpC5C,KAAKO,SAASO,IAAI,oBACb8B,GAAQ5C,KAAKO,SAAS0C,SAC3BjD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEqD,MAAM,WAC5ClD,KAAKyC,UACHzC,QAGJK,EAAOgB,UAAU8B,QAAU,WAC1BnD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAasB,SAClBpD,KAAKO,SAAS8C,WAAW,aACzBrD,KAAKO,SAAS+C,SAiBf,IAAIC,GAAM1D,EAAE2D,GAAGC,eAEf5D,GAAE2D,GAAGC,gBAA8B3D,EACnCD,EAAE2D,GAAGC,gBAAgBC,YAAcrD,EAKnCR,EAAE2D,GAAGb,OAAOgB,WAAa,WAExB,MADA9D,GAAE2D,GAAGC,gBAAkBF,EAChBvD,MAMRH,EAAE,WACDA,EAAE,6CAA6C4D,oBAGhD5D,EAAE+D,UAAU/C,GAAG,kBAAmB,2BAA4B,SAASgD,GACtE,GAAIC,GAAYjE,EAAEG,MAAM+D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}
-8
View File
@@ -1,8 +0,0 @@
/*!
DataTables Bootstrap 3 integration
©2011-2015 SpryMedia Ltd - datatables.net/license
*/
(function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes,
{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,m,j,n){var o=new f.Api(a),s=a.oClasses,k=a.oLanguage.oPaginate,t=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};
l=0;for(h=f.length;l<h;l++)if(c=f[l],b.isArray(c))q(d,c);else{g=e="";switch(c){case "ellipsis":e="&#x2026;";g="disabled";break;case "first":e=k.sFirst;g=c+(0<j?"":" disabled");break;case "previous":e=k.sPrevious;g=c+(0<j?"":" disabled");break;case "next":e=k.sNext;g=c+(j<n-1?"":" disabled");break;case "last":e=k.sLast;g=c+(j<n-1?"":" disabled");break;default:e=c+1,g=j===c?"active":""}e&&(i=b("<li>",{"class":s.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("<a>",{href:"#",
"aria-controls":a.sTableId,"aria-label":t[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(u){}q(b(h).empty().html('<ul class="pagination"/>').children("ul"),m);i&&b(h).find("[data-dt-idx="+i+"]").focus()};return f});
+208
View File
@@ -0,0 +1,208 @@
/*
* This combined file was created by the DataTables downloader builder:
* https://datatables.net/download
*
* To rebuild or modify this file with the latest versions of the included
* software please visit:
* https://datatables.net/download/#bs/dt-1.10.21
*
* Included libraries:
* DataTables 1.10.21
*/
/*!
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:{},build:"bs/dt-1.10.21",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});
/*!
DataTables Bootstrap 3 integration
©2011-2015 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 k=a[d];if(b.call(c,k,d,a))return{i:d,v:k}}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(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};$jscomp.getGlobal=function(a){a=["object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global,a];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.polyfill=function(a,b,c,e){if(b){c=$jscomp.global;a=a.split(".");for(e=0;e<a.length-1;e++){var d=a[e];d in c||(c[d]={});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.polyfill("Array.prototype.find",function(a){return a?a:function(a,c){return $jscomp.findInternal(this,a,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-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});a.extend(d.ext.classes,
{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});d.ext.renderer.pageButton.bootstrap=function(b,l,v,w,m,r){var k=new d.Api(b),x=b.oClasses,n=b.oLanguage.oPaginate,y=b.oLanguage.oAria.paginate||{},g,h,t=0,u=function(c,d){var e,l=function(b){b.preventDefault();a(b.currentTarget).hasClass("disabled")||k.page()==b.data.action||k.page(b.data.action).draw("page")};
var q=0;for(e=d.length;q<e;q++){var f=d[q];if(a.isArray(f))u(c,f);else{h=g="";switch(f){case "ellipsis":g="&#x2026;";h="disabled";break;case "first":g=n.sFirst;h=f+(0<m?"":" disabled");break;case "previous":g=n.sPrevious;h=f+(0<m?"":" disabled");break;case "next":g=n.sNext;h=f+(m<r-1?"":" disabled");break;case "last":g=n.sLast;h=f+(m<r-1?"":" disabled");break;default:g=f+1,h=m===f?"active":""}if(g){var p=a("<li>",{"class":x.sPageButton+" "+h,id:0===v&&"string"===typeof f?b.sTableId+"_"+f:null}).append(a("<a>",
{href:"#","aria-controls":b.sTableId,"aria-label":y[f],"data-dt-idx":t,tabindex:b.iTabIndex}).html(g)).appendTo(c);b.oApi._fnBindAction(p,{action:f},l);t++}}}};try{var p=a(l).find(c.activeElement).data("dt-idx")}catch(z){}u(a(l).empty().html('<ul class="pagination"/>').children("ul"),w);p!==e&&a(l).find("[data-dt-idx="+p+"]").trigger("focus")};return d});
-1565
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-13
View File
File diff suppressed because one or more lines are too long
-180
View File
@@ -1,180 +0,0 @@
/*!
Copyright 2008-2019 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.20
©2008-2019 SpryMedia Ltd - datatables.net/license
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(f,z,y){f instanceof String&&(f=String(f));for(var p=f.length,H=0;H<p;H++){var L=f[H];if(z.call(y,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,z,y){f!=Array.prototype&&f!=Object.prototype&&(f[z]=y.value)};$jscomp.getGlobal=function(f){return"undefined"!=typeof window&&window===f?f:"undefined"!=typeof global&&null!=global?global:f};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(f,z,y,p){if(z){y=$jscomp.global;f=f.split(".");for(p=0;p<f.length-1;p++){var H=f[p];H in y||(y[H]={});y=y[H]}f=f[f.length-1];p=y[f];z=z(p);z!=p&&null!=z&&$jscomp.defineProperty(y,f,{configurable:!0,writable:!0,value:z})}};$jscomp.polyfill("Array.prototype.find",function(f){return f?f:function(f,y){return $jscomp.findInternal(this,f,y).v}},"es6","es3");
(function(f){"function"===typeof define&&define.amd?define(["jquery"],function(z){return f(z,window,document)}):"object"===typeof exports?module.exports=function(z,y){z||(z=window);y||(y="undefined"!==typeof window?require("jquery"):require("jquery")(z));return f(y,z,z.document)}:f(jQuery,window,document)})(function(f,z,y,p){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===p||!c&&b[d]!==p||("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 Ga(a){var b=q.defaults.oLanguage,c=b.sDecimal;c&&Ha(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&&Ha(a)}}function jb(a){F(a,"ordering","bSort");F(a,"orderMulti","bSortMulti");F(a,"orderClasses","bSortClasses");F(a,"orderCellsTop","bSortCellsTop");F(a,"order","aaSorting");F(a,"orderFixed","aaSortingFixed");F(a,"paging","bPaginate");F(a,"pagingType","sPaginationType");F(a,"pageLength","iDisplayLength");F(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 kb(a){F(a,"orderable","bSortable");F(a,"orderData","aDataSort");F(a,"orderSequence","asSorting");F(a,"orderDataType","sortDataType");var b=a.aDataSort;"number"!==typeof b||f.isArray(b)||(a.aDataSort=[b])}function lb(a){if(!q.__browser){var b={};q.__browser=b;var c=f("<div/>").css({position:"fixed",top:0,left:-1*f(z).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 mb(a,b,c,d,e,h){var g=!1;if(c!==p){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 Ia(a,b){var c=q.defaults.column,d=a.aoColumns.length;c=f.extend({},q.models.oColumn,c,{nTh:b?b:y.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]);ma(a,d,f(b).data())}function ma(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!==p&&null!==c&&(kb(c),L(q.defaults.column,c,!0),c.mDataProp===p||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!==p&&(b.aDataSort=[c.iDataSort]),M(b,c,"aDataSort"));var g=b.mData,k=U(g),
l=b.mRender?U(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,p,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 aa(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ja(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||na(a);A(a,null,"column-sizing",[a])}function ba(a,b){a=oa(a,"bVisible");return"number"===
typeof a[b]?a[b]:null}function ca(a,b){a=oa(a,"bVisible");b=f.inArray(b,a);return-1!==b?b:null}function W(a){var b=0;f.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==f(d.nTh).css("display")&&b++});return b}function oa(a,b){var c=[];f.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ka(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 n=[];if(!f.sType&&f._sManualType)f.sType=f._sManualType;else if(!f.sType){var m=0;for(h=
d.length;m<h;m++){var w=0;for(g=c.length;w<g;w++){n[w]===p&&(n[w]=I(a,w,k,"type"));var u=d[m](n[w],a);if(!u&&m!==d.length-1)break;if("html"===u)break}if(u){f.sType=u;break}}f.sType||(f.sType="string")}}}function nb(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 n=l.targets!==p?l.targets:l.aTargets;f.isArray(n)||(n=[n]);var m=0;for(h=n.length;m<h;m++)if("number"===typeof n[m]&&0<=n[m]){for(;k.length<=n[m];)Ia(a);d(n[m],l)}else if("number"===typeof n[m]&&0>n[m])d(k.length+
n[m],l);else if("string"===typeof n[m]){var w=0;for(g=k.length;w<g;w++)("_all"==n[m]||f(k[w].nTh).hasClass(n[m]))&&d(w,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!==p&&(a.aIds[b]=h);!c&&a.oFeatures.bDeferRender||La(a,e,c,d);return e}function pa(a,b){var c;b instanceof
f||(b=f(b));return b.map(function(b,e){c=Ma(a,e);return R(a,c.data,e,c.cells)})}function I(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===p)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!==p)f=k;else if("function"===typeof f)return f.call(g);return null===
f&&"display"==d?"":f}function ob(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}function Na(a){return f.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function U(a){if(f.isPlainObject(a)){var b={};f.each(a,function(a,c){c&&(b[a]=U(c))});return function(a,c,h,g){var d=b[c]||b._;return d!==p?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=Na(h);for(var e=0,l=d.length;e<l;e++){h=d[e].match(da);var n=d[e].match(X);if(h){d[e]=d[e].replace(da,"");""!==d[e]&&(a=a[d[e]]);n=[];d.splice(0,e+1);d=d.join(".");if(f.isArray(a))for(e=0,l=a.length;e<l;e++)n.push(c(a[e],b,d));a=h[0].substring(1,h[0].length-1);a=""===a?n:n.join(a);break}else if(n){d[e]=d[e].replace(X,"");a=a[d[e]]();continue}if(null===a||a[d[e]]===
p)return p;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=Na(e);var c=e[e.length-1];for(var g,k,l=0,n=e.length-1;l<n;l++){g=e[l].match(da);k=e[l].match(X);if(g){e[l]=e[l].replace(da,"");a[e[l]]=[];c=e.slice();
c.splice(0,l+1);g=c.join(".");if(f.isArray(d))for(k=0,n=d.length;k<n;k++)c={},b(c,d[k],g),a[e[l]].push(c);else a[e[l]]=d;return}k&&(e[l]=e[l].replace(X,""),a=a[e[l]](d));if(null===a[e[l]]||a[e[l]]===p)a[e[l]]={};a=a[e[l]]}if(c.match(X))a[c.replace(X,"")](d);else a[c.replace(da,"")]=d};return function(c,d){return b(c,d,a)}}function Oa(a){return J(a.aoData,"_aData")}function qa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function ra(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===p&&a.splice(d,1)}function ea(a,b,c,d){var e=a.aoData[b],h,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=I(a,b,d,"display")};if("dom"!==c&&(c&&"auto"!==c||"dom"!==e.src)){var k=e.anCells;if(k)if(d!==p)g(k[d],d);else for(c=0,h=k.length;c<h;c++)g(k[c],c)}else e._aData=Ma(a,e,d,d===p?p:e._aData).data;e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==p)g[d].sType=null;else{c=0;for(h=g.length;c<h;c++)g[c].sType=null;
Pa(a,e)}}function Ma(a,b,c,d){var e=[],h=b.firstChild,g,k=0,l,n=a.aoColumns,m=a._rowReadObject;d=d!==p?d:m?{}:[];var w=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===p||c===k)g=n[k],l=f.trim(a.innerHTML),g&&g._bAttrSrc?(Q(g.mData._)(d,l),w(g.mData.sort,a),w(g.mData.type,a),w(g.mData.filter,a)):m?(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 La(a,b,c,d){var e=a.aoData[b],h=e._aData,g=[],k,l;if(null===e.nTr){var n=c||y.createElement("tr");e.nTr=n;e.anCells=g;n._DT_RowIndex=b;Pa(a,e);var m=0;for(k=a.aoColumns.length;m<k;m++){var w=a.aoColumns[m];var p=(l=c?!1:!0)?y.createElement(w.sCellType):d[m];p._DT_CellIndex={row:b,column:m};g.push(p);if(l||
!(c&&!w.mRender&&w.mData===m||f.isPlainObject(w.mData)&&w.mData._===m+".display"))p.innerHTML=I(a,b,m,"display");w.sClass&&(p.className+=" "+w.sClass);w.bVisible&&!c?n.appendChild(p):!w.bVisible&&c&&p.parentNode.removeChild(p);w.fnCreatedCell&&w.fnCreatedCell.call(a.oInstance,p,I(a,b,m),h,b,m)}A(a,"aoRowCreatedCallback",null,[n,h,b,g])}e.nTr.setAttribute("role","row")}function Pa(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?
ta(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 pb(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 n=k[l];var m=f(n.nTh).addClass(n.sClass);h&&m.appendTo(c);a.oFeatures.bSort&&(m.addClass(n.sSortingClass),!1!==n.bSortable&&(m.attr("tabindex",a.iTabIndex).attr("aria-controls",
a.sTableId),Qa(a,n.nTh,l)));n.sTitle!=m[0].innerHTML&&m.html(n.sTitle);Ra(a,"header")(a,m,n,g)}h&&fa(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++)n=k[l],n.nTf=a[l].cell,n.sClass&&f(n.nTf).addClass(n.sClass)}function ha(a,b,c){var d,e,h=[],g=[],k=a.aoColumns.length;if(b){c===p&&(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 n=k=1;if(g[l][e]===p){a.appendChild(h[l][e].cell);for(g[l][e]=1;h[l+k]!==p&&h[l][e].cell==h[l+k][e].cell;)g[l+k][e]=1,k++;for(;h[l][e+n]!==p&&h[l][e].cell==h[l][e+n].cell;){for(c=0;c<k;c++)g[l+c][e+n]=1;n++}f(h[l][e].cell).attr("rowspan",k).attr("colspan",n)}}}}}function S(a){var b=A(a,"aoPreDrawCallback",
"preDraw",[a]);if(-1!==f.inArray(!1,b))K(a,!1);else{b=[];var c=0,d=a.asStripeClasses,e=d.length,h=a.oLanguage,g=a.iInitDisplayStart,k="ssp"==D(a),l=a.aiDisplay;a.bDrawing=!0;g!==p&&-1!==g&&(a._iDisplayStart=k?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);g=a._iDisplayStart;var n=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,K(a,!1);else if(!k)a.iDraw++;else if(!a.bDestroying&&!qb(a))return;if(0!==l.length)for(h=k?a.aoData.length:n,k=k?0:g;k<h;k++){var m=l[k],w=a.aoData[m];
null===w.nTr&&La(a,m);var u=w.nTr;if(0!==e){var q=d[c%e];w._sRowStripe!=q&&(f(u).removeClass(w._sRowStripe).addClass(q),w._sRowStripe=q)}A(a,"aoRowCallback",null,[u,w._aData,c,k,m]);b.push(u);c++}else c=h.sZeroRecords,1==a.iDraw&&"ajax"==D(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:W(a),"class":a.oClasses.sRowEmpty}).html(c))[0];A(a,"aoHeaderCallback","header",[f(a.nTHead).children("tr")[0],
Oa(a),g,n,l]);A(a,"aoFooterCallback","footer",[f(a.nTFoot).children("tr")[0],Oa(a),g,n,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 V(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&rb(a);d?ia(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;S(a);a._drawHold=!1}function sb(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,n,m,p,u=0;u<h.length;u++){g=null;k=h[u];if("<"==k){l=f("<div/>")[0];n=h[u+1];if("'"==n||'"'==n){m="";for(p=2;h[u+p]!=n;)m+=h[u+p],p++;"H"==m?m=b.sJUIHeader:"F"==m&&(m=b.sJUIFooter);-1!=m.indexOf(".")?(n=m.split("."),l.id=n[0].substr(1,n[0].length-1),l.className=n[1]):"#"==m.charAt(0)?l.id=m.substr(1,
m.length-1):l.className=m;u+=p}e.append(l);e=f(l)}else if(">"==k)e=e.parent();else if("l"==k&&d.bPaginate&&d.bLengthChange)g=tb(a);else if("f"==k&&d.bFilter)g=ub(a);else if("r"==k&&d.bProcessing)g=vb(a);else if("t"==k)g=wb(a);else if("i"==k&&d.bInfo)g=xb(a);else if("p"==k&&d.bPaginate)g=yb(a);else if(0!==q.ext.feature.length)for(l=q.ext.feature,p=0,n=l.length;p<n;p++)if(k==l[p].cFeature){g=l[p].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 fa(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 n=0;for(d=a[h];d[n];)n++;var m=n;var p=1===k?!0:!1;for(d=0;d<k;d++)for(n=0;n<l;n++)a[h+n][m+d]={cell:c,unique:p},a[h+n].nTr=g}c=c.nextSibling}}}
function ua(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],fa(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 va(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 n="function"===typeof l?l(b,a):l;b="function"===typeof l&&n?n:f.extend(!0,b,n);delete h.data}n={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));K(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(n,{url:h||a.sAjaxSource})):"function"===typeof h?a.jqXHR=h.call(g,b,k,a):(a.jqXHR=f.ajax(f.extend(n,h)),h.data=l)}function qb(a){return a.bAjaxDataGet?(a.iDraw++,K(a,!0),va(a,zb(a),function(b){Ab(a,b)}),!1):!0}function zb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,h=a.aoPreSearchCols,g=[],k=Y(a);var l=a._iDisplayStart;var n=!1!==d.bPaginate?a._iDisplayLength:
-1;var m=function(a,b){g.push({name:a,value:b})};m("sEcho",a.iDraw);m("iColumns",c);m("sColumns",J(b,"sName").join(","));m("iDisplayStart",l);m("iDisplayLength",n);var p={draw:a.iDraw,columns:[],order:[],start:l,length:n,search:{value:e.sSearch,regex:e.bRegex}};for(l=0;l<c;l++){var u=b[l];var sa=h[l];n="function"==typeof u.mData?"function":u.mData;p.columns.push({data:n,name:u.sName,searchable:u.bSearchable,orderable:u.bSortable,search:{value:sa.sSearch,regex:sa.bRegex}});m("mDataProp_"+l,n);d.bFilter&&
(m("sSearch_"+l,sa.sSearch),m("bRegex_"+l,sa.bRegex),m("bSearchable_"+l,u.bSearchable));d.bSort&&m("bSortable_"+l,u.bSortable)}d.bFilter&&(m("sSearch",e.sSearch),m("bRegex",e.bRegex));d.bSort&&(f.each(k,function(a,b){p.order.push({column:b.col,dir:b.dir});m("iSortCol_"+a,b.col);m("sSortDir_"+a,b.dir)}),m("iSortingCols",k.length));b=q.ext.legacy.ajax;return null===b?a.sAjaxSource?g:p:b?g:p}function Ab(a,b){var c=function(a,c){return b[a]!==p?b[a]:b[c]},d=wa(a,b),e=c("sEcho","draw"),h=c("iTotalRecords",
"recordsTotal");c=c("iTotalDisplayRecords","recordsFiltered");if(e){if(1*e<a.iDraw)return;a.iDraw=1*e}qa(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||xa(a,b);a.bAjaxDataGet=!0;K(a,!1)}function wa(a,b){a=f.isPlainObject(a.ajax)&&a.ajax.dataSrc!==p?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===a?b.aaData||b[a]:""!==a?U(a)(b):b}function ub(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));h=function(){var b=this.value?this.value:"";b!=e.sSearch&&(ia(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,S(a))};g=null!==a.searchDelay?a.searchDelay:"ssp"===D(a)?400:0;var l=f("input",
b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",g?Sa(h,g):h).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{l[0]!==y.activeElement&&l.val(e.sSearch)}catch(w){}});return b[0]}function ia(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!==
p?!a.bEscapeRegex:a.bRegex};Ka(a);if("ssp"!=D(a)){Bb(a,b.sSearch,c,g(b),b.bSmart,b.bCaseInsensitive);h(b);for(b=0;b<e.length;b++)Cb(a,e[b].sSearch,b,g(e[b]),e[b].bSmart,e[b].bCaseInsensitive);Db(a)}else h(b);a.bFiltered=!0;A(a,null,"search",[a])}function Db(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,n=c.length;l<n;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 Cb(a,b,c,d,e,h){if(""!==b){var g=[],k=
a.aiDisplay;d=Ta(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 Bb(a,b,c,d,e,h){e=Ta(b,d,e,h);var g=a.oPreviousSearch.sSearch,k=a.aiDisplayMaster;h=[];0!==q.ext.search.length&&(c=!0);var f=Eb(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 Ta(a,b,
c,d){a=b?a:Ua(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 Eb(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 n=0;for(d=b.length;n<d;n++){h=b[n];if(h.bSearchable){var m=I(a,g,n,"filter");e[h.sType]&&(m=e[h.sType](m));null===m&&(m="");
"string"!==typeof m&&m.toString&&(m=m.toString())}else m="";m.indexOf&&-1!==m.indexOf("&")&&(ya.innerHTML=m,m=$b?ya.textContent:ya.innerText);m.replace&&(m=m.replace(/[\r\n\u2028]/g,""));f.push(m)}k._aFilterData=f;k._sFilterRow=f.join(" ");h=!0}}return h}function Fb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}function Gb(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function xb(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:Hb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),f(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Hb(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=Ib(a,k);c=c.fnInfoCallback;null!==c&&(k=c.call(a.oInstance,
a,d,e,h,g,k));f(b).html(k)}}function Ib(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 ja(a){var b=a.iInitDisplayStart,c=a.aoColumns;var d=a.oFeatures;var e=a.bDeferLoading;if(a.bInitialised){sb(a);
pb(a);ha(a,a.aoHeader);ha(a,a.aoFooter);K(a,!0);d.bAutoWidth&&Ja(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]);V(a);c=D(a);if("ssp"!=c||e)"ajax"==c?va(a,[],function(c){var d=wa(a,c);for(h=0;h<d.length;h++)R(a,d[h]);a.iInitDisplayStart=b;V(a);K(a,!1);xa(a,c)},a):(K(a,!1),xa(a))}else setTimeout(function(){ja(a)},200)}function xa(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&aa(a);A(a,null,"plugin-init",[a,b]);A(a,"aoInitComplete","init",
[a,b])}function Va(a,b){b=parseInt(b,10);a._iDisplayLength=b;Wa(a);A(a,null,"length",[a,b])}function tb(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){Va(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 yb(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(),m=-1===g;b=m?0:Math.ceil(b/g);g=m?1:Math.ceil(f/g);f=c(b,g);var p;m=0;for(p=h.p.length;m<p;m++)Ra(a,"pageButton")(a,h.p[m],m,f,b,g)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Xa(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 vb(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 K(a,b){a.oFeatures.bProcessing&&f(a.aanFeatures.r).css("display",b?"block":"none");A(a,null,"processing",[a,b])}function wb(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)),n=f(b[0].cloneNode(!1)),m=b.children("tfoot");m.length||(m=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));m&&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(n.removeAttr("id").css("margin-left",0).append("bottom"===k?g:null).append(b.children("tfoot")))));b=l.children();var p=b[0];h=b[1];var u=m?b[2]:null;if(d)f(h).on("scroll.DT",function(a){a=this.scrollLeft;p.scrollLeft=a;m&&(u.scrollLeft=a)});
f(h).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=p;a.nScrollBody=h;a.nScrollFoot=u;a.aoDrawCallback.push({fn:na,sName:"scrolling"});return l[0]}function na(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,n=k.children("table");k=a.nScrollBody;var m=f(k),w=k.style,u=f(a.nScrollFoot).children("div"),q=u.children("table"),t=f(a.nTHead),r=f(a.nTable),v=r[0],za=v.style,T=a.nTFoot?f(a.nTFoot):null,A=a.oBrowser,
x=A.bScrollOversize,ac=J(a.aoColumns,"nTh"),Ya=[],y=[],z=[],C=[],G,H=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!==p)a.scrollBarVis=D,aa(a);else{a.scrollBarVis=D;r.children("thead, tfoot").remove();if(T){var E=T.clone().prependTo(r);var F=T.find("tr");E=E.find("tr")}var I=t.clone().prependTo(r);t=t.find("tr");D=I.find("tr");I.find("th, td").removeAttr("tabindex");
c||(w.width="100%",h[0].style.width="100%");f.each(ua(a,I),function(b,c){G=ba(a,b);c.style.width=a.aoColumns[G].sWidth});T&&N(function(a){a.style.width=""},E);h=r.outerWidth();""===c?(za.width="100%",x&&(r.find("tbody").height()>k.offsetHeight||"scroll"==m.css("overflow-y"))&&(za.width=B(r.outerWidth()-b)),h=r.outerWidth()):""!==d&&(za.width=B(d),h=r.outerWidth());N(H,D);N(function(a){z.push(a.innerHTML);Ya.push(B(f(a).css("width")))},D);N(function(a,b){-1!==f.inArray(a,ac)&&(a.style.width=Ya[b])},
t);f(D).height(0);T&&(N(H,E),N(function(a){C.push(a.innerHTML);y.push(B(f(a).css("width")))},E),N(function(a,b){a.style.width=y[b]},F),f(E).height(0));N(function(a,b){a.innerHTML='<div class="dataTables_sizing">'+z[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=Ya[b]},D);T&&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=y[b]},E);r.outerWidth()<
h?(F=k.scrollHeight>k.offsetHeight||"scroll"==m.css("overflow-y")?h+b:h,x&&(k.scrollHeight>k.offsetHeight||"scroll"==m.css("overflow-y"))&&(za.width=B(F-b)),""!==c&&""===d||O(a,1,"Possible column misalignment",6)):F="100%";w.width=B(F);g.width=B(F);T&&(a.nScrollFoot.style.width=B(F));!e&&x&&(w.height=B(v.offsetHeight+b));c=r.outerWidth();n[0].style.width=B(c);l.width=B(c);d=r.height()>k.clientHeight||"scroll"==m.css("overflow-y");e="padding"+(A.bScrollbarLeft?"Left":"Right");l[e]=d?b+"px":"0px";T&&
(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"));m.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 Ja(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,h=d.sX,g=d.sXInner,k=c.length,l=oa(a,"bVisible"),
n=f("th",a.nTHead),m=b.getAttribute("width"),p=b.parentNode,u=!1,q,t=a.oBrowser;d=t.bScrollOversize;(q=b.style.width)&&-1!==q.indexOf("%")&&(m=q);for(q=0;q<l.length;q++){var r=c[l[q]];null!==r.sWidth&&(r.sWidth=Jb(r.sWidthOrig,p),u=!0)}if(d||!u&&!h&&!e&&k==W(a)&&k==n.length)for(q=0;q<k;q++)l=ba(a,q),null!==l&&(c[l].sWidth=B(n.eq(q).width()));else{k=f(b).clone().css("visibility","hidden").removeAttr("id");k.find("tbody tr").remove();var v=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","");n=ua(a,k.find("thead")[0]);for(q=0;q<l.length;q++)r=c[l[q]],n[q].style.width=null!==r.sWidthOrig&&""!==r.sWidthOrig?B(r.sWidthOrig):"",r.sWidthOrig&&h&&f(n[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(Kb(a,u)).clone(!1).append(r.sContentPadding).appendTo(v);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(p);h&&g?k.width(g):h?(k.css("width","auto"),k.removeAttr("width"),k.width()<p.clientWidth&&m&&k.width(p.clientWidth)):e?k.width(p.clientWidth):m&&k.width(m);for(q=e=0;q<l.length;q++)p=f(n[q]),g=p.outerWidth()-p.width(),p=t.bBounding?Math.ceil(n[q].getBoundingClientRect().width):p.outerWidth(),e+=p,c[l[q]].sWidth=B(p-g);b.style.width=B(e);r.remove()}m&&(b.style.width=B(m));!m&&!h||a._reszEvt||(b=function(){f(z).on("resize.DT-"+
a.sInstance,Sa(function(){aa(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0)}function Jb(a,b){if(!a)return 0;a=f("<div/>").css("width",B(a)).appendTo(b||y.body);b=a[0].offsetWidth;a.remove();return b}function Kb(a,b){var c=Lb(a,b);if(0>c)return null;var d=a.aoData[c];return d.nTr?d.anCells[b]:f("<td/>").html(I(a,c,b,"display"))[0]}function Lb(a,b){for(var c,d=-1,e=-1,h=0,g=a.aoData.length;h<g;h++)c=I(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 Y(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 n=c[l].sType||"string";h[a]._idx===p&&(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:n,formatter:q.ext.type.order[n+"-pre"]})}}return b}function rb(a){var b,c=[],d=q.ext.type.order,e=a.aoData,h=0,g=a.aiDisplayMaster;Ka(a);var k=Y(a);var f=0;for(b=k.length;f<b;f++){var n=k[f];n.formatter&&h++;Mb(a,n.col)}if("ssp"!=D(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 n=f[l.col];m=m<n?-1:m>n?1:0;
if(0!==m)return"asc"===l.dir?m:-m}m=c[a];n=c[b];return m<n?-1:m>n?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 n=f[m.col];var p=l[m.col];m=d[m.type+"-"+m.dir]||d["string-"+m.dir];n=m(n,p);if(0!==n)return n}n=c[a];p=c[b];return n<p?-1:n>p?1:0})}a.bSorted=!0}function Nb(a){var b=a.aoColumns,c=Y(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 Za(a,b,c,d){var e=a.aaSorting,h=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===p&&(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,J(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);V(a);"function"==typeof d&&d(a)}function Qa(a,b,c,d){var e=a.aoColumns[c];$a(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(K(a,!0),setTimeout(function(){Za(a,c,b.shiftKey,d);"ssp"!==D(a)&&K(a,!1)},0)):Za(a,c,b.shiftKey,d))})}function Aa(a){var b=a.aLastSort,
c=a.oClasses.sSortColumn,d=Y(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(J(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(J(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Mb(a,b){var c=a.aoColumns[b],d=q.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ca(a,b)));for(var h,g=q.ext.type.order[c.sType+"-pre"],k=0,f=a.aoData.length;k<f;k++)if(c=a.aoData[k],c._aSortData||(c._aSortData=
[]),!c._aSortData[b]||d)h=d?e[k]:I(a,k,b,"sort"),c._aSortData[b]=g?g(h):h}function Ba(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:Fb(a.oPreviousSearch),columns:f.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Fb(a.aoPreSearchCols[d])}})};A(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Ob(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!==p&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==p&&(a._iDisplayLength=b.length);b.order!==p&&(a.aaSorting=[],f.each(b.order,function(b,c){a.aaSorting.push(c[0]>=h.length?[0,c[1]]:c)}));b.search!==p&&f.extend(a.oPreviousSearch,
Gb(b.search));if(b.columns)for(d=0,e=b.columns.length;d<e;d++)g=b.columns[d],g.visible!==p&&(h[d].bVisible=g.visible),g.search!==p&&f.extend(a.aoPreSearchCols[d],Gb(g.search));A(a,"aoStateLoaded","stateLoaded",[a,b])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==p&&b(g)}else c()}function Ca(a){var b=q.settings;a=f.inArray(a,J(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)z.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===p&&(d=c),b[c]!==p&&(a[d]=b[c]))}function ab(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 $a(a,b,c){f(a).on("click.DT",b,function(b){f(a).blur();c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function E(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 Wa(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 Ra(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 D(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ka(a,b){var c=Pb.numbers_length,d=Math.floor(c/2);b<=c?a=Z(0,b):a<=d?(a=Z(0,c-2),a.push("ellipsis"),a.push(b-1)):(a>=b-1-d?a=Z(b-(c-2),b):(a=Z(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 Ha(a){f.each({num:function(b){return Da(b,a)},"num-fmt":function(b){return Da(b,a,bb)},"html-num":function(b){return Da(b,a,Ea)},"html-num-fmt":function(b){return Da(b,a,Ea,bb)}},function(b,c){C.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(C.type.search[b+a]=C.type.search.html)})}function Qb(a){return function(){var b=[Ca(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 v(Ca(this[C.iApiIndex])):new v(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===p||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===p||a?b.draw(!1):
(""!==d.sX||""!==d.sY)&&na(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===p||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===p||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===p?
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!==p){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==p||"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!==p?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===p||b)&&a.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===p||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Ca(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===p||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===p||e)&&h.columns.adjust();(d===p||d)&&h.draw();return 0};this.fnVersionCheck=C.fnVersionCheck;var b=this,c=a===p,d=this.length;c&&(a={});this.oApi=this.internal=C.internal;for(var e in q.ext.internal)e&&(this[e]=Qb(e));this.each(function(){var e={},g=1<d?ab(e,a,!0):a,k=0,l;e=this.getAttribute("id");var n=!1,m=q.defaults,w=f(this);if("table"!=
this.nodeName.toLowerCase())O(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{jb(m);kb(m.column);L(m,m,!0);L(m.column,m.column,!0);L(m,f.extend(g,w.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 v=g.bRetrieve!==p?g.bRetrieve:m.bRetrieve;if(c||v)return t.oInstance;if(g.bDestroy!==p?g.bDestroy:m.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:w[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:w.dataTable();jb(g);Ga(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=f.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);g=ab(f.extend(!0,{},m),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");E(r,"aoDrawCallback",g.fnDrawCallback,"user");E(r,"aoServerParams",g.fnServerParams,"user");E(r,"aoStateSaveParams",g.fnStateSaveParams,"user");E(r,"aoStateLoadParams",g.fnStateLoadParams,"user");E(r,"aoStateLoaded",g.fnStateLoaded,"user");E(r,"aoRowCallback",g.fnRowCallback,"user");E(r,"aoRowCreatedCallback",g.fnCreatedRow,"user");E(r,"aoHeaderCallback",g.fnHeaderCallback,"user");E(r,"aoFooterCallback",g.fnFooterCallback,
"user");E(r,"aoInitComplete",g.fnInitComplete,"user");E(r,"aoPreDrawCallback",g.fnPreDrawCallback,"user");r.rowIdFn=U(g.rowId);lb(r);var x=r.oClasses;f.extend(x,q.ext.classes,g.oClasses);w.addClass(x.sTable);r.iInitDisplayStart===p&&(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){Ga(a);L(m.oLanguage,a);f.extend(!0,y,a);ja(r)},error:function(){ja(r)}}),n=!0);null===g.asStripeClasses&&(r.asStripeClasses=[x.sStripeOdd,x.sStripeEven]);e=r.asStripeClasses;var z=w.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&&
(fa(r.aoHeader,u[0]),e=ua(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++)Ia(r,e?e[k]:null);nb(r,g.aoColumnDefs,u,function(a,b){ma(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:p,type:null!==d?a+".@data-"+d:p,filter:null!==b?a+".@data-"+b:p},ma(r,a)}})}var C=r.oFeatures;e=function(){if(g.aaSorting===p){var a=r.aaSorting;k=0;for(l=a.length;k<l;k++)a[k][1]=r.aoColumns[k].asSorting[0]}Aa(r);C.bSort&&E(r,"aoDrawCallback",function(){if(r.bSorted){var a=Y(r),b={};f.each(a,function(a,c){b[c.src]=c.dir});A(r,null,"order",[r,a,b]);Nb(r)}});E(r,"aoDrawCallback",function(){(r.bSorted||"ssp"===D(r)||C.bDeferRender)&&Aa(r)},"sc");a=w.children("caption").each(function(){this._captionSide=
f(this).css("caption-side")});var b=w.children("thead");0===b.length&&(b=f("<thead/>").appendTo(w));r.nTHead=b[0];b=w.children("tbody");0===b.length&&(b=f("<tbody/>").appendTo(w));r.nTBody=b[0];b=w.children("tfoot");0===b.length&&0<a.length&&(""!==r.oScroll.sX||""!==r.oScroll.sY)&&(b=f("<tfoot/>").appendTo(w));0===b.length||0===b.children().length?w.addClass(x.sNoFooter):0<b.length&&(r.nTFoot=b[0],fa(r.aoFooter,r.nTFoot));if(g.aaData)for(k=0;k<g.aaData.length;k++)R(r,g.aaData[k]);else(r.bDeferLoading||
"dom"==D(r))&&pa(r,f(r.nTBody).children("tr"));r.aiDisplay=r.aiDisplayMaster.slice();r.bInitialised=!0;!1===n&&ja(r)};g.bStateSave?(C.bStateSave=!0,E(r,"aoDrawCallback",Ba,"state_save"),Ob(r,g,e)):e()}});b=null;return this},C,t,x,cb={},Rb=/[\r\n\u2028]/g,Ea=/<.*?>/g,cc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,dc=/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\|\$|\^|\-)/g,bb=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,P=function(a){return a&&!0!==a&&"-"!==a?!1:
!0},Sb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Tb=function(a,b){cb[b]||(cb[b]=new RegExp(Ua(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(cb[b],"."):a},db=function(a,b,c){var d="string"===typeof a;if(P(a))return!0;b&&d&&(a=Tb(a,b));c&&d&&(a=a.replace(bb,""));return!isNaN(parseFloat(a))&&isFinite(a)},Ub=function(a,b,c){return P(a)?!0:P(a)||"string"===typeof a?db(a.replace(Ea,""),b,c)?!0:null:null},J=function(a,b,c){var d=[],e=0,h=a.length;if(c!==
p)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},la=function(a,b,c,d){var e=[],h=0,g=b.length;if(d!==p)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},Z=function(a,b){var c=[];if(b===p){b=0;var d=a}else d=b,b=a;for(a=b;a<d;a++)c.push(a);return c},Vb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},ta=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!==p?b:200,d,e;return function(){var b=this,g=+new Date,f=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=p;a.apply(b,f)},c)):(d=g,a.apply(b,f))}},escapeRegex:function(a){return a.replace(dc,"\\$1")}};var F=function(a,b,c){a[b]!==p&&(a[c]=a[b])},da=/\[.*?\]$/,
X=/\(\)$/,Ua=q.util.escapeRegex,ya=f("<div>")[0],$b=ya.textContent!==p,bc=/<.*?>/g,Sa=q.util.throttle,Wb=[],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 v=function(a,b){if(!(this instanceof v))return new v(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=ta(c);b&&f.merge(this,b);this.selector={rows:null,cols:null,opts:null};v.extend(this,this,Wb)};q.Api=v;f.extend(v.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 v(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 v(this.context,b)},flatten:function(){var a=[];return new v(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,n=this.selector;"string"===typeof a&&(d=c,c=b,b=a,a=!1);var m=0;for(h=f.length;m<h;m++){var q=new v(f[m]);if("table"===b){var u=c.call(q,f[m],m);u!==p&&e.push(u)}else if("columns"===b||"rows"===b)u=c.call(q,f[m],this[m],m),u!==p&&e.push(u);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){var t=this[m];"column-rows"===b&&(l=Fa(f[m],n.opts));var x=0;for(g=t.length;x<g;x++)u=t[x],u="cell"===b?c.call(q,f[m],u.row,
u.column,m,x):c.call(q,f[m],u,m,x,l),u!==p&&e.push(u)}}return e.length||d?(a=new v(f,a?e.concat.apply([],e):e),b=a.selector,b.rows=n.rows,b.cols=n.cols,b.opts=n.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 v(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 mb(this,a,b,0,this.length,1)},reduceRight:G.reduceRight||function(a,b){return mb(this,a,b,this.length-1,-1,-1)},reverse:G.reverse,selector:null,shift:G.shift,slice:function(){return new v(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 v(this.context,ta(this))},unshift:G.unshift});v.extend=function(a,
b,c){if(c.length&&b&&(b instanceof v||b.__dt_wrapper)){var d,e=function(a,b,c){return function(){var d=b.apply(a,arguments);v.extend(d,d,c.methodExt);return d}};var h=0;for(d=c.length;h<d;h++){var g=c[h];b[g.name]="function"===g.type?e(a,g.val,g):"object"===g.type?{}:g.val;b[g.name].__dt_wrapper=!0;v.extend(a,b[g.name],g.propExt)}}};v.register=t=function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)v.register(a[c],b);else{d=a.split(".");var e=Wb,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}}};v.registerPlural=x=function(a,b,c){v.register(a,c);v.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof v?a.length?f.isArray(a[0])?new v(a.context,
a[0]):a[0]:p:a})};var fc=function(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?new v(fc(a,this.context)):this});t("table()",function(a){a=this.tables(a);var b=a.context;return b.length?new v(b[0]):a});x("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});x("tables().body()","table().body()",
function(){return this.iterator("table",function(a){return a.nTBody},1)});x("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});x("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});x("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),V(b,!1===a))})});t("page()",function(a){return a===p?this.page.info().page:this.iterator("table",function(b){Xa(b,a)})});t("page.info()",function(a){if(0===this.context.length)return p;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"===D(a)}});t("page.len()",function(a){return a===p?0!==this.context.length?this.context[0]._iDisplayLength:p:this.iterator("table",function(b){Va(b,a)})});var Xb=function(a,b,c){if(c){var d=new v(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==D(a))V(a,b);else{K(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();va(a,[],function(c){qa(a);c=wa(a,c);for(var d=0,e=c.length;d<e;d++)R(a,c[d]);V(a,b);K(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===p){if(0===b.length)return p;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 eb=function(a,b,c,d,e){var h=[],g,k,l;var n=typeof b;b&&"string"!==n&&"function"!==n&&b.length!==p||(b=[b]);n=0;for(k=b.length;n<k;n++){var m=b[n]&&b[n].split&&!b[n].match(/[\[\(:]/)?b[n].split(","):[b[n]];var q=0;for(l=m.length;q<l;q++)(g=c("string"===typeof m[q]?f.trim(m[q]):m[q]))&&g.length&&(h=h.concat(g))}a=C.selector[a];if(a.length)for(n=0,k=a.length;n<k;n++)h=a[n](d,e,h);return ta(h)},fb=function(a){a||(a={});a.filter&&a.search===p&&(a.search=a.filter);return f.extend({search:"none",
order:"current",page:"all"},a)},gb=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},Fa=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"==D(a))return"removed"===h?[]:Z(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},gc=function(a,b,c){var d;return eb("row",b,function(b){var e=Sb(b),g=a.aoData;if(null!==e&&!c)return[e];d||(d=Fa(a,c));if(null!==e&&-1!==f.inArray(e,d))return[e];if(null===b||b===p||""===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!==p)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!==p))return[e.idx];e=Vb(la(a.aoData,d,"nTr"));return f(e).filter(b).map(function(){return this._DT_RowIndex}).toArray()},
a,c)};t("rows()",function(a,b){a===p?a="":f.isPlainObject(a)&&(b=a,a="");b=fb(b);var c=this.iterator("table",function(c){return gc(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||p},1)});t("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return la(a.aoData,b,"_aData")},1)});x("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)});x("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",function(b,c){ea(b,c,a)})});x("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});x("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var h=0,g=this[d].length;h<g;h++){var f=c[d].rowIdFn(c[d].aoData[this[d][h]]._aData);b.push((!0===a?"#":"")+f)}return new v(c,b)});x("rows().remove()",
"row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData,h=e[c],g,f;e.splice(c,1);var l=0;for(g=e.length;l<g;l++){var n=e[l];var m=n.anCells;null!==n.nTr&&(n.nTr._DT_RowIndex=l);if(null!==m)for(n=0,f=m.length;n<f;n++)m[n]._DT_CellIndex.row=l}ra(b.aiDisplayMaster,c);ra(b.aiDisplay,c);ra(a[d],c,!1);0<b._iRecordsDisplay&&b._iRecordsDisplay--;Wa(b);c=b.rowIdFn(h._aData);c!==p&&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 g=0;for(c=a.length;g<c;g++){var f=a[g];f.nodeName&&"TR"===f.nodeName.toUpperCase()?d.push(pa(b,f)[0]):d.push(R(b,f))}return d},1),c=this.rows(-1);c.pop();f.merge(c,b);return c});t("row()",function(a,b){return gb(this.rows(a,b))});t("row().data()",function(a){var b=this.context;if(a===p)return b.length&&this.length?b[0].aoData[this[0]]._aData:p;var c=b[0].aoData[this[0]];c._aData=a;f.isArray(a)&&c.nTr.id&&
Q(b[0].rowId)(a,c.nTr.id);ea(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()?pa(b,a)[0]:R(b,a)});return this.row(b[0])});var hc=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=W(a),e.push(d[0]))};h(c,d);b._details&&b._details.detach();b._details=f(e);b._detailsShow&&b._details.insertAfter(b.nTr)},hb=function(a,b){var c=a.context;c.length&&(a=c[0].aoData[b!==p?b:a[0]])&&a._details&&(a._details.remove(),a._detailsShow=p,a._details=p)},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(),ic(c[0])))},ic=function(a){var b=new v(a),c=a.aoData;b.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");0<J(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=W(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&&hb(b,d)}))};t("row().child()",function(a,b){var c=this.context;if(a===p)return c.length&&this.length?c[0].aoData[this[0]]._details:p;!0===a?this.child.show():!1===a?hb(this):c.length&&this.length&&hc(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(){hb(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 jc=/^([^:]+):(name|visIdx|visible)$/,Zb=function(a,b,c,d,e){c=[];d=0;for(var f=e.length;d<f;d++)c.push(I(a,e[d],b));return c},kc=function(a,b,c){var d=a.aoColumns,e=J(d,"sName"),h=J(d,"nTh");return eb("column",b,function(b){var g=Sb(b);if(""===b)return Z(d.length);if(null!==
g)return[0<=g?g:d.length+g];if("function"===typeof b){var l=Fa(a,c);return f.map(d,function(c,d){return b(d,Zb(a,d,0,0,l),h[d])?d:null})}var n="string"===typeof b?b.match(jc):"";if(n)switch(n[2]){case "visIdx":case "visible":g=parseInt(n[1],10);if(0>g){var m=f.map(d,function(a,b){return a.bVisible?b:null});return[m[m.length+g]]}return[ba(a,g)];case "name":return f.map(e,function(a,b){return a===n[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===p?a="":f.isPlainObject(a)&&(b=a,a="");b=fb(b);var c=this.iterator("table",function(c){return kc(c,a,b)},1);c.selector.cols=a;c.selector.opts=b;return c});x("columns().header()","column().header()",function(a,b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});x("columns().footer()","column().footer()",function(a,
b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});x("columns().data()","column().data()",function(){return this.iterator("column-rows",Zb,1)});x("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});x("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return la(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});x("columns().nodes()",
"column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return la(a.aoData,e,"anCells",b)},1)});x("columns().visible()","column().visible()",function(a,b){var c=this,d=this.iterator("column",function(b,c){if(a===p)return b.aoColumns[c].bVisible;var d=b.aoColumns,e=d[c],h=b.aoData,n;if(a!==p&&e.bVisible!==a){if(a){var m=f.inArray(!0,J(d,"bVisible"),c+1);d=0;for(n=h.length;d<n;d++){var q=h[d].nTr;b=h[d].anCells;q&&q.insertBefore(b[c],b[m]||null)}}else f(J(b.aoData,"anCells",
c)).detach();e.bVisible=a}});a!==p&&this.iterator("table",function(d){ha(d,d.aoHeader);ha(d,d.aoFooter);d.aiDisplay.length||f(d.nTBody).find("td[colspan]").attr("colspan",W(d));Ba(d);c.iterator("column",function(c,d){A(c,null,"column-visibility",[c,d,a,b])});(b===p||b)&&c.columns.adjust()});return d});x("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===a?ca(b,c):c},1)});t("columns.adjust()",function(){return this.iterator("table",function(a){aa(a)},
1)});t("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return ba(c,b);if("fromData"===a||"toVisible"===a)return ca(c,b)}});t("column()",function(a,b){return gb(this.columns(a,b))});var lc=function(a,b,c){var d=a.aoData,e=Fa(a,c),h=Vb(la(d,e,"anCells")),g=f([].concat.apply([],h)),k,l=a.aoColumns.length,n,m,q,u,t,v;return eb("cell",b,function(b){var c="function"===typeof b;if(null===b||b===p||c){n=[];m=0;for(q=e.length;m<q;m++)for(k=
e[m],u=0;u<l;u++)t={row:k,column:u},c?(v=d[k],b(t,I(a,k,u),v.anCells?v.anCells[u]:null)&&n.push(t)):n.push(t);return n}if(f.isPlainObject(b))return b.column!==p&&b.row!==p&&-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;v=f(b).closest("*[data-dt-row]");return v.length?[{row:v.data("dt-row"),column:v.data("dt-column")}]:[]},a,c)};t("cells()",function(a,b,c){f.isPlainObject(a)&&
(a.row===p?(c=a,a=null):(c=b,b=null));f.isPlainObject(b)&&(c=b,b=null);if(null===b||b===p)return this.iterator("table",function(b){return lc(b,a,fb(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,n;d=this.iterator("table",function(a,b){a=[];g=0;for(k=h[b].length;g<k;g++)for(l=0,n=e[b].length;l<n;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});x("cells().nodes()",
"cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b])&&a.anCells?a.anCells[c]:p},1)});t("cells().data()",function(){return this.iterator("cell",function(a,b,c){return I(a,b,c)},1)});x("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)});x("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return I(b,c,d,a)},
1)});x("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,b,c){return{row:b,column:c,columnVisible:ca(a,c)}},1)});x("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){ea(b,c,a,d)})});t("cell()",function(a,b,c){return gb(this.cells(a,b,c))});t("cell().data()",function(a){var b=this.context,c=this[0];if(a===p)return b.length&&c.length?I(b[0],c[0].row,c[0].column):p;ob(b[0],c[0].row,c[0].column,a);ea(b[0],c[0].row,
"data",c[0].column);return this});t("order()",function(a,b){var c=this.context;if(a===p)return 0!==c.length?c[0].aaSorting:p;"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){Qa(d,a,b,c)})});t("order.fixed()",function(a){if(!a){var b=this.context;b=b.length?b[0].aaSortingFixed:p;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===p?0!==e.length?e[0].oPreviousSearch.sSearch:p:this.iterator("table",function(e){e.oFeatures.bFilter&&ia(e,f.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===
c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});x("columns().search()","column().search()",function(a,b,c,d){return this.iterator("column",function(e,h){var g=e.aoPreSearchCols;if(a===p)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}),ia(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){Ba(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 v(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){qa(a)})});t("settings()",function(){return new v(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 J(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 n=f(b.nTableWrapper),m=f.map(b.aoData,function(a){return a.nTr}),p;b.bDestroying=!0;A(b,"aoDestroyCallback","destroy",[b]);a||(new v(b)).columns().visible(!0);n.off(".DT").find(":not(tbody *)").off(".DT");f(z).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=[];Aa(b);f(m).removeClass(b.asStripeClasses.join(" "));f("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);h.children().detach();h.append(m);g=a?"remove":"detach";l[g]();n[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),l.css("width",b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&
h.children().each(function(a){f(this).addClass(b.asDestroyStripes[a%p])}));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,n){a.call(e[b](f,"cell"===b?k:c,"cell"===b?c:p),f,k,l,n)})})});t("i18n()",function(a,b,c){var d=this.context[0];a=U(a)(d.oLanguage);a===p&&(a=b);c!==p&&f.isPlainObject(a)&&(a=a[c]!==p?a[c]:a._);return a.replace("%d",c)});
q.version="1.10.20";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){}},
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:p,oAjaxData:p,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"==D(this)?1*this._iRecordsTotal:
this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==D(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 Pb=q.ext.pager;f.extend(Pb,{simple:function(a,b){return["previous","next"]},full:function(a,b){return["first","previous","next","last"]},numbers:function(a,b){return[ka(a,b)]},simple_numbers:function(a,b){return["previous",ka(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ka(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ka(a,b),"last"]},_numbers:ka,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||{},n,m,q=0,t=function(b,d){var p,r=g.sPageButtonDisabled,u=function(b){Xa(a,b.data.action,!0)};var w=0;for(p=d.length;w<p;w++){var v=d[w];if(f.isArray(v)){var x=f("<"+(v.DT_el||"div")+"/>").appendTo(b);t(x,v)}else{n=null;m=v;x=a.iTabIndex;switch(v){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":n=k.sFirst;0===e&&(x=-1,m+=" "+r);break;case "previous":n=k.sPrevious;0===e&&(x=-1,m+=
" "+r);break;case "next":n=k.sNext;e===h-1&&(x=-1,m+=" "+r);break;case "last":n=k.sLast;e===h-1&&(x=-1,m+=" "+r);break;default:n=v+1,m=e===v?g.sPageButtonActive:""}null!==n&&(x=f("<a>",{"class":g.sPageButton+" "+m,"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(n).appendTo(b),$a(x,{action:v},u),q++)}}};try{var v=f(b).find(y.activeElement).data("dt-idx")}catch(mc){}t(f(b).empty(),d);v!==p&&f(b).find("[data-dt-idx="+
v+"]").focus()}}});f.extend(q.ext.type.detect,[function(a,b){b=b.oLanguage.sDecimal;return db(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 db(a,b,!0)?"num-fmt"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Ub(a,b)?"html-num"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Ub(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(Rb," ").replace(Ea,""):""},string:function(a){return P(a)?a:"string"===typeof a?a.replace(Rb," "):a}});var Da=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Tb(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}});Ha("");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 ib=function(a){return"string"===typeof a?a.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 ib(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:ib,filter:ib}}};f.extend(q.ext.internal,{_fnExternApiFunc:Qb,_fnBuildAjax:va,_fnAjaxUpdate:qb,_fnAjaxParameters:zb,_fnAjaxUpdateDraw:Ab,_fnAjaxDataSrc:wa,_fnAddColumn:Ia,_fnColumnOptions:ma,_fnAdjustColumnSizing:aa,_fnVisibleToColumnIndex:ba,_fnColumnIndexToVisible:ca,_fnVisbleColumns:W,_fnGetColumns:oa,_fnColumnTypes:Ka,_fnApplyColumnDefs:nb,_fnHungarianMap:H,_fnCamelToHungarian:L,_fnLanguageCompat:Ga,_fnBrowserDetect:lb,_fnAddData:R,_fnAddTr:pa,_fnNodeToDataIndex:function(a,
b){return b._DT_RowIndex!==p?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return f.inArray(c,a.aoData[b].anCells)},_fnGetCellData:I,_fnSetCellData:ob,_fnSplitObjNotation:Na,_fnGetObjectDataFn:U,_fnSetObjectDataFn:Q,_fnGetDataMaster:Oa,_fnClearTable:qa,_fnDeleteIndex:ra,_fnInvalidate:ea,_fnGetRowElements:Ma,_fnCreateTr:La,_fnBuildHead:pb,_fnDrawHead:ha,_fnDraw:S,_fnReDraw:V,_fnAddOptionsHtml:sb,_fnDetectHeader:fa,_fnGetUniqueThs:ua,_fnFeatureHtmlFilter:ub,_fnFilterComplete:ia,_fnFilterCustom:Db,
_fnFilterColumn:Cb,_fnFilter:Bb,_fnFilterCreateSearch:Ta,_fnEscapeRegex:Ua,_fnFilterData:Eb,_fnFeatureHtmlInfo:xb,_fnUpdateInfo:Hb,_fnInfoMacros:Ib,_fnInitialise:ja,_fnInitComplete:xa,_fnLengthChange:Va,_fnFeatureHtmlLength:tb,_fnFeatureHtmlPaginate:yb,_fnPageChange:Xa,_fnFeatureHtmlProcessing:vb,_fnProcessingDisplay:K,_fnFeatureHtmlTable:wb,_fnScrollDraw:na,_fnApplyToChildren:N,_fnCalculateColumnWidths:Ja,_fnThrottle:Sa,_fnConvertToWidth:Jb,_fnGetWidestNode:Kb,_fnGetMaxLenString:Lb,_fnStringToCss:B,
_fnSortFlatten:Y,_fnSort:rb,_fnSortAria:Nb,_fnSortListener:Za,_fnSortAttachListener:Qa,_fnSortingClasses:Aa,_fnSortData:Mb,_fnSaveState:Ba,_fnLoadState:Ob,_fnSettingsFromNode:Ca,_fnLog:O,_fnMap:M,_fnBindAction:$a,_fnCallbackReg:E,_fnCallbackFire:A,_fnLengthOverflow:Wa,_fnRenderer:Ra,_fnDataSource:D,_fnRowAttributes:Pa,_fnExtend:ab,_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 -4
View File
File diff suppressed because one or more lines are too long
+502 -353
View File
File diff suppressed because it is too large Load Diff
+201 -176
View File
@@ -6,274 +6,299 @@
* Please see LICENSE file for your rights under this license. */
.layout-boxed {
background: url('../img/boxed-bg.jpg') repeat fixed;
background: url("../img/boxed-bg.jpg") repeat fixed;
}
.small-box {
cursor: default;
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
/* Rules below not implemented in browsers yet */
-o-user-select: none;
user-select: none;
}
.small-box span {
-webkit-transition-duration: 500ms;
-o-transition-duration: 500ms;
transition-duration: 500ms;
transition-duration: 0.5s;
}
.small-box span.glow {
text-shadow: 0 0 5px #fff;
text-shadow: 0 0 5px currentColor;
}
.list-group-item:hover {
background: #ddd;
@-webkit-keyframes Pulse {
from {
color: #630030;
text-shadow: 0 0 2px transparent;
}
50% {
color: #e33100;
text-shadow: 0 0 5px #e33100;
}
to {
color: #630030;
text-shadow: 0 0 2px transparent;
}
}
@-webkit-keyframes Pulse{
from {color:#630030;-webkit-text-shadow:0 0 2px transparent;}
50% {color:#e33100;-webkit-text-shadow:0 0 5px #e33100;}
to {color:#630030;-webkit-text-shadow:0 0 2px transparent;}
}
@-o-keyframes Pulse{
from {color:#630030;text-shadow:0 0 2px transparent;}
50% {color:#e33100;text-shadow:0 0 5px #e33100;}
to {color:#630030;text-shadow:0 0 2px transparent;}
}
@keyframes Pulse{
from {color:#630030;text-shadow:0 0 2px transparent;}
50% {color:#e33100;text-shadow:0 0 5px #e33100;}
to {color:#630030;text-shadow:0 0 2px transparent;}
@keyframes Pulse {
from {
color: #630030;
text-shadow: 0 0 2px transparent;
}
50% {
color: #e33100;
text-shadow: 0 0 5px #e33100;
}
to {
color: #630030;
text-shadow: 0 0 2px transparent;
}
}
.lookatme {
-webkit-animation-name: Pulse;
-o-animation-name: Pulse;
animation-name: Pulse;
-webkit-animation-duration: 2s;
-o-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation: 2s infinite Pulse;
animation: 2s infinite Pulse;
}
.table-responsive {
-webkit-overflow-scrolling: touch;
-webkit-overflow-scrolling: touch;
}
/* Optimize Queries-Table for small screens */
#all-queries td:nth-of-type(1), /* Time column */
#all-queries td:nth-of-type(5) { /* Status column */
white-space: nowrap;
}
#all-queries td:nth-of-type(3) { /* Domain column */
min-width: 200px;
word-break: break-all;
white-space: pre-wrap;
}
#all-queries_info { /* Allow Info String to wrap (useful while filtering entries on small screen) */
white-space: unset;
}
#all-queries_wrapper .pagination > li > a { /* adjust the buttons width */
padding-left: 6px;
padding-right: 6px;
min-width: 34px;
text-align: center;
}
@media screen and (max-width: 500px),
screen and (min-width: 767px) and (max-width: 1000px) {
/* Hide "Previous" & "Next"-Buttons in Pagination */
#all-queries_wrapper .pagination > li.previous,
#all-queries_wrapper .pagination > li.next {
display: none;
}
#all-queries_wrapper .pagination > li:nth-of-type(2) a {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
#all-queries_wrapper .pagination > li:nth-last-of-type(2) a {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
/* Time column */
#all-queries td:nth-of-type(1),
/* Status column */
#all-queries td:nth-of-type(5) {
white-space: nowrap;
}
.main-header > .navbar,
.navbar > .sidebar-toggle {
height: 50px;
/* Domain column */
#all-queries td:nth-of-type(3) {
min-width: 200px;
word-break: break-all;
white-space: pre-wrap;
}
/* Allow Info String to wrap (useful while filtering entries on small screen) */
#all-queries_info {
white-space: unset;
}
/* adjust the buttons width */
#all-queries_wrapper .pagination > li > a {
padding-left: 6px;
padding-right: 6px;
min-width: 34px;
text-align: center;
}
@media screen and (max-width: 500px), screen and (min-width: 767px) and (max-width: 1000px) {
/* Hide "Previous" & "Next"-Buttons in Pagination */
#all-queries_wrapper .pagination > li.previous,
#all-queries_wrapper .pagination > li.next {
display: none;
}
#all-queries_wrapper .pagination > li:nth-of-type(2) a {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
#all-queries_wrapper .pagination > li:nth-last-of-type(2) a {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
}
#resetButton {
font-weight: 700;
font-weight: 700;
}
.vertical-alignment-helper {
display: table;
width: 100%;
height: 100%;
pointer-events: none;
display: table;
width: 100%;
height: 100%;
pointer-events: none;
}
.vertical-alignment-helper > .vertical-align-center {
display: table-cell;
vertical-align: middle;
display: table-cell;
vertical-align: middle;
}
.vertical-alignment-helper > .vertical-align-center > .modal-content {
width: 250px;
margin-left: auto;
margin-right: auto;
word-wrap: break-word;
pointer-events: all;
width: 250px;
margin-left: auto;
margin-right: auto;
word-wrap: break-word;
pointer-events: all;
}
.alSpinner {
top: 0.1em;
left: 0.1em;
width: 0.8em;
height: 0.8em;
border-radius: 50%;
border: 4px solid #c0c0c0;
border-right-color: transparent;
-webkit-animation: fa-spin 1s infinite linear;
-o-animation: fa-spin 1s infinite linear;
animation: fa-spin 1s infinite linear;
}
.extratooltipcanvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none
top: 0.1em;
left: 0.1em;
width: 0.8em;
height: 0.8em;
border-radius: 50%;
border: 4px solid #c0c0c0;
border-right-color: transparent;
-webkit-animation: fa-spin 1s infinite linear;
animation: fa-spin 1s infinite linear;
}
.chartjs-tooltip {
opacity: 0;
position: absolute;
pointer-events: none;
color: #fff;
background-color: rgba(0,0,0,0.8);
max-width: 95%;
z-index: 900;
opacity: 0;
position: absolute;
pointer-events: none;
color: #fff;
background-color: rgba(0, 0, 0, 0.8);
max-width: 95%;
z-index: 900;
}
.chartjs-tooltip th {
padding-bottom: 3px;
padding-bottom: 3px;
}
.chartjs-tooltip,
.chartjs-tooltip .arrow {
-webkit-transition: all .2s cubic-bezier(0.165, 0.84, 0.44, 1);
transition: all .2s cubic-bezier(0.165, 0.84, 0.44, 1);
transition: all 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.chartjs-tooltip .arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.chartjs-tooltip.bottom .arrow {
top: 100%;
left: 50%;
margin: 0 -5px -5px;
border-width: 5px 5px 0;
border-top-color: rgba(0, 0, 0, .8);
top: 100%;
left: 50%;
margin: 0 -5px -5px;
border-width: 5px 5px 0;
border-top-color: rgba(0, 0, 0, 0.8);
}
.chartjs-tooltip.top .arrow {
top: 0;
left: 50%;
border-width: 0 5px 5px;
margin: -5px -5px 0;
border-bottom-color: rgba(0, 0, 0, .8);
top: 0;
left: 50%;
border-width: 0 5px 5px;
margin: -5px -5px 0;
border-bottom-color: rgba(0, 0, 0, 0.8);
}
.chartjs-tooltip.right.center .arrow {
top: 50%;
left: 100%;
margin: -5px -5px -5px 0;
border-width: 5px 0 5px 5px;
border-left-color: rgba(0, 0, 0, .8);
top: 50%;
left: 100%;
margin: -5px -5px -5px 0;
border-width: 5px 0 5px 5px;
border-left-color: rgba(0, 0, 0, 0.8);
}
.chartjs-tooltip.left.center .arrow {
top: 50%;
left: 0;
margin: -5px 0 -5px -5px;
border-width: 5px 5px 5px 0;
border-right-color: rgba(0, 0, 0, .8);
top: 50%;
left: 0;
margin: -5px 0 -5px -5px;
border-width: 5px 5px 5px 0;
border-right-color: rgba(0, 0, 0, 0.8);
}
.chartjs-tooltip-key {
display: inline-block;
width: 12px;
height: 12px;
margin-right: 3px;
vertical-align: text-top;
display: inline-block;
width: 12px;
height: 12px;
margin-right: 3px;
vertical-align: text-top;
}
.chart-legend {
height: 250px;
overflow: auto;
height: 250px;
overflow: auto;
}
.chart-legend ul {
list-style-type: none;
list-style-type: none;
}
.chart-legend li {
cursor: pointer;
word-break: break-all;
cursor: pointer;
word-break: break-all;
}
.chart-legend li span {
display: inline-block;
width: 20px;
height: 12px;
margin-right: 5px;
display: inline-block;
width: 20px;
height: 12px;
margin-right: 5px;
}
.strike {
text-decoration: line-through !important;
text-decoration: line-through !important;
}
.fa-paypal-icon {
width: 18px;
margin-left: 2px;
}
.sidebar-toggle:before {
font-weight: 900;
font-family: "Font Awesome 5 Free";
/* These are needed because AdmintLTE 2.x doesn't support Font Awesome 5.x */
.sidebar-menu > li > a > .fab,
.sidebar-menu > li > a > .far,
.sidebar-menu > li > a > .fas {
width: 20px;
}
/* Utilities */
.text-underline {
text-decoration: underline;
text-decoration: underline;
}
code.breakall {
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
white-space: pre-wrap;
word-break: break-all;
word-wrap: break-word; /* Internet Explorer 5.5+ */
.breakall {
white-space: pre-wrap;
word-break: break-all;
word-wrap: break-word;
}
.no-user-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.pointer {
cursor: pointer;
cursor: pointer;
}
.bootstrap-select.bs-container.align-right {
left: unset !important;
right: 10px;
left: unset !important;
right: 10px;
}
.input-group-addon {
padding: 0 12px;
padding: 0 12px;
}
.user-panel > .info > span {
padding-right: 5px;
margin-top: 3px;
font-size: 11px;
}
.user-panel > .info i {
margin-right: 3px;
}
.row-centered > div[class^="col-"] {
display: inline-block;
float: none;
}
.version-info {
margin-top: 10px;
}
.daterangepicker {
font-family: inherit;
}
.form-inline .form-control {
display: inline-block;
width: 100%;
vertical-align: middle;
}
.select2-container--default .select2-results > .select2-results__options {
+30 -22
View File
@@ -88,7 +88,7 @@ h4 {
}
.sidebar-menu > li.header {
color: #556068;
background: #1e2225;
background-color: #1e2225;
}
.sidebar-menu > li > a {
border-left: 3px solid transparent;
@@ -96,12 +96,12 @@ h4 {
.sidebar-menu > li:hover > a,
.sidebar-menu > li.active > a {
color: #fff;
background: #22272a;
background-color: #22272a;
border-left-color: #272c30;
}
.sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background: #32393e;
background-color: #32393e;
}
.sidebar a {
color: #bec5cb;
@@ -175,7 +175,6 @@ h4 {
.box-solid > .box-header,
.box > .box-header {
color: #bec5cb;
background: #272c30;
background-color: #272c30;
}
.box-solid > .box-header a,
@@ -209,7 +208,8 @@ h4 {
.main-header .navbar {
background-color: #272c30;
}
.main-header .navbar .nav > li > a {
.main-header .navbar .nav > li > a,
.main-header .navbar .nav > li > .navbar-text {
color: #bec5cb;
}
.main-header .navbar .nav > li > a:hover,
@@ -219,7 +219,7 @@ h4 {
.main-header .navbar .nav .open > a:hover,
.main-header .navbar .nav .open > a:focus,
.main-header .navbar .nav > .active > a {
background: rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
color: #f6f6f6;
}
.main-header .navbar .sidebar-toggle {
@@ -227,7 +227,7 @@ h4 {
}
.main-header .navbar .sidebar-toggle:hover {
color: #f6f6f6;
background: rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
}
.timeline li .timeline-item {
color: #bec5cb;
@@ -318,16 +318,16 @@ h4 {
background: url("../../img/boxed-bg-dark.jpg") repeat fixed;
}
.not-used {
background: #eee;
background-color: #eee;
}
.not-used:hover {
background: #c5c5c5;
background-color: #c5c5c5;
}
.used {
background: #fff;
background-color: #fff;
}
.used:hover {
background: #ddd;
background-color: #ddd;
}
.graphs-grid {
@@ -461,9 +461,9 @@ fieldset[disabled] .form-control {
opacity: 1;
}
.dropdown-menu {
background-color: #353c42;
background-color: #4c5761;
color: #bec5cb;
border: 1px solid #353c42;
border: 1px solid #171c20;
}
.table-striped > tbody > tr:nth-of-type(2n + 1) {
background-color: #2d343a;
@@ -502,20 +502,28 @@ fieldset[disabled] .form-control {
.icheckbox_polaris,
.icheckbox_futurico,
.icheckbox_minimal-blue {
margin-right: 10px;
margin-right: 10px;
}
.iradio_polaris,
.iradio_futurico,
.iradio_minimal-blue {
margin-right: 8px;
margin-right: 8px;
}
/* Overlay box with spinners as shown during data collection for graphs */
.box .overlay, .overlay-wrapper .overlay {
z-index: 50;
background: #353c42bb;
border-radius: 3px;
.box .overlay,
.overlay-wrapper .overlay {
z-index: 50;
background-color: rgba(53, 60, 66, 0.733);
border-radius: 3px;
}
.box .overlay > .fa,
.overlay-wrapper .overlay > .fa,
.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
color: #bec5cb !important;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
background-color: #353c42bb;
padding: 10px;
}
.box .overlay > .fa, .overlay-wrapper .overlay > .fa {
color: #bec5cb;
}
+16 -17
View File
@@ -8,7 +8,8 @@
.main-header .navbar {
background-color: #3c8dbc;
}
.main-header .navbar .nav > li > a {
.main-header .navbar .nav > li > a,
.main-header .navbar .nav > li > .navbar-text {
color: #fff;
}
.main-header .navbar .nav > li > a:hover,
@@ -17,7 +18,7 @@
.main-header .navbar .nav .open > a,
.main-header .navbar .nav .open > a:hover,
.main-header .navbar .nav .open > a:focus {
background: rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
color: #f6f6f6;
}
.main-header .navbar .sidebar-toggle {
@@ -25,7 +26,7 @@
}
.main-header .navbar .sidebar-toggle:hover {
color: #f6f6f6;
background: rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
background-color: #367fa9;
}
@media (max-width: 767px) {
@@ -36,7 +37,7 @@
color: #fff;
}
.main-header .navbar .dropdown-menu li a:hover {
background: #367fa9;
background-color: #367fa9;
}
}
.main-header .logo {
@@ -51,7 +52,7 @@
background-color: #3c8dbc;
}
.content-header {
background: transparent;
background-color: transparent;
}
.wrapper,
.main-sidebar,
@@ -64,7 +65,7 @@
}
.sidebar-menu > li.header {
color: #4b646f;
background: #1a2226;
background-color: #1a2226;
}
.sidebar-menu > li > a {
border-left: 3px solid transparent;
@@ -72,12 +73,12 @@
.sidebar-menu > li:hover > a,
.sidebar-menu > li.active > a {
color: #fff;
background: #1e282c;
background-color: #1e282c;
border-left-color: #3c8dbc;
}
.sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background: #2c3b41;
background-color: #2c3b41;
}
.sidebar a {
color: #b8c7ce;
@@ -103,8 +104,6 @@
background-color: #374850;
border: 1px solid transparent;
height: 35px;
-webkit-transition: all 0.3s ease-in-out;
-o-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.sidebar-form input[type="text"] {
@@ -139,16 +138,16 @@
}
.not-used {
background: #eee;
background-color: #eee;
}
.not-used:hover {
background: #c5c5c5;
background-color: #c5c5c5;
}
.used {
background: #fff;
background-color: #fff;
}
.used:hover {
background: #ddd;
background-color: #ddd;
}
.graphs-grid {
@@ -213,8 +212,8 @@ td.highlight {
}
.icheckbox_minimal-blue {
margin-right: 10px;
margin-right: 10px;
}
.iradio_minimal-blue {
margin-right: 8px;
}
margin-right: 8px;
}
-92
View File
@@ -1,92 +0,0 @@
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+69 -26
View File
@@ -1,42 +1,85 @@
/*
Generated with https://google-webfonts-helper.herokuapp.com/fonts/source-sans-pro
(Modern Browsers option) and added `font-display: swap;` after that.
The `font-weight`s are taken from the official AdminLTE 2 Google Font docs:
https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic
*/
/* source-sans-pro-300 - latin */
@font-face {
font-family: 'Source Sans Pro';
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 300;
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url(SourceSansPro-Light.ttf) format('truetype');
font-display: swap;
src: local("Source Sans Pro Light"), local("SourceSansPro-Light"),
url("source-sans-pro-v13-latin-300.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-300.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-300italic - latin */
@font-face {
font-family: 'Source Sans Pro';
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 300;
font-display: swap;
src: local("Source Sans Pro Light Italic"), local("SourceSansPro-LightItalic"),
url("source-sans-pro-v13-latin-300italic.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-300italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-regular - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(SourceSansPro-Regular.ttf) format('truetype');
font-display: swap;
src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
url("source-sans-pro-v13-latin-regular.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-italic - latin */
@font-face {
font-family: 'Source Sans Pro';
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 400;
font-display: swap;
src: local("Source Sans Pro Italic"), local("SourceSansPro-Italic"),
url("source-sans-pro-v13-latin-italic.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-600 - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 600;
src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url(SourceSansPro-Semibold.ttf) format('truetype');
font-display: swap;
src: local("Source Sans Pro SemiBold"), local("SourceSansPro-SemiBold"),
url("source-sans-pro-v13-latin-600.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-600italic - latin */
@font-face {
font-family: 'Source Sans Pro';
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 600;
font-display: swap;
src: local("Source Sans Pro SemiBold Italic"), local("SourceSansPro-SemiBoldItalic"),
url("source-sans-pro-v13-latin-600italic.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-600italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* source-sans-pro-700 - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(SourceSansPro-Bold.ttf) format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 300;
src: local('Source Sans Pro Light Italic'), local('SourceSansPro-LightIt'), url(SourceSansPro-LightItalic.ttf) format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url(SourceSansPro-Italic.ttf) format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 600;
src: local('Source Sans Pro Semibold Italic'), local('SourceSansPro-SemiboldIt'), url(SourceSansPro-SemiboldItalic.ttf) format('truetype');
font-display: swap;
src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
url("source-sans-pro-v13-latin-700.woff2") format("woff2"), /* Chrome 26+, Opera 23+, Firefox 39+ */
url("source-sans-pro-v13-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

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