diff --git a/.gitignore b/.gitignore
index cbb3a13..c03592a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
*.rpm
*.log
*spec-20*
+*.tar.xz
*.tar.gz
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias
index 86a6212..f32da1c 100644
--- a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias
@@ -4,13 +4,12 @@ Alias /phpsysinfo /opt/phpsysinfo
SSLRequireSSL
Options -Indexes
- AuthName "phpSysInfo"
- AuthBasicProvider external
- AuthType Basic
- AuthExternal pwauth
+ #AuthName "phpSysInfo"
+ #AuthBasicProvider external
+ #AuthType Basic
+ #AuthExternal pwauth
- Require user admin
Require {(($phpmyadmin{access} || 'private' ) eq "public" ) ? "all granted": "ip $localAccess $externalSSLAccess";}
@@ -19,5 +18,4 @@ Alias /phpsysinfo /opt/phpsysinfo
SetHandler "proxy:unix:/var/run/php-fpm/php.sock|fcgi://localhost"
-
-
+
\ No newline at end of file
diff --git a/root/opt/phpsysinfo/.browserslistrc-bootstrap b/root/opt/phpsysinfo/.browserslistrc-bootstrap
new file mode 100644
index 0000000..a48549c
--- /dev/null
+++ b/root/opt/phpsysinfo/.browserslistrc-bootstrap
@@ -0,0 +1,6 @@
+Explorer >= 8
+Firefox >= 3.6
+Sarafi >= 5.1
+Chrome >= 25
+Edge >= 12
+Opera >= 11
diff --git a/root/opt/phpsysinfo/.browserslistrc-dynamic b/root/opt/phpsysinfo/.browserslistrc-dynamic
new file mode 100644
index 0000000..2c42c69
--- /dev/null
+++ b/root/opt/phpsysinfo/.browserslistrc-dynamic
@@ -0,0 +1,6 @@
+Explorer >= 6
+Firefox >= 1.5
+Sarafi >= 5.1
+Chrome >= 1
+Edge >= 12
+Opera >= 11
diff --git a/root/opt/phpsysinfo/.browserslistrc-static b/root/opt/phpsysinfo/.browserslistrc-static
new file mode 100644
index 0000000..34adc86
--- /dev/null
+++ b/root/opt/phpsysinfo/.browserslistrc-static
@@ -0,0 +1 @@
+>= 0%
diff --git a/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md b/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..66eb307
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [phpsysinfo@yahoo.com](mailto:phpsysinfo@yahoo.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/root/opt/phpsysinfo/.github/CONTRIBUTING.md b/root/opt/phpsysinfo/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..c6e3f84
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/CONTRIBUTING.md
@@ -0,0 +1,7 @@
+# Contributing to phpSysInfo
+First time contributing to phpSysInfo? Read our [Code of Conduct](https://github.com/phpsysinfo/phpsysinfo/blob/main/CODE_OF_CONDUCT.md).
+
+### Propose a feature
+
+If you have a great idea or want to help out, just create a pull request with your change proposal
+in the [phpSysInfo](https://github.com/phpsysinfo/phpsysinfo) repository.
diff --git a/root/opt/phpsysinfo/.github/FUNDING.yml b/root/opt/phpsysinfo/.github/FUNDING.yml
new file mode 100644
index 0000000..e95f376
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: [https://phpsysinfo.github.io/phpsysinfo/]
diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..a0f79af
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,41 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
+
+***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini`
+and include any error messages in your bug report / help request !!***
diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md
new file mode 100644
index 0000000..48d5f81
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/custom.md
@@ -0,0 +1,10 @@
+---
+name: Custom issue template
+about: Describe this issue template's purpose here.
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+
diff --git a/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..bbcbbe7
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md b/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..7973f9c
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,25 @@
+### Summary ###
+
+
+### Types of changes ###
+
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to change)
+
+### Code Preparation ###
+
+
+- [ ] Check for unused code
+- [ ] No unrelated changes are included
+- [ ] None of the changed files are reformatting only
+- [ ] Code is self explanatory or documented
+- [ ] All written text is properly translated (english language)
diff --git a/root/opt/phpsysinfo/.github/workflows/phplint.yml b/root/opt/phpsysinfo/.github/workflows/phplint.yml
new file mode 100644
index 0000000..f6d7626
--- /dev/null
+++ b/root/opt/phpsysinfo/.github/workflows/phplint.yml
@@ -0,0 +1,38 @@
+name: PHP Linting
+
+jobs:
+ phplint:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: PHP Lint 5.4
+ uses: prestashop/github-action-php-lint/5.4@v2.1
+ - name: PHP Lint 5.5
+ uses: prestashop/github-action-php-lint/5.5@v2.1
+ - name: PHP Lint 5.6
+ uses: prestashop/github-action-php-lint/5.6@v2.1
+ - name: PHP Lint 7.1
+ uses: prestashop/github-action-php-lint/7.1@v2.1
+ - name: PHP Lint 7.2
+ uses: prestashop/github-action-php-lint/7.2@v2.1
+ - name: PHP Lint 7.3
+ uses: prestashop/github-action-php-lint/7.3@v2.1
+ - name: PHP Lint 7.4
+ uses: prestashop/github-action-php-lint/7.4@v2.1
+ - name: PHP Lint 8.0
+ uses: prestashop/github-action-php-lint/8.0@v2.1
+ - name: PHP Lint 8.1
+ uses: prestashop/github-action-php-lint/8.1@v2.1
+ - name: PHP Lint 8.2
+ uses: prestashop/github-action-php-lint/8.2@v2.1
+
+on:
+ push:
+ branches:
+ - main
+ - stable
diff --git a/root/opt/phpsysinfo/.gitignore b/root/opt/phpsysinfo/.gitignore
index dbb8d5e..7c76f68 100644
--- a/root/opt/phpsysinfo/.gitignore
+++ b/root/opt/phpsysinfo/.gitignore
@@ -1 +1,2 @@
phpsysinfo.ini
+composer.lock
diff --git a/root/opt/phpsysinfo/.htaccess b/root/opt/phpsysinfo/.htaccess
index 9c15814..a27adc9 100644
--- a/root/opt/phpsysinfo/.htaccess
+++ b/root/opt/phpsysinfo/.htaccess
@@ -6,6 +6,30 @@
# Deny all requests from Apache 2.4+
- Require all granted
+ Require all denied
+
+
+# Deny all requests from Apache 2.0-2.2
+
+ order deny,allow
+ deny from all
+
+# Deny all requests from Apache 2.4+
+
+ Require all denied
+
+
+
+
+# Deny all requests from Apache 2.0-2.2
+
+ order deny,allow
+ deny from all
+
+# Deny all requests from Apache 2.4+
+
+ Require all denied
+
+
diff --git a/root/opt/phpsysinfo/.travis.yml b/root/opt/phpsysinfo/.travis.yml
deleted file mode 100644
index 9ed9bd0..0000000
--- a/root/opt/phpsysinfo/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: php
-
-php:
- - 5.2
- - 5.3
- - 5.4
- - 5.5
- - 5.6
-
-script: for i in `find . -name "*.php"`; do php -l $i; done;
-
-branches:
- only:
- - "master"
- - "stable"
-
-notifications:
- email: false
diff --git a/root/opt/phpsysinfo/CHANGELOG.md b/root/opt/phpsysinfo/CHANGELOG.md
index 0451ba5..4bf6608 100644
--- a/root/opt/phpsysinfo/CHANGELOG.md
+++ b/root/opt/phpsysinfo/CHANGELOG.md
@@ -3,8 +3,242 @@ Changelog of phpSysInfo
http://phpsysinfo.sourceforge.net/
+phpSysInfo 3.4.4
+----------------
+ - [ADD] Proxmox to detected distros
+
+ - [NEW] HIDE_SENSORS option
+
+ - [FIX] pmset - UPS support for macOS 10.15
+
+ - [UPD] IPMIcfg sensor program - pminfo
+ - [UPD] SMART Plugin - rebuilt to show the state of any defined attributes IDs
+
+phpSysInfo 3.4.3
+----------------
+ - [ADD] Linux Lite, BigLinux, Linspire, Tuxedo, Armbian, Photon, RebeccaBlackOS, QuemOS, dahliaOS, openEuler, Runtu, risiOS, Nobara, Fatdog, CachyOS, Snal, Feren, Archman, Elive, RoboLinux, ExTiX, Kaisen, LXLE, Neptune, Regata, Archcraft, Kodachi, Bodhi, Siduction, Vanilla, Q4OS, Guix, XeroLinux, OpenWRT, Gnoppix, Uruk, Laclin, Clear, Sparky and Venom Linux to detected distros
+
+ - [NEW] SHOW_NETWORK_BRIDGE option
+ - [NEW] JSONP option for enable JSONP data mode
+ - [NEW] plugin DiskLoad - show Disk Load information on WinNT
+
+phpSysInfo 3.4.2
+----------------
+ - [ADD] RebornOS, Parrot OS, Pop!_OS, Nitrux, Makulu, Absolute, Bluestar, Ultramarine Linux and TrueNAS to detected distros
+ - [ADD] schabau_bootstrap template
+ - [ADD] Raid plugin - storcli and perccli status
+
+ - [NEW] Partial support for GNU Hurd
+ - [NEW] Ability to retrieve Linux, GNU Hurd, DrayOS and FortiOS system information via SSH
+
+phpSysInfo 3.4.1
+----------------
+ - [ADD] Linuxfx, EndeavourOS, Garuda, Arco and Artix Linux to detected distros
+
+ - [FIX] Fixed sensors voltages
+
+ - [UPD] UpdateNotifier plugin - compatibility with newer data formats
+
+phpSysInfo 3.4.0
+----------------
+ - [ADD] Omarine, NethServer, JingOS, KDE neon, Alma, Virtuozzo, EuroLinux and Rocky Linux to detected distros
+
+ - [NEW] HIDE_NETWORK_INTERFACE_REGEX option to use a regular expression in the name of a hidden network interface
+ - [NEW] Ability to read UPS information from a file
+ - [NEW] Virtualizer detection on Linux, Android, FreeBSD, NetBSD, OpenBSD and WinNT
+ - [NEW] ROOTFS option to set root path of the system
+
+ - [UPD] Changed all data file extensions from .txt to .tmp
+ - [UPD] Sensor CoreTemp renamed to CpuMem and extended to read the CPU and memory supply voltages
+
+phpSysInfo 3.3.4
+----------------
+
+ - [FIX] Fixed display in static mode
+
+phpSysInfo 3.3.3
+----------------
+
+ - [ADD] Persian (Farsi) Translation fa.xml
+ - [ADD] Croatian Translation hr.xml
+ - [ADD] Mabox, Milis, FreeNAS, UOS and Septor to detected distros
+ - [ADD] SMART plugin - reading contents of wmic command for WinNT
+ - [ADD] Raid plugin - 3ware-status status
+ - [ADD] IPMIcfg sensor program support
+
+ - [NEW] Ability to read information from an external WinNT server (new WMI_HOSTNAME, WMI_USER and WMI_PASSWORD parameters)
+ - [NEW] NvidiaSMI - sensors monitoring for Nvidia GPU
+ - [NEW] plugin Viewer - show output of any command or file viewer.txt contents
+ - [NEW] Memory chips information
+ - [NEW] USB devices speed info on Linux
+ - [NEW] IGNORE_TOTAL option
+ - [NEW] HIDE_TOTALS option
+ - [NEW] INCREASE_WIDTH option for frontend "dynamic"
+
+ - [DEL] Removed deprecated plugin Iptables
+
+phpSysInfo 3.3.2
+----------------
+
+ - [UPD] Korean Translation ko.xml
+
+ - [ADD] Exherbo and EasyOS to detected distros
+ - [ADD] PCI devices list on SunOS
+ - [ADD] Raid plugin - megaclisas-status status
+
+ - [NEW] OS Type information
+ - [NEW] CPU manufacturer information
+ - [NEW] Frontend Bootstrap view in web app mode on mobile devices
+
+phpSysInfo 3.3.1
+----------------
+
+ - [UPD] bootstrap 4.3.1
+ - [UPD] bootstrap-ie 4.3.100
+
+ - [ADD] Indonesian Translation id.xml
+
+ - [NEW] HIDE_BOOTSTRAP_LOADER option
+ - [NEW] Uprecords plugin - DENOTE_BY_ASTERISK option
+
+ - [DEL] jQuery 3.3.1
+
+phpSysInfo 3.3.0
+----------------
+
+ - [UPD] Frontend Bootstrap3 to Bootstrap4 with IE8 and IE9 compatibility modules
+
+ - [ADD] Endless, Kali, Redcore and MX Linux to detected distros
+ - [ADD] SMART plugin - support for NVMe disks
+ - [ADD] Uprecords plugin - SHORT_MODE option
+ - [ADD] Raid plugin - IDRAC RAID status
+
+ - [NEW] NVMe devices list on Linux
+ - [NEW] Docker plugin - docker stats
+ - [NEW] SORT_NETWORK_INTERFACES_LIST and SORT_SENSORS_LIST options
+ - [NEW] IGNORE_FREE, IGNORE_USAGE and IGNORE_THRESHOLD_FS_TYPES options
+
+phpSysInfo 3.2.10
+----------------
+
+ - [UPD] jQuery 3.3.1
+
+ - [ADD] NuTyX to detected distros
+
+ - [FIX] Raid plugin - fixed zpool analize
+
+phpSysInfo 3.2.9
+----------------
+
+ - [UPD] Greek Translation gr.xml
+
+ - [ADD] BAT plugin - Model, Manufacturer and Serial Number information
+ - [ADD] BAT plugin - SHOW_SERIAL and UPOWER option
+ - [ADD] Springdale Linux to detected distros
+
+ - [NEW] SHOW_DEVICES_INFOS and SHOW_DEVICES_SERIAL options
+ - [NEW] Thinkpad - Lenovo Thinkpad sensors monitoring for Linux
+ - [NEW] StableBit plugin - StableBit Scanner info
+ - [NEW] HyperV plugin - Hyper-V info
+ - [NEW] Raid plugin - software, fake, zpool and megaraid RAID status
+
+ - [DEL] Removed deprecated MDStatus and DMRaid plugins
+
+phpSysInfo 3.2.8
+----------------
+
+ - [UPD] jQuery 3.2.1
+ - [UPD] French Translation fr.xml
+ - [UPD] CPU usage on WinNT
+ - [UPD] Ukrainian Translation uk.xml
+
+ - [FIX] Fixed incorrect network usage on FreeBSD 11
+ - [FIX] Fixed healthd sensors
+ - [FIX] Fixed displaying for code pages windows-932, windows-949 and windows-950 for WinNT
+
+ - [ADD] Container Linux, PureOS, OpenELEC, LibreELEC and Lakka to detected distros
+ - [ADD] FreeIPMI, IPMItool and IPMIutil other information
+ - [ADD] PS plugin - CPU usage
+ - [ADD] PS plugin - MEMORY_USAGE, CPU_USAGE and SHOW_PID1CHILD_EXPANDED options
+ - [ADD] SMART plugin - WMI access for WinNT
+
+ - [NEW] DATETIME_FORMAT option
+ - [NEW] BLOCKS option - order of data blocks
+ - [NEW] SHOW_NETWORK_ACTIVE_SPEED option
+ - [NEW] Ability to generate only part of the data
+ - [NEW] LOAD_BAR compact mode option
+ - [NEW] PingTest plugin
+
+ - [DEL] Removed deprecated IPMIinfo plugin
+
+phpSysInfo 3.2.7
+----------------
+
+ - [UPD] jQuery 3.1.1
+ - [UPD] Network interfaces info for WinNT
+ - [UPD] Turkish Translation tr.xml
+ - [UPD] Greek Translation gr.xml
+ - [UPD] Korean Translation ko.xml
+ - [UPD] Ukrainian Translation uk.xml
+
+ - [ADD] Devuan and SalentOS to detected distros
+ - [ADD] HIDE_NETWORK_MACADDR option
+
+ - [NEW] Raspberry Pi detection on Linux
+
+phpSysInfo 3.2.6
+----------------
+
+ - [UPD] jQuery 3.1.0 and jQuery 1.12.4
+ - [UPD] bootstrap 3.3.7
+ - [UPD] Swedish Translation sv.xml
+ - [UPD] Norwegian Translation no.xml
+
+ - [ADD] NeoKylin and Void to detected distros
+ - [ADD] schabau and lingruby template
+ - [ADD] DMRaid plugin - FreeBSD graid info
+ - [ADD] SNMPPInfo plugin - support for Ricoh printers
+ - [ADD] UpdateNotifier plugin - ACCESS option
+
+ - [NEW] sudo commands list
+ - [NEW] plugin Iptables - iptables rules list
+
+phpSysInfo 3.2.5
+----------------
+
+ - [UPD] jQuery 2.2.0 and jQuery 1.12.0
+
+ - [ADD] Show network interfaces infos for NetBSD and OpenBSD
+ - [ADD] SHOW_NETWORK_INFOS_EXPANDED option
+ - [ADD] SHOW_MEMORY_INFOS_EXPANDED option
+ - [ADD] QTS, OpenMamba and HipServ to detected distros
+ - [ADD] SNMPups - monitoring UPS via SNMP
+
+ - [NEW] reloading plugins also for frontend "bootstrap"
+ - [NEW] Network speed info on WinNT, Linux, Android, Darwin, NetBSD, OpenBSD and FreeBSD
+ - [NEW] Coretemp monitoring also on Linux
+ - [NEW] QTSsnmp - SNMP sensors monitoring for QTS Linux
+ - [NEW] Hwmon - sensors monitoring for Linux
+ - [NEW] SpeedFan - sensors monitoring for WinNT
+ - [NEW] Separate configuration sections for motherboard monitoring sensors programs
+ - [NEW] List of IP addresses of clients authorized to run
+
+phpSysInfo 3.2.4
+----------------
+
+ - [ADD] Solus to detected distros
+ - [ADD] Uprecords plugin - MAX_ENTRIES option - maximum number of entries to show
+
+ - [UPD] Refreshing status of all plugins for dynamic mode
+ - [UPD] bootstrap 3.3.6
+
+ - [NEW] language and template selection also for frontend "bootstrap"
+
+ - [FIX] PHP 7 class Error issues
+
phpSysInfo 3.2.3
----------------
+
- [UPD] jQuery 2.1.4 and jQuery 1.11.3
- [UPD] bootstrap 3.3.5
@@ -14,6 +248,7 @@ phpSysInfo 3.2.3
phpSysInfo 3.2.2
----------------
+
- [UPD] bootstrap 3.3.4
- [NEW] Thunderbolt (TB) devices list on Darwin
@@ -27,6 +262,7 @@ phpSysInfo 3.2.2
phpSysInfo 3.2.1
----------------
+
- [UPD] bootstrap 3.3.2
- [NEW] REFRESH parameter also for frontend "bootstrap"
@@ -37,6 +273,7 @@ phpSysInfo 3.2.1
phpSysInfo 3.2.0
----------------
+
- [UPD] jQuery 2.1.3 and jQuery 1.11.2
- [NEW] Frontend "bootstrap" with Bootstrap3 and Transparency (JSON)
@@ -121,7 +358,8 @@ phpSysInfo 3.1.11
- [ADD] Generations Linux and SliTaz to detected distros
- [ADD] IPMI and LMSensors currents information
- [ADD] Plugin IPMIInfo - added powers and currents values
- - [ADD] Partial support of QNX
+
+ - [NEW] Partial support of QNX
- [FIX] Reduce execution time on Linux systems when showing load average PR#47
@@ -135,7 +373,7 @@ phpSysInfo 3.1.10
phpSysInfo 3.1.9
----------------
- - [NEW] New plugin DMRaid - software raid status
+ - [NEW] plugin DMRaid - software raid status
- [ADD] Calculate, Tails, SMEServer, Semplice, SolydXK, Parsix, RedFlag, Amazon, Korora, OpenMandriva, SteamOS, ROSA Enterprise Server and ROSA Desktop Fresh to detected distros
diff --git a/root/opt/phpsysinfo/COPYING b/root/opt/phpsysinfo/COPYING
index d511905..14db8fc 100644
--- a/root/opt/phpsysinfo/COPYING
+++ b/root/opt/phpsysinfo/COPYING
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
+the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
-
+
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
-
+
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
-
+
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
-
+
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-
+
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@@ -303,9 +303,10 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
Also add information on how to contact you by electronic and paper mail.
@@ -335,5 +336,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
+library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
diff --git a/root/opt/phpsysinfo/Dockerfile b/root/opt/phpsysinfo/Dockerfile
index 5b62375..59d10ec 100644
--- a/root/opt/phpsysinfo/Dockerfile
+++ b/root/opt/phpsysinfo/Dockerfile
@@ -1,20 +1,24 @@
# phpSysInfo
-# VERSION 2
+# VERSION 4
-FROM ubuntu:14.04
+FROM ubuntu:20.04
+ENV LC_ALL C.UTF-8
+ARG DEBIAN_FRONTEND=noninteractive
+ARG http_proxy=""
+ARG https_proxy=""
MAINTAINER phpSysInfo
# Update sources
-RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list
-RUN apt-get update
+RUN apt-get -q update && \
+ apt-get -qy install apache2 php7.4 php7.4-xml php7.4-mbstring libapache2-mod-php7.4 git pciutils && \
+ apt-get clean && \
+ rm -Rf /var/lib/apt/lists/*
-RUN apt-get install -y apache2 php5 git pciutils
-
-RUN git clone https://github.com/phpsysinfo/phpsysinfo.git /var/www/html/phpsysinfo
-#RUN cp /var/www/html/phpsysinfo/phpsysinfo.ini.new /var/www/html/phpsysinfo/phpsysinfo.ini
-RUN cat /var/www/html/phpsysinfo/phpsysinfo.ini.new | sed 's/^LOAD_BAR=false/LOAD_BAR=true/' >/var/www/html/phpsysinfo/phpsysinfo.ini
+RUN git clone https://github.com/phpsysinfo/phpsysinfo.git /var/www/html/phpsysinfo && \
+ cp /var/www/html/phpsysinfo/phpsysinfo.ini.new /var/www/html/phpsysinfo/phpsysinfo.ini
+ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
diff --git a/root/opt/phpsysinfo/README.md b/root/opt/phpsysinfo/README.md
index 8f342bb..499c3de 100644
--- a/root/opt/phpsysinfo/README.md
+++ b/root/opt/phpsysinfo/README.md
@@ -1,45 +1,56 @@
phpSysInfo
==============
-* Copyright (c), 1999-2008, Uriah Welcome (precision@users.sf.net)
-* Copyright (c), 1999-2009, Michael Cramer (bigmichi1@users.sf.net)
-* Copyright (c), 2007-2008, Audun Larsen (xqus@users.sf.net)
-* Copyright (c), 2007-2015, Erkan Valentin
-* Copyright (c), 2009-2015, Mieczyslaw Nalewaj (namiltd@users.sf.net)
-* Copyright (c), 2010-2012, Damien Roth (iysaak@users.sf.net)
+* Copyright (c), 1999-2008, Uriah Welcome ([sf.net/users/precision](https://sf.net/users/precision))
+* Copyright (c), 1999-2009, Michael Cramer ([github.com/bigmichi1](https://github.com/bigmichi1), [sf.net/users/bigmichi1](https://sf.net/users/bigmichi1))
+* Copyright (c), 2007-2008, Audun Larsen ([sf.net/users/xqus](https://sf.net/users/xqus))
+* Copyright (c), 2007-2015, Erkan Valentin ([github.com/rk4an](https://github.com/rk4an), [sf.net/users/jacky672](https://sf.net/users/jacky672))
+* Copyright (c), 2009-2024, Mieczyslaw Nalewaj ([github.com/namiltd](https://github.com/namiltd), [sf.net/users/namiltd](https://sf.net/users/namiltd))
+* Copyright (c), 2010-2012, Damien Roth ([sf.net/users/iysaak](https://sf.net/users/iysaak))
+REQUIREMENTS
+------------
+
+PHP 5.1.3 or later with SimpleXML, PCRE, XML and DOM extension.
+
+#### Suggested extensions:
+- mbstring: Required for *nix non UTF-8 systems
+- com_dotnet: Required for Windows environments
+- xsl: Required for static mode
+- json: Required for bootstrap mode
CURRENT TESTED PLATFORMS
------------------------
-- Linux 2.6.x
-- FreeBSD 7.x
+- Linux 2.6+
+- FreeBSD 7+
- OpenBSD 2.8+
- NetBSD
- DragonFly
- HP-UX
-- Darwin/OSX
-- Windows 2000 / 2003 / XP / Vista / 7 / 8 / 8.1 / 10
+- Darwin / Mac OS / OS X / iOS
+- Windows 2000 / XP / 2003 / Vista / 2008 / 7 / 2011 / 2012 / 8 / 8.1 / 10 / 10 IoT / 2016 / 2019 / 2022 / 11
- Android
-- > PHP 5.2 or later
- - With PCRE, XML, XSL, MBString and SimpleXML extension.
-####Platforms currently in progress:
+#### Platforms currently in progress:
- Haiku
- Minix
- SunOS
- ReactOS
- IBM AIX
- QNX
+- GNU Hurd
+- FortiOS (via SSH)
+- DrayOS (via SSH)
If your platform is not here try checking out the mailing list archives or
-the message boards on SourceForge.
+the message boards on Github.
INSTALLATION AND CONFIGURATION
------------------------------
-####Typical installation
+#### Typical installation
Just decompress and untar the source (which you should have done by now,
if you're reading this...), into your webserver's document root.
@@ -59,10 +70,10 @@ can do this.
That's it. Restart your webserver (if you changed php.ini), and voila.
-####Docker container installation
+#### Docker container installation
-- sudo docker build -t phpsysinfo github.com/phpsysinfo/phpsysinfo
-- sudo docker run -i -p 8080:80 -t phpsysinfo
+- `sudo docker build -t phpsysinfo github.com/phpsysinfo/phpsysinfo#main`
+- `sudo docker run -i -p 8080:80 -t phpsysinfo`
- go to http://localhost:8080/phpsysinfo/
KNOWN PROBLEMS
@@ -74,21 +85,21 @@ KNOWN PROBLEMS
PLATFORM SPECIFIC ISSUES
------------------------
-####Windows with IIS
+#### Windows with IIS
On Windows systems we get our informations through the WMI interface.
If you run phpSysInfo on the IIS webserver, phpSysInfo will not connect
to the WMI interface for security reasons. At this point you MUST set
an authentication mechanism for the directory in the IIS admin
interface for the directory where phpSysInfo is installed. Then you
will be asked for an user and a password when opening the page. At this
- point it is necassary to log in with an user that will be able to
+ point it is necessary to log in with an user that will be able to
connect to the WMI interface. If you use the wrong user and/or password
you might get an "ACCESS DENIED ERROR".
SENSOR RELATED INFORMATION
---------------------------
-####MBM5
+#### MBM5
Make sure you set MBM5 Interval Logging to csv and to the data
directory of phpSysInfo. The file must be called MBM5. Also make sure
MBM5 doesn't add symbols to the values. This is a Quick MBM5 log parser,
@@ -101,21 +112,19 @@ First make sure you've read this file completely, especially the
"INSTALLATION AND CONFIGURATION" section. If it still doesn't work then
you can:
-Submit a bug on SourceForge (preferred) (http://sourceforge.net/projects/phpsysinfo/)
+Ask for help or submit a bug on Github (https://github.com/phpsysinfo/phpsysinfo/issues)
-Ask for help in the forum (http://sourceforge.net/projects/phpsysinfo/)
-
-***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini`
+***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini`
and include any error messages in your bug report / help request !!***
OTHER NOTES
-----------
-If you have a great idea or want to help out, just drop by the project
-page at SourceForge (http://sourceforge.net/projects/phpsysinfo/).
+If you have a great idea or want to help out, just create a pull request with your change proposal
+in the [phpSysInfo](https://github.com/phpsysinfo/phpsysinfo) repository.
LICENSING
---------
-This program and all associated files are released under the GNU Public
-License, see [COPYING](COPYING) for details.
+This program is released under the GNU Public License Version 2 or
+(at your option) any later version, see [COPYING](COPYING) for details.
diff --git a/root/opt/phpsysinfo/README_PLUGIN.md b/root/opt/phpsysinfo/README_PLUGIN.md
index 26140ac..d86ae0a 100644
--- a/root/opt/phpsysinfo/README_PLUGIN.md
+++ b/root/opt/phpsysinfo/README_PLUGIN.md
@@ -13,13 +13,13 @@ Beginning with phpSysInfo 3.0, phpSysInfo can be extended by Plugins. So here is
a description that a developer of a plugin must take care of. Plugins can be
enabled through the `phpsysinfo.ini` in the PLUGINS variable. The name of the
plugin is essential for the function of the plugin system. Lets say you write a
-plugin with the name 'hdd_stats', then this name is added to the PLUGINS
+plugin with the name 'pingtest', then this name is added to the PLUGINS
variable in `phpsysinfo.ini`. And this is also then the name which is everywhere in
the plugin system used, like creating the object, locate the needed files and
so on.
So if the name is now specified, phpSysInfo needs a special directory structure
-to find the needed files. The directory structure for the example `hdd_stats`
+to find the needed files. The directory structure for the example `pingtest`
plugin can be seen here:
```
@@ -27,22 +27,22 @@ plugin can be seen here:
|
+---+ plugins (directory in that plugins are installed)
| |
- | +---+ hdd_stats (the real plugin directory, must have the same name like
+ | +---+ pingtest (the real plugin directory, must have the same name like
| | | the plugin named in PLUGINS, else it won't be found)
| | |
| | +---+ js (directory in which the needed JavaScript file is located,
| | | | to generate the html output out of the xml)
- | | | # hdd_stats.js (the js file must have the same name, like the
+ | | | # pingtest.js (the js file must have the same name, like the
| | | plugin in PSI_PLUGINS with the extension js)
| | +---+ css (directory in which the needed style sheet information are
| | | | located, can exists, but it's up to the author)
- | | | # hdd_stats.css (the css file must have the same name, like the
+ | | | # pingtest.css (the css file must have the same name, like the
| | | plugin in PSI_PLUGINS with the extension css)
| | +---+ lang (directory where translations for the plugin are located)
| | | |
| | | # en.xml (at least an english translation file must exist)
| | |
- | | # class.hdd_stats.inc.php (this is the core file of the plugin,
+ | | # class.pingtest.inc.php (this is the core file of the plugin,
| | name must consists of 'class' +
| | name from PSI_PLUGINS + '.inc.php')
```
@@ -57,7 +57,7 @@ If the directory structure is build up, then it's time to start programming.
Files
-----
-An example implementation is the mdstat plugin, which is shipped with phpSysInfo
+An example implementation is the pingtest plugin, which is shipped with phpSysInfo
* en.xml - at least this file must exist to get the translation working, and the
the first entry in this file is normally the headline of the plugin.
@@ -70,12 +70,12 @@ An example implementation is the mdstat plugin, which is shipped with phpSysInfo
other plugins don't redefine your translations. At the time of writing
this, there is no check to verify the id's, so be carfull.
-* hdd_stats.css - here can all custom style sheet informations written down. The
+* pingtest.css - here can all custom style sheet informations written down. The
names of the id's and classes SHOULD also begin, like the translation
id's, with `'plugin_' + pluginname`. If thats not the case it might be
possible that another plugin is overwriting your css definitions.
-* class.hdd_stats.inc.php - this file MUST include a class with the plugin name
+* class.pingtest.inc.php - this file MUST include a class with the plugin name
and also this class MUST extend the 'psi_plugin' class. A check that
such a class exist and also extends 'psi_plugin' will be included in
the near future. And if the check fails the plugin won't be loaded.
@@ -93,26 +93,26 @@ An example implementation is the mdstat plugin, which is shipped with phpSysInfo
standalone xml. So there is no need to do some special things, only
create a xml object for the plugin.
-* hdd_stats.js - this file is called when the page is loaded. A block for the
+* pingtest.js - this file is called when the page is loaded. A block for the
plugin is automatically created. This one is a div container with the
- id `'plugin_'+ pluginname ("plugin_hdd_stats")`. The entire output must be
+ id `'plugin_'+ pluginname ("plugin_pingtest")`. The entire output must be
placed in that container.
There is a helper function for creating the headline: buildBlock() that
can be called. This function returns a string with the html code of the
headline, this code can then be appended to the plugin block. The
generated headline can provide a reload icon for an ajax request. Only
the click action of that icon must be created. The id of this icon is
- `'reload_' + pluginname + 'Table' ("reload_hdd_statsTable")`.
+ `'reload_' + pluginname + 'Table' ("reload_pingtestTable")`.
Everything that then is done to get the html output out of the xml is up
to the author.
To get the xml document the ajax request url is `'xml.php?plugin=' +
- pluginname (xml.php?plugin=hdd_stats)`. This xml includes only the xml
+ pluginname (xml.php?plugin=pingtest)`. This xml includes only the xml
from the plugin nothing more.
The last two executed commands should/must be the translation call and
the unhide of the filled div container.
The translation function that needs to be called is named
plugin_traslate() with one argument, that is the pluginname like in
- `PSI_PLUGINS (plugin_translate("hdd_stats");)`.
+ `PSI_PLUGINS (plugin_translate("pingtest");)`.
To unhide the filled container call the .show() function of it.
`$("plugin_" + pluginname).show() ($("plugin_hdd_stat").show())`.
diff --git a/root/opt/phpsysinfo/SECURITY.md b/root/opt/phpsysinfo/SECURITY.md
new file mode 100644
index 0000000..4e5b490
--- /dev/null
+++ b/root/opt/phpsysinfo/SECURITY.md
@@ -0,0 +1,12 @@
+# Security Policy
+
+## Supported Versions
+
+The [latest released version](https://github.com/phpsysinfo/phpsysinfo/releases) of phpSysInfo is supported.
+
+## Reporting a Vulnerability
+
+Please email phpsysinfo@yahoo.com, and we will respond as quickly as possible.
+
+If the vulnerability is considered valid and accepted, a patch will be made for the latest phpSysInfo version.
+If the vulnerability is deemed invalid, no further action is required.
diff --git a/root/opt/phpsysinfo/composer.json b/root/opt/phpsysinfo/composer.json
index d839520..8423869 100644
--- a/root/opt/phpsysinfo/composer.json
+++ b/root/opt/phpsysinfo/composer.json
@@ -1,10 +1,10 @@
{
"name": "phpsysinfo/phpsysinfo",
"description": "phpSysInfo is a customizable PHP Script that parses /proc, and formats information nicely. It will display information about system facts like Uptime, CPU, Memory, PCI devices, SCSI devices, IDE devices, Network adapters, Disk usage, and more.",
- "license": "GPL",
+ "license": "GPL-2.0-or-later",
"homepage": "http://phpsysinfo.github.io/phpsysinfo/",
"require": {
- "php": ">=5.2.0",
+ "php": ">=5.1.3",
"ext-simplexml": "*",
"ext-pcre": "*",
"ext-xml": "*",
@@ -13,6 +13,7 @@
"suggest": {
"ext-mbstring": "Required for *nix non UTF-8 systems",
"ext-com_dotnet": "Required for Windows environments",
- "ext-xsl": "Required for static mode"
+ "ext-xsl": "Required for static mode",
+ "ext-json": "Required for bootstrap mode"
}
-}
\ No newline at end of file
+}
diff --git a/root/opt/phpsysinfo/data/.htaccess b/root/opt/phpsysinfo/data/.htaccess
new file mode 100644
index 0000000..1c4ee05
--- /dev/null
+++ b/root/opt/phpsysinfo/data/.htaccess
@@ -0,0 +1,9 @@
+# Deny all requests from Apache 2.0-2.2
+
+ order deny,allow
+ deny from all
+
+# Deny all requests from Apache 2.4+
+
+ Require all denied
+
diff --git a/root/opt/phpsysinfo/data/ModelTranslation.txt b/root/opt/phpsysinfo/data/ModelTranslation.txt
index dfa05e1..1faee2e 100644
--- a/root/opt/phpsysinfo/data/ModelTranslation.txt
+++ b/root/opt/phpsysinfo/data/ModelTranslation.txt
@@ -21,7 +21,44 @@ iMac13,2:iMac Core i5/i7:Intel Core I5-3470/I5-3470S/I7-3770
iMac14,1:iMac Core i5:Intel Core I5-4570R
iMac14,2:iMac Core i5/i7:Intel Core I5-4570/I5-4670/I7-4771
iMac14,3:iMac Core i5/i7:Intel Core I5-4570S/I7-4770S
+iMac14,4:iMac Core i5:Intel Core I5-4260U
+iMac15,1:iMac Core i5/i7:Intel Core I5-4590/I5-4690/I7-4790K
+iMac16,1:iMac Core i5:Intel Core I5-5250U
+iMac16,2:iMac Core i5/i7:Intel Core I5-5575R/I5-5675R/I7-5775R
+iMac17,1:iMac Core i5/i7:Intel Core I5-6500/I5-6600/I7-6700K
+iMac18,1:iMac Core i5:Intel Core I5-7360U
+iMac18,2:iMac Core i5/i7:Intel Core I5-7400/I5-7500/I7-7700
+iMac18,3:iMac Core i5/i7:Intel Core I5-7500/I5-7600/I5-7600K/I7-7700K
+iMac19,1:iMac Core i5/i9:Intel Core I5-8500/I5-8600/I5-9600K/I9-9900K
+iMac19,2:iMac Core i3/i5/i7:Intel Core I3-8100/I5-8500/I7-8700
+iMac20,1:iMac Core i5/i7/i9:Intel Core I5-10500/I5-10600/I7-10700K/I9-10910
+iMac20,2:iMac Core i7/i9:Intel Core I7-10700K/I9-10910
+iMac21,1:MacBook Air M1:Apple M1
+iMac21,2:MacBook Air M1:Apple M1
M43ADP1,1:Development Mac Pro:Intel Xeon X5340
+Mac13,1:Mac Studio M1 Max:Apple M1 Max
+Mac13,2:Mac Studio M1 Ultra:Apple M1 Ultra
+Mac14,2:MacBook Air M2:Apple M2
+Mac14,3:Mac mini M2:Apple M2
+Mac14,5:MacBook Pro M2 Max:Apple M2 Max
+Mac14,6:MacBook Pro M2 Max:Apple M2 Max
+Mac14,7:MacBook Pro M2:Apple M2
+Mac14,8:Mac Pro M2 Ultra:Apple M2 Ultra
+Mac14,9:MacBook Pro M2 Pro:Apple M2 Pro
+Mac14,10:MacBook Pro M2 Pro:Apple M2 Pro
+Mac14,12:Mac mini M2 Pro:Apple M2 Pro
+Mac14,13:Mac Studio M2 Max:Apple M2 Max
+Mac14,14:Mac Studio M2 Ultra:Apple M2 Ultra
+Mac14,15:MacBook Air 15" M2:Apple M2
+Mac15,3:MacBook Pro 14" M3:Apple M3
+Mac15,4:iMac 24" M3:Apple M3
+Mac15,5:iMac 24" M3:Apple M3
+Mac15,6:MacBook Pro 14" M3 Pro:Apple M3 Pro
+Mac15,7:MacBook Pro 16" M3 Pro:Apple M3 Pro
+Mac15,8:MacBook Pro 14" M3 Max:Apple M3 Max
+Mac15,9:MacBook Pro 16" M3 Max:Apple M3 Max
+Mac15,10:MacBook Pro 14" M3 Max:Apple M3 Max
+Mac15,11:MacBook Pro 16" M3 Max:Apple M3 Max
MacBook1,1:MacBook Core Duo:Intel Core Duo T2400/T2500
MacBook2,1:MacBook Core 2 Duo:Intel Core 2 Duo T5600/T7200/T7400
MacBook3,1:MacBook Core 2 Duo:Intel Core 2 Duo T7300/T7500
@@ -30,6 +67,9 @@ MacBook5,1:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P8600
MacBook5,2:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P7450
MacBook6,1:MacBook Core 2 Duo:Intel Core 2 Duo P7550
MacBook7,1:MacBook Core 2 Duo:Intel Core 2 Duo P8600
+MacBook8,1:MacBook Core M:Intel Core M-5Y31/M-5Y51/M-5Y71
+MacBook9,1:MacBook Core m3/m5/m7:Intel Core M3-6Y30/M5-6Y54/M7-6Y75
+MacBook10,1:MacBook Core m3/i5/i7:Intel Core M3-7Y32/i5-7Y54/i7-7Y75
MacBookAir1,1:MacBook Air Core 2 Duo:Intel Core 2 Duo P7500/P7700
MacBookAir2,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SL9300/SL9400/SL9600
MacBookAir3,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SU9400/SU9600
@@ -40,6 +80,11 @@ MacBookAir5,1:MacBook Air Core i5/i7:Intel Core I5-3317U/I7-3667U
MacBookAir5,2:MacBook Air Core i5/i7:Intel Core I5-3427U/I7-3667U
MacBookAir6,1:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U
MacBookAir6,2:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U
+MacBookAir7,1:MacBook Air Core i5/i7:Intel Core I5-5250U/I7-5650U
+MacBookAir7,2:MacBook Air Core i5/i7:Intel Core I5-5250U/I7-5650U
+MacBookAir8,1:MacBook Air Core i5:Intel Core I5-8210Y
+MacBookAir9,1:MacBook Air Core i3/i5/i7:Intel Core I3-1000NG4/I5-1030NG7/I7-1060NG7
+MacBookAir10,1:MacBook Air M1:Apple M1
MacBookPro1,1:MacBook Pro Core Duo:Intel Core Duo L2400/T2400/T2500/T2600
MacBookPro1,2:MacBook Pro Core Duo:Intel Core Duo T2600
MacBookPro2,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo T7600
@@ -61,24 +106,50 @@ MacBookPro9,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3720QM/I7-3820QM
MacBookPro9,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I7-3520M
MacBookPro10,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3635QM/I7-3720QM/I7-3740QM/I7-3820QM/I7-3840QM
MacBookPro10,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I5-3230M/I7-3520M/I7-3540M
-MacBookPro11,1:MacBook Pro Core i5/i7:Intel Core I5-4258U/I5-4288U/I7-4558U
-MacBookPro11,2:MacBook Pro Core i7:Intel Core I7-4750HQ/I7-4850HQ/I7-4960HQ
-MacBookPro11,3:MacBook Pro Core i7:Intel Core I7-4850HQ/I7-4960HQ
+MacBookPro11,1:MacBook Pro Core i5/i7:Intel Core I5-4258U/I5-4278U/I5-4288U/I5-4308U/I7-4558U/I5-4578U
+MacBookPro11,2:MacBook Pro Core i7:Intel Core I7-4750HQ/I7-4770HQ/I7-4850HQ/I7-4870HQ/I7-4960HQ/I7-4980HQ
+MacBookPro11,3:MacBook Pro Core i7:Intel Core I7-4850HQ/I7-4870HQ/I7-4960HQ/I7-4980HQ
+MacBookPro11,4:MacBook Pro Core i7:Intel Core I7-4770HQ/I7-4870HQ/I7-4980HQ
+MacBookPro11,5:MacBook Pro Core i7:Intel Core I7-4870HQ/I7-4980HQ
+MacBookPro12,1:MacBook Pro Core i5/i7:Intel Core I5-5257U/I5-5287U/I7-5557U
+MacBookPro13,1:MacBook Pro Core i5/i7:Intel Core I5-6360U/I7-6660U
+MacBookPro13,2:MacBook Pro Core i5/i7:Intel Core I5-6267U/I5-6287U/I7-6567U
+MacBookPro13,3:MacBook Pro Core i7:Intel Core I7-6700HQ/I7-6820HQ/I7-6920HQ
+MacBookPro14,1:MacBook Pro Core i5/i7:Intel Core I5-7360U/I7-7660U
+MacBookPro14,2:MacBook Pro Core i5/i7:Intel Core I5-7267U/I5-7287U/I7-7567U
+MacBookPro14,3:MacBook Pro Core i7:Intel Core I7-7700HQ/I7-7820HQ/I7-7920HQ
+MacBookPro15,1:MacBook Pro Core i7/i9:Intel Core I7-8750H/I7-8850H/I7-9750H/I9-8950HK/I9-9880H/I9-9980HK
+MacBookPro15,2:MacBook Pro Core i5/i7:Intel Core I5-8259U/I5-8279U/I7-8559U/I7-8569U
+MacBookPro15,3:MacBook Pro Core i7/i9:Intel Core I7-8850H/I9-8950HK/I9-9880H/I9-9980HK
+MacBookPro15,4:MacBook Pro Core i5/i7:Intel Core I5-8257U/I7-8557U
+MacBookPro16,1:MacBook Pro Core i7/i9:Intel Core I7-9750H/I9-9880H/I9-9980HK
+MacBookPro16,2:MacBook Pro Core i5/i7:Intel Core I5-1038NG7/I7-1068NG7
+MacBookPro16,3:MacBook Pro Core i5/i7:Intel Core I5-8257U/I7-8557U
+MacBookPro16,4:MacBook Pro Core i7/i9:Intel Core I7-9750H/I9-9880H/I9-9980HK
+MacBookPro17,1:MacBook Pro M1:Apple M1
+MacBookPro18,1:MacBook Pro M1 Pro:Apple M1 Pro
+MacBookPro18,2:MacBook Pro M1 Max:Apple M1 Max
+MacBookPro18,3:MacBook Pro M1 Pro:Apple M1 Pro
+MacBookPro18,4:MacBook Pro M1 Max:Apple M1 Max
Macmini1,1:Mac mini Core Solo/Duo:Intel Core Duo T2300/T2400 Solo T1200
Macmini2,1:Mac mini Core 2 Duo:Intel Core 2 Duo T5600/T7200
Macmini3,1:Mac mini Core 2 Duo:Intel Core 2 Duo P7350/P8400/P7550/P8700/P8800
Macmini4,1:Mac mini Core 2 Duo:Intel Core 2 Duo P8600/P8800
Macmini5,1:Mac mini Core i5:Intel Core I5-2415M
Macmini5,2:Mac mini Core i5/i7:Intel Core I5-2520M/I7-2620M
-Macmini5,3:Mac mini Core i7:Intel Core I7-2635QM
+Macmini5,3:Mac mini Core i7:Intel Core I7-2635QM
Macmini6,1:Mac mini Core i5:Intel Core I5-3210M
-Macmini6,2:Mac mini Core i7:Intel Core i7 I7-3615QM/I7-3720QM
+Macmini6,2:Mac mini Core i7:Intel Core I7-3615QM/I7-3720QM
+Macmini7,1:Mac mini Core i5/i7:Intel Core I5-4260U/I5-4278U/I5-4308U/I7-4578U
+Macmini8,1:Mac mini Core i3/i5/i7:Intel Core I3-8100/I5-8500B/I7-8700B
+Macmini9,1:Mac mini M1:Apple M1
MacPro1,1:Mac Pro Quad Core:Intel Xeon 5130/5150/5160
MacPro2,1:Mac Pro Eight Core:Intel Xeon X5365
MacPro3,1:Mac Pro Quad/Eight Core:Intel Xeon E5462/E5472/X5482
MacPro4,1:Mac Pro Quad/Eight Core:Intel Xeon E5520/E5550/X5570/W3520/W3540/W3580
MacPro5,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5620/E5645/W3530/W3565/W3680/X5650/X5670/X5675
MacPro6,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5-1620v2/E5-1650v2/E5-1680v2/E5-2697v2
+MacPro7,1:Mac Pro Eight/12/16/24/28 Core:Intel Xeon W-3223/W-3235/W-3245/W-3265M/W-3275M
PowerBook1,1:PowerBook G3:PowerPC 750 (G3)
PowerBook2,1:iBook G3:PowerPC 750 (G3)
PowerBook2,2:iBook G3:PowerPC 750cx (G3)
diff --git a/root/opt/phpsysinfo/data/cpus.ini b/root/opt/phpsysinfo/data/cpus.ini
new file mode 100644
index 0000000..d7a1b39
--- /dev/null
+++ b/root/opt/phpsysinfo/data/cpus.ini
@@ -0,0 +1,229 @@
+[cpu]
+; Qemu
+0x0,0x51="QEMU TCG"
+
+; Ampere Computing
+;0xc0
+
+; ARM Limited
+0x41,0x810="ARM810"
+0x41,0x920="ARM920"
+0x41,0x922="ARM922"
+0x41,0x926="ARM926"
+0x41,0x940="ARM940"
+0x41,0x946="ARM946"
+0x41,0x966="ARM966"
+0x41,0xa20="ARM1020"
+0x41,0xa22="ARM1022"
+0x41,0xa26="ARM1026"
+0x41,0xb02="ARM11 MPCore"
+0x41,0xb36="ARM1136"
+0x41,0xb56="ARM1156"
+0x41,0xb76="ARM1176"
+0x41,0xc05="Cortex-A5"
+0x41,0xc07="Cortex-A7"
+0x41,0xc08="Cortex-A8"
+0x41,0xc09="Cortex-A9"
+0x41,0xc0d="Cortex-A12"
+0x41,0xc0f="Cortex-A15"
+0x41,0xc0e="Cortex-A17"
+0x41,0xc14="Cortex-R4"
+0x41,0xc15="Cortex-R5"
+0x41,0xc17="Cortex-R7"
+0x41,0xc18="Cortex-R8"
+0x41,0xc20="Cortex-M0"
+0x41,0xc21="Cortex-M1"
+0x41,0xc23="Cortex-M3"
+0x41,0xc24="Cortex-M4"
+0x41,0xc20="Cortex-M7"
+0x41,0xc60="Cortex-M0+"
+0x41,0xd01="Cortex-A32"
+0x41,0xd02="Cortex-A34"
+0x41,0xd03="Cortex-A53"
+0x41,0xd04="Cortex-A35"
+0x41,0xd05="Cortex-A55"
+0x41,0xd06="Cortex-A65"
+0x41,0xd07="Cortex-A57"
+0x41,0xd08="Cortex-A72"
+0x41,0xd09="Cortex-A73"
+0x41,0xd0a="Cortex-A75"
+0x41,0xd0b="Cortex-A76"
+0x41,0xd0c="Neoverse-N1"
+0x41,0xd0d="Cortex-A77"
+0x41,0xd0e="Cortex-A76AE"
+0x41,0xd13="Cortex-R52"
+0x41,0xd15="Cortex-R82"
+0x41,0xd20="Cortex-M23"
+0x41,0xd21="Cortex-M33"
+0x41,0xd22="Cortex-M55"
+0x41,0xd23="Cortex-M85"
+0x41,0xd40="Neoverse-V1"
+0x41,0xd41="Cortex-A78"
+0x41,0xd42="Cortex-A78AE"
+0x41,0xd43="Cortex-A65AE"
+0x41,0xd44="Cortex-X1"
+0x41,0xd46="Cortex-A510"
+0x41,0xd47="Cortex-A710"
+0x41,0xd48="Cortex-X2"
+0x41,0xd49="Neoverse-N2"
+0x41,0xd4a="Neoverse-E1"
+0x41,0xd4b="Cortex-A78C"
+0x41,0xd4c="Cortex-X1C"
+0x41,0xd4d="Cortex-A715"
+0x41,0xd4e="Cortex-X3"
+0x41,0xd4f="Neoverse-V2"
+0x41,0xd80="Cortex-A520"
+0x41,0xd81="Cortex-A720"
+0x41,0xd82="Cortex-X4"
+0x41,0xd83="Neoverse-V3AE"
+0x41,0xd84="Neoverse-V3"
+0x41,0xd85="Cortex-X925"
+0x41,0xd87="Cortex-A725"
+0x41,0xd8e="Neoverse-N3"
+
+; Broadcom Corporation - ('B') cores.
+0x42,0xf="Brahma B15"
+0x42,0x100="Brahma B53"
+0x42,0x516="Vulcan/ThunderX2 T99p1"
+
+; Cavium Inc. - ('C') cores.
+0x43,0xa0="ThunderX"
+0x43,0xa1="ThunderX T88"
+0x43,0xa2="Octeon TX T81"
+0x43,0xa3="Octeon TX T83"
+0x43,0xaf="ThunderX2 T99"
+0x43,0xb0="Octeon TX2"
+0x43,0xb1="Octeon TX2 T98"
+0x43,0xb2="Octeon TX2 T93/T96"
+0x43,0xb3="Octeon TX2 F95"
+0x43,0xb4="Octeon TX2 F95N"
+0x43,0xb5="Octeon TX2 F95MM"
+0x43,0xb8="ThunderX3 T110"
+
+; DEC - Digital Equipment Corporation
+0x44,0xa10="SA110"
+0x44,0xa11="SA1100"
+
+; Fujitsu Ltd.
+0x46,0x1="A64FX"
+
+; HiSilicon Technologies, Inc.
+0x48,0xd01="TSV110"
+0x48,0xd40="Cortex-A76"
+
+; Infineon Technologies AG
+;0x49
+
+; Motorola or Freescale Semiconductor Inc.
+;0x4d
+
+; NVIDIA Corporation
+0x4e,0x0="Denver"
+0x4e,0x3="Denver 2"
+
+; APM - Applied Micro Circuits Corporation - ('P') cores.
+0x50,0x0="xgene1"
+
+; Qualcomm Inc. - ('Q') cores.
+0x51,0xf="Scorpion"
+0x51,0x2d="Scorpion"
+0x51,0x4d="Krait"
+0x51,0x6f="Krait"
+0x51,0x201="Kryo Silver"
+0x51,0x205="Kryo Gold"
+0x51,0x211="Kryo Silver"
+0x51,0x800="Kryo 2xx Gold (Cortex-A73)"
+0x51,0x801="Kryo 2xx Silver (Cortex-A53)"
+0x51,0x802="Kryo 3xx Gold (Cortex-A75)"
+0x51,0x803="Kryo 3xx Silver (Cortex-A55)"
+0x51,0x804="Kryo 4xx Gold (Cortex-A76)"
+0x51,0x805="Kryo 4xx/5xx Silver (Cortex-A55)"
+0x51,0xc00="Falkor"
+0x51,0xc01="Saphira"
+
+; Samsung ('S') cores.
+0x53,0x1="Exynos M1/M2 Mongoose"
+0x53,0x1,0x1="Exynos M1 Mongoose"
+0x53,0x1,0x4="Exynos M2 Mongoose"
+0x53,0x2="Exynos M3 Mongoose"
+0x53,0x3="Exynos M4 Mongoose"
+0x53,0x4="Exynos M5 Mongoose"
+
+; Texas Instruments
+0x54,0x925="TI925"
+
+; Marvell Semiconductor Inc.
+0x56,0x131="Feroceon 88FR131"
+0x56,0x581="PJ4/PJ4B"
+0x56,0x584="PJ4B-MP/PJ4C"
+
+; Apple Inc.
+0x61,0x1="Cyclone"
+0x61,0x2="Typhoon"
+0x61,0x3="Typhoon/Capri"
+0x61,0x4="Twister"
+0x61,0x5="Twister/Elba/Malta"
+0x61,0x6="Hurricane"
+0x61,0x7="Hurricane/Myst"
+
+; Faraday
+0x66,0x526="FA526"
+0x66,0x626="FA626"
+
+; HXT
+0x68,0x0="Phecda"
+
+;Intel Corporation/Marvell
+0x69,0x200="i80200"
+0x69,0x210="PXA250A"
+0x69,0x212="PXA210A"
+0x69,0x242="i80321-400"
+0x69,0x243="i80321-600"
+0x69,0x290="PXA250B/PXA26x"
+0x69,0x292="PXA210B"
+0x69,0x2c2="i80321-400-B0"
+0x69,0x2c3="i80321-600-B0"
+0x69,0x2d0="PXA250C/PXA255/PXA26x"
+0x69,0x2d2="PXA210C"
+0x69,0x411="PXA27x"
+0x69,0x41c="IPX425-533"
+0x69,0x41d="IPX425-400"
+0x69,0x41f="IPX425-266"
+0x69,0x682="PXA32x"
+0x69,0x683="PXA930/PXA935"
+0x69,0x688="PXA30x"
+0x69,0x689="PXA31x"
+0x69,0xb11="SA1110"
+0x69,0xc12="IPX1200"
+
+[manufacturer]
+AMDisbetter="AMD"
+AuthenticAMD="AMD"
+CentaurHauls="IDT WinChip/Centaur"
+CyrixInstead="Cyrix/STMicro./IBM"
+HygonGenuine="Hygon"
+GenuineIntel="Intel"
+TransmetaCPU="Transmeta"
+GenuineTMx86="Transmeta"
+GeodebyNSC="National Semiconductor"
+NexGenDriven="NexGen"
+RiseRiseRise="Rise"
+SiSSiSSiS="SiS"
+Shanghai="Zhaoxin"
+UMCUMCUMC="UMC"
+VIAVIAVIA="VIA"
+Vortex86SoC="DM&P Vortex"
+E2KMACHINE="MCST Elbrus"
+GenuineAO486="ao486 soft CPU"
+bhyvebhyve="bhyve"
+KVMKVMKVM="KVM"
+MicrosoftHv="Microsoft Hyper-V"
+lrpepyhvr="Parallels"
+VMwareVMware="VMware"
+XenVMMXenVMM="Xen HVM"
+ACRNACRNACRN="Project ACRN"
+TCGTCGTCGTCG="QEMU"
+QNXQVMBSQG="QNX Hypervisor"
+UnisysSpar64="Unisys sPar"
+VBoxVBoxVBox="Oracle VM VirtualBox"
+IBM/S390="IBM"
diff --git a/root/opt/phpsysinfo/data/distros.ini b/root/opt/phpsysinfo/data/distros.ini
index 16747ab..e8e6b7a 100644
--- a/root/opt/phpsysinfo/data/distros.ini
+++ b/root/opt/phpsysinfo/data/distros.ini
@@ -3,174 +3,707 @@
; $Id: distros.ini 709 2012-12-05 11:20:40Z namiltd $
;
-[GoboLinux]
+[solaris sunos]
+Image = "Solaris.png"
+
+[oraclesolaris sunos]
+Image = "Solaris.png"
+
+[smartos sunos]
+Image = "SmartOS.png"
+
+[opensolaris sunos]
+Image = "OpenSolaris.png"
+
+[openindiana sunos]
+Image = "OpenIndiana.png"
+
+[omnios sunos]
+Image = "OmniOS.png"
+
+[openstorage sunos]
+Image = "NexentaStor.png"
+Name = "NexentaStor"
+
+[openwrt]
+Image = "OpenWRT.png"
+Name = "OpenWrt"
+Mode = "Detection"
+Files = "/etc/openwrt_release"
+Files2 = "/etc/openwrt_release"
+;detected in "/etc/os-release"
+
+[vmware photon os]
+Image = "Photon.png"
+Files = "/etc/photon-release"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+
+[guix system]
+Image = "Guix.png"
+;detected in "/etc/os-release"
+
+[gobolinux]
Image = "Gobo.png"
Name = "GoboLinux"
Files = "/etc/GoboLinuxVersion"
-[SliTaz]
+[slitaz]
Image = "SliTaz.png"
Name = "SliTaz"
Files = "/etc/slitaz-release"
[eisfair]
Image = "Eisfair.png"
+;detected in "/etc/os-release"
+
+[eisfair project]
+Image = "Eisfair.png"
Files = "/etc/eisfair-system"
Files2 = "/etc/version"
+;detected in "lsb_release -a"
-[TinyCore]
+[tinycore]
Image = "TinyCore.png"
Name = "Tiny Core Linux"
Files = "/usr/share/doc/tc/release.txt"
-[Frugalware]
+[venom linux]
+Image = "Venom.png"
+Name = "Venom Linux"
+Files = "/etc/venom-release"
+;detected in "/etc/os-release"
+
+[linux plop]
+Image = "Plop.png"
+;detected in "/etc/os-release"
+
+[frugalware]
Image = "Frugalware.png"
Files = "/etc/frugalware-release"
;detected in "/etc/os-release"
-[antiX]
+[rbos]
+Image = "RebeccaBlackOS.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[quemos]
+Image = "QuemOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[rebeccablackos]
+Image = "RebeccaBlackOS.png"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[proxmox]
+Image = "Proxmox.png"
+Name = "Proxmox"
+Files = "/usr/bin/pveversion"
+Mode = "Execute"
+;wrong in "/etc/os-release" Debian GNU/Linux
+;wrong in "/etc/debian_version" Debian
+
+[q4os]
+Image = "Q4OS.png"
+Name = "Q4OS"
+Files = "/etc/q4os_version"
+;wrong in "lsb_release -a" Debian
+;wrong in "/etc/os-release" Debian GNU/Linux
+;wrong in "/etc/debian_version" Debian
+
+[siduction]
+Image = "Siduction.png"
+Files = "/etc/siduction-version"
+;wrong in "lsb_release -a" Debian
+;wrong in "/etc/os-release" Debian GNU/Linux
+;wrong in "/etc/debian_version" Debian
+
+[sparkylinux]
+Image = "Sparky.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[sparky]
+Image = "Sparky.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[regata os]
+Image = "Regata.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+
+[tuxedo]
+Image = "Tuxedo.png"
+Files = "/etc/tuxedo-os-version"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu tuxedo]
+Image = "Tuxedo.png"
+;detected in "/etc/lsb-release"
+
+[tuxedo os]
+Image = "Tuxedo.png"
+;detected in "/etc/os-release"
+
+[ubuntu linspire]
+Image = "Linspire.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu lxle]
+Image = "LXLE.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/lsb-release" Ubuntu
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu linux lite]
+Image = "LinuxLite.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu bodhi]
+Image = "Bodhi.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu linux kodachi]
+Image = "Kodachi.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu kodachi]
+Image = "Kodachi.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[robolinux]
+Image = "RoboLinux.png"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu robolinux]
+Image = "RoboLinux.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[feren os classic]
+Image = "Feren.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu feren]
+Image = "Feren.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[debian gnu/linux armbian]
+Image = "Armbian.png"
+Name = "Armbian"
+Mode = "Detection"
+Files = "/etc/armbian-release;/etc/armbian-image-release"
+Files2 = "/etc/armbian-release;/etc/armbian-image-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[debian elive]
+Image = "Elive.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" debian
+
+[elive]
+Image = "Elive.png"
+Mode = "Detection"
+Files = "/etc/elive-version"
+Files2 = "/etc/elive-version"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" debian
+
+[debian neptune]
+Image = "Neptune.png"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" debian
+
+[neptune]
+Image = "Neptune.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" debian
+
+[kaisen]
+Image = "Kaisen.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" debian
+
+[kaisen gnu/linux]
+Image = "Kaisen.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" debian
+
+[deepin extix]
+Image = "ExTiX.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" debian
+
+[mx]
+Image = "MX.png"
+Files = "/etc/mx-version"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/os-release" Debian GNU/Linux
+;wrong in "/etc/antix-version" antiX
+;wrong in "/etc/debian_version" Debian
+
+; at the end because some distros may also have the same files (like MX)
+[antix]
Image = "antiX.png"
Files = "/etc/antix-version"
;wrong in "/etc/os-release" Debian GNU/Linux
;wrong in "/etc/debian_version" Debian
-[IPFire]
+[ipfire]
Image = "IPFire.png"
;detected in "/etc/system-release"
-[4MLinux]
+[qts]
+Image = "QTS.png"
+Name = "QTS"
+;detected in "/etc/config/uLinux.conf"
+
+[4mlinux]
Image = "4MLinux.png"
Name = "4MLinux"
Files = "/etc/4MLinux-version"
-[Lunar Linux]
+[milis linux]
+Image = "Milis.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+
+[lunar linux]
Image = "Lunar.png"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
-[CRUX]
+[crux]
Image = "Crux.png"
Mode = "Execute"
Files = "/usr/bin/crux"
-[Foresight]
+[omarine]
+Image = "Omarine.png"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+
+[foresight]
Image = "Foresight.png"
;detected in "/etc/distro-release"
-[Trustix]
+[trustix]
Image = "Trustix.png"
Files = "/etc/trustix-release;/etc/trustix-version"
-[NixOS]
+[nixos]
Image = "NixOS.png"
;detected in "/etc/os-release"
-[FreeEOS]
-Image = "free-eos.png"
-Files = "/etc/eos-version"
+[free-eos]
+Image = "FreeEOS.png"
+Files = "/etc/eos-release;/etc/eos-version"
+
+[nutyx]
+Image = "NuTyX.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
[generations]
Image = "Generations.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[Generations Linux]
+[generations linux]
Image = "Generations.png"
;detected in "/etc/os-release"
-[Manjaro Linux]
-Image = "Manjaro.png"
-Files = "/etc/manjaro-release"
+[dahliaos]
+Image = "dahliaOS.png"
;detected in "/etc/os-release"
-[ManjaroLinux]
-Image = "Manjaro.png"
+[laclin]
+Image = "Laclin.png"
+Mode = "Detection"
+Files = "/etc/laclin-release"
+Files2 = "/etc/laclin-release"
+;detected in "/etc/os-release" but wrong name Slackware
+
+[artix]
+Image = "Artix.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[Arch Linux]
-Image = "Arch.png"
-Files = "/etc/arch-release"
+[artix linux]
+Image = "Artix.png"
+Mode = "Detection"
+Files = "/etc/artix-release"
;detected in "/etc/os-release"
-[Arch]
+[xerolinux]
+Image = "XeroLinux.png"
+Mode = "Detection"
+Files = "/etc/xerolinux-release"
+;detected in "/etc/os-release"
+
+[xerolinux-kde]
+Image = "XeroLinux.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/arch-release" none
+
+[cachyos linux]
+Image = "CachyOS.png"
+;detected in "/etc/os-release"
+
+[cachyos]
+Image = "CachyOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/arch-release" none
+
+[archcraft]
+Image = "Archcraft.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" none
+
+[snal linux]
+Image = "Snal.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" none
+
+[snal]
+Image = "Snal.png"
+Name = "Snal Linux"
+Files = "/etc/snal-release"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/arch-release" none
+
+[archman]
+Image = "Archman.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" none
+
+[rebornos]
+Image = "RebornOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/os-release" Arch
+;wrong in "/etc/arch-release" Arch
+
+[rebornos linux]
+Image = "RebornOS.png"
+;wrong in "/etc/os-release"
+
+[bluestarlinux]
+Image = "Bluestar.png"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/os-release" Arch
+;wrong in "/etc/arch-release" Arch
+
+[endeavouros]
+Image = "EndeavourOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" Arch
+
+[arcolinux]
+Image = "Arco.png"
+Mode = "Detection"
+Files = "/etc/arcolinux-release"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" Arch
+
+[garuda]
+Image = "Garuda.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/arch-release" Arch
+
+[garuda linux]
+Image = "Garuda.png"
+;detected in "/etc/os-release"
+
+[ubuntu biglinux]
+Image = "BigLinux.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[biglinux based in ubuntu]
+Image = "BigLinux.png"
+;detected in "/etc/os-release"
+
+[biglinux based in ubuntu 19.04]
+Image = "BigLinux.png"
+;detected in "/etc/lsb-release"
+
+[deepin biglinux]
+Image = "BigLinux.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/deepin-version" Deepin
+;wrong in "/etc/os-release" Deepin
+;wrong in "/etc/debian_version" Debian
+
+[biglinux based in manjaro linux]
+Image = "BigLinux.png"
+Name = "BigLinux"
+Files = "/etc/big-release"
+Mode = "Detection"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" Manjaro
+;wrong in "/etc/manjaro-release" Manjaro
+
+[maboxlinux]
+Image = "Mabox.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/os-release" Manjaro
+;wrong in "/etc/manjaro-release" Manjaro
+;wrong in "/etc/arch-release" Arch | Manjaro
+
+[netrunner]
+Image = "Netrunner.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[netrunnerse]
+Image = "Netrunner.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[netrunner rolling]
+Image = "Netrunner.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/manjaro-release" Manjaro
+
+[voidlinux]
+Image = "Void.png"
+;detected in "lsb_release -a""
+
+[void]
+Image = "Void.png"
+;detected in "/etc/os-release"
+
+[arch]
Image = "Arch.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[Cobalt]
+[cobalt]
Image = "Cobalt.png"
Files = "/etc/cobalt-release"
-[LinuxFromScratch]
+[linuxfromscratch]
Image = "LFS.png"
Files = "/etc/lfs-release"
-[Rubix]
+[rubix]
Image = "Rubix.png"
Files = "/etc/rubix-version"
-[Tails]
+[tails]
Image = "Tails.png"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[Tanglu]
+[tanglu]
Image = "Tanglu.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/debian_version" Debian
-[Tanglu GNU/Linux]
+[tanglu gnu/linux]
Image = "Tanglu.png"
;detected in "/etc/os-release"
-[Mer]
+[gnoppix]
+Image = "Gnoppix.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[kali]
+Image = "Kali.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[kali gnu/linux]
+Image = "Kali.png"
+;detected in "/etc/os-release"
+
+[urukos]
+Image = "Uruk.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[pureos]
+Image = "PureOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[pureos gnu/linux]
+Image = "PureOS.png"
+;detected in "/etc/os-release"
+
+[septor]
+Image = "Septor.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[salentos]
+Image = "SalentOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[pop]
+Image = "Pop.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[pop!_os]
+Image = "Pop.png"
+;detected in "/etc/os-release"
+
+[mer]
Image = "Mer.png"
Mode = "Analyse"
Files = "/etc/mer-release;/etc/meego-release;/etc/moblin-release"
;detected in "lsb_release -a"
;detected in "/etc/system-release"
-[KaOS]
+[kaos]
Image = "KaOS.png"
Files = "/etc/KaOS-release"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
-[CoreOS]
+[openmamba]
+Image = "OpenMamba.png"
+Files = "/etc/openmamba-release"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;detected in "/etc/system-release"
+
+[coreos]
Image = "CoreOS.png"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
-[BOSS]
+[container linux by coreos]
+Image = "Container.png"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+
+[parrot]
+Image = "Parrot.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[parrot os]
+Image = "Parrot.png"
+;detected in "/etc/os-release"
+
+[boss]
Image = "BOSS.png"
Name = "BOSS GNU/Linux"
Files = "/etc/boss_version"
;detected in "lsb_release -a"
;wrong in "/etc/debian_version" Debian
-[BOSS GNU/Linux]
+[boss gnu/linux]
Image = "BOSS.png"
;detected in "/etc/os-release"
-[BOSS Server Beta]
+[boss server beta]
Image = "BOSS.png"
;detected in "lsb_release -a"
-[Canaima]
+[solus]
+Image = "Solus.png"
+Files = "/etc/solus-release"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+
+[solus operating system]
+Image = "Solus.png"
+;detected in "/etc/os-release"
+
+[canaima]
Image = "Canaima.png"
Name = "Canaima GNU/Linux"
Files = "/etc/canaima_version"
;detected in "lsb_release -a"
;wrong in "/etc/debian_version" Debian
-[Canaima GNU/Linux]
+[canaima gnu/linux]
Image = "Canaima.png"
;detected in "/etc/os-release"
-[Semplice]
+[ubuntu runtu]
+Image = "Runtu.png"
+;detected in "/etc/lsb-release"
+;wrong detected in "lsb_release -a" Ubuntu
+;wrong in "/etc/os-release" Ubuntu
+;wrong in "/etc/debian_version" Debian
+
+[semplice]
Image = "Semplice.png"
Name = "Semplice"
Files = "/etc/semplice_version"
@@ -179,78 +712,139 @@ Files = "/etc/semplice_version"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[SolydXK]
+[solydxk]
Image = "SolydXK.png"
+Name = "SolydXK"
+Mode = "Detection"
+Files = "/etc/solydxk/info"
+Files2 = "/etc/solydxk/info"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-;detected in "/etc/solydxk/info"
;wrong in "/etc/os-release" Debian GNU/Linux
;wrong in "/etc/debian_version" Debian
-[HandyLinux]
+[handylinux]
Image = "Handy.png"
Files = "/etc/handylinux_version"
;detected in "lsb_release -a"
;wrong in "/etc/os-release" Debian GNU/Linux
;wrong in "/etc/debian_version" Debian
-[Parsix]
+[parsix gnu/linux]
+Image = "Parsix.png"
+;detected in "/etc/os-release" but sometimes wrong version
+;wrong in "/etc/debian_version" Debian
+
+[parsix]
Image = "Parsix.png"
Files = "/etc/parsix-version"
;detected in "lsb_release -a"
-;detected or wrong version in "/etc/os-release" | Parsix 4.0
;wrong in "/etc/debian_version" Debian
-[Linaro]
+[linaro]
Image = "Linaro.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[LinuxDeepin]
+[endless]
+Image = "Endless.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[uos]
+Image = "UOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[deepin]
+Image = "Deepin.png"
+Files = "/etc/deepin-version"
+Mode = "Detection"
+Files2 = "/etc/deepin-version"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[linuxdeepin]
Image = "Deepin.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/os-release" Debian GNU/Linux
;wrong in "/etc/debian_version" Debian
-[Ultimate_Edition]
+[ultimate_edition]
Image = "UltimateEdition.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[elementary OS]
+[elementary]
+Image = "elementaryOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;wrong in "/etc/debian_version" Debian
+
+[elementary os]
Image = "elementaryOS.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[PearLinux]
+[jingos]
+Image = "JingOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[kde neon]
+Image = "KDEneon.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[kde]
+Image = "KDEneon.png"
+;detected in "lsb_release -a"
+
+[neon]
+Image = "KDEneon.png"
+;detected in "/etc/lsb-release"
+
+[pearlinux]
Image = "Pear.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/os-release" Ubuntu
;wrong in "/etc/debian_version" Debian
-[Pear Linux]
+[pear linux]
Image = "Pear.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/os-release" Ubuntu
;wrong in "/etc/debian_version" Debian
-[PearOS]
+[pearos]
Image = "Pear.png"
-;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-;wrong in "/etc/os-release" Ubuntu
+;detected in "/etc/os-release" (simetimes wrong Ubuntu)
;wrong in "/etc/debian_version" Debian
-[SolusOS]
+[neon pearos]
+Image = "Pear.png"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[solusos]
Image = "SolusOS.png"
Files = "/etc/solusos_version"
;detected in "lsb_release -a"
@@ -258,79 +852,139 @@ Files = "/etc/solusos_version"
;wrong in "/etc/os-release" Debian GNU/Linux
;wrong in "/etc/debian_version" Debian
-[LinuxMint]
+[linuxmint]
Image = "Mint.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/os-release" Ubuntu
;wrong in "/etc/debian_version" Debian
-[Trisquel]
+[linux mint]
+Image = "Mint.png"
+;detected in "/etc/os-release
+
+[lmde]
+Image = "Mint.png"
+;detected in "/etc/os-release"
+
+[trisquel]
Image = "Trisquel.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/os-release" Ubuntu
;wrong in "/etc/debian_version" Debian
-[Zorin]
+[zorin]
Image = "Zorin.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong or almost in "/etc/os-release" Ubuntu | Zorin OS
;wrong in "/etc/debian_version" Debian
-[Zorin OS]
+[zorin os]
Image = "Zorin.png"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[Netrunner]
-Image = "Netrunner.png"
-;detected in "lsb_release -a"
-;detected in "/etc/lsb-release"
-;detected in "/etc/os-release"
-;wrong in "/etc/debian_version" Debian
-
-[NetrunnerSE]
-Image = "Netrunner.png"
-;detected in "lsb_release -a"
-;detected in "/etc/lsb-release"
-;wrong in "/etc/debian_version" Debian
-
-[Netrunner Rolling]
-Image = "Netrunner.png"
-;detected in "/etc/os-release"
-;wrong in "/etc/manjaro-release" Manjaro
-
-[Peppermint]
+[peppermint]
Image = "Peppermint.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[Ubuntu]
-Image = "Ubuntu.png"
+[nitrux]
+Image = "Nitrux.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
;wrong in "/etc/debian_version" Debian
-[Chakra]
+[ubuntu vanillaos]
+Image = "Vanilla.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+
+[vanillaos]
+Image = "Vanilla.png"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[makululinux]
+Image = "Makulu.png"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu makululinux]
+Image = "Makulu.png"
+;detected in "lsb_release -a"
+
+[linuxfx]
+Image = "Linuxfx.png"
+Name="Linuxfx"
+Files = "/etc/fx.version"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[ubuntu linuxfx]
+Image = "Linuxfx.png"
+;detected in "lsb_release -a"
+
+[ubuntu]
+Image = "Ubuntu.png"
+Test = "nolsbfirst"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/debian_version" Debian
+
+[chakra]
Image = "Chakra.png"
Files = "/etc/chakra-release"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[The Chakra-Project]
+[the chakra-project]
Image = "Chakra.png"
;detected in "/etc/os-release"
-[IYCC]
-Image = "iycc.png"
+[iycc]
+Image = "IYCC.png"
;detected in "/etc/lsb-release"
-[Mageia]
+[openeuler]
+Image = "openEuler.png"
+Files = "/etc/openEuler-release"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+;detected in "/etc/system-release"
+
+[risios]
+Image = "risiOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/fedora-release"
+;detected in "/etc/os-release"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[hipserv]
+Image = "HipServ.png"
+;detected in "/etc/redhat-release"
+
+[neokylin]
+Image = "NeoKylin.png"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[neokylin linux desktop]
+Image = "NeoKylin.png"
+Files = "/etc/neokylin-release;/etc/cs2c-release"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+
+[mageia]
Image = "Mageia.png"
Files = "/etc/mageia-release"
;detected in "lsb_release -a"
@@ -340,161 +994,305 @@ Files = "/etc/mageia-release"
;detected in "/etc/redhat-release"
;detected in "/etc/os-release"
-[PLD Linux]
+[pld linux]
Image = "PLD.png"
Files = "/etc/pld-release"
;detected in "/etc/os-release"
-[LFS]
+[lfs]
Image = "lfs.png"
Files = "/etc/lfs-release;/etc/lfs_version"
-[HLFS]
+[hlfs]
Image = "lfs.png"
Files = "/etc/hlfs-release;/etc/hlfs_version"
-[Synology]
+[synology]
Image = "Synology.png"
Mode = "Detection"
Files = "/etc/synoinfo.conf"
Files2 = "/etc/VERSION"
-[Alpine]
-Name = "Alpine"
+[alpine]
Image = "Alpine.png"
+Name = "Alpine"
Files = "/etc/alpine-release"
-[Puppy]
-Image = "Puppy.png"
+[fatdog64 linux]
+Image = "Fatdog.png"
+;detected in "/etc/os-release"
+
+[fatdog64]
+Image = "Fatdog.png"
+Name = "Fatdog64 Linux"
+Files = "/etc/fatdog-version"
;detected in "/etc/DISTRO_SPECS"
-[Lucid]
+[puppy]
+Image = "Puppy.png"
+Name = "Puppy"
+;detected in "/etc/os-release"
+;detected in "/etc/DISTRO_SPECS"
+
+[lucid]
+Image = "Puppy.png"
Name = "Lucid Puppy"
+;detected in "/etc/DISTRO_SPECS"
+
+[slacko puppy]
Image = "Puppy.png"
;detected in "/etc/DISTRO_SPECS"
-[Slacko Puppy]
+[wary puppy]
Image = "Puppy.png"
;detected in "/etc/DISTRO_SPECS"
-[Wary Puppy]
-Image = "Puppy.png"
+[quirky]
+Image = "EasyOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+
+[easyos]
+Image = "EasyOS.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+
+[easy os]
+Image = "EasyOS.png"
;detected in "/etc/DISTRO_SPECS"
-[Turbolinux]
+[easy beaver]
+Image = "EasyOS.png"
+;detected in "/etc/DISTRO_SPECS"
+
+[easy pyro64]
+Image = "EasyOS.png"
+;detected in "/etc/DISTRO_SPECS"
+
+[easy buster64]
+Image = "EasyOS.png"
+;detected in "/etc/DISTRO_SPECS"
+
+[easy dunfell64]
+Image = "EasyOS.png"
+;detected in "/etc/DISTRO_SPECS"
+
+[easyos kirkstone64]
+Image = "EasyOS.png"
+;detected in "/etc/DISTRO_SPECS"
+
+[turbolinux]
Image = "Turbo.png"
Files = "/etc/turbolinux-release"
-[Amazon]
+[amazon]
Image = "Amazon.png"
;detected in "/etc/system-release"
-[AmazonAMI]
+[amazonami]
Image = "Amazon.png"
;detected in "lsb_release -a"
-[RedFlag]
+[amazon linux ami]
+Image = "Amazon.png"
+;detected in /etc/os-release
+
+[redflag]
Image = "RedFlag.png"
Files = "/etc/redflag-release"
;detected in "/etc/system-release"
-[Red Flag inWise]
+[red flag inwise]
Image = "RedFlag.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
-[StartOS]
+[startos]
Image = "StartOS.png"
Files = "/etc/startos-release"
;detected in "lsb_release -a"
-[PisiLinux]
+[openelec]
+Image = "OpenELEC.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+
+[libreelec]
+Image = "LibreELEC.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+
+[lakka]
+Image = "Lakka.png"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+
+[pisilinux]
Image = "Pisi.png"
Files = "/etc/pisilinux-release"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[Pisi_Linux]
+[pisi_linux]
Image = "Pisi.png"
;detected in "/etc/system-release"
-[SME]
+[springdale linux]
+Image = "Springdale.png"
+;detected in "/etc/os-release"
+
+[springdale]
+Image = "Springdale.png"
+Files = "/etc/PU_IAS-release;/etc/puias-release;/etc/springdale-release"
+;detected in "lsb_release -a"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[nethserver]
+Image = "NethServer.png"
+Files = "/etc/nethserver-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/centos-release" CentOS
+;wrong in "/etc/redhat-release" CentOS
+;wrong in "/etc/system-release" CentOS
+
+[sme]
Image = "SMEServer.png"
Files = "/etc/e-smith-release"
;wrong in "/etc/centos-release" CentOS
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[SMEServer]
+[smeserver]
Image = "SMEServer.png"
;detected in "lsb_release -a"
-[Scientific]
+[koozali sme server]
+Image = "SMEServer.png"
+;detected in "/etc/os-release"
+
+[scientific]
Image = "Scientific.png"
;detected in "lsb_release -a"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[ScientificSL]
+[scientificsl]
Image = "Scientific.png"
;detected in "lsb_release -a"
-[ScientificCERNSLC]
+[scientificcernslc]
Image = "Scientific.png"
;detected in "lsb_release -a"
-[ScientificFermi]
+[scientificfermi]
Image = "Scientific.png"
;detected in "lsb_release -a"
-[ScientificFermiLTS]
+[scientificfermilts]
Image = "Scientific.png"
;detected in "lsb_release -a"
-[ScientificSLF]
+[scientificslf]
Image = "Scientific.png"
;detected in "lsb_release -a"
-[ClearOS]
+[clear linux os]
+Image = "Clear.png"
+;detected in "/etc/os-release"
+
+[clearos]
Image = "ClearOS.png"
Files = "/etc/clearos-release"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[CloudLinuxServer]
+[cloudlinuxserver]
Image = "Cloud.png"
;detected in "lsb_release -a"
-[CloudLinux]
+[cloudlinux]
Image = "Cloud.png"
Files = "/etc/CloudLinux-release"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-; at the end because some distros may also have the same files (like SMEServer)
-[CentOS]
+[almalinux]
+Image = "Alma.png"
+Files = "/etc/almalinux-release"
+;detected in "lsb_release -a"
+;wrong in "/etc/centos-release" CentOS
+;detected in "/etc/os-release"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[virtuozzo linux]
+Image = "Virtuozzo.png"
+;detected in "/etc/os-release"
+
+[virtuozzo]
+Image = "Virtuozzo.png"
+Files = "/etc/vzlinux-release"
+;detected in "lsb_release -a"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[rocky linux]
+Image = "Rocky.png"
+;detected in "/etc/os-release"
+
+[rocky]
+Image = "Rocky.png"
+Files = "/etc/rocky-release"
+;detected in "lsb_release -a"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[eurolinux]
+Image = "EuroLinux.png"
+Files = "/etc/el-release"
+;detected in "lsb_release -a"
+;detected in "/etc/os-release"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[centosstream]
Image = "CentOS.png"
+;detected in "lsb_release -a"
+
+[centos stream]
+Image = "CentOS.png"
+;detected in "/etc/os-release"
+
+[centos linux]
+Image = "CentOS.png"
+;detected in "/etc/os-release"
+
+; at the end because some distros may also have the same files (like SMEServer, AlmaLinux, NethServer)
+[centos]
+Image = "CentOS.png"
+Test = "nolsbfirst"
Files = "/etc/centos-release"
;detected in "lsb_release -a"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[Oracle]
+[oracle]
Image = "Oracle.png"
Files = "/etc/oracle-release;/etc/enterprise-release"
;detected in "/etc/system-release"
;wrong in "/etc/redhat-release" RedHat
-[OracleServer]
+[oracleserver]
Image = "Oracle.png"
;detected in "lsb_release -a"
-[EnterpriseEnterpriseServer]
+[enterpriseenterpriseserver]
Image = "Oracle.png"
;detected in "lsb_release -a"
-[PCLinuxOS]
+[pclinuxos]
Image = "PCLinuxOS.png"
Files = "/etc/pclinuxos-release"
;detected in "lsb_release -a"
@@ -503,7 +1301,12 @@ Files = "/etc/pclinuxos-release"
;detected in "/etc/mandrake-release;/etc/mandrakelinux-release"
;detected in "/etc/redhat-release"
-[Salix]
+[absolute]
+Image = "Absolute.png"
+;delected in "/etc/os-release"
+;wrong in "/etc/slackware-version" Slackware
+
+[salix]
Image = "Salix.png"
Mode = "Detection"
Files = "/etc/salix-update-notifier.conf"
@@ -511,48 +1314,66 @@ Files2 = "/etc/slackware-version"
;wrong in "/etc/os-release" Slackware
;wrong in "/etc/slackware-version" Slackware
-[Slax]
+[slax]
Image = "Slax.png"
Files = "/etc/slax-version"
;wrong in "/etc/os-release" Slackware
;wrong in "/etc/slackware-version" Slackware
-[SMS]
+[sms]
Image = "SMS.png"
Files = "/etc/sms-version"
;detected in "/etc/os-release"
;wrong in "/etc/slackware-version" Slackware
-[Porteus]
+[porteus]
Image = "Porteus.png"
Files = "/etc/porteus-version"
;wrong in "/etc/os-release" Slackware
;wrong in "/etc/slackware-version" Slackware
-[Vector]
+[vector]
Image = "Vector.png"
Files = "/etc/vector-version"
;wrong in "/etc/slackware-version" Slackware
-[Zenwalk]
-Name = "Zenwalk"
+[zenwalk]
Image = "Zenwalk.png"
+Name = "Zenwalk"
Files = "/etc/zenwalk-version"
;detected in "/etc/os-release"
;wrong in "/etc/slackware-version" Slackware
-[Calculate]
+[slackware]
+Image = "Slackware.png"
+Files = "/etc/slackware-release"
+;detected in "/etc/os-release"
+;detected in "/etc/slackware-version"
+
+[calculate]
Image = "Calculate.png"
;detected in "/etc/gentoo-release"
;wrong in "/etc/os-release" Gentoo
-[Tizen]
+[redcore]
+Image = "Redcore.png"
+;detected in "/etc/gentoo-release"
+;detected in "/etc/os-release"
+
+[exherbo]
+Image = "Exherbo.png"
+Name = "Exherbo Linux"
+Mode = "Detection"
+Files = "/etc/exherbo-release"
+;detected in "/etc/os-release"
+
+[tizen]
Image = "Tizen.png"
Files = "/etc/tizen-release"
;detected in "/etc/system-release"
;detected in "/etc/os-release"
-[Sabayon]
+[sabayon]
Image = "Sabayon.png"
Files = "/etc/sabayon-release"
;detected in "lsb_release -a"
@@ -561,7 +1382,7 @@ Files = "/etc/sabayon-release"
;detected in "/etc/os-release"
;wrong in "/etc/gentoo-release" Gentoo
-[VortexBox]
+[vortexbox]
Image = "VortexBox.png"
Name = "VortexBox"
Files = "/etc/vortexbox/vortexbox-version"
@@ -570,28 +1391,50 @@ Files = "/etc/vortexbox/vortexbox-version"
;wrong in "/etc/system-release" Fedora
;wrong in "/etc/os-release" Fedora
-[ALT]
+[nobara]
+Image = "Nobara.png"
+Files = "/etc/nobara-release"
+;detected in "lsb_release -a"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[nobara linux]
+Image = "Nobara.png"
+;detected in "/etc/os-release"
+
+[ultramarine]
+Image = "Ultramarine.png"
+Files = "/etc/ultramarine-release"
+;detected in "lsb_release -a"
+;detected in "/etc/redhat-release"
+;detected in "/etc/system-release"
+
+[ultramarine linux]
+Image = "Ultramarine.png"
+;detected in "/etc/os-release"
+
+[alt]
Image = "ALT.png"
Files = "/etc/altlinux-release"
;detected in "/etc/fedora-release"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[Simply]
+[alt linux]
+Image = "ALT.png"
+;detected in "/etc/os-release"
+
+[simply]
Image = "ALT.png"
;detected in "/etc/fedora-release"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[Simply Linux]
+[simply linux]
Image = "ALT.png"
;detected in "/etc/os-release"
-[ALT Linux]
-Image = "ALT.png"
-;detected in "/etc/os-release"
-
-[Fuduntu]
+[fuduntu]
Image = "Fuduntu.png"
Files = "/etc/fuduntu-release"
;detected in "lsb_release -a"
@@ -600,60 +1443,92 @@ Files = "/etc/fuduntu-release"
;detected in "/etc/redhat-release"
;detected in "/etc/system-release"
-[gNewSense]
+[gnewsense]
Image = "gNewSense.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/debian_version" Debian
-[SteamOS]
+[steamos]
Image = "SteamOS.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;wrong in "/etc/debian_version" Debian
-[SteamOS GNU/Linux]
+[steamos gnu/linux]
Image = "SteamOS.png"
;detected in "/etc/os-release"
-[Raspbian]
+[raspbian]
Image = "Raspbian.png"
;detected in "lsb_release -a"
;wrong in "/etc/debian_version" Debian
-[Raspbian GNU/Linux]
+[raspbian gnu/linux]
Image = "Raspbian.png"
;detected in "/etc/os-release"
-[Debian]
-Name = "Debian"
+[devuan]
+Image = "Devuan.png"
+Name = "Devuan"
+Files = "/etc/devuan_version"
+;detected in "lsb_release -a"
+;wrong in "/etc/debian_version" Debian
+
+[devuan gnu/linux]
+Image = "Devuan.png"
+;detected in "/etc/os-release"
+
+[debian]
Image = "Debian.png"
+Test = "nolsbfirst"
+Name = "Debian"
Files = "/etc/debian_release"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
;detected in "/etc/debian_version"
-[Debian GNU/Linux]
+[debian gnu/linux]
Image = "Debian.png"
;detected in "/etc/os-release"
-[openSUSE]
+[opensuse]
Image = "openSUSE.png"
;detected in "/etc/os-release"
;detected in "/etc/SuSE-release"
-[openSUSE project]
+[opensuse leap]
+Image = "openSUSE.png"
+;detected in "/etc/os-release"
+
+[opensuse tumbleweed]
+Image = "openSUSE.png"
+;detected in "/etc/os-release"
+
+[opensuse project]
Image = "openSUSE.png"
;detected in "lsb_release -a"
-; at the end because some distros may also have the same files (like openSUSE)
-[SUSE LINUX]
+[suse linux opensuse]
+Image = "openSUSE.png"
+;detected in "lsb_release -a"
+
+[suse]
+Image = "SUSE.png"
+;detected in "/etc/SuSE-release"
+
+[sles]
+Image = "SUSE.png"
+;detected in "/etc/os-release"
+
+; at the end because some distros may also have the same files (like openSUSE, SUSE)
+[suse linux]
Image = "SUSE.png"
Mode = "Analyse"
Files = "/etc/SuSE-release;/etc/UnitedLinux-release"
; at the end because some distros may also have the same files (like Sabayon, Calculate)
-[Gentoo]
+[gentoo]
Image = "Gentoo.png"
Mode = "Analyse"
Files = "/etc/gentoo-release"
@@ -661,13 +1536,7 @@ Files = "/etc/gentoo-release"
;detected in "/etc/lsb-release"
;detected in "/etc/os-release"
-; at the end because some distros may also have the same files (like Salix, Slax, SMS, Porteus, Vector, Zenwalk)
-[Slackware]
-Image = "Slackware.png"
-Files = "/etc/slackware-release;/etc/slackware-version"
-;detected in "/etc/os-release"
-
-[Qubes]
+[qubes]
Image = "Qubes.png"
Files = "/etc/qubes-release"
;detected in "/etc/fedora-release"
@@ -675,7 +1544,7 @@ Files = "/etc/qubes-release"
;detected in "/etc/system-release"
;detected in "/etc/os-release"
-[Korora]
+[korora]
Image = "Korora.png"
;detected in "lsb_release -a"
;detected in "/etc/fedora-release"
@@ -684,7 +1553,7 @@ Image = "Korora.png"
;detected in "/etc/os-release"
; at the end because some distros may also have the same files (like Fuduntu, ALT, VortexBox, Qubes, Korora)
-[Fedora]
+[fedora]
Image = "Fedora.png"
Mode = "Analyse"
Files = "/etc/fedora-release"
@@ -693,11 +1562,11 @@ Files = "/etc/fedora-release"
;detected in "/etc/system-release"
;detected in "/etc/os-release"
-[FedoraCore]
+[fedoracore]
Image = "Fedora.png"
;detected in "/etc/lsb-release"
-[OpenMandriva]
+[openmandriva]
Image = "OpenMandriva.png"
;detected in "/etc/rosa-release"
;detected in "/etc/mandriva-release"
@@ -706,43 +1575,74 @@ Image = "OpenMandriva.png"
;detected in "/etc/distro-release"
;detected in "/etc/system-release"
-[OpenMandriva Lx]
+[openmandriva lx]
Image = "OpenMandriva.png"
;detected in "/etc/os-release"
-[OpenMandrivaLinux]
+[openmandrivalinux]
Image = "OpenMandriva.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[ROSA MarathonLinux]
+[rosa marathonlinux]
Image = "ROSA.png"
;detected in "/etc/lsb-release"
-[RosaDesktop.Marathon]
+[rosadesktop.marathon]
Image = "ROSA.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[RosaDesktop.Fresh]
+[rosadesktop.fresh]
Image = "ROSA.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
-[ROSA Desktop Fresh]
+[rosa desktop fresh]
Image = "ROSA.png"
;detected in "/etc/os-release"
-[ROSA Marathon]
+[rosa marathon]
Image = "ROSA.png"
;detected in "/etc/os-release"
-[ROSAEnterpriseServer]
+[rosaenterpriseserver]
Image = "ROSA.png"
;detected in "lsb_release -a"
+[manjarolinux]
+Image = "Manjaro.png"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+
+[manjaro-arm]
+Image = "Manjaro.png"
+Name = "Manjaro ARM"
+Files = "/etc/manjaro-arm-version"
+;detected in "lsb_release -a"
+;detected in "/etc/lsb-release"
+;detected in "/etc/os-release"
+;wrong in "/etc/arch-release" Arch
+
+; at the end because some distros may also have the same files (like BigLinux, Mabox, Netrunner)
+[manjaro linux]
+Image = "Manjaro.png"
+Files = "/etc/manjaro-release"
+;detected in "/etc/os-release"
+
+[arch linux arm]
+Image = "Arch.png"
+;detected in "/etc/os-release"
+
+; at the end because some distros may also have the same files (like XeroLinux-KDE, CachyOS, Archcraft, Snal, Archman, RebornOS, BluestarLinux, EndeavourOS, Arco, Garuda, BigLinux, Mabox, Manjaro ARM)
+[arch linux]
+Image = "Arch.png"
+Mode = "Analyse"
+Files = "/etc/arch-release"
+;detected in "/etc/os-release"
+
; at the end because some distros may also have the same files (like OpenMandriva)
-[ROSA]
+[rosa]
Image = "ROSA.png"
Mode = "Analyse"
Files = "/etc/rosa-release"
@@ -752,13 +1652,13 @@ Files = "/etc/rosa-release"
;detected in "/etc/mandrake-release;/etc/mandrakelinux-release"
;detected in "/etc/redhat-release"
-[MandrivaLinux]
+[mandrivalinux]
Image = "Mandrake.png"
;detected in "lsb_release -a"
;detected in "/etc/lsb-release"
; at the end because some distros may also have the same files (like Mageia, PCLinuxOS, ROSA, OpenMandriva)
-[Mandriva]
+[mandriva]
Image = "Mandrake.png"
Mode = "Analyse"
Files = "/etc/mandriva-release"
@@ -766,34 +1666,38 @@ Files = "/etc/mandriva-release"
;detected in "/etc/redhat-release"
; at the end because some distros may also have the same files (like Mandriva, Mageia, PCLinuxOS, ROSA, OpenMandriva)
-[Mandrake]
+[mandrake]
Image = "Mandrake.png"
Mode = "Analyse"
Files = "/etc/mandrake-release;/etc/mandrakelinux-release"
-; at the end because some distros may also have the same files (like SMEServer, Fuduntu, ALT, VortexBox, Qubes, Korora, Fedora, CentOS, Oracle, Scientific, CloudLinux, Mandrake, MandrivaLinux, Mageia, PCLinuxOS, ROSA, OpenMandriva)
-[RedHat]
+; at the end because some distros may also have the same files (like SMEServer, Fuduntu, ALT, VortexBox, Qubes, Korora, Fedora, CentOS, Oracle, Scientific, CloudLinux, Mandrake, MandrivaLinux, Mageia, PCLinuxOS, ROSA, OpenMandriva, HipServ, NeoKylin, Springdale, Rocky, EuroLinux, AlmaLinux, Virtuozzo, NethServer)
+[redhat]
Image = "RedHat.png"
Mode = "Analyse"
Files = "/etc/redhat-release;/etc/redhat_version"
;detected in "/etc/system-release"
-[Red Hat Enterprise Linux Everything]
+[red hat enterprise linux server]
Image = "RedHat.png"
;detected in "/etc/os-release"
-[RedHatEnterpriseES]
+[red hat enterprise linux everything]
+Image = "RedHat.png"
+;detected in "/etc/os-release"
+
+[redhatenterprisees]
Image = "RedHat.png"
;detected in "lsb_release -a"
-[RedHatEnterpriseAS]
+[redhatenterpriseas]
Image = "RedHat.png"
;detected in "lsb_release -a"
-[RedHatEnterpriseServer]
+[redhatenterpriseserver]
Image = "RedHat.png"
;detected in "lsb_release -a"
-[RedHatEnterpriseClient]
+[redhatenterpriseclient]
Image = "RedHat.png"
;detected in "lsb_release -a"
diff --git a/root/opt/phpsysinfo/data/languages.ini b/root/opt/phpsysinfo/data/languages.ini
index c93aea4..eb3a21c 100644
--- a/root/opt/phpsysinfo/data/languages.ini
+++ b/root/opt/phpsysinfo/data/languages.ini
@@ -304,6 +304,7 @@ _en_BE="English Belgium"
_en_BW="English Botswana"
_en_BZ="English Belize"
_en_CA="English Canada"
+_en_DK="English Denmark"
_en_Dsrt="English (Deseret)"
_en_Dsrt_US="English United States (Deseret)"
_en="English"
@@ -687,7 +688,6 @@ _nob="Norwegian Bokmål"
_no_NO="Norwegian Nynorsk Norway"
_no_NO_NY="Norwegian Nynorsk Norway"
_no="Norwegian"
-_no="Norwegian Nynorsk"
_nor="Norwegian"
_norwegian="Norwegian"
_nr="South Ndebele"
diff --git a/root/opt/phpsysinfo/data/osnames.ini b/root/opt/phpsysinfo/data/osnames.ini
index 08751d6..b42cad9 100644
--- a/root/opt/phpsysinfo/data/osnames.ini
+++ b/root/opt/phpsysinfo/data/osnames.ini
@@ -18,8 +18,13 @@
5.0="Lollipop"
5.1="Lollipop"
6.0="Marshmallow"
+7.0="Nougat"
+7.1="Nougat"
+8.0="Oreo"
+8.1="Oreo"
+9.0="Pie"
-[OS X]
+[macOS]
10.0="Cheetah"
10.1="Puma"
10.2="Jaguar"
@@ -32,3 +37,31 @@
10.9="Mavericks"
10.10="Yosemite"
10.11="El Capitan"
+10.12="Sierra"
+10.13="High Sierra"
+10.14="Mojave"
+10.15="Catalina"
+11="Big Sur"
+12="Monterey"
+13="Ventura"
+14="Sonoma"
+
+[win10]
+10240="1507"
+10586="1511"
+14393="1607"
+15063="1703"
+16299="1709"
+17134="1803"
+17763="1809"
+18362="1903"
+18363="1909"
+19041="2004"
+19042="20H2"
+19043="21H1"
+19044="21H2"
+19045="22H2"
+21996="leaked"
+22000="21H2"
+22621="22H2"
+22631="23H2"
diff --git a/root/opt/phpsysinfo/data/raspberry.ini b/root/opt/phpsysinfo/data/raspberry.ini
new file mode 100644
index 0000000..ef37b01
--- /dev/null
+++ b/root/opt/phpsysinfo/data/raspberry.ini
@@ -0,0 +1,46 @@
+[old]
+2="B (PCB 1.0 Egoman)"
+3="B ECN0001 (PCB 1.0 Egoman)"
+4="B (PCB 2.0 Sony UK)"
+5="B (PCB 2.0 Qisda)"
+6="B (PCB 2.0 Egoman)"
+7="A (PCB 2.0 Egoman)"
+8="A (PCB 2.0 Sony UK)"
+9="A (PCB 2.0 Qisda)"
+13="B (PCB 2.0 Egoman)"
+14="B (PCB 2.0 Sony UK)"
+15="B (PCB 2.0 Qisda)"
+16="B+ (PCB 1.0 Sony UK)"
+17="Compute Module (PCB 1.0 Sony UK)"
+18="A+ (PCB 1.1 Sony UK)"
+19="B+ (PCB 1.2 Embest)"
+20="Compute Module (PCB 1.0 Embest)"
+21="A+ (PCB 1.1 Embest)"
+
+[model]
+0="A"
+1="B"
+2="A+"
+3="B+"
+4="2 B"
+5="Alpha"
+6="Compute Module"
+8="3 B"
+9="Zero"
+10="Compute Module 3"
+12="Zero W"
+13="3 B+"
+14="3 A+"
+16="Compute Module 3+"
+17="4 B"
+19="400"
+20="Compute Module 4"
+21="Compute Module 4S"
+23="5"
+
+[manufacturer]
+0="Sony UK"
+1="Egoman"
+2="Embest"
+3="Sony Japan"
+4="Embest"
diff --git a/root/opt/phpsysinfo/gfx/attention.gif b/root/opt/phpsysinfo/gfx/attention.gif
new file mode 100644
index 0000000..48ede3f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/attention.gif differ
diff --git a/root/opt/phpsysinfo/gfx/attention.png b/root/opt/phpsysinfo/gfx/attention.png
deleted file mode 100644
index 4170d83..0000000
Binary files a/root/opt/phpsysinfo/gfx/attention.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/blank.gif b/root/opt/phpsysinfo/gfx/blank.gif
new file mode 100644
index 0000000..75b945d
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/blank.gif differ
diff --git a/root/opt/phpsysinfo/gfx/body.gif b/root/opt/phpsysinfo/gfx/body.gif
new file mode 100644
index 0000000..76d78ff
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/body.gif differ
diff --git a/root/opt/phpsysinfo/gfx/body.png b/root/opt/phpsysinfo/gfx/body.png
deleted file mode 100644
index 6bcf6d3..0000000
Binary files a/root/opt/phpsysinfo/gfx/body.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_minus.gif b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.gif
new file mode 100644
index 0000000..dde6ba3
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.gif differ
diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png
deleted file mode 100644
index b47ce55..0000000
Binary files a/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_plus.gif b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.gif
new file mode 100644
index 0000000..17efd6f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.gif differ
diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png
deleted file mode 100644
index 9ab4a89..0000000
Binary files a/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/down_black.gif b/root/opt/phpsysinfo/gfx/down_black.gif
new file mode 100644
index 0000000..81ba91c
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/down_black.gif differ
diff --git a/root/opt/phpsysinfo/gfx/down_gray.gif b/root/opt/phpsysinfo/gfx/down_gray.gif
new file mode 100644
index 0000000..3223369
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/down_gray.gif differ
diff --git a/root/opt/phpsysinfo/gfx/favicon.gif b/root/opt/phpsysinfo/gfx/favicon.gif
new file mode 100644
index 0000000..ffecf9b
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/favicon.gif differ
diff --git a/root/opt/phpsysinfo/gfx/favicon.png b/root/opt/phpsysinfo/gfx/favicon.png
deleted file mode 100644
index 80dd64e..0000000
Binary files a/root/opt/phpsysinfo/gfx/favicon.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/htmlrest.gif b/root/opt/phpsysinfo/gfx/htmlrest.gif
new file mode 100644
index 0000000..cf2e2c0
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/htmlrest.gif differ
diff --git a/root/opt/phpsysinfo/gfx/images/4MLinux.png b/root/opt/phpsysinfo/gfx/images/4MLinux.png
index e504fc7..ea6a141 100644
Binary files a/root/opt/phpsysinfo/gfx/images/4MLinux.png and b/root/opt/phpsysinfo/gfx/images/4MLinux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/AIX.png b/root/opt/phpsysinfo/gfx/images/AIX.png
index f3314f5..2a16e0a 100644
Binary files a/root/opt/phpsysinfo/gfx/images/AIX.png and b/root/opt/phpsysinfo/gfx/images/AIX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/ALT.png b/root/opt/phpsysinfo/gfx/images/ALT.png
index e9c64a5..17f6a84 100644
Binary files a/root/opt/phpsysinfo/gfx/images/ALT.png and b/root/opt/phpsysinfo/gfx/images/ALT.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Absolute.png b/root/opt/phpsysinfo/gfx/images/Absolute.png
new file mode 100644
index 0000000..1e676d5
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Absolute.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Alma.png b/root/opt/phpsysinfo/gfx/images/Alma.png
new file mode 100644
index 0000000..04a0a5f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Alma.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Amazon.png b/root/opt/phpsysinfo/gfx/images/Amazon.png
index 3ed73c2..f641862 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Amazon.png and b/root/opt/phpsysinfo/gfx/images/Amazon.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Android.png b/root/opt/phpsysinfo/gfx/images/Android.png
index fdf819e..96992b4 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Android.png and b/root/opt/phpsysinfo/gfx/images/Android.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Apple.png b/root/opt/phpsysinfo/gfx/images/Apple.png
index ac1178d..c8635b4 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Apple.png and b/root/opt/phpsysinfo/gfx/images/Apple.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Archcraft.png b/root/opt/phpsysinfo/gfx/images/Archcraft.png
new file mode 100644
index 0000000..09e5d9e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Archcraft.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Archman.png b/root/opt/phpsysinfo/gfx/images/Archman.png
new file mode 100644
index 0000000..6d3b31e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Archman.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Arco.png b/root/opt/phpsysinfo/gfx/images/Arco.png
new file mode 100644
index 0000000..f32ace9
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Arco.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Armbian.png b/root/opt/phpsysinfo/gfx/images/Armbian.png
new file mode 100644
index 0000000..eed2a82
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Armbian.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Artix.png b/root/opt/phpsysinfo/gfx/images/Artix.png
new file mode 100644
index 0000000..4a43a38
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Artix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/BOSS.png b/root/opt/phpsysinfo/gfx/images/BOSS.png
index 23745c6..a8138ab 100644
Binary files a/root/opt/phpsysinfo/gfx/images/BOSS.png and b/root/opt/phpsysinfo/gfx/images/BOSS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/BigLinux.png b/root/opt/phpsysinfo/gfx/images/BigLinux.png
new file mode 100644
index 0000000..428d0b4
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/BigLinux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Bluestar.png b/root/opt/phpsysinfo/gfx/images/Bluestar.png
new file mode 100644
index 0000000..5ea4ed4
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Bluestar.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Bodhi.png b/root/opt/phpsysinfo/gfx/images/Bodhi.png
new file mode 100644
index 0000000..a9e7124
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Bodhi.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/CachyOS.png b/root/opt/phpsysinfo/gfx/images/CachyOS.png
new file mode 100644
index 0000000..6cc2fc1
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/CachyOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Calculate.png b/root/opt/phpsysinfo/gfx/images/Calculate.png
index 808b295..ee08a6e 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Calculate.png and b/root/opt/phpsysinfo/gfx/images/Calculate.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Canaima.png b/root/opt/phpsysinfo/gfx/images/Canaima.png
index 7388c47..12705ea 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Canaima.png and b/root/opt/phpsysinfo/gfx/images/Canaima.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/CentOS.png b/root/opt/phpsysinfo/gfx/images/CentOS.png
index e2c8a11..6424841 100644
Binary files a/root/opt/phpsysinfo/gfx/images/CentOS.png and b/root/opt/phpsysinfo/gfx/images/CentOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Chakra.png b/root/opt/phpsysinfo/gfx/images/Chakra.png
index 06a5609..1a2c8b0 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Chakra.png and b/root/opt/phpsysinfo/gfx/images/Chakra.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Clear.png b/root/opt/phpsysinfo/gfx/images/Clear.png
new file mode 100644
index 0000000..70994b7
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Clear.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/ClearOS.png b/root/opt/phpsysinfo/gfx/images/ClearOS.png
index f2a1f2e..3d88eee 100644
Binary files a/root/opt/phpsysinfo/gfx/images/ClearOS.png and b/root/opt/phpsysinfo/gfx/images/ClearOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Cloud.png b/root/opt/phpsysinfo/gfx/images/Cloud.png
index 0b0fd83..12f9b6c 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Cloud.png and b/root/opt/phpsysinfo/gfx/images/Cloud.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Cobalt.png b/root/opt/phpsysinfo/gfx/images/Cobalt.png
index 674def8..826095d 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Cobalt.png and b/root/opt/phpsysinfo/gfx/images/Cobalt.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Container.png b/root/opt/phpsysinfo/gfx/images/Container.png
new file mode 100644
index 0000000..4cde49e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Container.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/CoreOS.png b/root/opt/phpsysinfo/gfx/images/CoreOS.png
index c955f77..d120535 100644
Binary files a/root/opt/phpsysinfo/gfx/images/CoreOS.png and b/root/opt/phpsysinfo/gfx/images/CoreOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Crux.png b/root/opt/phpsysinfo/gfx/images/Crux.png
index ba889da..8915812 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Crux.png and b/root/opt/phpsysinfo/gfx/images/Crux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Darwin.png b/root/opt/phpsysinfo/gfx/images/Darwin.png
index a4d8d2d..e54b4a0 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Darwin.png and b/root/opt/phpsysinfo/gfx/images/Darwin.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Debian.png b/root/opt/phpsysinfo/gfx/images/Debian.png
index 00093f9..76c1628 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Debian.png and b/root/opt/phpsysinfo/gfx/images/Debian.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Deepin.png b/root/opt/phpsysinfo/gfx/images/Deepin.png
index 8a9e502..ed576ed 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Deepin.png and b/root/opt/phpsysinfo/gfx/images/Deepin.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Devuan.png b/root/opt/phpsysinfo/gfx/images/Devuan.png
new file mode 100644
index 0000000..d1888d6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Devuan.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/DragonFly.png b/root/opt/phpsysinfo/gfx/images/DragonFly.png
index e51e1ae..574bb6a 100644
Binary files a/root/opt/phpsysinfo/gfx/images/DragonFly.png and b/root/opt/phpsysinfo/gfx/images/DragonFly.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/DrayOS.png b/root/opt/phpsysinfo/gfx/images/DrayOS.png
new file mode 100644
index 0000000..8bef5c1
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/DrayOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/EasyOS.png b/root/opt/phpsysinfo/gfx/images/EasyOS.png
new file mode 100644
index 0000000..2b9b202
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/EasyOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Eisfair.png b/root/opt/phpsysinfo/gfx/images/Eisfair.png
index 3450cef..4d5aa07 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Eisfair.png and b/root/opt/phpsysinfo/gfx/images/Eisfair.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Elive.png b/root/opt/phpsysinfo/gfx/images/Elive.png
new file mode 100644
index 0000000..8adcafb
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Elive.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/EndeavourOS.png b/root/opt/phpsysinfo/gfx/images/EndeavourOS.png
new file mode 100644
index 0000000..3aa60cf
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/EndeavourOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Endless.png b/root/opt/phpsysinfo/gfx/images/Endless.png
new file mode 100644
index 0000000..bb902d6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Endless.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/EuroLinux.png b/root/opt/phpsysinfo/gfx/images/EuroLinux.png
new file mode 100644
index 0000000..219759e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/EuroLinux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/ExTiX.png b/root/opt/phpsysinfo/gfx/images/ExTiX.png
new file mode 100644
index 0000000..f0348b7
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/ExTiX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Exherbo.png b/root/opt/phpsysinfo/gfx/images/Exherbo.png
new file mode 100644
index 0000000..505cb65
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Exherbo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Fatdog.png b/root/opt/phpsysinfo/gfx/images/Fatdog.png
new file mode 100644
index 0000000..58380a3
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Fatdog.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Fedora.png b/root/opt/phpsysinfo/gfx/images/Fedora.png
index 883e96a..0b0a451 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Fedora.png and b/root/opt/phpsysinfo/gfx/images/Fedora.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Feren.png b/root/opt/phpsysinfo/gfx/images/Feren.png
new file mode 100644
index 0000000..d1168c8
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Feren.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Foresight.png b/root/opt/phpsysinfo/gfx/images/Foresight.png
index 34d427d..213257b 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Foresight.png and b/root/opt/phpsysinfo/gfx/images/Foresight.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/FortiOS.png b/root/opt/phpsysinfo/gfx/images/FortiOS.png
new file mode 100644
index 0000000..3a7a604
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/FortiOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/FreeEOS.png b/root/opt/phpsysinfo/gfx/images/FreeEOS.png
new file mode 100644
index 0000000..eaed473
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/FreeEOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/FreeNAS.png b/root/opt/phpsysinfo/gfx/images/FreeNAS.png
new file mode 100644
index 0000000..f28907c
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/FreeNAS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Frugalware.png b/root/opt/phpsysinfo/gfx/images/Frugalware.png
index b30c4cd..8bd8439 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Frugalware.png and b/root/opt/phpsysinfo/gfx/images/Frugalware.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Fuduntu.png b/root/opt/phpsysinfo/gfx/images/Fuduntu.png
index 73e2e43..472d473 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Fuduntu.png and b/root/opt/phpsysinfo/gfx/images/Fuduntu.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Garuda.png b/root/opt/phpsysinfo/gfx/images/Garuda.png
new file mode 100644
index 0000000..6f2ab6e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Garuda.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Generations.png b/root/opt/phpsysinfo/gfx/images/Generations.png
index f3adfd0..1938481 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Generations.png and b/root/opt/phpsysinfo/gfx/images/Generations.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Gentoo.png b/root/opt/phpsysinfo/gfx/images/Gentoo.png
index d806c57..c4ad6b0 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Gentoo.png and b/root/opt/phpsysinfo/gfx/images/Gentoo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Gnoppix.png b/root/opt/phpsysinfo/gfx/images/Gnoppix.png
new file mode 100644
index 0000000..c637148
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Gnoppix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Gobo.png b/root/opt/phpsysinfo/gfx/images/Gobo.png
index 9efde30..ed53d8a 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Gobo.png and b/root/opt/phpsysinfo/gfx/images/Gobo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Guix.png b/root/opt/phpsysinfo/gfx/images/Guix.png
new file mode 100644
index 0000000..b4fc134
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Guix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/HPUX.png b/root/opt/phpsysinfo/gfx/images/HPUX.png
index 6f55dd4..0ebb4ad 100644
Binary files a/root/opt/phpsysinfo/gfx/images/HPUX.png and b/root/opt/phpsysinfo/gfx/images/HPUX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Haiku.png b/root/opt/phpsysinfo/gfx/images/Haiku.png
index 21fb376..1a60a0c 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Haiku.png and b/root/opt/phpsysinfo/gfx/images/Haiku.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/HipServ.png b/root/opt/phpsysinfo/gfx/images/HipServ.png
new file mode 100644
index 0000000..4df68cc
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/HipServ.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Hurd.png b/root/opt/phpsysinfo/gfx/images/Hurd.png
new file mode 100644
index 0000000..1d851e5
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Hurd.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/IPFire.png b/root/opt/phpsysinfo/gfx/images/IPFire.png
index 5e7870f..c367882 100644
Binary files a/root/opt/phpsysinfo/gfx/images/IPFire.png and b/root/opt/phpsysinfo/gfx/images/IPFire.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/IYCC.png b/root/opt/phpsysinfo/gfx/images/IYCC.png
new file mode 100644
index 0000000..0c30fab
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/IYCC.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/JingOS.png b/root/opt/phpsysinfo/gfx/images/JingOS.png
new file mode 100644
index 0000000..22edebc
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/JingOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/KDEneon.png b/root/opt/phpsysinfo/gfx/images/KDEneon.png
new file mode 100644
index 0000000..3a92b55
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/KDEneon.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/KaOS.png b/root/opt/phpsysinfo/gfx/images/KaOS.png
index ea6bdad..0e50498 100644
Binary files a/root/opt/phpsysinfo/gfx/images/KaOS.png and b/root/opt/phpsysinfo/gfx/images/KaOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Kaisen.png b/root/opt/phpsysinfo/gfx/images/Kaisen.png
new file mode 100644
index 0000000..4316e68
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Kaisen.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Kali.png b/root/opt/phpsysinfo/gfx/images/Kali.png
new file mode 100644
index 0000000..2fb8e28
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Kali.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Kodachi.png b/root/opt/phpsysinfo/gfx/images/Kodachi.png
new file mode 100644
index 0000000..2c39783
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Kodachi.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Korora.png b/root/opt/phpsysinfo/gfx/images/Korora.png
index 8abd2f3..2595fd0 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Korora.png and b/root/opt/phpsysinfo/gfx/images/Korora.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/LFS.png b/root/opt/phpsysinfo/gfx/images/LFS.png
index 3796f48..a009ccb 100644
Binary files a/root/opt/phpsysinfo/gfx/images/LFS.png and b/root/opt/phpsysinfo/gfx/images/LFS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/LXLE.png b/root/opt/phpsysinfo/gfx/images/LXLE.png
new file mode 100644
index 0000000..1e76f12
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/LXLE.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Laclin.png b/root/opt/phpsysinfo/gfx/images/Laclin.png
new file mode 100644
index 0000000..9667874
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Laclin.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Lakka.png b/root/opt/phpsysinfo/gfx/images/Lakka.png
new file mode 100644
index 0000000..7e7c18b
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Lakka.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/LibreELEC.png b/root/opt/phpsysinfo/gfx/images/LibreELEC.png
new file mode 100644
index 0000000..77dfab2
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/LibreELEC.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Linaro.png b/root/opt/phpsysinfo/gfx/images/Linaro.png
index b076f7a..244f4cd 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Linaro.png and b/root/opt/phpsysinfo/gfx/images/Linaro.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Linspire.png b/root/opt/phpsysinfo/gfx/images/Linspire.png
new file mode 100644
index 0000000..3371fab
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Linspire.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Linux.png b/root/opt/phpsysinfo/gfx/images/Linux.png
new file mode 100644
index 0000000..77cd23f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Linux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/LinuxLite.png b/root/opt/phpsysinfo/gfx/images/LinuxLite.png
new file mode 100644
index 0000000..f321bb3
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/LinuxLite.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Linuxfx.png b/root/opt/phpsysinfo/gfx/images/Linuxfx.png
new file mode 100644
index 0000000..0e3b005
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Linuxfx.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Lunar.png b/root/opt/phpsysinfo/gfx/images/Lunar.png
index 4d25176..89e0449 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Lunar.png and b/root/opt/phpsysinfo/gfx/images/Lunar.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/MX.png b/root/opt/phpsysinfo/gfx/images/MX.png
new file mode 100644
index 0000000..1d12776
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/MX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Mabox.png b/root/opt/phpsysinfo/gfx/images/Mabox.png
new file mode 100644
index 0000000..604d9f0
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Mabox.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Mageia.png b/root/opt/phpsysinfo/gfx/images/Mageia.png
index 0bfd1a8..c885533 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Mageia.png and b/root/opt/phpsysinfo/gfx/images/Mageia.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Makulu.png b/root/opt/phpsysinfo/gfx/images/Makulu.png
new file mode 100644
index 0000000..d197c35
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Makulu.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Mandrake.png b/root/opt/phpsysinfo/gfx/images/Mandrake.png
index 09ccd20..f93e148 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Mandrake.png and b/root/opt/phpsysinfo/gfx/images/Mandrake.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Manjaro.png b/root/opt/phpsysinfo/gfx/images/Manjaro.png
index ae3a642..17af946 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Manjaro.png and b/root/opt/phpsysinfo/gfx/images/Manjaro.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Mer.png b/root/opt/phpsysinfo/gfx/images/Mer.png
index 9048964..2eeb38e 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Mer.png and b/root/opt/phpsysinfo/gfx/images/Mer.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Milis.png b/root/opt/phpsysinfo/gfx/images/Milis.png
new file mode 100644
index 0000000..2ee4e8b
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Milis.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Minix.png b/root/opt/phpsysinfo/gfx/images/Minix.png
index 73feadb..1858151 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Minix.png and b/root/opt/phpsysinfo/gfx/images/Minix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Mint.png b/root/opt/phpsysinfo/gfx/images/Mint.png
index a886bb3..31d86e4 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Mint.png and b/root/opt/phpsysinfo/gfx/images/Mint.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NeoKylin.png b/root/opt/phpsysinfo/gfx/images/NeoKylin.png
new file mode 100644
index 0000000..3fcf530
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NeoKylin.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Neptune.png b/root/opt/phpsysinfo/gfx/images/Neptune.png
new file mode 100644
index 0000000..798cd33
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Neptune.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NetBSD.png b/root/opt/phpsysinfo/gfx/images/NetBSD.png
index d3ea334..ebcc33f 100644
Binary files a/root/opt/phpsysinfo/gfx/images/NetBSD.png and b/root/opt/phpsysinfo/gfx/images/NetBSD.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NethServer.png b/root/opt/phpsysinfo/gfx/images/NethServer.png
new file mode 100644
index 0000000..1f5aad3
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NethServer.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Netrunner.png b/root/opt/phpsysinfo/gfx/images/Netrunner.png
index 7616118..7813e27 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Netrunner.png and b/root/opt/phpsysinfo/gfx/images/Netrunner.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NexentaStor.png b/root/opt/phpsysinfo/gfx/images/NexentaStor.png
new file mode 100644
index 0000000..9aca266
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NexentaStor.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Nitrux.png b/root/opt/phpsysinfo/gfx/images/Nitrux.png
new file mode 100644
index 0000000..7c8d640
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Nitrux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NixOS.png b/root/opt/phpsysinfo/gfx/images/NixOS.png
index 054a0b0..c580b5e 100644
Binary files a/root/opt/phpsysinfo/gfx/images/NixOS.png and b/root/opt/phpsysinfo/gfx/images/NixOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Nobara.png b/root/opt/phpsysinfo/gfx/images/Nobara.png
new file mode 100644
index 0000000..e1f56a4
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Nobara.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/NuTyX.png b/root/opt/phpsysinfo/gfx/images/NuTyX.png
new file mode 100644
index 0000000..2cd37d2
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NuTyX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Omarine.png b/root/opt/phpsysinfo/gfx/images/Omarine.png
new file mode 100644
index 0000000..1b4eb3e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Omarine.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OmniOS.png b/root/opt/phpsysinfo/gfx/images/OmniOS.png
new file mode 100644
index 0000000..ff6c26e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OmniOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenBSD.png b/root/opt/phpsysinfo/gfx/images/OpenBSD.png
index 84da5c7..b269f12 100644
Binary files a/root/opt/phpsysinfo/gfx/images/OpenBSD.png and b/root/opt/phpsysinfo/gfx/images/OpenBSD.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenELEC.png b/root/opt/phpsysinfo/gfx/images/OpenELEC.png
new file mode 100644
index 0000000..42b3537
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenELEC.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenIndiana.png b/root/opt/phpsysinfo/gfx/images/OpenIndiana.png
new file mode 100644
index 0000000..553d8dc
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenIndiana.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenMamba.png b/root/opt/phpsysinfo/gfx/images/OpenMamba.png
new file mode 100644
index 0000000..a7d9c88
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenMamba.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenMandriva.png b/root/opt/phpsysinfo/gfx/images/OpenMandriva.png
index 0df0ebf..94348e8 100644
Binary files a/root/opt/phpsysinfo/gfx/images/OpenMandriva.png and b/root/opt/phpsysinfo/gfx/images/OpenMandriva.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenSolaris.png b/root/opt/phpsysinfo/gfx/images/OpenSolaris.png
new file mode 100644
index 0000000..15eefe6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenSolaris.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/OpenWRT.png b/root/opt/phpsysinfo/gfx/images/OpenWRT.png
new file mode 100644
index 0000000..d163c41
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenWRT.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png b/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png
index 4a3a4bb..23b5d1b 100644
Binary files a/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png and b/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/PLD.png b/root/opt/phpsysinfo/gfx/images/PLD.png
index 2b09d7d..41cfd68 100644
Binary files a/root/opt/phpsysinfo/gfx/images/PLD.png and b/root/opt/phpsysinfo/gfx/images/PLD.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Parrot.png b/root/opt/phpsysinfo/gfx/images/Parrot.png
new file mode 100644
index 0000000..cfe6d6e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Parrot.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Parsix.png b/root/opt/phpsysinfo/gfx/images/Parsix.png
index 9cddb1d..4b4671d 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Parsix.png and b/root/opt/phpsysinfo/gfx/images/Parsix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Pear.png b/root/opt/phpsysinfo/gfx/images/Pear.png
index 8811a7b..d2c5e0b 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Pear.png and b/root/opt/phpsysinfo/gfx/images/Pear.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Peppermint.png b/root/opt/phpsysinfo/gfx/images/Peppermint.png
index 59d8e68..46e2f6d 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Peppermint.png and b/root/opt/phpsysinfo/gfx/images/Peppermint.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Photon.png b/root/opt/phpsysinfo/gfx/images/Photon.png
new file mode 100644
index 0000000..9d6e248
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Photon.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Pisi.png b/root/opt/phpsysinfo/gfx/images/Pisi.png
index 3d44955..09c1d6f 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Pisi.png and b/root/opt/phpsysinfo/gfx/images/Pisi.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Plop.png b/root/opt/phpsysinfo/gfx/images/Plop.png
new file mode 100644
index 0000000..e37eece
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Plop.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Pop.png b/root/opt/phpsysinfo/gfx/images/Pop.png
new file mode 100644
index 0000000..97736f0
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Pop.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Porteus.png b/root/opt/phpsysinfo/gfx/images/Porteus.png
index 0ddafdb..29c07d6 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Porteus.png and b/root/opt/phpsysinfo/gfx/images/Porteus.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Proxmox.png b/root/opt/phpsysinfo/gfx/images/Proxmox.png
new file mode 100644
index 0000000..203ac0b
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Proxmox.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Puppy.png b/root/opt/phpsysinfo/gfx/images/Puppy.png
index b4835e8..a009195 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Puppy.png and b/root/opt/phpsysinfo/gfx/images/Puppy.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/PureOS.png b/root/opt/phpsysinfo/gfx/images/PureOS.png
new file mode 100644
index 0000000..46b0163
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/PureOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Q4OS.png b/root/opt/phpsysinfo/gfx/images/Q4OS.png
new file mode 100644
index 0000000..1f76028
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Q4OS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/QNX.png b/root/opt/phpsysinfo/gfx/images/QNX.png
index cb0f559..cb22e83 100644
Binary files a/root/opt/phpsysinfo/gfx/images/QNX.png and b/root/opt/phpsysinfo/gfx/images/QNX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/QTS.png b/root/opt/phpsysinfo/gfx/images/QTS.png
new file mode 100644
index 0000000..0d4406b
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/QTS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/QuemOS.png b/root/opt/phpsysinfo/gfx/images/QuemOS.png
new file mode 100644
index 0000000..34d0168
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/QuemOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/ROSA.png b/root/opt/phpsysinfo/gfx/images/ROSA.png
index de0a0b5..eece93c 100644
Binary files a/root/opt/phpsysinfo/gfx/images/ROSA.png and b/root/opt/phpsysinfo/gfx/images/ROSA.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Raspbian.png b/root/opt/phpsysinfo/gfx/images/Raspbian.png
index 8c2ced5..85e5ad5 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Raspbian.png and b/root/opt/phpsysinfo/gfx/images/Raspbian.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/RebeccaBlackOS.png b/root/opt/phpsysinfo/gfx/images/RebeccaBlackOS.png
new file mode 100644
index 0000000..fde9985
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/RebeccaBlackOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/RebornOS.png b/root/opt/phpsysinfo/gfx/images/RebornOS.png
new file mode 100644
index 0000000..a7f5ca6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/RebornOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/RedFlag.png b/root/opt/phpsysinfo/gfx/images/RedFlag.png
index c291121..3763ca3 100644
Binary files a/root/opt/phpsysinfo/gfx/images/RedFlag.png and b/root/opt/phpsysinfo/gfx/images/RedFlag.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/RedHat.png b/root/opt/phpsysinfo/gfx/images/RedHat.png
index 2092015..3bec990 100644
Binary files a/root/opt/phpsysinfo/gfx/images/RedHat.png and b/root/opt/phpsysinfo/gfx/images/RedHat.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Redcore.png b/root/opt/phpsysinfo/gfx/images/Redcore.png
new file mode 100644
index 0000000..d00c340
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Redcore.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Regata.png b/root/opt/phpsysinfo/gfx/images/Regata.png
new file mode 100644
index 0000000..81cd7f2
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Regata.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/RoboLinux.png b/root/opt/phpsysinfo/gfx/images/RoboLinux.png
new file mode 100644
index 0000000..658106d
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/RoboLinux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Rocky.png b/root/opt/phpsysinfo/gfx/images/Rocky.png
new file mode 100644
index 0000000..479b5ee
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Rocky.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Runtu.png b/root/opt/phpsysinfo/gfx/images/Runtu.png
new file mode 100644
index 0000000..c410e6d
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Runtu.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SMEServer.png b/root/opt/phpsysinfo/gfx/images/SMEServer.png
index 75712f6..744b9a8 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SMEServer.png and b/root/opt/phpsysinfo/gfx/images/SMEServer.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SMS.png b/root/opt/phpsysinfo/gfx/images/SMS.png
index fdabecd..3dd4784 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SMS.png and b/root/opt/phpsysinfo/gfx/images/SMS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SUSE.png b/root/opt/phpsysinfo/gfx/images/SUSE.png
index f4a3536..a4d1126 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SUSE.png and b/root/opt/phpsysinfo/gfx/images/SUSE.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Sabayon.png b/root/opt/phpsysinfo/gfx/images/Sabayon.png
index 8213c2b..bed8c2a 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Sabayon.png and b/root/opt/phpsysinfo/gfx/images/Sabayon.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SalentOS.png b/root/opt/phpsysinfo/gfx/images/SalentOS.png
new file mode 100644
index 0000000..8b4043c
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SalentOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Salix.png b/root/opt/phpsysinfo/gfx/images/Salix.png
index fe1b474..759f1b2 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Salix.png and b/root/opt/phpsysinfo/gfx/images/Salix.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Scientific.png b/root/opt/phpsysinfo/gfx/images/Scientific.png
index cb5621f..27e31bd 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Scientific.png and b/root/opt/phpsysinfo/gfx/images/Scientific.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Semplice.png b/root/opt/phpsysinfo/gfx/images/Semplice.png
index 9875c7e..9322a04 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Semplice.png and b/root/opt/phpsysinfo/gfx/images/Semplice.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Septor.png b/root/opt/phpsysinfo/gfx/images/Septor.png
new file mode 100644
index 0000000..a797ba6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Septor.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Siduction.png b/root/opt/phpsysinfo/gfx/images/Siduction.png
new file mode 100644
index 0000000..6443e84
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Siduction.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Slax.png b/root/opt/phpsysinfo/gfx/images/Slax.png
index 6f01c94..10d3176 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Slax.png and b/root/opt/phpsysinfo/gfx/images/Slax.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SliTaz.png b/root/opt/phpsysinfo/gfx/images/SliTaz.png
index 8dd4293..3fb1aed 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SliTaz.png and b/root/opt/phpsysinfo/gfx/images/SliTaz.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SmartOS.png b/root/opt/phpsysinfo/gfx/images/SmartOS.png
new file mode 100644
index 0000000..459283c
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SmartOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Snal.png b/root/opt/phpsysinfo/gfx/images/Snal.png
new file mode 100644
index 0000000..97b1814
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Snal.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Solaris.png b/root/opt/phpsysinfo/gfx/images/Solaris.png
new file mode 100644
index 0000000..cec7ad5
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Solaris.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Solus.png b/root/opt/phpsysinfo/gfx/images/Solus.png
new file mode 100644
index 0000000..002cb3a
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Solus.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SolusOS.png b/root/opt/phpsysinfo/gfx/images/SolusOS.png
index 522d160..63bcb19 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SolusOS.png and b/root/opt/phpsysinfo/gfx/images/SolusOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SolydXK.png b/root/opt/phpsysinfo/gfx/images/SolydXK.png
index 2143593..2c21d1c 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SolydXK.png and b/root/opt/phpsysinfo/gfx/images/SolydXK.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Sparky.png b/root/opt/phpsysinfo/gfx/images/Sparky.png
new file mode 100644
index 0000000..6e58344
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Sparky.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Springdale.png b/root/opt/phpsysinfo/gfx/images/Springdale.png
new file mode 100644
index 0000000..507e262
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Springdale.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/StartOS.png b/root/opt/phpsysinfo/gfx/images/StartOS.png
index a133f42..ab48528 100644
Binary files a/root/opt/phpsysinfo/gfx/images/StartOS.png and b/root/opt/phpsysinfo/gfx/images/StartOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/SteamOS.png b/root/opt/phpsysinfo/gfx/images/SteamOS.png
index ed61bc3..ddd679e 100644
Binary files a/root/opt/phpsysinfo/gfx/images/SteamOS.png and b/root/opt/phpsysinfo/gfx/images/SteamOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Synology.png b/root/opt/phpsysinfo/gfx/images/Synology.png
index 06662d5..12e2718 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Synology.png and b/root/opt/phpsysinfo/gfx/images/Synology.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Tails.png b/root/opt/phpsysinfo/gfx/images/Tails.png
index 4058145..b090089 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Tails.png and b/root/opt/phpsysinfo/gfx/images/Tails.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Tanglu.png b/root/opt/phpsysinfo/gfx/images/Tanglu.png
index f215845..523a357 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Tanglu.png and b/root/opt/phpsysinfo/gfx/images/Tanglu.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/TinyCore.png b/root/opt/phpsysinfo/gfx/images/TinyCore.png
index cf72da4..3b18b95 100644
Binary files a/root/opt/phpsysinfo/gfx/images/TinyCore.png and b/root/opt/phpsysinfo/gfx/images/TinyCore.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Trisquel.png b/root/opt/phpsysinfo/gfx/images/Trisquel.png
index d632108..867f910 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Trisquel.png and b/root/opt/phpsysinfo/gfx/images/Trisquel.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/TrueNAS.png b/root/opt/phpsysinfo/gfx/images/TrueNAS.png
new file mode 100644
index 0000000..5a72723
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/TrueNAS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Turbo.png b/root/opt/phpsysinfo/gfx/images/Turbo.png
index 4d040d9..60c39d7 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Turbo.png and b/root/opt/phpsysinfo/gfx/images/Turbo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Tuxedo.png b/root/opt/phpsysinfo/gfx/images/Tuxedo.png
new file mode 100644
index 0000000..db40510
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Tuxedo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/UOS.png b/root/opt/phpsysinfo/gfx/images/UOS.png
new file mode 100644
index 0000000..e309a0d
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/UOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Ubuntu.png b/root/opt/phpsysinfo/gfx/images/Ubuntu.png
index a0ea4a4..7e9f8b6 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Ubuntu.png and b/root/opt/phpsysinfo/gfx/images/Ubuntu.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/UltimateEdition.png b/root/opt/phpsysinfo/gfx/images/UltimateEdition.png
index 9eb8f0b..baeab3b 100644
Binary files a/root/opt/phpsysinfo/gfx/images/UltimateEdition.png and b/root/opt/phpsysinfo/gfx/images/UltimateEdition.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Ultramarine.png b/root/opt/phpsysinfo/gfx/images/Ultramarine.png
new file mode 100644
index 0000000..2bd0f65
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Ultramarine.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Uruk.png b/root/opt/phpsysinfo/gfx/images/Uruk.png
new file mode 100644
index 0000000..106a195
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Uruk.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Vanilla.png b/root/opt/phpsysinfo/gfx/images/Vanilla.png
new file mode 100644
index 0000000..f3a37a2
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Vanilla.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Vector.png b/root/opt/phpsysinfo/gfx/images/Vector.png
index b469504..cb625ba 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Vector.png and b/root/opt/phpsysinfo/gfx/images/Vector.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Venom.png b/root/opt/phpsysinfo/gfx/images/Venom.png
new file mode 100644
index 0000000..d54939d
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Venom.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Virtuozzo.png b/root/opt/phpsysinfo/gfx/images/Virtuozzo.png
new file mode 100644
index 0000000..131be5f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Virtuozzo.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Void.png b/root/opt/phpsysinfo/gfx/images/Void.png
new file mode 100644
index 0000000..bc1bfdc
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Void.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/VortexBox.png b/root/opt/phpsysinfo/gfx/images/VortexBox.png
index db6158e..e3a98be 100644
Binary files a/root/opt/phpsysinfo/gfx/images/VortexBox.png and b/root/opt/phpsysinfo/gfx/images/VortexBox.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/WINNT.png b/root/opt/phpsysinfo/gfx/images/WINNT.png
new file mode 100644
index 0000000..47eeb02
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/WINNT.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Win11.png b/root/opt/phpsysinfo/gfx/images/Win11.png
new file mode 100644
index 0000000..0d7b8ac
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Win11.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Win2000.png b/root/opt/phpsysinfo/gfx/images/Win2000.png
index 3147daa..1ac8d7c 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Win2000.png and b/root/opt/phpsysinfo/gfx/images/Win2000.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Win8.png b/root/opt/phpsysinfo/gfx/images/Win8.png
index 96f0ae1..157d353 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Win8.png and b/root/opt/phpsysinfo/gfx/images/Win8.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/XeroLinux.png b/root/opt/phpsysinfo/gfx/images/XeroLinux.png
new file mode 100644
index 0000000..f2f1bda
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/XeroLinux.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Zenwalk.png b/root/opt/phpsysinfo/gfx/images/Zenwalk.png
index 0820e02..17c8bd9 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Zenwalk.png and b/root/opt/phpsysinfo/gfx/images/Zenwalk.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/Zorin.png b/root/opt/phpsysinfo/gfx/images/Zorin.png
index 215ea8a..ad9b2a3 100644
Binary files a/root/opt/phpsysinfo/gfx/images/Zorin.png and b/root/opt/phpsysinfo/gfx/images/Zorin.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/antiX.png b/root/opt/phpsysinfo/gfx/images/antiX.png
index 014811e..7c00384 100644
Binary files a/root/opt/phpsysinfo/gfx/images/antiX.png and b/root/opt/phpsysinfo/gfx/images/antiX.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/dahliaOS.png b/root/opt/phpsysinfo/gfx/images/dahliaOS.png
new file mode 100644
index 0000000..8c5c831
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/dahliaOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/elementaryOS.png b/root/opt/phpsysinfo/gfx/images/elementaryOS.png
index 263d4de..f50452a 100644
Binary files a/root/opt/phpsysinfo/gfx/images/elementaryOS.png and b/root/opt/phpsysinfo/gfx/images/elementaryOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/free-eos.png b/root/opt/phpsysinfo/gfx/images/free-eos.png
deleted file mode 100644
index 0cee490..0000000
Binary files a/root/opt/phpsysinfo/gfx/images/free-eos.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/images/gNewSense.png b/root/opt/phpsysinfo/gfx/images/gNewSense.png
index 8ea5932..767a9f9 100644
Binary files a/root/opt/phpsysinfo/gfx/images/gNewSense.png and b/root/opt/phpsysinfo/gfx/images/gNewSense.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/iycc.png b/root/opt/phpsysinfo/gfx/images/iycc.png
deleted file mode 100644
index 4a92f70..0000000
Binary files a/root/opt/phpsysinfo/gfx/images/iycc.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/images/openEuler.png b/root/opt/phpsysinfo/gfx/images/openEuler.png
new file mode 100644
index 0000000..c56d3a6
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/openEuler.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/pfSense.png b/root/opt/phpsysinfo/gfx/images/pfSense.png
index eeba67f..0042992 100644
Binary files a/root/opt/phpsysinfo/gfx/images/pfSense.png and b/root/opt/phpsysinfo/gfx/images/pfSense.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/risiOS.png b/root/opt/phpsysinfo/gfx/images/risiOS.png
new file mode 100644
index 0000000..79a5df5
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/risiOS.png differ
diff --git a/root/opt/phpsysinfo/gfx/images/unknown.png b/root/opt/phpsysinfo/gfx/images/unknown.png
index 63e5e3c..e7e4f9f 100644
Binary files a/root/opt/phpsysinfo/gfx/images/unknown.png and b/root/opt/phpsysinfo/gfx/images/unknown.png differ
diff --git a/root/opt/phpsysinfo/gfx/logo_32.gif b/root/opt/phpsysinfo/gfx/logo_32.gif
new file mode 100644
index 0000000..86c1b5e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/logo_32.gif differ
diff --git a/root/opt/phpsysinfo/gfx/logo_48.png b/root/opt/phpsysinfo/gfx/logo_48.png
deleted file mode 100644
index 2157475..0000000
Binary files a/root/opt/phpsysinfo/gfx/logo_48.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/next.gif b/root/opt/phpsysinfo/gfx/next.gif
new file mode 100644
index 0000000..97df05a
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/next.gif differ
diff --git a/root/opt/phpsysinfo/gfx/next.png b/root/opt/phpsysinfo/gfx/next.png
deleted file mode 100644
index 53a3475..0000000
Binary files a/root/opt/phpsysinfo/gfx/next.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/prev.gif b/root/opt/phpsysinfo/gfx/prev.gif
new file mode 100644
index 0000000..b55211e
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/prev.gif differ
diff --git a/root/opt/phpsysinfo/gfx/prev.png b/root/opt/phpsysinfo/gfx/prev.png
deleted file mode 100644
index 5c5c551..0000000
Binary files a/root/opt/phpsysinfo/gfx/prev.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/reload.gif b/root/opt/phpsysinfo/gfx/reload.gif
new file mode 100644
index 0000000..0b73329
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/reload.gif differ
diff --git a/root/opt/phpsysinfo/gfx/reload.png b/root/opt/phpsysinfo/gfx/reload.png
deleted file mode 100644
index 0de2656..0000000
Binary files a/root/opt/phpsysinfo/gfx/reload.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/right_black.gif b/root/opt/phpsysinfo/gfx/right_black.gif
new file mode 100644
index 0000000..fb7517f
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/right_black.gif differ
diff --git a/root/opt/phpsysinfo/gfx/right_gray.gif b/root/opt/phpsysinfo/gfx/right_gray.gif
new file mode 100644
index 0000000..9abe96a
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/right_gray.gif differ
diff --git a/root/opt/phpsysinfo/gfx/sort_asc.gif b/root/opt/phpsysinfo/gfx/sort_asc.gif
new file mode 100644
index 0000000..0c4d151
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_asc.gif differ
diff --git a/root/opt/phpsysinfo/gfx/sort_asc.png b/root/opt/phpsysinfo/gfx/sort_asc.png
deleted file mode 100644
index 6393e0e..0000000
Binary files a/root/opt/phpsysinfo/gfx/sort_asc.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/sort_both.gif b/root/opt/phpsysinfo/gfx/sort_both.gif
new file mode 100644
index 0000000..46bee9c
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_both.gif differ
diff --git a/root/opt/phpsysinfo/gfx/sort_both.png b/root/opt/phpsysinfo/gfx/sort_both.png
deleted file mode 100644
index 7a1c378..0000000
Binary files a/root/opt/phpsysinfo/gfx/sort_both.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/gfx/sort_desc.gif b/root/opt/phpsysinfo/gfx/sort_desc.gif
new file mode 100644
index 0000000..00e76f4
Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_desc.gif differ
diff --git a/root/opt/phpsysinfo/gfx/sort_desc.png b/root/opt/phpsysinfo/gfx/sort_desc.png
deleted file mode 100644
index b768c6f..0000000
Binary files a/root/opt/phpsysinfo/gfx/sort_desc.png and /dev/null differ
diff --git a/root/opt/phpsysinfo/includes/autoloader.inc.php b/root/opt/phpsysinfo/includes/autoloader.inc.php
index 75e6f7f..f3a2c44 100644
--- a/root/opt/phpsysinfo/includes/autoloader.inc.php
+++ b/root/opt/phpsysinfo/includes/autoloader.inc.php
@@ -8,7 +8,7 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: autoloader.inc.php 660 2012-08-27 11:08:40Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -22,7 +22,7 @@ error_reporting(E_ALL | E_STRICT);
*
* @return void
*/
-function __autoload($class_name)
+function psi_autoload($class_name)
{
//$class_name = str_replace('-', '', $class_name);
@@ -30,8 +30,8 @@ function __autoload($class_name)
$dirs = array('/plugins/'.strtolower($class_name).'/', '/includes/mb/', '/includes/ups/');
foreach ($dirs as $dir) {
- if (file_exists(APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php')) {
- include_once APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php';
+ if (file_exists(PSI_APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php')) {
+ include_once PSI_APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php';
return;
}
@@ -41,19 +41,21 @@ function __autoload($class_name)
$dirs = array('/includes/', '/includes/interface/', '/includes/to/', '/includes/to/device/', '/includes/os/', '/includes/plugin/', '/includes/xml/', '/includes/web/', '/includes/error/', '/includes/js/', '/includes/output/');
foreach ($dirs as $dir) {
- if (file_exists(APP_ROOT.$dir.'class.'.$class_name.'.inc.php')) {
- include_once APP_ROOT.$dir.'class.'.$class_name.'.inc.php';
+ if (file_exists(PSI_APP_ROOT.$dir.'class.'.$class_name.'.inc.php')) {
+ include_once PSI_APP_ROOT.$dir.'class.'.$class_name.'.inc.php';
return;
}
}
- $error = Error::singleton();
+ $error = PSI_Error::singleton();
- $error->addError("_autoload(\"".$class_name."\")", "autoloading of class file (class.".$class_name.".inc.php) failed!");
+ $error->addError("psi_autoload(\"".$class_name."\")", "autoloading of class file (class.".$class_name.".inc.php) failed!");
$error->errorsAsXML();
}
+spl_autoload_register('psi_autoload');
+
/**
* sets a user-defined error handler function
*
@@ -66,8 +68,10 @@ function __autoload($class_name)
*/
function errorHandlerPsi($level, $message, $file, $line)
{
- $error = Error::singleton();
- $error->addPhpError("errorHandlerPsi : ", "Level : ".$level." Message : ".$message." File : ".$file." Line : ".$line);
+ $error = PSI_Error::singleton();
+ if ((PSI_DEBUG && !preg_match("/^fgets\(|^stream_select\(/", $message)) || (($level !== 2) && ($level !== 8)) || !preg_match("/^[^:]*: open_basedir |^fopen\(|^fwrite\(|^is_readable\(|^file_exists\(|^fgets\(|^stream_select\(/", $message)) { // disable open_basedir, fopen, is_readable, file_exists, fgets and stream_select warnings and notices
+ $error->addPhpError("errorHandlerPsi : ", "Level : ".$level." Message : ".$message." File : ".$file." Line : ".$line);
+ }
}
set_error_handler('errorHandlerPsi');
diff --git a/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php
index d7885c0..a90b8a8 100644
--- a/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php
+++ b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php
@@ -8,7 +8,7 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.CommonFunctions.inc.php 699 2012-09-15 11:57:13Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,12 +19,19 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class CommonFunctions
{
+ /**
+ * holds dmi memory data
+ *
+ * @var array
+ */
+ private static $_dmimd = null;
+
private static function _parse_log_file($string)
{
if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) {
@@ -56,24 +63,32 @@ class CommonFunctions
*
* @param string $strProgram name of the program
*
- * @return string complete path and name of the program
+ * @return string|null complete path and name of the program
*/
- private static function _findProgram($strProgram)
+ public static function _findProgram($strProgram)
{
$path_parts = pathinfo($strProgram);
if (empty($path_parts['basename'])) {
- return;
+ return null;
}
$arrPath = array();
- if ((PSI_OS == 'WINNT') && empty($path_parts['extension'])) {
- $strProgram .= '.exe';
- $path_parts = pathinfo($strProgram);
- }
+
if (empty($path_parts['dirname']) || ($path_parts['dirname'] == '.')) {
+ if ((PSI_OS == 'WINNT') && empty($path_parts['extension'])) {
+ $strProgram .= '.exe';
+ $path_parts = pathinfo($strProgram);
+ }
if (PSI_OS == 'WINNT') {
- $arrPath = preg_split('/;/', getenv("Path"), -1, PREG_SPLIT_NO_EMPTY);
+ if (self::readenv('Path', $serverpath)) {
+ $arrPath = preg_split('/;/', $serverpath, -1, PREG_SPLIT_NO_EMPTY);
+ }
} else {
- $arrPath = preg_split('/:/', getenv("PATH"), -1, PREG_SPLIT_NO_EMPTY);
+ if (self::readenv('PATH', $serverpath)) {
+ $arrPath = preg_split('/:/', $serverpath, -1, PREG_SPLIT_NO_EMPTY);
+ }
+ }
+ if (defined('PSI_UNAMEO') && (PSI_UNAMEO === 'Android') && !empty($arrPath)) {
+ array_push($arrPath, '/system/bin'); // Termux patch
}
if (defined('PSI_ADD_PATHS') && is_string(PSI_ADD_PATHS)) {
if (preg_match(ARRAY_EXP, PSI_ADD_PATHS)) {
@@ -82,13 +97,13 @@ class CommonFunctions
$arrPath = array_merge(array(PSI_ADD_PATHS), $arrPath); // In this order so $addpaths is before $arrPath when looking for a program
}
}
- } else {
+ } else { //directory defined
array_push($arrPath, $path_parts['dirname']);
$strProgram = $path_parts['basename'];
}
//add some default paths if we still have no paths here
- if (empty($arrPath) && PSI_OS != 'WINNT') {
+ if (empty($arrPath) && (PSI_OS != 'WINNT')) {
if (PSI_OS == 'Android') {
array_push($arrPath, '/system/bin');
} else {
@@ -97,97 +112,74 @@ class CommonFunctions
}
$exceptPath = "";
- if ((PSI_OS == 'WINNT') && (($windir = getenv("WinDir")) !== false)) {
- $windir = strtolower($windir);
+ if ((PSI_OS == 'WINNT') && self::readenv('WinDir', $windir)) {
foreach ($arrPath as $strPath) {
- if ((strtolower($strPath) == $windir."\\system32") && is_dir($windir."\\SysWOW64")) {
- $exceptPath = $windir."\\sysnative";
+ if ((strtolower($strPath) == strtolower($windir)."\\system32") && is_dir($windir."\\SysWOW64")) {
+ if (is_dir($windir."\\sysnative\\drivers")) { // or strlen(decbin(~0)) == 32; is_dir($windir."\\sysnative") sometimes does not work
+ $exceptPath = $windir."\\sysnative"; //32-bit PHP on 64-bit Windows
+ } else {
+ $exceptPath = $windir."\\SysWOW64"; //64-bit PHP on 64-bit Windows
+ }
array_push($arrPath, $exceptPath);
break;
}
}
- } else if (PSI_OS == 'Android') {
- $exceptPath = '/system/bin';
+ } elseif (PSI_OS == 'Android') {
+ $exceptPath = '/system/bin';
}
- // If open_basedir defined, fill the $open_basedir array with authorized paths,. (Not tested when no open_basedir restriction)
- if ((bool) ini_get('open_basedir')) {
- if (PSI_OS == 'WINNT') {
- $open_basedir = preg_split('/;/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY);
- } else {
- $open_basedir = preg_split('/:/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY);
- }
- }
foreach ($arrPath as $strPath) {
- // Path with trailing slash
+ // Path with and without trailing slash
if (PSI_OS == 'WINNT') {
- $strPathS = rtrim($strPath, "\\")."\\";
+ $strPath = rtrim($strPath, "\\");
+ $strPathS = $strPath."\\";
} else {
- $strPathS = rtrim($strPath, "/")."/";
- }
- // To avoid "open_basedir restriction in effect" error when testing paths if restriction is enabled
- if (isset($open_basedir)) {
- $inBaseDir = false;
- if (PSI_OS == 'WINNT') {
- foreach ($open_basedir as $openbasedir) {
- if (substr($openbasedir, -1)=="\\") {
- $str_Path = $strPathS;
- } else {
- $str_Path = $strPath;
- }
- if (stripos($str_Path, $openbasedir) === 0) {
- $inBaseDir = true;
- break;
- }
- }
- } else {
- foreach ($open_basedir as $openbasedir) {
- if (substr($openbasedir, -1)=="/") {
- $str_Path = $strPathS;
- } else {
- $str_Path = $strPath;
- }
- if (strpos($str_Path, $openbasedir) === 0) {
- $inBaseDir = true;
- break;
- }
- }
- }
- if ($inBaseDir == false) {
- continue;
- }
+ $strPath = rtrim($strPath, "/");
+ $strPathS = $strPath."/";
}
if (($strPath !== $exceptPath) && !is_dir($strPath)) {
continue;
}
- if (PSI_OS == 'WINNT') {
- $strProgrammpath = rtrim($strPath, "\\")."\\".$strProgram;
- } else {
- $strProgrammpath = rtrim($strPath, "/")."/".$strProgram;
- }
- if (is_executable($strProgrammpath)) {
+ $strProgrammpath = $strPathS.$strProgram;
+ if (is_executable($strProgrammpath) || ((PSI_OS == 'WINNT') && (strtolower($path_parts['extension']) == 'py') && is_file($strProgrammpath))) {
return $strProgrammpath;
}
}
+
+ return null;
}
/**
* Execute a system program. return a trim()'d result.
- * does very crude pipe checking. you need ' | ' for it to work
+ * does very crude pipe and multiple commands (on WinNT) checking. you need ' | ' or ' & ' for it to work
* ie $program = CommonFunctions::executeProgram('netstat', '-anp | grep LIST');
* NOT $program = CommonFunctions::executeProgram('netstat', '-anp|grep LIST');
*
* @param string $strProgramname name of the program
- * @param string $strArgs arguments to the program
+ * @param string $strArguments arguments to the program
* @param string &$strBuffer output of the command
* @param boolean $booErrorRep en- or disables the reporting of errors which should be logged
+ * @param int $timeout timeout value in seconds (default value is PSI_EXEC_TIMEOUT_INT)
*
* @return boolean command successfull or not
*/
- public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true)
+ public static function executeProgram($strProgramname, $strArguments, &$strBuffer, $booErrorRep = true, $timeout = PSI_EXEC_TIMEOUT_INT, $separator = '')
{
+ if (PSI_ROOT_FILESYSTEM !== '') { // disabled if ROOTFS defined
+
+ return false;
+ }
+
+ if ((PSI_OS != 'WINNT') && preg_match('/^([^=]+=[^ \t]+)[ \t]+(.*)$/', $strProgramname, $strmatch)) {
+ $strSet = $strmatch[1].' ';
+ $strProgramname = $strmatch[2];
+ } else {
+ $strSet = '';
+ }
+ $strAll = trim($strSet.$strProgramname.' '.$strArguments);
+
if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) {
- $out = self::_parse_log_file("Executing: ".trim($strProgramname.' '.$strArgs));
+ $out = self::_parse_log_file("Executing: ".$strAll);
if ($out == false) {
if (substr(PSI_LOG, 0, 1)=="-") {
$strBuffer = '';
@@ -201,42 +193,164 @@ class CommonFunctions
}
}
- $strBuffer = '';
- $strError = '';
- $pipes = array();
+ $PathStr = '';
+ if (defined('PSI_EMU_PORT') && !in_array($strProgramname, array('ping', 'snmpwalk'))) {
+ if (defined('PSI_SUDO_COMMANDS') && is_string(PSI_SUDO_COMMANDS)) {
+ if (preg_match(ARRAY_EXP, PSI_SUDO_COMMANDS)) {
+ $sudocommands = eval(PSI_SUDO_COMMANDS);
+ } else {
+ $sudocommands = array(PSI_SUDO_COMMANDS);
+ }
+ if (in_array($strProgramname, $sudocommands)) {
+ $strAll = 'sudo '.$strAll;
+ }
+ }
+ $strSet = '';
+ $strProgramname = 'sshpass';
+ $strOptions = '';
+ if (defined('PSI_EMU_ADD_OPTIONS') && is_string(PSI_EMU_ADD_OPTIONS)) {
+ if (preg_match(ARRAY_EXP, PSI_EMU_ADD_OPTIONS)) {
+ $arrParams = eval(PSI_EMU_ADD_OPTIONS);
+ } else {
+ $arrParams = array(PSI_EMU_ADD_OPTIONS);
+ }
+ foreach ($arrParams as $Params) if (preg_match('/(\S+)\s*\=\s*(\S+)/', $Params, $obuf)) {
+ $strOptions = $strOptions.'-o '.$obuf[1].'='.$obuf[2].' ';
+ }
+ }
+ if (defined('PSI_EMU_ADD_PATHS') && is_string(PSI_EMU_ADD_PATHS)) {
+ if (preg_match(ARRAY_EXP, PSI_EMU_ADD_PATHS)) {
+ $arrPath = eval(PSI_EMU_ADD_PATHS);
+ } else {
+ $arrPath = array(PSI_EMU_ADD_PATHS);
+ }
+ foreach ($arrPath as $Path) {
+ if ($PathStr === '') {
+ $PathStr = $Path;
+ } else {
+ $PathStr = $PathStr.':'.$Path;
+ }
+ }
+ if ($separator === '') {
+ $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT.' "PATH=\''.$PathStr.':$PATH\' '.$strAll.'"' ;
+ } else {
+ $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT;
+ }
+ } else {
+ if ($separator === '') {
+ $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT.' "'.$strAll.'"' ;
+ } else {
+ $strArguments = '-e ssh -Tq '.$strOptions.'-o ConnectTimeout='.$timeout.' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '.PSI_EMU_USER.'@'.PSI_EMU_HOSTNAME.' -p '.PSI_EMU_PORT;
+ }
+ }
+ $externally = true;
+ } else {
+ $externally = false;
+ }
+
$strProgram = self::_findProgram($strProgramname);
- $error = Error::singleton();
+ $error = PSI_Error::singleton();
if (!$strProgram) {
- if ($booErrorRep) {
- $error->addError('find_program('.$strProgramname.')', 'program not found on the machine');
+ if ($booErrorRep || $externally) {
+ $error->addError('find_program("'.$strProgramname.'")', 'program not found on the machine');
}
return false;
+ } else {
+ if (preg_match('/\s/', $strProgram)) {
+ $strProgram = '"'.$strProgram.'"';
+ }
}
- // see if we've gotten a |, if we have we need to do path checking on the cmd
- if ($strArgs) {
- $arrArgs = preg_split('/ /', $strArgs, -1, PREG_SPLIT_NO_EMPTY);
- for ($i = 0, $cnt_args = count($arrArgs); $i < $cnt_args; $i++) {
- if ($arrArgs[$i] == '|') {
- $strCmd = $arrArgs[$i + 1];
- $strNewcmd = self::_findProgram($strCmd);
- $strArgs = preg_replace("/\| ".$strCmd.'/', '| "'.$strNewcmd.'"', $strArgs);
+
+ if ((PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME') && defined('PSI_SUDO_COMMANDS') && is_string(PSI_SUDO_COMMANDS)) {
+ if (preg_match(ARRAY_EXP, PSI_SUDO_COMMANDS)) {
+ $sudocommands = eval(PSI_SUDO_COMMANDS);
+ } else {
+ $sudocommands = array(PSI_SUDO_COMMANDS);
+ }
+ if (in_array($strProgramname, $sudocommands)) {
+ $sudoProgram = self::_findProgram("sudo");
+ if (!$sudoProgram) {
+ $error->addError('find_program("sudo")', 'program not found on the machine');
+
+ return false;
+ } else {
+ if (preg_match('/\s/', $sudoProgram)) {
+ $strProgram = '"'.$sudoProgram.'" '.$strProgram;
+ } else {
+ $strProgram = $sudoProgram.' '.$strProgram;
+ }
}
}
}
+
+ $strArgs = $strArguments;
+ // see if we've gotten a | or &, if we have we need to do path checking on the cmd
+ if ($strArgs) {
+ $arrArgs = preg_split('/ /', $strArgs, -1, PREG_SPLIT_NO_EMPTY);
+ for ($i = 0, $cnt_args = count($arrArgs); $i < $cnt_args; $i++) {
+ if (($arrArgs[$i] == '|') || ($arrArgs[$i] == '&')) {
+ $strCmd = $arrArgs[$i + 1];
+ $strNewcmd = self::_findProgram($strCmd);
+ if (!$strNewcmd) {
+ if ($booErrorRep || $externally) {
+ $error->addError('find_program("'.$strCmd.'")', 'program not found on the machine');
+ }
+
+ return false;
+ }
+ if (preg_match('/\s/', $strNewcmd)) {
+ if ($arrArgs[$i] == '|') {
+ $strArgs = preg_replace('/\| '.$strCmd.'/', '| "'.$strNewcmd.'"', $strArgs);
+ } else {
+ $strArgs = preg_replace('/& '.$strCmd.'/', '& "'.$strNewcmd.'"', $strArgs);
+ }
+ } else {
+ if ($arrArgs[$i] == '|') {
+ $strArgs = preg_replace('/\| '.$strCmd.'/', '| '.$strNewcmd, $strArgs);
+ } else {
+ $strArgs = preg_replace('/& '.$strCmd.'/', '& '.$strNewcmd, $strArgs);
+ }
+ }
+ }
+ }
+ $strArgs = ' '.$strArgs;
+ }
+
+ $strBuffer = '';
+ $strError = '';
+ $pipes = array();
$descriptorspec = array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w"));
- if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) {
+ if ($externally) {
+ putenv('SSHPASS='.PSI_EMU_PASSWORD);
+ }
+ if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) {
+ if ($separator !== '') {
+ $error->addError('executeProgram', 'wrong execution mode');
+
+ return false;
+ }
if (PSI_OS == 'WINNT') {
- $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>nul", "r");
+ $process = $pipes[1] = popen($strSet.$strProgram.$strArgs." 2>nul", "r");
} else {
- $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>/dev/null", "r");
+ $process = $pipes[1] = popen($strSet.$strProgram.$strArgs." 2>/dev/null", "r");
}
} else {
- $process = proc_open('"'.$strProgram.'" '.$strArgs, $descriptorspec, $pipes);
+ $process = proc_open($strSet.$strProgram.$strArgs, $descriptorspec, $pipes);
+ if ($separator !== '') {
+ if ($PathStr === '') {
+ fwrite($pipes[0], $strAll."\n "); // spaces at end for handling 'more'
+ } else {
+ fwrite($pipes[0], 'PATH=\''.$PathStr.':$PATH\' '.$strAll."\n");
+ }
+ }
+ }
+ if ($externally) {
+ putenv('SSHPASS');
}
if (is_resource($process)) {
- self::_timeoutfgets($pipes, $strBuffer, $strError);
- if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) {
+ $te = self::_timeoutfgets($pipes, $strBuffer, $strError, $timeout, $separator);
+ if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) {
$return_value = pclose($pipes[1]);
} else {
fclose($pipes[0]);
@@ -244,7 +358,12 @@ class CommonFunctions
fclose($pipes[2]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
- $return_value = proc_close($process);
+ if ($te) {
+ proc_terminate($process); // proc_close tends to hang if the process is timing out
+ $return_value = 0;
+ } else {
+ $return_value = proc_close($process);
+ }
}
} else {
if ($booErrorRep) {
@@ -256,7 +375,7 @@ class CommonFunctions
$strError = trim($strError);
$strBuffer = trim($strBuffer);
if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) {
- error_log("---".gmdate('r T')."--- Executing: ".trim($strProgramname.' '.$strArgs)."\n".$strBuffer."\n", 3, PSI_LOG);
+ error_log("---".gmdate('r T')."--- Executing: ".$strAll."\n".$strBuffer."\n", 3, PSI_LOG);
}
if (! empty($strError)) {
if ($booErrorRep) {
@@ -269,19 +388,74 @@ class CommonFunctions
return true;
}
+ /**
+ * read a one-line value from a file with a similar name
+ *
+ * @return value if successfull or null if not
+ */
+ public static function rolv($similarFileName, $match = "//", $replace = "")
+ {
+ if (defined('PSI_EMU_PORT')) {
+ return null;
+ }
+
+ $filename = preg_replace($match, $replace, $similarFileName);
+ if (self::fileexists($filename) && self::rfts($filename, $buf, 1, 4096, false) && (($buf=trim($buf)) != "")) {
+ return $buf;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * read data from array $_SERVER
+ *
+ * @param string $strElem element of array
+ * @param string &$strBuffer output of the command
+ *
+ * @return string
+ */
+ public static function readenv($strElem, &$strBuffer)
+ {
+ $strBuffer = '';
+ if (PSI_OS == 'WINNT') { //case insensitive
+ if (isset($_SERVER)) {
+ foreach ($_SERVER as $index=>$value) {
+ if (is_string($value) && (trim($value) !== '') && (strtolower($index) === strtolower($strElem))) {
+ $strBuffer = $value;
+
+ return true;
+ }
+ }
+ }
+ } else {
+ if (isset($_SERVER[$strElem]) && is_string($value = $_SERVER[$strElem]) && (trim($value) !== '')) {
+ $strBuffer = $value;
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* read a file and return the content as a string
*
* @param string $strFileName name of the file which should be read
* @param string &$strRet content of the file (reference)
- * @param integer $intLines control how many lines should be read
- * @param integer $intBytes control how many bytes of each line should be read
+ * @param int $intLines control how many lines should be read
+ * @param int $intBytes control how many bytes of each line should be read
* @param boolean $booErrorRep en- or disables the reporting of errors which should be logged
*
* @return boolean command successfull or not
*/
public static function rfts($strFileName, &$strRet, $intLines = 0, $intBytes = 4096, $booErrorRep = true)
{
+ if (defined('PSI_EMU_PORT')) {
+ return false;
+ }
+
if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) {
$out = self::_parse_log_file("Reading: ".$strFileName);
if ($out == false) {
@@ -297,12 +471,18 @@ class CommonFunctions
}
}
+ if (PSI_ROOT_FILESYSTEM !== '') {
+ $rfsinfo = "[".PSI_ROOT_FILESYSTEM."]";
+ } else {
+ $rfsinfo = '';
+ }
+
$strFile = "";
$intCurLine = 1;
- $error = Error::singleton();
- if (file_exists($strFileName)) {
- if (is_readable($strFileName)) {
- if ($fd = fopen($strFileName, 'r')) {
+ $error = PSI_Error::singleton();
+ if (file_exists(PSI_ROOT_FILESYSTEM.$strFileName)) {
+ if (is_readable(PSI_ROOT_FILESYSTEM.$strFileName)) {
+ if ($fd = fopen(PSI_ROOT_FILESYSTEM.$strFileName, 'r')) {
while (!feof($fd)) {
$strFile .= fgets($fd, $intBytes);
if ($intLines <= $intCurLine && $intLines != 0) {
@@ -322,21 +502,21 @@ class CommonFunctions
}
} else {
if ($booErrorRep) {
- $error->addError('fopen('.$strFileName.')', 'file can not read by phpsysinfo');
+ $error->addError('fopen('.$rfsinfo.$strFileName.')', 'file can not read by phpsysinfo');
}
return false;
}
} else {
- if ($booErrorRep) {
- $error->addError('fopen('.$strFileName.')', 'file permission error');
- }
+ if ($booErrorRep) {
+ $error->addError('fopen('.$rfsinfo.$strFileName.')', 'file permission error');
+ }
- return false;
+ return false;
}
} else {
if ($booErrorRep) {
- $error->addError('file_exists('.$strFileName.')', 'the file does not exist on your machine');
+ $error->addError('file_exists('.$rfsinfo.$strFileName.')', 'the file does not exist on your machine');
}
return false;
@@ -345,6 +525,76 @@ class CommonFunctions
return true;
}
+ /**
+ * read a data file and return the content as a string
+ *
+ * @param string $strDataFileName name of the data file which should be read
+ * @param string &$strRet content of the data file (reference)
+ *
+ * @return boolean command successfull or not
+ */
+ public static function rftsdata($strDataFileName, &$strRet)
+ {
+ $strFile = "";
+ $strFileName = PSI_APP_ROOT."/data/".$strDataFileName;
+ $error = PSI_Error::singleton();
+ if (file_exists($strFileName)) {
+ if (is_readable($strFileName)) {
+ if ($fd = fopen($strFileName, 'r')) {
+ while (!feof($fd)) {
+ $strFile .= fgets($fd, 4096);
+ }
+ fclose($fd);
+ $strRet = $strFile;
+ } else {
+ $error->addError('fopen('.$strFileName.')', 'file can not read by phpsysinfo');
+
+ return false;
+ }
+ } else {
+ $error->addError('fopen('.$strFileName.')', 'file permission error');
+
+ return false;
+ }
+ } else {
+ $error->addError('file_exists('.$strFileName.')', 'the file does not exist on your machine');
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Find pathnames matching a pattern
+ *
+ * @param string $pattern the pattern. No tilde expansion or parameter substitution is done.
+ * @param int $flags
+ *
+ * @return an array containing the matched files/directories, an empty array if no file matched or false on error
+ */
+ public static function findglob($pattern, $flags = 0)
+ {
+ if (defined('PSI_EMU_PORT')) {
+ return false;
+ }
+
+ $outarr = glob(PSI_ROOT_FILESYSTEM.$pattern, $flags);
+ if (PSI_ROOT_FILESYSTEM == '') {
+ return $outarr;
+ } elseif ($outarr === false) {
+ return false;
+ } else {
+ $len = strlen(PSI_ROOT_FILESYSTEM);
+ $newoutarr = array();
+ foreach ($outarr as $out) {
+ $newoutarr[] = substr($out, $len); // path without ROOTFS
+ }
+
+ return $newoutarr;
+ }
+ }
+
/**
* file exists
*
@@ -354,6 +604,10 @@ class CommonFunctions
*/
public static function fileexists($strFileName)
{
+ if (defined('PSI_EMU_PORT')) {
+ return false;
+ }
+
if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) {
$log_file = substr(PSI_LOG, 1);
if (file_exists($log_file)
@@ -367,7 +621,14 @@ class CommonFunctions
}
}
- return file_exists($strFileName);
+ $exists = file_exists(PSI_ROOT_FILESYSTEM.$strFileName);
+ if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) {
+ if ((substr($strFileName, 0, 5) === "/dev/") && $exists) {
+ error_log("---".gmdate('r T')."--- Reading: ".$strFileName."\ndevice exists\n", 3, PSI_LOG);
+ }
+ }
+
+ return $exists;
}
/**
@@ -381,7 +642,7 @@ class CommonFunctions
public static function gdc($strPath, $booErrorRep = true)
{
$arrDirectoryContent = array();
- $error = Error::singleton();
+ $error = PSI_Error::singleton();
if (is_dir($strPath)) {
if ($handle = opendir($strPath)) {
while (($strFile = readdir($handle)) !== false) {
@@ -419,12 +680,12 @@ class CommonFunctions
*/
public static function checkForExtensions($arrExt = array())
{
- if ((strcasecmp(PSI_SYSTEM_CODEPAGE, "UTF-8") == 0) || (strcasecmp(PSI_SYSTEM_CODEPAGE, "CP437") == 0))
+ if (defined('PSI_SYSTEM_CODEPAGE') && (PSI_SYSTEM_CODEPAGE !== null) && ((strcasecmp(PSI_SYSTEM_CODEPAGE, "UTF-8") == 0) || (strcasecmp(PSI_SYSTEM_CODEPAGE, "CP437") == 0)))
$arrReq = array('simplexml', 'pcre', 'xml', 'dom');
- elseif (PSI_OS == "WINNT")
- $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom', 'com_dotnet');
+ elseif (PSI_OS == 'WINNT')
+ $arrReq = array('simplexml', 'pcre', 'xml', 'dom', 'mbstring', 'com_dotnet');
else
- $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom');
+ $arrReq = array('simplexml', 'pcre', 'xml', 'dom', 'mbstring');
$extensions = array_merge($arrExt, $arrReq);
$text = "";
$error = false;
@@ -441,7 +702,7 @@ class CommonFunctions
$text .= " \n";
$text .= "";
if ($error) {
- header("Content-Type: text/xml\n\n");
+ header('Content-Type: text/xml');
echo $text;
die();
}
@@ -450,19 +711,20 @@ class CommonFunctions
/**
* get the content of stdout/stderr with the option to set a timeout for reading
*
- * @param array $pipes array of file pointers for stdin, stdout, stderr (proc_open())
- * @param string &$out target string for the output message (reference)
- * @param string &$err target string for the error message (reference)
- * @param integer $timeout timeout value in seconds (default value is 30)
+ * @param array $pipes array of file pointers for stdin, stdout, stderr (proc_open())
+ * @param string &$out target string for the output message (reference)
+ * @param string &$err target string for the error message (reference)
+ * @param int $timeout timeout value in seconds
*
- * @return void
+ * @return boolean timeout expired or not
*/
- private static function _timeoutfgets($pipes, &$out, &$err, $timeout = 30)
+ private static function _timeoutfgets($pipes, &$out, &$err, $timeout, $separator = '')
{
$w = null;
$e = null;
+ $te = false;
- if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) {
+ if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) {
$pipe2 = false;
} else {
$pipe2 = true;
@@ -481,66 +743,30 @@ class CommonFunctions
break;
} elseif ($n === 0) {
error_log('stream_select: timeout expired !');
+// if ($separator !== '') {
+// fwrite($pipes[0], "q");
+// }
+ $te = true;
break;
}
foreach ($read as $r) {
if ($r == $pipes[1]) {
$out .= fread($r, 4096);
- } else if (feof($pipes[1]) && $pipe2 && ($r == $pipes[2])) {//read STDERR after STDOUT
+ } elseif (feof($pipes[1]) && $pipe2 && ($r == $pipes[2])) {//read STDERR after STDOUT
$err .= fread($r, 4096);
}
}
- }
- }
-
- /**
- * function for getting a list of values in the specified context
- * optionally filter this list, based on the list from third parameter
- *
- * @param $wmi holds the COM object that we pull the WMI data from
- * @param string $strClass name of the class where the values are stored
- * @param array $strValue filter out only needed values, if not set all values of the class are returned
- *
- * @return array content of the class stored in an array
- */
- public static function getWMI($wmi, $strClass, $strValue = array())
- {
- $arrData = array();
- if ($wmi) {
- $value = "";
- try {
- $objWEBM = $wmi->Get($strClass);
- $arrProp = $objWEBM->Properties_;
- $arrWEBMCol = $objWEBM->Instances_();
- foreach ($arrWEBMCol as $objItem) {
- if (is_array($arrProp)) {
- reset($arrProp);
- }
- $arrInstance = array();
- foreach ($arrProp as $propItem) {
- $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";");
- if (empty($strValue)) {
- if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
- else $arrInstance[$propItem->Name] = $value;
- } else {
- if (in_array($propItem->Name, $strValue)) {
- if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
- else $arrInstance[$propItem->Name] = $value;
- }
- }
- }
- $arrData[] = $arrInstance;
- }
- } catch (Exception $e) {
- if (PSI_DEBUG) {
- $error = Error::singleton();
- $error->addError($e->getCode(), $e->getMessage());
- }
+// if (($separator !== '') && preg_match('/'.$separator.'[^'.$separator.']+'.$separator.'/', $out)) {
+ if (($separator !== '') && preg_match('/'.$separator.'[\s\S]+'.$separator.'/', $out)) {
+ fwrite($pipes[0], "quit\n");
+ $separator = ''; //only one time
+ // $te = true;
+ // break;
}
}
- return $arrData;
+ return $te;
}
/**
@@ -560,4 +786,111 @@ class CommonFunctions
return array();
}
}
+
+ /**
+ * name natural compare function
+ *
+ * @return comprasion result
+ */
+ public static function name_natural_compare($a, $b)
+ {
+ return strnatcmp($a->getName(), $b->getName());
+ }
+
+ /**
+ * get virtualizer from dmi data
+ *
+ * @return string|null
+ */
+ public static function decodevirtualizer($vendor_data)
+ {
+ if (gettype($vendor_data) === "array") {
+ $vendarray = array(
+ 'KVM' => 'kvm', // KVM
+ 'OpenStack' => 'kvm', // Detect OpenStack instance as KVM in non x86 architecture
+ 'KubeVirt' => 'kvm', // Detect KubeVirt instance as KVM in non x86 architecture
+ 'Amazon EC2' => 'amazon', // Amazon EC2 Nitro using Linux KVM
+ 'QEMU' => 'qemu', // QEMU
+ 'VMware' => 'vmware', // VMware https://kb.vmware.com/s/article/1009458
+ 'VMW' => 'vmware',
+ 'innotek GmbH' => 'oracle', // Oracle VM VirtualBox
+ 'VirtualBox' => 'oracle',
+ 'Xen' => 'xen', // Xen hypervisor
+ 'Bochs' => 'bochs', // Bochs
+ 'Parallels' => 'parallels', // Parallels
+ // https://wiki.freebsd.org/bhyve
+ 'BHYVE' => 'bhyve', // bhyve
+ 'Hyper-V' => 'microsoft', // Hyper-V
+ 'Apple Virtualization' => 'apple', // Apple Virtualization.framework guests
+ 'Microsoft Corporation Virtual Machine' => 'microsoft' // Hyper-V
+ );
+ for ($i = 0; $i < count($vendor_data); $i++) {
+ foreach ($vendarray as $vend=>$virt) {
+ if (preg_match('/^'.$vend.'/', $vendor_data[$i])) {
+ return $virt;
+ }
+ }
+ }
+ } elseif (gettype($vendor_data) === "string") {
+ $vidarray = array(
+ 'bhyvebhyve' => 'bhyve', // bhyve
+ 'KVMKVMKVM' => 'kvm', // KVM
+ 'LinuxKVMHv' => 'hv-kvm', // KVM (KVM + HyperV Enlightenments)
+ 'MicrosoftHv' => 'microsoft', // Hyper-V
+ 'lrpepyhvr' => 'parallels', // Parallels
+ 'UnisysSpar64' => 'spar', // Unisys sPar
+ 'VMwareVMware' => 'vmware', // VMware
+ 'XenVMMXenVMM' => 'xen', // Xen hypervisor
+ 'ACRNACRNACRN' => 'acrn', // ACRN hypervisor
+ 'TCGTCGTCGTCG' => 'qemu', // QEMU
+ 'QNXQVMBSQG' => 'qnx', // QNX hypervisor
+ 'VBoxVBoxVBox' => 'oracle', // Oracle VM VirtualBox
+ 'SRESRESRESRE' => 'sre' // LMHS SRE hypervisor
+ );
+ $shortvendorid = trim(preg_replace('/[\s!\.]/', '', $vendor_data));
+ if (($shortvendorid !== "") && isset($vidarray[$shortvendorid])) {
+ return $vidarray[$shortvendorid];
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * readdmimemdata function
+ *
+ * @return array
+ */
+ public static function readdmimemdata()
+ {
+ if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) && (self::$_dmimd === null)) {
+ self::$_dmimd = array();
+ $buffer = '';
+ if (defined('PSI_DMIDECODE_ACCESS') && (strtolower(PSI_DMIDECODE_ACCESS)==='data')) {
+ self::rftsdata('dmidecode.tmp', $buffer);
+ } elseif (self::_findProgram('dmidecode')) {
+ self::executeProgram('dmidecode', '-t 17', $buffer, PSI_DEBUG);
+ }
+ if (!empty($buffer)) {
+ $banks = preg_split('/^(?=Handle\s)/m', $buffer, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($banks as $bank) if (preg_match('/^Handle\s/', $bank)) {
+ $lines = preg_split("/\n/", $bank, -1, PREG_SPLIT_NO_EMPTY);
+ $mem = array();
+ foreach ($lines as $line) if (preg_match('/^\s+([^:]+):(.+)/', $line, $params)) {
+ if (preg_match('/^0x([A-F\d]+)/', $params2 = trim($params[2]), $buff)) {
+ $mem[trim($params[1])] = trim($buff[1]);
+ } elseif ($params2 != '') {
+ $mem[trim($params[1])] = $params2;
+ }
+ }
+ if (!empty($mem)) {
+ self::$_dmimd[] = $mem;
+ }
+ }
+ }
+ }
+
+ return self::$_dmimd;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/class.Parser.inc.php b/root/opt/phpsysinfo/includes/class.Parser.inc.php
index f137e4a..61ab062 100644
--- a/root/opt/phpsysinfo/includes/class.Parser.inc.php
+++ b/root/opt/phpsysinfo/includes/class.Parser.inc.php
@@ -8,7 +8,7 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Parser.inc.php 604 2012-07-10 07:31:34Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,22 +28,44 @@ class Parser
/**
* parsing the output of lspci command
*
- * @return Array
+ * @param bool $debug
+ * @return array
*/
public static function lspci($debug = PSI_DEBUG)
{
$arrResults = array();
- if (CommonFunctions::executeProgram("lspci", "", $strBuf, $debug)) {
+ if (CommonFunctions::executeProgram("lspci", (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS)?"-m":"", $strBuf, $debug)) {
$arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
foreach ($arrLines as $strLine) {
- $arrParams = preg_split('/ /', trim($strLine), 2);
- if (count($arrParams) == 2)
- $strName = $arrParams[1];
- else
- $strName = "unknown";
- $strName = preg_replace('/\(.*\)/', '', $strName);
$dev = new HWDevice();
- $dev->setName($strName);
+ $arrParams = preg_split('/(\"? ")|(\" (?=-))/', trim($strLine));
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && ($cp = count($arrParams)) >= 6) {
+ $arrParams[$cp-1] = trim($arrParams[$cp-1], '"'); // remove last "
+ $dev->setName($arrParams[1].': '.$arrParams[2].' '.$arrParams[3]);
+ if (preg_match('/^-/', $arrParams[4])) {
+ if (($arrParams[5] !== "") && !preg_match('/^Unknown vendor/', $arrParams[5])) {
+ $dev->setManufacturer(trim($arrParams[5]));
+ }
+ if (($arrParams[6] !== "") && !preg_match('/^Device /', $arrParams[6])) {
+ $dev->setProduct(trim($arrParams[6]));
+ }
+ } else {
+ if (($arrParams[4] !== "") && !preg_match('/^Unknown vendor/', $arrParams[4])) {
+ $dev->setManufacturer(trim($arrParams[4]));
+ }
+ if (($arrParams[5] !== "") && !preg_match('/^Device /', $arrParams[5])) {
+ $dev->setProduct(trim($arrParams[5]));
+ }
+ }
+ } else {
+ $strLine=trim(preg_replace('/(")|( -\S+)/', '', $strLine));
+ $arrParams = preg_split('/ /', trim($strLine), 2);
+ if (count($arrParams) == 2)
+ $strName = preg_replace('/\(rev\s[^\)]+\)/', '', $arrParams[1]);
+ else
+ $strName = "unknown";
+ $dev->setName($strName);
+ }
$arrResults[] = $dev;
}
}
@@ -54,48 +76,66 @@ class Parser
/**
* parsing the output of df command
*
- * @param string $df_param additional parameter for df command
+ * @param string $df_param additional parameter for df command
+ * @param bool $get_inodes
*
* @return array
*/
- public static function df($df_param = "")
+ public static function df($df_param = "", $get_inodes = true)
{
$arrResult = array();
if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) {
$mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY);
foreach ($mount as $mount_line) {
if (preg_match("/(\S+) on ([\S ]+) type (.*) \((.*)\)/", $mount_line, $mount_buf)) {
- $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3];
- $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1];
- if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = $mount_buf[4];
+ $parm = array();
+ $parm['mountpoint'] = trim($mount_buf[2]);
+ $parm['fstype'] = $mount_buf[3];
+ $parm['name'] = $mount_buf[1];
+ if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4];
+ $mount_parm[] = $parm;
} elseif (preg_match("/(\S+) is (.*) mounted on (\S+) \(type (.*)\)/", $mount_line, $mount_buf)) {
- $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[4];
- $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1];
- if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[2];
+ $parm = array();
+ $parm['mountpoint'] = trim($mount_buf[3]);
+ $parm['fstype'] = $mount_buf[4];
+ $parm['name'] = $mount_buf[1];
+ if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[2];
+ $mount_parm[] = $parm;
} elseif (preg_match("/(\S+) (.*) on (\S+) \((.*)\)/", $mount_line, $mount_buf)) {
- $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[2];
- $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1];
- if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[4];
+ $parm = array();
+ $parm['mountpoint'] = trim($mount_buf[3]);
+ $parm['fstype'] = $mount_buf[2];
+ $parm['name'] = $mount_buf[1];
+ if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4];
+ $mount_parm[] = $parm;
} elseif (preg_match("/(\S+) on ([\S ]+) \((\S+)(,\s(.*))?\)/", $mount_line, $mount_buf)) {
- $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3];
- $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1];
- if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = isset($mount_buf[5]) ? $mount_buf[5] : '';
+ $parm = array();
+ $parm['mountpoint'] = trim($mount_buf[2]);
+ $parm['fstype'] = $mount_buf[3];
+ $parm['name'] = $mount_buf[1];
+ if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = isset($mount_buf[5]) ? $mount_buf[5] : '';
+ $mount_parm[] = $parm;
}
}
- } elseif (CommonFunctions::rfts("/etc/mtab", $mount)) {
+ } elseif (CommonFunctions::rfts(((PSI_ROOT_FILESYSTEM === '')||(PSI_OS !== 'Linux'))?"/etc/mtab":"/proc/1/mounts", $mount)) {
$mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY);
foreach ($mount as $mount_line) {
if (preg_match("/(\S+) (\S+) (\S+) (\S+) ([0-9]+) ([0-9]+)/", $mount_line, $mount_buf)) {
+ $parm = array();
$mount_point = preg_replace("/\\\\040/i", ' ', $mount_buf[2]); //space as \040
- $mount_parm[$mount_point]['fstype'] = $mount_buf[3];
- $mount_parm[$mount_point]['name'] = $mount_buf[1];
- if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_point]['options'] = $mount_buf[4];
+ $parm['mountpoint'] = $mount_point;
+ $parm['fstype'] = $mount_buf[3];
+ $parm['name'] = $mount_buf[1];
+ if (PSI_SHOW_MOUNT_OPTION) $parm['options'] = $mount_buf[4];
+ $mount_parm[] = $parm;
}
}
}
- if (CommonFunctions::executeProgram('df', '-k '.$df_param, $df, PSI_DEBUG)) {
+ $df = "";
+ CommonFunctions::executeProgram('df', '-k '.$df_param, $df, PSI_DEBUG);
+ if ($df!=="") {
$df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
- if (PSI_SHOW_INODES) {
+ if ($get_inodes && PSI_SHOW_INODES) {
if (CommonFunctions::executeProgram('df', '-i '.$df_param, $df2, PSI_DEBUG)) {
$df2 = preg_split("/\n/", $df2, -1, PREG_SPLIT_NO_EMPTY);
// Store inode use% in an associative array (df_inodes) for later use
@@ -133,13 +173,103 @@ class Parser
}
if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[5]);
- if (isset($mount_parm[$df_buf[5]])) {
- $dev->setFsType($mount_parm[$df_buf[5]]['fstype']);
+ $notwas = true;
+ if (isset($mount_parm)) {
+ foreach ($mount_parm as $mount_param) { //name and mountpoint find
+ if (($mount_param['name']===trim($df_buf[0])) && ($mount_param['mountpoint']===$df_buf[5])) {
+ $dev->setFsType($mount_param['fstype']);
+ if (PSI_SHOW_MOUNT_OPTION && (trim($mount_param['options'])!=="")) {
+ if (PSI_SHOW_MOUNT_CREDENTIALS) {
+ $dev->setOptions($mount_param['options']);
+ } else {
+ $mpo=$mount_param['options'];
+
+ $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo);
+ $mpo=preg_replace('/,guest,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo);
+
+ $dev->setOptions($mpo);
+ }
+ }
+ $notwas = false;
+ break;
+ }
+ }
+ if ($notwas) foreach ($mount_parm as $mount_param) { //mountpoint find
+ if ($mount_param['mountpoint']===$df_buf[5]) {
+ $dev->setFsType($mount_param['fstype']);
+ if (PSI_SHOW_MOUNT_OPTION && (trim($mount_param['options'])!=="")) {
+ if (PSI_SHOW_MOUNT_CREDENTIALS) {
+ $dev->setOptions($mount_param['options']);
+ } else {
+ $mpo=$mount_param['options'];
+
+ $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo);
+ $mpo=preg_replace('/,guest,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo);
+
+ $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo);
+ $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo);
+
+ $dev->setOptions($mpo);
+ }
+ }
+ $notwas = false;
+ break;
+ }
+ }
+ }
+
+ if ($notwas) {
+ $dev->setFsType('unknown');
+ }
+
+ if ($get_inodes && PSI_SHOW_INODES && isset($df_inodes[trim($df_buf[0])])) {
+ $dev->setPercentInodesUsed($df_inodes[trim($df_buf[0])]);
+ }
+ $arrResult[] = $dev;
+ }
+ }
+ }
+ } else {
+ if (isset($mount_parm)) {
+ foreach ($mount_parm as $mount_param) {
+ if (is_dir($mount_param['mountpoint'])) {
+ $total = disk_total_space($mount_param['mountpoint']);
+ if (($mount_param['fstype'] != 'none') && ($total > 0)) {
+ $dev = new DiskDevice();
+ $dev->setName($mount_param['name']);
+ $dev->setFsType($mount_param['fstype']);
+
+ if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($mount_param['mountpoint']);
+
+ $dev->setTotal($total);
+ $free = disk_free_space($mount_param['mountpoint']);
+ if ($free > 0) {
+ $dev->setFree($free);
+ } else {
+ $free = 0;
+ }
+ if ($total > $free) $dev->setUsed($total - $free);
+
if (PSI_SHOW_MOUNT_OPTION) {
if (PSI_SHOW_MOUNT_CREDENTIALS) {
- $dev->setOptions($mount_parm[$df_buf[5]]['options']);
+ $dev->setOptions($mount_param['options']);
} else {
- $mpo=$mount_parm[$df_buf[5]]['options'];
+ $mpo=$mount_param['options'];
$mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo);
$mpo=preg_replace('/,guest,/i', ',', $mpo);
@@ -156,56 +286,8 @@ class Parser
$dev->setOptions($mpo);
}
}
+ $arrResult[] = $dev;
}
- if (PSI_SHOW_INODES && isset($df_inodes[trim($df_buf[0])])) {
- $dev->setPercentInodesUsed($df_inodes[trim($df_buf[0])]);
- }
- $arrResult[] = $dev;
- }
- }
- }
- } else {
- if (isset($mount_parm)) {
- foreach ($mount_parm as $mount_point=>$mount_param) {
- $total = disk_total_space($mount_point);
- if (($mount_param['fstype'] != 'none') && ($total > 0)) {
- $dev = new DiskDevice();
- $dev->setName($mount_param['name']);
- $dev->setFsType($mount_param['fstype']);
-
- if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($mount_point);
-
- $dev->setTotal($total);
- $free = disk_free_space($mount_point);
- if ($free > 0) {
- $dev->setFree($free);
- } else {
- $free = 0;
- }
- if ($total > $free) $dev->setUsed($total - $free);
-
- if (PSI_SHOW_MOUNT_OPTION) {
- if (PSI_SHOW_MOUNT_CREDENTIALS) {
- $dev->setOptions($mount_param['options']);
- } else {
- $mpo=$mount_param['options'];
-
- $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo);
- $mpo=preg_replace('/,guest,/i', ',', $mpo);
-
- $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo);
- $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo);
-
- $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo);
- $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo);
-
- $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo);
- $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo);
-
- $dev->setOptions($mpo);
- }
- }
- $arrResult[] = $dev;
}
}
}
diff --git a/root/opt/phpsysinfo/includes/error/class.Error.inc.php b/root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php
similarity index 87%
rename from root/opt/phpsysinfo/includes/error/class.Error.inc.php
rename to root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php
index 684678f..a93e58b 100644
--- a/root/opt/phpsysinfo/includes/error/class.Error.inc.php
+++ b/root/opt/phpsysinfo/includes/error/class.PSI_Error.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Error.inc.php 569 2012-04-16 06:08:18Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,17 +19,17 @@
* @package PSI_Error
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
-class Error
+class PSI_Error
{
/**
* holds the instance of this class
*
* @static
- * @var object
+ * @var PSI_Error
*/
private static $_instance;
@@ -59,7 +59,7 @@ class Error
/**
* Singleton function
*
- * @return Error instance of the class
+ * @return PSI_Error instance of the class
*/
public static function singleton()
{
@@ -113,8 +113,8 @@ class Error
/**
* add a config error to the internal list
*
- * @param object $strCommand Command, which cause the Error
- * @param object $strMessage additional Message, to describe the Error
+ * @param string $strCommand Command, which cause the Error
+ * @param string $strMessage additional Message, to describe the Error
*
* @return void
*/
@@ -126,8 +126,8 @@ class Error
/**
* add a php error to the internal list
*
- * @param object $strCommand Command, which cause the Error
- * @param object $strMessage additional Message, to describe the Error
+ * @param string $strCommand Command, which cause the Error
+ * @param string $strMessage additional Message, to describe the Error
*
* @return void
*/
@@ -171,8 +171,8 @@ class Error
$error->addAttribute('Message', $arrLine['message']);
$error->addAttribute('Function', $arrLine['command']);
}
- header("Cache-Control: no-cache, must-revalidate\n");
- header("Content-Type: text/xml\n\n");
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Content-Type: text/xml');
echo $xml->getSimpleXmlElement()->asXML();
exit();
}
@@ -229,7 +229,9 @@ class Error
if ($val == $arrTrace[count($arrTrace) - 1]) {
break;
}
- $strBacktrace .= str_replace(APP_ROOT, ".", $val['file']).' on line '.$val['line'];
+ if (isset($val['file'])) {
+ $strBacktrace .= str_replace(PSI_APP_ROOT, ".", $val['file']).' on line '.$val['line'];
+ }
if ($strFunc) {
$strBacktrace .= ' in function '.$strFunc;
}
@@ -238,10 +240,14 @@ class Error
} else {
$strFunc = $val['function'].'(';
if (isset($val['args'][0])) {
+ if (($val['function'] == 'executeProgram') && ($val['args'][0] == 'sshpass')
+ && isset($val['args'][1]) && preg_match('/"([^"]+)"$/', $val['args'][1], $tmpout)) {
+ $val['args'][1] = 'ssh: '. $tmpout[1];
+ }
$strFunc .= ' ';
$strComma = '';
- foreach ($val['args'] as $val) {
- $strFunc .= $strComma.$this->_printVar($val);
+ foreach ($val['args'] as $valArgs) {
+ $strFunc .= $strComma.$this->_printVar($valArgs);
$strComma = ', ';
}
$strFunc .= ' ';
diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php
index 7fca97d..3a3b9e7 100644
--- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php
+++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Interface_OS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,7 +21,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -47,4 +47,11 @@ interface PSI_Interface_OS
* @return System
*/
public function getSys();
+
+ /**
+ * get os specific language
+ *
+ * @return string
+ */
+ public function getLanguage();
}
diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php
index 7582403..9f89edc 100644
--- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php
+++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Interface_Output.inc.php 214 2009-05-25 08:32:40Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php
index 138169c..08b474e 100644
--- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php
+++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Interface_Plugin.inc.php 273 2009-06-24 11:40:09Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,7 +21,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -37,7 +37,7 @@ interface PSI_Interface_Plugin
/**
* build the xml
*
- * @return SimpleXMLObject entire XML content for the plugin which than can be appended to the main XML
+ * @return SimpleXMLElement entire XML content for the plugin which than can be appended to the main XML
*/
public function xml();
}
diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php
index 3113d37..64e1c87 100644
--- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php
+++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Interface_Sensor.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,7 +21,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php
index 73dd1f5..e776b09 100644
--- a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php
+++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Interface_UPS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI_Interfaces
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
diff --git a/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php
index 48e3ccd..ec6a4e4 100644
--- a/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php
+++ b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php
@@ -159,8 +159,9 @@ class JavaScriptPacker
{
$parser = new ParseMaster();
// replace: $name -> n, $$name -> na
- $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/',
- array('fn' => '_replace_name')
+ $parser->add(
+ '/((\\x24+)([a-zA-Z$_]+))(\\d*)/',
+ array('fn' => '_replace_name')
);
// replace: _name -> _0, double-underscore (__name) is ignored
$regexp = '/\\b_[A-Za-z\\d]\\w*/';
@@ -169,7 +170,8 @@ class JavaScriptPacker
// quick ref
$encoded = $keywords['encoded'];
- $parser->add($regexp,
+ $parser->add(
+ $regexp,
array(
'fn' => '_replace_encoded',
'data' => $encoded
@@ -194,7 +196,8 @@ class JavaScriptPacker
$encoded = $keywords['encoded'];
// encode
- $parser->add($regexp,
+ $parser->add(
+ $regexp,
array(
'fn' => '_replace_encoded',
'data' => $encoded
@@ -521,7 +524,7 @@ class JavaScriptPacker
';
//};
/*
-' if (!\'\'.replace(/^/, String)) {
+' if (!\'\'.replace(/^/, String)) {
// decode all the values we need
while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);
// global replacement function
diff --git a/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php
deleted file mode 100644
index 33af328..0000000
--- a/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php
+++ /dev/null
@@ -1,62 +0,0 @@
-
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.coretemp.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting hardware temperature information through sysctl
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @author William Johansson
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version Release: 3.0
- * @link http://phpsysinfo.sourceforge.net
- */
-class Coretemp extends Sensors
-{
- /**
- * get temperature information
- *
- * @return void
- */
- private function _temperature()
- {
- $smp = 1;
- CommonFunctions::executeProgram('sysctl', '-n kern.smp.cpus', $smp);
- for ($i = 0; $i < $smp; $i++) {
- $temp = 0;
- if (CommonFunctions::executeProgram('sysctl', '-n dev.cpu.'.$i.'.temperature', $temp)) {
- $temp = preg_replace('/C/', '', $temp);
- $dev = new SensorDevice();
- $dev->setName("CPU ".($i + 1));
- $dev->setValue($temp);
- $dev->setMax(70);
- $this->mbinfo->setMbTemp($dev);
- }
- }
- }
-
- /**
- * get the information
- *
- * @see PSI_Interface_Sensor::build()
- *
- * @return Void
- */
- public function build()
- {
- $this->_temperature();
- }
-}
diff --git a/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php b/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php
new file mode 100644
index 0000000..132ece6
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.cpumem.inc.php
@@ -0,0 +1,96 @@
+
+ * @author William Johansson
+ * @copyright 2009 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class CpuMem extends Hwmon
+{
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) {
+ $hwpaths = CommonFunctions::findglob("/sys/devices/platform/coretemp.*/", GLOB_NOSORT);
+ if (is_array($hwpaths) && (count($hwpaths) > 0)) {
+ $hwpaths2 = CommonFunctions::findglob("/sys/devices/platform/coretemp.*/hwmon/hwmon*/", GLOB_NOSORT);
+ if (is_array($hwpaths2) && (count($hwpaths2) > 0)) {
+ $hwpaths = array_merge($hwpaths, $hwpaths2);
+ }
+ $totalh = count($hwpaths);
+ for ($h = 0; $h < $totalh; $h++) {
+ $this->_temperature($hwpaths[$h]);
+ }
+ }
+ } elseif (PSI_OS == 'FreeBSD') {
+ $smp = 1;
+ CommonFunctions::executeProgram('sysctl', '-n kern.smp.cpus', $smp);
+ for ($i = 0; $i < $smp; $i++) {
+ $temp = 0;
+ if (CommonFunctions::executeProgram('sysctl', '-n dev.cpu.'.$i.'.temperature', $temp)) {
+ $temp = preg_replace('/,/', '.', preg_replace('/C/', '', $temp));
+ $dev = new SensorDevice();
+ $dev->setName("CPU ".($i + 1));
+ $dev->setValue($temp);
+// $dev->setMax(70);
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ } elseif ((PSI_OS == 'WINNT') || defined('PSI_EMU_HOSTNAME')) {
+ $allCpus = WINNT::_get_Win32_Processor();
+ foreach ($allCpus as $oneCpu) if (isset($oneCpu['CurrentVoltage']) && ($oneCpu['CurrentVoltage'] > 0)) {
+ $dev = new SensorDevice();
+ $dev->setName($oneCpu['DeviceID']);
+ $dev->setValue($oneCpu['CurrentVoltage']/10);
+ $this->mbinfo->setMbVolt($dev);
+ }
+ $allMems = WINNT::_get_Win32_PhysicalMemory();
+ $counter = 0;
+ foreach ($allMems as $oneMem) if (isset($oneMem['ConfiguredVoltage']) && ($oneMem['ConfiguredVoltage'] > 0)) {
+ $dev = new SensorDevice();
+ $dev->setName('Mem'.($counter++));
+ $dev->setValue($oneMem['ConfiguredVoltage']/1000);
+ if (isset($oneMem['MaxVoltage']) && ($oneMem['MaxVoltage'] > 0)) {
+ $dev->setMax($oneMem['MaxVoltage']/1000);
+ }
+ if (isset($oneMem['MinVoltage']) && ($oneMem['MinVoltage'] > 0)) {
+ $dev->setMin($oneMem['MinVoltage']/1000);
+ }
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) {
+ $dmimd = CommonFunctions::readdmimemdata();
+ $counter = 0;
+ foreach ($dmimd as $mem) {
+ if (isset($mem['Size']) && preg_match('/^(\d+)\s(M|G)B$/', $mem['Size'], $size) && ($size[1] > 0)
+ && isset($mem['Configured Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Configured Voltage'], $voltage) && ($voltage[1] > 0)) {
+ $dev = new SensorDevice();
+ $dev->setName('Mem'.($counter++));
+ $dev->setValue($voltage[1]);
+ if (isset($mem['Minimum Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Minimum Voltage'], $minv) && ($minv[1] > 0)) {
+ $dev->setMin($minv[1]);
+ }
+ if (isset($mem['Maximum Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Maximum Voltage'], $maxv) && ($maxv[1] > 0)) {
+ $dev->setMax($maxv[1]);
+ }
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php b/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php
new file mode 100644
index 0000000..4dcc2b5
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.fortisensor.inc.php
@@ -0,0 +1,122 @@
+
+ * @copyright 2022 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class FortiSensor extends Sensors
+{
+ /**
+ * content to parse
+ *
+ * @var array
+ */
+ private $_lines = array();
+
+ /**
+ * fill the private array
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $lines = "";
+ if (defined('PSI_EMU_PORT') && CommonFunctions::executeProgram('execute', 'sensor list', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $resulti = substr($resulte, strlen($resulto[1][0]));
+ if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) {
+ $lines = substr($resulti, 0, $resulto[1][1]);
+ }
+ }
+ $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ }
+
+ /**
+ * get temperature information
+ *
+ * @return void
+ */
+ private function _temperature()
+ {
+ foreach ($this->_lines as $line) {
+ if (preg_match('/^\s*\d+\s(.+)\sTemperature\s+([\d\.]+)\s\S*C\s*$/', $line, $data)) {
+ $dev = new SensorDevice();
+ $dev->setName($data[1]);
+ $dev->setValue($data[2]);
+ $this->mbinfo->setMbTemp($dev);
+ } elseif (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=(\d+)\s/', $line, $data)
+ && !preg_match('/fan| vin/i', $data[1])) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($data[1]));
+ $dev->setValue($data[3]);
+ if ($data[2] != 0) {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get voltage information
+ *
+ * @return void
+ */
+ private function _voltage()
+ {
+ foreach ($this->_lines as $line) {
+ if (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=([\d\.]+)\s/', $line, $data)
+ && preg_match('/\./', $data[3])
+ && !preg_match('/fan|temp/i', $data[1])) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($data[1]));
+ $dev->setValue($data[3]);
+ if ($data[2] != 0) {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @return void
+ */
+ private function _fans()
+ {
+ foreach ($this->_lines as $line) {
+ if (preg_match('/^\s*\d+\s(.+)\s+alarm=(\d)\s+value=(\d+)\s/', $line, $data)
+ && preg_match('/fan/i', $data[1])) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($data[1]));
+ $dev->setValue($data[3]);
+ if ($data[2] != 0) {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbFan($dev);
+ }
+ }
+ }
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->_temperature();
+ $this->_voltage();
+ $this->_fans();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php
index 753e3d6..ac572a9 100644
--- a/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php
@@ -1,25 +1,14 @@
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.freeipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from ipmi-sensors
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2014 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -33,24 +22,23 @@ class FreeIPMI extends Sensors
private $_lines = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through command or data access
*/
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_FREEIPMI_ACCESS')?strtolower(PSI_SENSOR_FREEIPMI_ACCESS):'command') {
case 'command':
CommonFunctions::executeProgram('ipmi-sensors', '--output-sensor-thresholds', $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/freeipmi.txt', $lines)) {
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('freeipmi.tmp', $lines)) {
+ $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_freeipmi] ACCESS');
}
}
@@ -152,6 +140,7 @@ class FreeIPMI extends Sensors
$dev = new SensorDevice();
$dev->setName($buffer[1]);
$dev->setValue($buffer[3]);
+ if ($buffer[6] != "N/A") $dev->setMin($buffer[6]);
if ($buffer[9] != "N/A") $dev->setMax($buffer[9]);
if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'"));
$this->mbinfo->setMbCurrent($dev);
@@ -159,12 +148,31 @@ class FreeIPMI extends Sensors
}
}
+ /**
+ * get other information
+ *
+ * @return void
+ */
+ private function _other()
+ {
+ foreach ($this->_lines as $line) {
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if ($buffer[4] == "N/A"
+ && $buffer[2] != "OEM Reserved" && $buffer[11] != "N/A") {
+ $dev = new SensorDevice();
+ $dev->setName($buffer[1].' ('.$buffer[2].')');
+ $dev->setValue(trim($buffer[11], '\''));
+ $this->mbinfo->setMbOther($dev);
+ }
+ }
+ }
+
/**
* get the information
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
@@ -173,5 +181,6 @@ class FreeIPMI extends Sensors
$this->_fans();
$this->_power();
$this->_current();
+ $this->_other();
}
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php
index 7b8add4..a9694a9 100644
--- a/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php
@@ -1,26 +1,15 @@
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.hddtemp.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from hddtemp
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
* @author T.A. van Roermund
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,16 +19,16 @@ class HDDTemp extends Sensors
* get the temperature information from hddtemp
* access is available through tcp or command
*
- * @return array temperatures in array
+ * @return void
*/
private function _temperature()
{
$ar_buf = array();
- switch (strtolower(PSI_HDD_TEMP)) {
- case "tcp":
+ if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_HDDTEMP_ACCESS')?strtolower(PSI_SENSOR_HDDTEMP_ACCESS):'command') {
+ case 'tcp':
$lines = '';
// Timo van Roermund: connect to the hddtemp daemon, use a 5 second timeout.
- $fp = @fsockopen('localhost', 7634, $errno, $errstr, 5);
+ $fp = @fsockopen(defined('PSI_EMU_HOSTNAME')?PSI_EMU_HOSTNAME:'localhost', 7634, $errno, $errstr, 5);
// if connected, read the output of the hddtemp daemon
if ($fp) {
while (!feof($fp)) {
@@ -52,7 +41,7 @@ class HDDTemp extends Sensors
$lines = str_replace("||", "|\n|", $lines);
$ar_buf = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
break;
- case "command":
+ case 'command':
$strDrives = "";
$strContent = "";
$hddtemp_value = "";
@@ -100,8 +89,7 @@ class HDDTemp extends Sensors
}
break;
default:
- $this->error->addConfigError("temperature()", "PSI_HDD_TEMP");
- break;
+ $this->error->addConfigError("temperature()", "[sensor_hddtemp] ACCESS");
}
// Timo van Roermund: parse the info from the hddtemp daemon.
foreach ($ar_buf as $line) {
@@ -114,7 +102,7 @@ class HDDTemp extends Sensors
if (is_numeric($data[3])) {
$dev->setValue($data[3]);
}
- $dev->setMax(60);
+// $dev->setMax(60);
$this->mbinfo->setMbTemp($dev);
}
}
@@ -126,7 +114,7 @@ class HDDTemp extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php
index dce6759..23a401f 100644
--- a/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.healthd.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from healthd
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,28 +19,33 @@ class Healthd extends Sensors
*
* @var array
*/
- private $_lines = array();
+ private $_values = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through command or data access
*/
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ if (PSI_OS == 'FreeBSD') switch (defined('PSI_SENSOR_HEALTHD_ACCESS')?strtolower(PSI_SENSOR_HEALTHD_ACCESS):'command') {
case 'command':
- $lines = "";
- CommonFunctions::executeProgram('healthdc', '-t', $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ if (CommonFunctions::executeProgram('healthdc', '-t', $lines)) {
+ $lines0 = preg_split("/\n/", $lines, 1, PREG_SPLIT_NO_EMPTY);
+ if (count($lines0) == 1) {
+ $this->_values = preg_split("/\t+/", $lines0[0]);
+ }
+ }
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/healthd.txt', $lines)) {
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('healthd.tmp', $lines)) {
+ $lines0 = preg_split("/\n/", $lines, 1, PREG_SPLIT_NO_EMPTY);
+ if (count($lines0) == 1) {
+ $this->_values = preg_split("/\t+/", $lines0[0]);
+ }
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_healthd] ACCESS');
}
}
@@ -62,22 +56,23 @@ class Healthd extends Sensors
*/
private function _temperature()
{
- $ar_buf = preg_split("/\t+/", $this->_lines);
- $dev1 = new SensorDevice();
- $dev1->setName('temp1');
- $dev1->setValue($ar_buf[1]);
- $dev1->setMax(70);
- $this->mbinfo->setMbTemp($dev1);
- $dev2 = new SensorDevice();
- $dev2->setName('temp1');
- $dev2->setValue($ar_buf[2]);
- $dev2->setMax(70);
- $this->mbinfo->setMbTemp($dev2);
- $dev3 = new SensorDevice();
- $dev3->setName('temp1');
- $dev3->setValue($ar_buf[3]);
- $dev3->setMax(70);
- $this->mbinfo->setMbTemp($dev3);
+ if (count($this->_values) == 14) {
+ $dev1 = new SensorDevice();
+ $dev1->setName('temp1');
+ $dev1->setValue($this->_values[1]);
+// $dev1->setMax(70);
+ $this->mbinfo->setMbTemp($dev1);
+ $dev2 = new SensorDevice();
+ $dev2->setName('temp1');
+ $dev2->setValue($this->_values[2]);
+// $dev2->setMax(70);
+ $this->mbinfo->setMbTemp($dev2);
+ $dev3 = new SensorDevice();
+ $dev3->setName('temp1');
+ $dev3->setValue($this->_values[3]);
+// $dev3->setMax(70);
+ $this->mbinfo->setMbTemp($dev3);
+ }
}
/**
@@ -87,60 +82,62 @@ class Healthd extends Sensors
*/
private function _fans()
{
- $ar_buf = preg_split("/\t+/", $this->_lines);
- $dev1 = new SensorDevice();
- $dev1->setName('fan1');
- $dev1->setValue($ar_buf[4]);
- $dev1->setMin(3000);
- $this->mbinfo->setMbFan($dev1);
- $dev2 = new SensorDevice();
- $dev2->setName('fan2');
- $dev2->setValue($ar_buf[5]);
- $dev2->setMin(3000);
- $this->mbinfo->setMbFan($dev2);
- $dev3 = new SensorDevice();
- $dev3->setName('fan3');
- $dev3->setValue($ar_buf[6]);
- $dev3->setMin(3000);
- $this->mbinfo->setMbFan($dev3);
+ if (count($this->_values) == 14) {
+ $dev1 = new SensorDevice();
+ $dev1->setName('fan1');
+ $dev1->setValue($this->_values[4]);
+// $dev1->setMin(3000);
+ $this->mbinfo->setMbFan($dev1);
+ $dev2 = new SensorDevice();
+ $dev2->setName('fan2');
+ $dev2->setValue($this->_values[5]);
+// $dev2->setMin(3000);
+ $this->mbinfo->setMbFan($dev2);
+ $dev3 = new SensorDevice();
+ $dev3->setName('fan3');
+ $dev3->setValue($this->_values[6]);
+// $dev3->setMin(3000);
+ $this->mbinfo->setMbFan($dev3);
+ }
}
/**
* get voltage information
*
- * @return array voltage in array with lable
+ * @return void
*/
private function _voltage()
{
- $ar_buf = preg_split("/\t+/", $this->_lines);
- $dev1 = new SensorDevice();
- $dev1->setName('Vcore1');
- $dev1->setValue($ar_buf[7]);
- $this->mbinfo->setMbVolt($dev1);
- $dev2 = new SensorDevice();
- $dev2->setName('Vcore2');
- $dev2->setValue($ar_buf[8]);
- $this->mbinfo->setMbVolt($dev2);
- $dev3 = new SensorDevice();
- $dev3->setName('3volt');
- $dev3->setValue($ar_buf[9]);
- $this->mbinfo->setMbVolt($dev3);
- $dev4 = new SensorDevice();
- $dev4->setName('+5Volt');
- $dev4->setValue($ar_buf[10]);
- $this->mbinfo->setMbVolt($dev4);
- $dev5 = new SensorDevice();
- $dev5->setName('+12Volt');
- $dev5->setValue($ar_buf[11]);
- $this->mbinfo->setMbVolt($dev5);
- $dev6 = new SensorDevice();
- $dev6->setName('-12Volt');
- $dev6->setValue($ar_buf[12]);
- $this->mbinfo->setMbVolt($dev6);
- $dev7 = new SensorDevice();
- $dev7->setName('-5Volt');
- $dev7->setValue($ar_buf[13]);
- $this->mbinfo->setMbVolt($dev7);
+ if (count($this->_values) == 14) {
+ $dev1 = new SensorDevice();
+ $dev1->setName('Vcore1');
+ $dev1->setValue($this->_values[7]);
+ $this->mbinfo->setMbVolt($dev1);
+ $dev2 = new SensorDevice();
+ $dev2->setName('Vcore2');
+ $dev2->setValue($this->_values[8]);
+ $this->mbinfo->setMbVolt($dev2);
+ $dev3 = new SensorDevice();
+ $dev3->setName('3volt');
+ $dev3->setValue($this->_values[9]);
+ $this->mbinfo->setMbVolt($dev3);
+ $dev4 = new SensorDevice();
+ $dev4->setName('+5Volt');
+ $dev4->setValue($this->_values[10]);
+ $this->mbinfo->setMbVolt($dev4);
+ $dev5 = new SensorDevice();
+ $dev5->setName('+12Volt');
+ $dev5->setValue($this->_values[11]);
+ $this->mbinfo->setMbVolt($dev5);
+ $dev6 = new SensorDevice();
+ $dev6->setName('-12Volt');
+ $dev6->setValue($this->_values[12]);
+ $this->mbinfo->setMbVolt($dev6);
+ $dev7 = new SensorDevice();
+ $dev7->setName('-5Volt');
+ $dev7->setValue($this->_values[13]);
+ $this->mbinfo->setMbVolt($dev7);
+ }
}
/**
@@ -148,7 +145,7 @@ class Healthd extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php b/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php
new file mode 100644
index 0000000..077cfaf
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.hwmon.inc.php
@@ -0,0 +1,267 @@
+
+ * @copyright 2016 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class Hwmon extends Sensors
+{
+ /**
+ * get temperature information
+ *
+ * @param string $hwpath
+ * @return void
+ */
+ protected function _temperature($hwpath)
+ {
+ $sensor = CommonFunctions::findglob($hwpath."temp*_input", GLOB_NOSORT);
+ if (is_array($sensor) && (($total = count($sensor)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) {
+ $dev = new SensorDevice();
+ $dev->setValue($buf/1000);
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) {
+ $name = " (".$buf.")";
+ } else {
+ $name = "";
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) {
+ $dev->setName($buf.$name);
+ } else {
+ $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME)));
+ if (($name == " (drivetemp)") && (count($buf = CommonFunctions::gdc($hwpath . "device/block", false)))) {
+ $labelname = "/dev/" . $buf[0];
+ if (($buf = CommonFunctions::rolv($hwpath . "device/model"))!==null) {
+ $labelname .= " (".$buf.")";
+ $name = "";
+ }
+ }
+ if ($labelname !== "") {
+ $dev->setName($labelname.$name);
+ } else {
+ $dev->setName('unknown'.$name);
+ }
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_crit"))!==null) {
+ $dev->setMax($buf/1000);
+ if (CommonFunctions::rolv($sensor[$i], "/_input$/", "_crit_alarm")==="1") {
+ $dev->setEvent("Critical Alarm");
+ }
+ } elseif (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) {
+ $dev->setMax($buf/1000);
+ }
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get voltage information
+ *
+ * @param string $hwpath
+ * @return void
+ */
+ private function _voltage($hwpath)
+ {
+ $sensor = CommonFunctions::findglob($hwpath."in*_input", GLOB_NOSORT);
+ if (is_array($sensor) && (($total = count($sensor)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) {
+ $dev = new SensorDevice();
+ $dev->setValue($buf/1000);
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) {
+ $name = " (".$buf.")";
+ } else {
+ $name = "";
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) {
+ $dev->setName($buf.$name);
+ } else {
+ $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME)));
+ if ($labelname !== "") {
+ $dev->setName($labelname.$name);
+ } else {
+ $dev->setName('unknown'.$name);
+ }
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) {
+ $dev->setMax($buf/1000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) {
+ $dev->setMin($buf/1000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @param string $hwpath
+ * @return void
+ */
+ protected function _fans($hwpath)
+ {
+ $sensor = CommonFunctions::findglob($hwpath."fan*_input", GLOB_NOSORT);
+ if (is_array($sensor) && (($total = count($sensor)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) {
+ $dev = new SensorDevice();
+ $dev->setValue($buf);
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) {
+ $name = " (".$buf.")";
+ } else {
+ $name = "";
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) {
+ $dev->setName($buf.$name);
+ } else {
+ $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME)));
+ if ($labelname !== "") {
+ $dev->setName($labelname.$name);
+ } else {
+ $dev->setName('unknown'.$name);
+ }
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_full_speed"))!==null) {
+ $dev->setMax($buf);
+ } elseif (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) {
+ $dev->setMax($buf);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) {
+ $dev->setMin($buf);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbFan($dev);
+ }
+ }
+ }
+
+ /**
+ * get power information
+ *
+ * @param string $hwpath
+ * @return void
+ */
+ private function _power($hwpath)
+ {
+ $sensor = CommonFunctions::findglob($hwpath."power*_input", GLOB_NOSORT);
+ if (is_array($sensor) && (($total = count($sensor)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) {
+ $dev = new SensorDevice();
+ $dev->setValue($buf/1000000);
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) {
+ $name = " (".$buf.")";
+ } else {
+ $name = "";
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) {
+ $dev->setName($buf.$name);
+ } else {
+ $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME)));
+ if ($labelname !== "") {
+ $dev->setName($labelname.$name);
+ } else {
+ $dev->setName('unknown'.$name);
+ }
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) {
+ $dev->setMax($buf/1000000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) {
+ $dev->setMin($buf/1000000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbPower($dev);
+ }
+ }
+ }
+
+ /**
+ * get current information
+ *
+ * @param string $hwpath
+ * @return void
+ */
+ private function _current($hwpath)
+ {
+ $sensor = CommonFunctions::findglob($hwpath."curr*_input", GLOB_NOSORT);
+ if (is_array($sensor) && (($total = count($sensor)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) if (($buf = CommonFunctions::rolv($sensor[$i]))!==null) {
+ $dev = new SensorDevice();
+ $dev->setValue($buf/1000);
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/\/[^\/]*_input$/", "/name"))!==null) {
+ $name = " (".$buf.")";
+ } else {
+ $name = "";
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_label"))!==null) {
+ $dev->setName($buf.$name);
+ } else {
+ $labelname = trim(preg_replace("/_input$/", "", pathinfo($sensor[$i], PATHINFO_BASENAME)));
+ if ($labelname !== "") {
+ $dev->setName($labelname.$name);
+ } else {
+ $dev->setName('unknown'.$name);
+ }
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_max"))!==null) {
+ $dev->setMax($buf/1000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_min"))!==null) {
+ $dev->setMin($buf/1000);
+ }
+ if (($buf = CommonFunctions::rolv($sensor[$i], "/_input$/", "_alarm"))==="1") {
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbCurrent($dev);
+ }
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) {
+ $hwpaths = CommonFunctions::findglob("/sys/class/hwmon/hwmon*/", GLOB_NOSORT);
+ if (is_array($hwpaths) && (count($hwpaths) > 0)) {
+ $hwpaths2 = CommonFunctions::findglob("/sys/class/hwmon/hwmon*/device/", GLOB_NOSORT);
+ if (is_array($hwpaths2) && (count($hwpaths2) > 0)) {
+ $hwpaths = array_merge($hwpaths, $hwpaths2);
+ }
+ $totalh = count($hwpaths);
+ for ($h = 0; $h < $totalh; $h++) {
+ $this->_temperature($hwpaths[$h]);
+ $this->_voltage($hwpaths[$h]);
+ $this->_fans($hwpaths[$h]);
+ $this->_power($hwpaths[$h]);
+ $this->_current($hwpaths[$h]);
+ }
+ }
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php
index 948fba6..19e1199 100644
--- a/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.hwsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from hwsensors
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -33,15 +22,17 @@ class HWSensors extends Sensors
private $_lines = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through command
*/
public function __construct()
{
parent::__construct();
- $lines = "";
-// CommonFunctions::executeProgram('sysctl', '-w hw.sensors', $lines);
- CommonFunctions::executeProgram('sysctl', 'hw.sensors', $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ if (PSI_OS == 'OpenBSD') {
+ $lines = "";
+// CommonFunctions::executeProgram('sysctl', '-w hw.sensors', $lines);
+ CommonFunctions::executeProgram('sysctl', 'hw.sensors', $lines);
+ $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ }
}
/**
@@ -145,7 +136,7 @@ class HWSensors extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php
deleted file mode 100644
index 1d16bde..0000000
--- a/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php
+++ /dev/null
@@ -1,197 +0,0 @@
-
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.ipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from ipmitool
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version Release: 3.0
- * @link http://phpsysinfo.sourceforge.net
- */
-class IPMI extends Sensors
-{
- /**
- * content to parse
- *
- * @var array
- */
- private $_lines = array();
-
- /**
- * fill the private content var through tcp or file access
- */
- public function __construct()
- {
- parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
- case 'command':
- CommonFunctions::executeProgram('ipmitool', 'sensor', $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
- break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/ipmi.txt', $lines)) {
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
- }
- break;
- default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
- }
- }
-
- /**
- * get temperature information
- *
- * @return void
- */
- private function _temperature()
- {
- foreach ($this->_lines as $line) {
- $buffer = preg_split("/\s*\|\s*/", $line);
- if ($buffer[2] == "degrees C" && $buffer[3] != "na") {
- $dev = new SensorDevice();
- $dev->setName($buffer[0]);
- $dev->setValue($buffer[1]);
- if ($buffer[8] != "na") $dev->setMax($buffer[8]);
- switch ($buffer[3]) {
- case "nr": $dev->setEvent("Non-Recoverable"); break;
- case "cr": $dev->setEvent("Critical"); break;
- case "nc": $dev->setEvent("Non-Critical"); break;
- }
- $this->mbinfo->setMbTemp($dev);
- }
- }
- }
-
- /**
- * get voltage information
- *
- * @return void
- */
- private function _voltage()
- {
- foreach ($this->_lines as $line) {
- $buffer = preg_split("/\s*\|\s*/", $line);
- if ($buffer[2] == "Volts" && $buffer[3] != "na") {
- $dev = new SensorDevice();
- $dev->setName($buffer[0]);
- $dev->setValue($buffer[1]);
- if ($buffer[5] != "na") $dev->setMin($buffer[5]);
- if ($buffer[8] != "na") $dev->setMax($buffer[8]);
- switch ($buffer[3]) {
- case "nr": $dev->setEvent("Non-Recoverable"); break;
- case "cr": $dev->setEvent("Critical"); break;
- case "nc": $dev->setEvent("Non-Critical"); break;
- }
- $this->mbinfo->setMbVolt($dev);
- }
- }
- }
-
- /**
- * get fan information
- *
- * @return void
- */
- private function _fans()
- {
- foreach ($this->_lines as $line) {
- $buffer = preg_split("/\s*\|\s*/", $line);
- if ($buffer[2] == "RPM" && $buffer[3] != "na") {
- $dev = new SensorDevice();
- $dev->setName($buffer[0]);
- $dev->setValue($buffer[1]);
- if ($buffer[8] != "na") {
- $dev->setMin($buffer[8]);
- } elseif (($buffer[5] != "na") && ($buffer[5]<$buffer[1])) { //max instead min issue
- $dev->setMin($buffer[5]);
- }
- switch ($buffer[3]) {
- case "nr": $dev->setEvent("Non-Recoverable"); break;
- case "cr": $dev->setEvent("Critical"); break;
- case "nc": $dev->setEvent("Non-Critical"); break;
- }
- $this->mbinfo->setMbFan($dev);
- }
- }
- }
-
- /**
- * get power information
- *
- * @return void
- */
- private function _power()
- {
- foreach ($this->_lines as $line) {
- $buffer = preg_split("/\s*\|\s*/", $line);
- if ($buffer[2] == "Watts" && $buffer[3] != "na") {
- $dev = new SensorDevice();
- $dev->setName($buffer[0]);
- $dev->setValue($buffer[1]);
- if ($buffer[8] != "na") $dev->setMax($buffer[8]);
- switch ($buffer[3]) {
- case "nr": $dev->setEvent("Non-Recoverable"); break;
- case "cr": $dev->setEvent("Critical"); break;
- case "nc": $dev->setEvent("Non-Critical"); break;
- }
- $this->mbinfo->setMbPower($dev);
- }
- }
- }
-
- /**
- * get current information
- *
- * @return void
- */
- private function _current()
- {
- foreach ($this->_lines as $line) {
- $buffer = preg_split("/\s*\|\s*/", $line);
- if ($buffer[2] == "Amps" && $buffer[3] != "na") {
- $dev = new SensorDevice();
- $dev->setName($buffer[0]);
- $dev->setValue($buffer[1]);
- if ($buffer[8] != "na") $dev->setMax($buffer[8]);
- switch ($buffer[3]) {
- case "nr": $dev->setEvent("Non-Recoverable"); break;
- case "cr": $dev->setEvent("Critical"); break;
- case "nc": $dev->setEvent("Non-Critical"); break;
- }
- $this->mbinfo->setMbCurrent($dev);
- }
- }
- }
-
- /**
- * get the information
- *
- * @see PSI_Interface_Sensor::build()
- *
- * @return Void
- */
- public function build()
- {
- $this->_temperature();
- $this->_voltage();
- $this->_fans();
- $this->_power();
- $this->_current();
- }
-}
diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php
new file mode 100644
index 0000000..0fd3e6e
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.ipmicfg.inc.php
@@ -0,0 +1,321 @@
+
+ * @copyright 2021 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class IPMIcfg extends Sensors
+{
+ /**
+ * content to parse
+ *
+ * @var array
+ */
+ private $_lines = array();
+
+ /**
+ * fill the private content var through command or data access
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMICFG_ACCESS')?strtolower(PSI_SENSOR_IPMICFG_ACCESS):'command') {
+ case 'command':
+ if ((!defined('PSI_SENSOR_IPMICFG_SDR') || (PSI_SENSOR_IPMICFG_SDR!==false)) ||
+ (!defined('PSI_SENSOR_IPMICFG_PSFRUINFO') || (PSI_SENSOR_IPMICFG_PSFRUINFO!==false)) ||
+ (!defined('PSI_SENSOR_IPMICFG_PMINFO') || (PSI_SENSOR_IPMICFG_PMINFO!==false))) {
+ $lines='';
+ $first=true;
+ if (!defined('PSI_SENSOR_IPMICFG_SDR') || (PSI_SENSOR_IPMICFG_SDR!==false)) {
+ $linestmp='';
+ if (CommonFunctions::executeProgram('ipmicfg', '-sdr', $linestmp)) {
+ $lines=$linestmp;
+ }
+ $first=false;
+ }
+ if (!defined('PSI_SENSOR_IPMICFG_PSFRUINFO') || (PSI_SENSOR_IPMICFG_PSFRUINFO!==false)) {
+ $linestmp='';
+ if (CommonFunctions::executeProgram('ipmicfg', '-psfruinfo', $linestmp, $first || PSI_DEBUG)) {
+ $lines.=$linestmp;
+ }
+ $first=false;
+ }
+ if (!defined('PSI_SENSOR_IPMICFG_PMINFO') || (PSI_SENSOR_IPMICFG_PMINFO!==false)) {
+ $linestmp='';
+ if (CommonFunctions::executeProgram('ipmicfg', '-pminfo', $linestmp, $first || PSI_DEBUG)) {
+ $lines.=$linestmp;
+ }
+ }
+ $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ } else {
+ $this->error->addConfigError('__construct()', '[sensor_ipmicfg] Not defined: SDR or PSFRUINFO or PMINFO');
+ }
+ break;
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('ipmicfg.tmp', $lines)) {
+ $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ }
+ break;
+ default:
+ $this->error->addConfigError('__construct()', '[sensor_ipmicfg] ACCESS');
+ }
+
+ if ($this->_lines===false) {
+ $this->_lines = array();
+ } else {
+ $pmbus=false;
+ for ($licz=count($this->_lines); $licz--; $licz>0) {
+ $line=$this->_lines[$licz];
+ if (preg_match("/^\s*PMBus Revision\s*\|/", $line)) {
+ $pmbus=true;
+ } else if (preg_match("/^(\s*\[SlaveAddress = [\da..fA..F]+h\] \[)(Module )(\d+\])/", $line, $tmpbuf)) {
+ $this->_lines[$licz]=$tmpbuf[1].($pmbus?"PMBus ":"SMBus ").$tmpbuf[3];
+ $pmbus=false;
+ } else {
+ $this->_lines[$licz]=preg_replace("/\|\s*$/", "", $line);
+ }
+ }
+ }
+ }
+
+ /**
+ * get temperature information
+ *
+ * @return void
+ */
+ private function _temperature()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ if ($valbuff[1]<-128) $valbuff[1]+=256; //+256 correction
+ $dev->setValue($valbuff[1]);
+ if (preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[3], $valbuffmin)) {
+ if ($valbuffmin[1]<-128) $valbuffmin[1]+=256; //+256 correction
+ }
+ if (preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[4], $valbuffmax)) {
+ if ($valbuffmax[1]<-128) $valbuffmax[1]+=256; //+256 correction
+ $dev->setMax($valbuffmax[1]);
+ }
+ if ((isset($valbuffmin[1]) && ($valbuff[1]<=$valbuffmin[1])) || (isset($valbuffmax[1]) && ($valbuff[1]>=$valbuffmax[1]))) { //own range test due to errors with +256 correction
+ $dev->setEvent("Alarm");
+ }
+ $this->mbinfo->setMbTemp($dev);
+ } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([-\d]+)C\/[-\d]+F\s*$/", $buffer[1], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($valbuff[1]);
+ $this->mbinfo->setMBTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get voltage information
+ *
+ * @return void
+ */
+ private function _voltage()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([\d\.]+)\sV\s*$/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($valbuff[1]);
+ if (preg_match("/^\s*([\d\.].+)\sV\s*$/", $buffer[3], $valbuffmin)) {
+ $dev->setMin($valbuffmin[1]);
+ }
+ if (preg_match("/^\s*([\d\.].+)\sV\s*$/", $buffer[4], $valbuffmax)) {
+ $dev->setMax($valbuffmax[1]);
+ }
+ if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0]));
+ $this->mbinfo->setMbVolt($dev);
+ } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([\d\.]+)\sV\s*$/", $buffer[1], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($valbuff[1]);
+ $this->mbinfo->setMBVolt($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @return void
+ */
+ private function _fans()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($valbuff[1]);
+ if (preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[3], $valbuffmin)) {
+ $dev->setMin($valbuffmin[1]);
+ }
+ if ((trim($buffer[0]) != "OK") && isset($valbuffmin[1])) {
+ $dev->setEvent(trim($buffer[0]));
+ }
+ $this->mbinfo->setMbFan($dev);
+ } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*(\d+)\sRPM\s*$/", $buffer[1], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($valbuff[1]);
+ $this->mbinfo->setMBFan($dev);
+ }
+ }
+ }
+
+ /**
+ * get power information
+ *
+ * @return void
+ */
+ private function _power()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*(\d+)\sWatts\s*$/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($valbuff[1]);
+ if (preg_match("/^\s*(\d+)\sWatts\s*$/", $buffer[4], $valbuffmax)) {
+ $dev->setMax($valbuffmax[1]);
+ }
+ if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0]));
+ $this->mbinfo->setMbPower($dev);
+ } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*(\d+)\sW\s*$/", $buffer[1], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($valbuff[1]);
+ $this->mbinfo->setMBPower($dev);
+ }
+ }
+ }
+
+ /**
+ * get current information
+ *
+ * @return void
+ */
+ private function _current()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)==5) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff) && preg_match("/^\s*([\d\.]+)\sAmps\s*$/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($valbuff[1]);
+ if (preg_match("/^\s*([\d\.].+)\sAmps\s*$/", $buffer[3], $valbuffmin)) {
+ $dev->setMin($valbuffmin[1]);
+ }
+ if (preg_match("/^\s*([\d\.].+)\sAmps\s*$/", $buffer[4], $valbuffmax)) {
+ $dev->setMax($valbuffmax[1]);
+ }
+ if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0]));
+ $this->mbinfo->setMbCurrent($dev);
+ } elseif (($mdid!='') && (count($buffer)==2) && preg_match("/^\s*([\d\.]+)\sA\s*$/", $buffer[1], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($valbuff[1]);
+ $this->mbinfo->setMBCurrent($dev);
+ }
+ }
+ }
+
+ /**
+ * get other information
+ *
+ * @return void
+ */
+ private function _other()
+ {
+ $mdid='';
+ foreach ($this->_lines as $line) {
+ if (preg_match("/^\s*\[SlaveAddress = [\da..fA..F]+h\] \[((PMBus \d+)|(SMBus \d+))\]/", $line, $mdidtmp)) {
+ $mdid=$mdidtmp[1];
+ continue;
+ }
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (($mdid=='') && (count($buffer)>=3) && preg_match("/^\s*\(\d+\)\s(.*)\s*$/", $buffer[1], $namebuff)) {
+ $buffer[2]=trim($buffer[2]);
+ if ((count($buffer)==3) &&
+ ($buffer[2]!=="Correctable ECC / other correctable memory error") &&
+ ($buffer[2]!=="Not Present") &&
+ ($buffer[2]!=="N/A") &&
+ (trim($buffer[0]) != "")) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($buffer[2]);
+ if (trim($buffer[0]) != "OK") $dev->setEvent(trim($buffer[0]));
+ $this->mbinfo->setMbOther($dev);
+ } elseif ((count($buffer)==5)&& preg_match("/(^\s*[\d\.]+\s*$)|(^\s*[\da-fA-F]{2}\s+[\da-fA-F]{2}\s+[\da-fA-F]{2}\s+[\da-fA-F]{2}\s*$)/", $buffer[2], $valbuff)) {
+ $dev = new SensorDevice();
+ $dev->setName($namebuff[1]);
+ $dev->setValue($buffer[0]);
+ $this->mbinfo->setMbOther($dev);
+ }
+ } elseif (($mdid!='') && (count($buffer)==2) && ((trim($buffer[0])=="Status") || (trim($buffer[0])=="Current Sharing Control"))) {
+ $dev = new SensorDevice();
+ $dev->setName(trim($buffer[0])." (".$mdid.")");
+ $dev->setValue($buffer[1]);
+ $this->mbinfo->setMbOther($dev);
+ }
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->_temperature();
+ $this->_voltage();
+ $this->_fans();
+ $this->_power();
+ $this->_current();
+ $this->_other();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php
new file mode 100644
index 0000000..bcdfcc7
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.ipmitool.inc.php
@@ -0,0 +1,320 @@
+
+ * @copyright 2009 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class IPMItool extends Sensors
+{
+ /**
+ * content to parse
+ *
+ * @var array
+ */
+ private $_buf = array();
+
+ /**
+ * fill the private content var through command or data access
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $lines = "";
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMITOOL_ACCESS')?strtolower(PSI_SENSOR_IPMITOOL_ACCESS):'command') {
+ case 'command':
+ CommonFunctions::executeProgram('ipmitool', 'sensor -v', $lines);
+ break;
+ case 'data':
+ if (!defined('PSI_EMU_PORT')) {
+ CommonFunctions::rftsdata('ipmitool.tmp', $lines);
+ }
+ break;
+ default:
+ $this->error->addConfigError('__construct()', '[sensor_ipmitool] ACCESS');
+ }
+ if (trim($lines) !== "") {
+ if (preg_match("/^Sensor ID\s+/", $lines)) { //new data format ('ipmitool sensor -v')
+ $lines = preg_replace("/\n?Unable to read sensor/", "\nUnable to read sensor", $lines);
+ $sensors = preg_split("/Sensor ID\s+/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($sensors as $sensor) {
+ if (preg_match("/^:\s*(.+)\s\((0x[a-f\d]+)\)\r?\n/", $sensor, $name) && (($name1 = trim($name[1])) !== "")) {
+ $sensorvalues = preg_split("/\r?\n/", $sensor, -1, PREG_SPLIT_NO_EMPTY);
+ unset($sensorvalues[0]); //skip first
+ $sens = array();
+ $was = false;
+ foreach ($sensorvalues as $sensorvalue) {
+ if (preg_match("/^\s+\[(.+)\]$/", $sensorvalue, $buffer) && (($buffer1 = trim($buffer[1])) !== "")) {
+ if (isset($sens['State'])) {
+ $sens['State'] .= ', '.$buffer1;
+ } else {
+ $sens['State'] = $buffer1;
+ }
+ $was = true;
+ } elseif (preg_match("/^([^:]+):(.+)$/", $sensorvalue, $buffer)
+ && (($buffer1 = trim($buffer[1])) !== "")
+ && (($buffer2 = trim($buffer[2])) !== "")) {
+ $sens[$buffer1] = $buffer2;
+ $was = true;
+ }
+ }
+ if ($was && !isset($sens['Unable to read sensor'])) {
+ $sens['Sensor'] = $name1;
+ if (isset($sens['Sensor Reading'])
+ && preg_match("/^([\d\.]+)\s+\([^\)]*\)\s+(.+)$/", $sens['Sensor Reading'], $buffer)
+ && (($buffer2 = trim($buffer[2])) !== "")) {
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer2;
+ }
+ $this->_buf[intval($name[2], 0)] = $sens;
+ }
+ }
+ }
+ } else {
+ $lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ if (count($lines)>0) {
+ $buffer = preg_split("/\s*\|\s*/", $lines[0]);
+ if (count($buffer)>8) { //old data format ('ipmitool sensor')
+ foreach ($lines as $line) {
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (count($buffer)>8) {
+ $sens = array();
+ $sens['Sensor'] = $buffer[0];
+ switch ($buffer[2]) {
+ case 'degrees C':
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer[2];
+ $sens['Upper Critical'] = $buffer[8];
+ $sens['Sensor Type (Threshold)'] = 'Temperature';
+ break;
+ case 'Volts':
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer[2];
+ $sens['Lower Critical'] = $buffer[5];
+ $sens['Upper Critical'] = $buffer[8];
+ $sens['Sensor Type (Threshold)'] = 'Voltage';
+ break;
+ case 'RPM':
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer[2];
+ $sens['Lower Critical'] = $buffer[5];
+ $sens['Upper Critical'] = $buffer[8];
+ $sens['Sensor Type (Threshold)'] = 'Fan';
+ break;
+ case 'Watts':
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer[2];
+ $sens['Upper Critical'] = $buffer[8];
+ $sens['Sensor Type (Threshold)'] = 'Current';
+ break;
+ case 'Amps':
+ $sens['Value'] = $buffer[1];
+ $sens['Unit'] = $buffer[2];
+ $sens['Lower Critical'] = $buffer[5];
+ $sens['Upper Critical'] = $buffer[8];
+ $sens['Sensor Type (Threshold)'] = 'Current';
+ break;
+ case 'discrete':
+ if (($buffer[1]==='0x0') || ($buffer[1]==='0x1')) {
+ $sens['State'] = $buffer[1];
+ $sens['Sensor Type (Discrete)'] = '';
+ $sens['State'] = $buffer[1];
+ }
+ }
+ $this->_buf[] = $sens;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * get temperature information
+ *
+ * @return void
+ */
+ private function _temperature()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Temperature'))
+ ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Temperature')))
+ && isset($sensor['Unit']) && ($sensor['Unit'] == 'degrees C')
+ && isset($sensor['Value'])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor['Sensor']);
+ $dev->setValue($sensor['Value']);
+ if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) {
+ $dev->setMax($max);
+ }
+ if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) {
+ $dev->setEvent($status);
+ }
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get voltage information
+ *
+ * @return void
+ */
+ private function _voltage()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Voltage'))
+ ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Voltage')))
+ && isset($sensor['Unit']) && ($sensor['Unit'] == 'Volts')
+ && isset($sensor['Value'])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor['Sensor']);
+ $dev->setValue($sensor['Value']);
+ if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) {
+ $dev->setMax($max);
+ }
+ if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) {
+ $dev->setMin($min);
+ }
+ if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) {
+ $dev->setEvent($status);
+ }
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @return void
+ */
+ private function _fans()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Fan'))
+ ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Fan')))
+ && isset($sensor['Unit']) && ($sensor['Unit'] == 'RPM')
+ && isset($sensor['Value'])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor['Sensor']);
+ $dev->setValue($value = $sensor['Value']);
+ if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) {
+ $dev->setMin($min);
+ } elseif (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")
+ && ($max < $value)) { // max instead min issue
+ $dev->setMin($max);
+ }
+ if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) {
+ $dev->setEvent($status);
+ }
+ $this->mbinfo->setMbFan($dev);
+ }
+ }
+ }
+
+ /**
+ * get power information
+ *
+ * @return void
+ */
+ private function _power()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Current'))
+ ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Current')))
+ && isset($sensor['Unit']) && ($sensor['Unit'] == 'Watts')
+ && isset($sensor['Value'])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor['Sensor']);
+ $dev->setValue($sensor['Value']);
+ if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) {
+ $dev->setMax($max);
+ }
+ if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) {
+ $dev->setEvent($status);
+ }
+ $this->mbinfo->setMbPower($dev);
+ }
+ }
+ }
+
+ /**
+ * get current information
+ *
+ * @return void
+ */
+ private function _current()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (((isset($sensor['Sensor Type (Threshold)']) && ($sensor['Sensor Type (Threshold)'] == 'Current'))
+ ||(isset($sensor['Sensor Type (Analog)']) && ($sensor['Sensor Type (Analog)'] == 'Current')))
+ && isset($sensor['Unit']) && ($sensor['Unit'] == 'Amps')
+ && isset($sensor['Value'])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor['Sensor']);
+ $dev->setValue($sensor['Value']);
+ if (isset($sensor['Upper Critical']) && (($max = $sensor['Upper Critical']) != "na")) {
+ $dev->setMax($max);
+ }
+ if (isset($sensor['Lower Critical']) && (($min = $sensor['Lower Critical']) != "na")) {
+ $dev->setMin($min);
+ }
+ if (isset($sensor['Status']) && (($status = $sensor['Status']) != "ok")) {
+ $dev->setEvent($status);
+ }
+ $this->mbinfo->setMbCurrent($dev);
+ }
+ }
+ }
+
+ /**
+ * get other information
+ *
+ * @return void
+ */
+ private function _other()
+ {
+ foreach ($this->_buf as $sensor) {
+ if (isset($sensor['Sensor Type (Discrete)'])) {
+ $dev = new SensorDevice();
+ if ($sensor['Sensor Type (Discrete)']!=='') {
+ $dev->setName($sensor['Sensor'].' ('.$sensor['Sensor Type (Discrete)'].')');
+ } else {
+ $dev->setName($sensor['Sensor']);
+ }
+ if (isset($sensor['State'])) {
+ $dev->setValue($sensor['State']);
+ } else {
+ $dev->setValue('0x0');
+ }
+ $this->mbinfo->setMbOther($dev);
+ }
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->_temperature();
+ $this->_voltage();
+ $this->_fans();
+ $this->_power();
+ $this->_current();
+ $this->_other();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php
index 68613c3..ed36181 100644
--- a/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php
@@ -1,25 +1,14 @@
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.ipmiutil.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from ipmi-sensors
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2014 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -33,24 +22,23 @@ class IPMIutil extends Sensors
private $_lines = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through command or data access
*/
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_IPMIUTIL_ACCESS')?strtolower(PSI_SENSOR_IPMIUTIL_ACCESS):'command') {
case 'command':
CommonFunctions::executeProgram('ipmiutil', 'sensor -stw', $lines);
$this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/ipmiutil.txt', $lines)) {
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('ipmiutil.tmp', $lines)) {
$this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_ipmiutil] ACCESS');
}
}
@@ -63,7 +51,10 @@ class IPMIutil extends Sensors
{
foreach ($this->_lines as $line) {
$buffer = preg_split("/\s*\|\s*/", $line);
- if (isset($buffer[2]) && $buffer[2] == "Temperature" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sC$/", $buffer[6], $value)) {
+ if (isset($buffer[2]) && $buffer[2] == "Temperature"
+ && $buffer[1] == "Full"
+ && isset($buffer[6]) && preg_match("/^(\S+)\sC$/", $buffer[6], $value)
+ && $buffer[5] !== "Init") {
$dev = new SensorDevice();
$dev->setName($buffer[4]);
$dev->setValue($value[1]);
@@ -90,7 +81,10 @@ class IPMIutil extends Sensors
{
foreach ($this->_lines as $line) {
$buffer = preg_split("/\s*\|\s*/", $line);
- if (isset($buffer[2]) && $buffer[2] == "Voltage" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sV$/", $buffer[6], $value)) {
+ if (isset($buffer[2]) && $buffer[2] == "Voltage"
+ && $buffer[1] == "Full"
+ && isset($buffer[6]) && preg_match("/^(\S+)\sV$/", $buffer[6], $value)
+ && $buffer[5] !== "Init") {
$dev = new SensorDevice();
$dev->setName($buffer[4]);
$dev->setValue($value[1]);
@@ -123,7 +117,10 @@ class IPMIutil extends Sensors
{
foreach ($this->_lines as $line) {
$buffer = preg_split("/\s*\|\s*/", $line);
- if (isset($buffer[2]) && $buffer[2] == "Fan" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sRPM$/", $buffer[6], $value)) {
+ if (isset($buffer[2]) && $buffer[2] == "Fan"
+ && $buffer[1] == "Full"
+ && isset($buffer[6]) && preg_match("/^(\S+)\sRPM$/", $buffer[6], $value)
+ && $buffer[5] !== "Init") {
$dev = new SensorDevice();
$dev->setName($buffer[4]);
$dev->setValue($value[1]);
@@ -157,7 +154,10 @@ class IPMIutil extends Sensors
{
foreach ($this->_lines as $line) {
$buffer = preg_split("/\s*\|\s*/", $line);
- if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sW$/", $buffer[6], $value)) {
+ if (isset($buffer[2]) && $buffer[2] == "Current"
+ && $buffer[1] == "Full"
+ && isset($buffer[6]) && preg_match("/^(\S+)\sW$/", $buffer[6], $value)
+ && $buffer[5] !== "Init") {
$dev = new SensorDevice();
$dev->setName($buffer[4]);
$dev->setValue($value[1]);
@@ -184,11 +184,20 @@ class IPMIutil extends Sensors
{
foreach ($this->_lines as $line) {
$buffer = preg_split("/\s*\|\s*/", $line);
- if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sA$/", $buffer[6], $value)) {
+ if (isset($buffer[2]) && $buffer[2] == "Current"
+ && $buffer[1] == "Full"
+ && isset($buffer[6]) && preg_match("/^(\S+)\sA$/", $buffer[6], $value)
+ && $buffer[5] !== "Init") {
$dev = new SensorDevice();
$dev->setName($buffer[4]);
$dev->setValue($value[1]);
if (isset($buffer[7]) && $buffer[7] == "Thresholds") {
+ if ((isset($buffer[8]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[8], $limits))
+ ||(isset($buffer[9]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[9], $limits))
+ ||(isset($buffer[10]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[10], $limits))
+ ||(isset($buffer[11]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[11], $limits))) {
+ $dev->setMin($limits[1]);
+ }
if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits))
||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits))
||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits))
@@ -202,12 +211,50 @@ class IPMIutil extends Sensors
}
}
+ /**
+ * get other information
+ *
+ * @return void
+ */
+ private function _other()
+ {
+ foreach ($this->_lines as $line) {
+ $buffer = preg_split("/\s*\|\s*/", $line);
+ if (isset($buffer[1]) && $buffer[1] == "Compact"
+ && $buffer[5] !== "Init"
+ && $buffer[5] !== "Unknown"
+ && $buffer[5] !== "NotAvailable") {
+ $dev = new SensorDevice();
+ $dev->setName($buffer[4].' ('.$buffer[2].')');
+
+ $buffer5s = preg_split("/\s+/", $buffer5 = $buffer[5]);
+ if (isset($buffer5s[1])) {
+ if (preg_match('/^[0-9A-Fa-f]+$/', $buffer5s[0])) {
+ $value = hexdec($buffer5s[0]) & 0xff;
+ if ($buffer5s[1] === 'DiscreteEvt') {
+ $dev->setValue('0x'.dechex($value));
+ } elseif (($buffer5s[1] === 'DiscreteUnit') && ($value > 0)) {
+ $dev->setValue('0x'.dechex($value - 1));
+ } else {
+ $dev->setValue($buffer5);
+ }
+ } else {
+ $dev->setValue($buffer5);
+ }
+ } else {
+ $dev->setValue($buffer5);
+ }
+ $this->mbinfo->setMbOther($dev);
+ }
+ }
+ }
+
/**
* get the information
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
@@ -216,5 +263,6 @@ class IPMIutil extends Sensors
$this->_fans();
$this->_power();
$this->_current();
+ $this->_other();
}
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php
index 9383353..d64611c 100644
--- a/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.k8temp.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from k8temp
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -38,20 +27,19 @@ class K8Temp extends Sensors
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_K8TEMP_ACCESS')?strtolower(PSI_SENSOR_K8TEMP_ACCESS):'command') {
case 'command':
$lines = "";
CommonFunctions::executeProgram('k8temp', '', $lines);
$this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/k8temp.txt', $lines)) {
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('k8temp.tmp', $lines)) {
$this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_k8temp] ACCESS');
}
}
@@ -67,7 +55,7 @@ class K8Temp extends Sensors
if ($data[2] > 0) {
$dev = new SensorDevice();
$dev->setName($data[1]);
- $dev->setMax('70.0');
+// $dev->setMax('70.0');
if ($data[2] < 250) {
$dev->setValue($data[2]);
}
@@ -82,7 +70,7 @@ class K8Temp extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php
index e883c1e..5801767 100644
--- a/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.lmsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from lmsensor
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class LMSensors extends Sensors
{
/**
- * content to parse
+ * array of values
*
* @var array
*/
- private $_lines = array();
+ private $_values = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through command or data access
*/
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ $lines = "";
+ if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_LMSENSORS_ACCESS')?strtolower(PSI_SENSOR_LMSENSORS_ACCESS):'command') {
case 'command':
- if (CommonFunctions::executeProgram("sensors", "", $lines)) {
- // Martijn Stolk: Dirty fix for misinterpreted output of sensors,
- // where info could come on next line when the label is too long.
- $lines = str_replace(":\n", ":", $lines);
- $lines = str_replace("\n\n", "\n", $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
- }
+ CommonFunctions::executeProgram("sensors", "", $lines);
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/lmsensors.txt', $lines)) {
- $lines = str_replace(":\n", ":", $lines);
- $lines = str_replace("\n\n", "\n", $lines);
- $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ case 'data':
+ if (!defined('PSI_EMU_PORT')) {
+ CommonFunctions::rftsdata('lmsensors.tmp', $lines);
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_lmsensors] ACCESS');
+ }
+
+ if (trim($lines) !== "") {
+ $lines = str_replace("\r\n", "\n", $lines);
+ $lines = str_replace(":\n", ":", $lines);
+ $lines = str_replace("\n\n", "\n", $lines);
+ $lines = preg_replace("/\n\s+\(/m", " (", $lines);
+ $_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+
+ $applearray1 = array(
+ "A" => "Ambient",
+ "B" => "Battery",
+ "C" => "CPU",
+ "G" => "GPU",
+ "H" => "Harddisk Bay",
+ "h" => "Heatpipe",
+ "L" => "LCD",
+ "M" => "Memory",
+ "m" => "Memory Contr.",
+ "N" => "Northbridge",
+ "O" => "Optical Drive",
+ "p" => "Power supply",
+ "S" => "Slot",
+ "s" => "Slot",
+ "W" => "Airport"
+ );
+ $applearray3 = array(
+ "H" => "Heatsink",
+ "P" => "Proximity",
+ "D" => "Die"
+ );
+
+ $tmpvalue=array();
+ $applesmc = false;
+ $sname = '';
+ foreach ($_lines as $line) {
+ if ((trim($line) !== "") && (strpos($line, ':') === false)) {
+ if (sizeof($tmpvalue)>0) {
+ $this->_values[] = $tmpvalue;
+ $tmpvalue = array();
+ }
+ $sname = trim($line);
+ $applesmc = ($sname === "applesmc-isa-0300");
+ if (preg_match('/^([^-]+)-/', $sname, $snamebuf)) {
+ $sname = $snamebuf[1];
+ } else {
+ $sname = '';
+ }
+ } else {
+ if (preg_match("/^(.+):(.+)$/", trim($line), $data) && ($data[1]!=="Adapter")) {
+ if ($applesmc && (strlen($data[1]) == 4) && ($data[1][0] == "T")) {
+ if (isset($applearray1[$data[1][1]])) $data[1] .= " ".$applearray1[$data[1][1]];
+ if (isset($applearray3[$data[1][3]])) $data[1] .= " ".$applearray3[$data[1][3]];
+ }
+
+ $arrtemp=array();
+ if ($sname !== "" ) {
+ $arrtemp["name"] = $data[1]." (".$sname.")";
+ } else {
+ $arrtemp["name"] = $data[1];
+ }
+ if (preg_match("/^([^\(]+)\s+\(/", $data[2], $tmp) || preg_match("/^(.+)\s+ALARM$/", $data[2], $tmp)) {
+ if (($tmp[1] = trim($tmp[1])) == "") {
+ $arrtemp["value"] = "ALARM";
+ } else {
+ $arrtemp["value"] = $tmp[1];
+ }
+ if (preg_match("/\s(ALARM)\s*$/", $data[2]) || preg_match("/\s(ALARM)\s+\(/", $data[2]) || preg_match("/\s(ALARM)\s+sensor\s+=/", $data[2])) {
+ $arrtemp["alarm"]="ALARM";
+ }
+
+ if (preg_match_all("/\(([^\)]+\s+=\s+[^\)]+)\)/", $data[2], $tmp2)) foreach ($tmp2[1] as $tmp3) {
+ $arrtmp3 = preg_split('/,/', $tmp3);
+ foreach ($arrtmp3 as $tmp4) if (preg_match("/^(\S+)\s+=\s+(.*)$/", trim($tmp4), $tmp5)) {
+ $arrtemp[$tmp5[1]]=trim($tmp5[2]);
+ }
+ }
+ } else {
+ $arrtemp["value"] = trim($data[2]);
+ }
+ $tmpvalue[] = $arrtemp;
+ }
+ }
+ }
+ if (sizeof($tmpvalue)>0) $this->_values[] = $tmpvalue;
}
}
@@ -68,88 +134,35 @@ class LMSensors extends Sensors
*/
private function _temperature()
{
- $ar_buf = array();
- foreach ($this->_lines as $line) {
- $data = array();
- if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*)/", $line, $data);
- }
- if (count($data) > 1) {
- $temp = substr(trim($data[2]), -1);
- switch ($temp) {
- case "C":
-// case "F":
- array_push($ar_buf, $line);
- }
- }
- }
- foreach ($ar_buf as $line) {
- $data = array();
- if (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)\)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*).C[ \t]+/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*).C$/", $line, $data);
- }
- foreach ($data as $key=>$value) {
- if (preg_match("/^\+?(-?[0-9\.]+).?$/", trim($value), $newvalue)) {
- $data[$key] = 0+trim($newvalue[1]);
- } else {
- $data[$key] = trim($value);
- }
- }
- $dev = new SensorDevice();
-
- if (strlen($data[1]) == 4) {
- if ($data[1][0] == "T") {
-
- if ($data[1][1] == "A") {
- $data[1] = $data[1] . " Ambient";
- } elseif ($data[1][1] == "C") {
- $data[1] = $data[1] . " CPU";
- } elseif ($data[1][1] == "G") {
- $data[1] = $data[1] . " GPU";
- } elseif ($data[1][1] == "H") {
- $data[1] = $data[1] . " Harddisk";
- } elseif ($data[1][1] == "L") {
- $data[1] = $data[1] . " LCD";
- } elseif ($data[1][1] == "O") {
- $data[1] = $data[1] . " ODD";
- } elseif ($data[1][1] == "B") {
- $data[1] = $data[1] . " Battery";
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ $limit = "";
+ if (preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor["value"], $tmpbuf) ||
+ ((isset($sensor[$limit="crit"]) || isset($sensor[$limit="high"]) || isset($sensor[$limit="hyst"])) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit]))) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ if ($limit != "") {
+ $dev->setValue($sensor["value"]);
+ $dev->setEvent("FAULT");
+ } else {
+ if ($tmpbuf[1] == -110.8) {
+ $dev->setValue("FAULT");
+ $dev->setEvent("FAULT");
+ } else {
+ $dev->setValue(floatval($tmpbuf[1]));
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
+ }
}
- if ($data[1][3] == "H") {
- $data[1] = $data[1] . " Heatsink";
- } elseif ($data[1][3] == "P") {
- $data[1] = $data[1] . " Proximity";
- } elseif ($data[1][3] == "D") {
- $data[1] = $data[1] . " Die";
+ if (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit], $tmpbuf) && (($tmpbuf[1]=floatval($tmpbuf[1])) > 0)) {
+ $dev->setMax(floatval($tmpbuf[1]));
+ } elseif (isset($sensor[$limit="high"]) && preg_match("/^\+?(-?[\d\.]+)[^\w\r\n\t]+C$/", $sensor[$limit], $tmpbuf) && (($tmpbuf[1]=floatval($tmpbuf[1])) > 0) && ($tmpbuf[1]<65261.8)) {
+ $dev->setMax(floatval($tmpbuf[1]));
}
+
+ $this->mbinfo->setMbTemp($dev);
}
}
-
- $dev->setName($data[1]);
- $dev->setValue($data[2]);
-
- if (isset($data[6]) && $data[2] <= $data[6]) {
- $dev->setMax(max($data[4], $data[6]));
- } elseif (isset($data[4]) && $data[2] <= $data[4]) {
- $dev->setMax($data[4]);
- }
- if (preg_match("/\sALARM(\s*)$/", $line)) {
- $dev->setEvent("Alarm");
- }
- $this->mbinfo->setMbTemp($dev);
}
}
@@ -160,50 +173,32 @@ class LMSensors extends Sensors
*/
private function _fans()
{
- $ar_buf = array();
- foreach ($this->_lines as $line) {
- $data = array();
- if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*)/", $line, $data);
- }
- if (count($data) > 1) {
- $temp = substr(trim($data[2]), -4);
- switch ($temp) {
- case " RPM":
- array_push($ar_buf, $line);
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ $limit = "";
+ if (preg_match("/^(\d+) RPM$/", $sensor["value"], $tmpbuf) ||
+ ((isset($sensor[$limit="min"]) || isset($sensor[$limit="max"])) && preg_match("/^(\d+) RPM$/", $sensor[$limit]))) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ if ($limit != "") {
+ $dev->setValue($sensor["value"]);
+ $dev->setEvent("FAULT");
+ } else {
+ $dev->setValue($tmpbuf[1]);
+ }
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
+
+ if (isset($sensor[$limit="min"]) && preg_match("/^(\d+) RPM$/", $sensor[$limit], $tmpbuf) && ($tmpbuf[1] > 0)) {
+ $dev->setMin($tmpbuf[1]);
+ }
+
+ $this->mbinfo->setMbFan($dev);
}
}
}
- foreach ($ar_buf as $line) {
- $data = array();
- if (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)\)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) RPM[ \t]+/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*) RPM$/", $line, $data);
- }
- $dev = new SensorDevice();
- $dev->setName(trim($data[1]));
- $dev->setValue(trim($data[2]));
- if (isset($data[4])) {
- $dev->setMin(trim($data[4]));
- }
- if (preg_match("/\sALARM(\s*)$/", $line)) {
- $dev->setEvent("Alarm");
- }
- $this->mbinfo->setMbFan($dev);
- }
}
+
/**
* get voltage information
*
@@ -211,58 +206,37 @@ class LMSensors extends Sensors
*/
private function _voltage()
{
- $ar_buf = array();
- foreach ($this->_lines as $line) {
- $data = array();
- if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*)\(/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*)/", $line, $data);
- }
- if (count($data) > 1) {
- $temp = substr(trim($data[2]), -2);
- switch ($temp) {
- case " V":
- array_push($ar_buf, $line);
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ $limit = "";
+ if (preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor["value"], $tmpbuf) ||
+ ((isset($sensor[$limit="min"]) || isset($sensor[$limit="max"])) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit]))) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ if ($limit != "") {
+ $dev->setValue($sensor["value"]);
+ $dev->setEvent("FAULT");
+ } else {
+ if ($tmpbuf[2] == "m") {
+ $dev->setValue(floatval($tmpbuf[1])/1000);
+ } else {
+ $dev->setValue(floatval($tmpbuf[1]));
+ }
+ }
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
+
+ if (isset($sensor[$limit="min"]) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit], $tmpbuf)) {
+ $dev->setMin(floatval($tmpbuf[1]));
+ }
+
+ if (isset($sensor[$limit="max"]) && preg_match("/^\+?(-?[\d\.]+) (m?)V$/", $sensor[$limit], $tmpbuf)) {
+ $dev->setMax(floatval($tmpbuf[1]));
+ }
+
+ $this->mbinfo->setMbVolt($dev);
}
}
}
- foreach ($ar_buf as $line) {
- $data = array();
- if (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)\)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) V[ \t]+/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*) V$/", $line, $data);
- }
- foreach ($data as $key=>$value) {
- if (preg_match("/^\+?(-?[0-9\.]+)$/", trim($value), $newvalue)) {
- $data[$key] = 0+trim($newvalue[1]);
- } else {
- $data[$key] = trim($value);
- }
- }
- if (isset($data[1])) {
- $dev = new SensorDevice();
- $dev->setName($data[1]);
- $dev->setValue($data[2]);
- if (isset($data[4])) {
- $dev->setMin($data[4]);
- }
- if (isset($data[6])) {
- $dev->setMax($data[6]);
- }
- if (preg_match("/\sALARM(\s*)$/", $line)) {
- $dev->setEvent("Alarm");
- }
- $this->mbinfo->setMbVolt($dev);
- }
- }
}
/**
@@ -272,63 +246,32 @@ class LMSensors extends Sensors
*/
private function _power()
{
- $ar_buf = array();
- foreach ($this->_lines as $line) {
- $data = array();
- if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*)/", $line, $data);
- }
- if (count($data) > 1) {
- $temp = substr(trim($data[2]), -2);
- switch ($temp) {
- case " W":
- array_push($ar_buf, $line);
- }
- }
- }
- foreach ($ar_buf as $line) {
- $data = array();
-/* not tested yet
- if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)\)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)/", $line, $data)) {
- ;
- } else
-*/
- if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) W[ \t]+/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*) W$/", $line, $data);
- }
- foreach ($data as $key=>$value) {
- if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) {
- $data[$key] = trim($newvalue[1]);
- } else {
- $data[$key] = trim($value);
- }
- }
- $dev = new SensorDevice();
- $dev->setName($data[1]);
- $dev->setValue($data[2]);
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ $limit = "";
+ if (preg_match("/^\+?(-?[\d\.]+) W$/", $sensor["value"], $tmpbuf) ||
+ (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) W$/", $sensor[$limit]))) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ if ($limit != "") {
+ $dev->setValue($sensor["value"]);
+ $dev->setEvent("FAULT");
+ } else {
+ $dev->setValue(floatval($tmpbuf[1]));
+ }
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
- if (isset($data[6]) && $data[2] <= $data[6]) {
- $dev->setMax(max($data[4], $data[6]));
- } elseif (isset($data[4]) && $data[2] <= $data[4]) {
- $dev->setMax($data[4]);
+ if (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) W$/", $sensor[$limit], $tmpbuf)) {
+ $dev->setMax(floatval($tmpbuf[1]));
+ }
+
+ $this->mbinfo->setMbPower($dev);
+ }
}
- if (preg_match("/\sALARM(\s*)$/", $line)) {
- $dev->setEvent("Alarm");
- }
- $this->mbinfo->setMbPower($dev);
}
}
+
/**
* get current information
*
@@ -336,60 +279,54 @@ class LMSensors extends Sensors
*/
private function _current()
{
- $ar_buf = array();
- foreach ($this->_lines as $line) {
- $data = array();
- if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*)/", $line, $data);
- }
- if (count($data) > 1) {
- $temp = substr(trim($data[2]), -2);
- switch ($temp) {
- case " A":
- array_push($ar_buf, $line);
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ $limit = "";
+ if (preg_match("/^\+?(-?[\d\.]+) A$/", $sensor["value"], $tmpbuf) ||
+ (isset($sensor[$limit="crit"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit]))) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ if ($limit != "") {
+ $dev->setValue($sensor["value"]);
+ $dev->setEvent("FAULT");
+ } else {
+ $dev->setValue(floatval($tmpbuf[1]));
+ }
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
+
+ if (isset($sensor[$limit="min"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit], $tmpbuf)) {
+ $dev->setMin(floatval($tmpbuf[1]));
+ }
+
+ if (isset($sensor[$limit="max"]) && preg_match("/^\+?(-?[\d\.]+) A$/", $sensor[$limit], $tmpbuf)) {
+ $dev->setMax(floatval($tmpbuf[1]));
+ }
+
+ $this->mbinfo->setMbCurrent($dev);
}
}
}
- foreach ($ar_buf as $line) {
- $data = array();
-/* not tested yet
- if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)\)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)/", $line, $data)) {
- ;
- } else
-*/
- if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A\)(.*)/", $line, $data)) {
- ;
- } elseif (preg_match("/(.*):(.*) A[ \t]+/", $line, $data)) {
- ;
- } else {
- preg_match("/(.*):(.*) A$/", $line, $data);
- }
- foreach ($data as $key=>$value) {
- if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) {
- $data[$key] = trim($newvalue[1]);
- } else {
- $data[$key] = trim($value);
+ }
+
+ /**
+ * get other information
+ *
+ * @return void
+ */
+ private function _other()
+ {
+ foreach ($this->_values as $sensors) foreach ($sensors as $sensor){
+ if (isset($sensor["value"])) {
+ if ((preg_match("/^[^\-\+\d]/", $sensor["value"]) || preg_match("/^\d+$/", $sensor["value"])) && ($sensor["value"] !== 'failed') &&
+ !isset($sensor[$limit="min"]) && !isset($sensor[$limit="max"]) && !isset($sensor[$limit="crit"]) && !isset($sensor[$limit="high"]) && !isset($sensor[$limit="hyst"])) {
+ $dev = new SensorDevice();
+ $dev->setName($sensor["name"]);
+ $dev->setValue($sensor["value"]);
+ if (isset($sensor["alarm"])) $dev->setEvent("ALARM");
+
+ $this->mbinfo->setMbOther($dev);
}
}
- $dev = new SensorDevice();
- $dev->setName($data[1]);
- $dev->setValue($data[2]);
-
- if (isset($data[6]) && $data[2] <= $data[6]) {
- $dev->setMax(max($data[4], $data[6]));
- } elseif (isset($data[4]) && $data[2] <= $data[4]) {
- $dev->setMax($data[4]);
- }
- if (preg_match("/\sALARM(\s*)$/", $line)) {
- $dev->setEvent("Alarm");
- }
- $this->mbinfo->setMbCurrent($dev);
}
}
@@ -398,14 +335,15 @@ class LMSensors extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
$this->_temperature();
- $this->_voltage();
$this->_fans();
+ $this->_voltage();
$this->_power();
$this->_current();
+ $this->_other();
}
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php
index bd22b40..19b81ad 100644
--- a/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.mbm5.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from Motherboard Monitor 5
- * information retrival through csv file
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -46,20 +34,15 @@ class MBM5 extends Sensors
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
- case 'file':
+ if ((PSI_OS == 'WINNT') && !defined('PSI_EMU_HOSTNAME')) {
$delim = "/;/";
- CommonFunctions::rfts(APP_ROOT."/data/MBM5.csv", $buffer);
+ CommonFunctions::rftsdata("MBM5.csv", $buffer);
if (strpos($buffer, ";") === false) {
$delim = "/,/";
}
$buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY);
$this->_buf_label = preg_split($delim, substr($buffer[0], 0, -2), -1, PREG_SPLIT_NO_EMPTY);
$this->_buf_value = preg_split($delim, substr($buffer[1], 0, -2), -1, PREG_SPLIT_NO_EMPTY);
- break;
- default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
}
}
@@ -78,7 +61,7 @@ class MBM5 extends Sensors
$dev = new SensorDevice();
$dev->setName($this->_buf_label[$intPosi]);
$dev->setValue($hits[0]);
- $dev->setMax(70);
+// $dev->setMax(70);
$this->mbinfo->setMbTemp($dev);
}
}
@@ -98,7 +81,7 @@ class MBM5 extends Sensors
$dev = new SensorDevice();
$dev->setName($this->_buf_label[$intPosi]);
$dev->setValue($hits[0]);
- $dev->setMin(3000);
+// $dev->setMin(3000);
$this->mbinfo->setMbFan($dev);
}
}
@@ -127,7 +110,7 @@ class MBM5 extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php
index 351b0a8..05a00dc 100644
--- a/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php
@@ -1,6 +1,6 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.mbmon.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from mbmon
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -33,14 +22,14 @@ class MBMon extends Sensors
private $_lines = array();
/**
- * fill the private content var through tcp or file access
+ * fill the private content var through tcp, command or data access
*/
public function __construct()
{
parent::__construct();
- switch (strtolower(PSI_SENSOR_ACCESS)) {
+ if ((PSI_OS != 'WINNT') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) switch (defined('PSI_SENSOR_MBMON_ACCESS')?strtolower(PSI_SENSOR_MBMON_ACCESS):'command') {
case 'tcp':
- $fp = fsockopen("localhost", 411, $errno, $errstr, 5);
+ $fp = fsockopen(defined('PSI_EMU_HOSTNAME')?PSI_EMU_HOSTNAME:'localhost', 411, $errno, $errstr, 5);
if ($fp) {
$lines = "";
while (!feof($fp)) {
@@ -55,14 +44,13 @@ class MBMon extends Sensors
CommonFunctions::executeProgram('mbmon', '-c 1 -r', $lines, PSI_DEBUG);
$this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
break;
- case 'file':
- if (CommonFunctions::rfts(APP_ROOT.'/data/mbmon.txt', $lines)) {
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('mbmon.tmp', $lines)) {
$this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
}
break;
default:
- $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS');
- break;
+ $this->error->addConfigError('__construct()', '[sensor_mbmon] ACCESS');
}
}
@@ -78,7 +66,7 @@ class MBMon extends Sensors
if ($data[2] <> '0') {
$dev = new SensorDevice();
$dev->setName($data[1]);
- $dev->setMax(70);
+// $dev->setMax(70);
if ($data[2] < 250) {
$dev->setValue($data[2]);
}
@@ -101,7 +89,7 @@ class MBMon extends Sensors
$dev = new SensorDevice();
$dev->setName($data[1]);
$dev->setValue($data[2]);
- $dev->setMax(3000);
+// $dev->setMax(3000);
$this->mbinfo->setMbFan($dev);
}
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php
new file mode 100644
index 0000000..149627f
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.nvidiasmi.inc.php
@@ -0,0 +1,136 @@
+
+ * @copyright 2020 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class NvidiaSMI extends Sensors
+{
+ /**
+ * content to parse
+ *
+ * @var array
+ */
+ private $_gpus = array();
+
+ /**
+ * fill the private array
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) switch (defined('PSI_SENSOR_NVIDIASMI_ACCESS')?strtolower(PSI_SENSOR_NVIDIASMI_ACCESS):'command') {
+ case 'command':
+ if (PSI_OS == 'WINNT') {
+ $winnt_exe = (defined('PSI_SENSOR_NVIDIASMI_EXE_PATH') && is_string(PSI_SENSOR_NVIDIASMI_EXE_PATH))?strtolower(PSI_SENSOR_NVIDIASMI_EXE_PATH):"c:\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe";
+ if (($_exe=realpath(trim($winnt_exe))) && preg_match("/^([a-zA-Z]:\\\\[^\\\\]+)/", $_exe, $out)) {
+ CommonFunctions::executeProgram('cmd', "/c set ProgramFiles=".$out[1]."^&\"".$_exe."\" -q", $lines);
+ } else {
+ $this->error->addConfigError('__construct()', '[sensor_nvidiasmi] EXE_PATH="'.$winnt_exe.'"');
+ }
+ } else {
+ CommonFunctions::executeProgram('nvidia-smi', '-q', $lines);
+ }
+
+ $this->_gpus = preg_split("/^(?=GPU )/m", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ break;
+ case 'data':
+ if (!defined('PSI_EMU_PORT') && CommonFunctions::rftsdata('nvidiasmi.tmp', $lines)) {
+ $this->_gpus = preg_split("/^(?=GPU )/m", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ }
+ break;
+ default:
+ $this->error->addConfigError('__construct()', '[sensor_nvidiasmi] ACCESS');
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $gpuc=count($this->_gpus);
+ switch ($gpuc) {
+ case 0:
+ $this->error->addError("nvidia-smi", "No values");
+ break;
+ case 1:
+ $this->error->addError("nvidia-smi", "Error: ".$this->_gpus[0]);
+ break;
+ default:
+ for ($c = 0; $c < $gpuc; $c++) {
+ if (preg_match("/^\s+GPU Current Temp\s+:\s*(\d+)\s*C\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." (nvidiasmi)");
+ $dev->setValue($out[1]);
+ if (preg_match("/^\s+GPU Shutdown Temp\s+:\s*(\d+)\s*C\s*$/m", $this->_gpus[$c], $out)) {
+ $dev->setMax($out[1]);
+ }
+ $this->mbinfo->setMbTemp($dev);
+ }
+ if (preg_match("/^\s+Power Draw\s+:\s*([\d\.]+)\s*W\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." (nvidiasmi)");
+ $dev->setValue($out[1]);
+ if (preg_match("/^\s+Power Limit\s+:\s*([\d\.]+)\s*W\s*$/m", $this->_gpus[$c], $out)) {
+ $dev->setMax($out[1]);
+ }
+ $this->mbinfo->setMbPower($dev);
+ }
+ if (preg_match("/^\s+Fan Speed\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $dev->setUnit("%");
+ $this->mbinfo->setMbFan($dev);
+ }
+ if (preg_match("/^\s+Performance State\s+:\s*(\S+)\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." Performance State (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $this->mbinfo->setMbOther($dev);
+ }
+ if (preg_match("/^\s+Gpu\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." Utilization (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $dev->setUnit("%");
+ $this->mbinfo->setMbOther($dev);
+ }
+ if (preg_match("/^\s+Memory\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." Memory Utilization (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $dev->setUnit("%");
+ $this->mbinfo->setMbOther($dev);
+ }
+ if (preg_match("/^\s+Encoder\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." Encoder Utilization (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $dev->setUnit("%");
+ $this->mbinfo->setMbOther($dev);
+ }
+ if (preg_match("/^\s+Decoder\s+:\s*(\d+)\s*%\s*$/m", $this->_gpus[$c], $out)) {
+ $dev = new SensorDevice();
+ $dev->setName("GPU ".($c)." Decoder Utilization (nvidiasmi)");
+ $dev->setValue($out[1]);
+ $dev->setUnit("%");
+ $this->mbinfo->setMbOther($dev);
+ }
+ }
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php
index baed9bb..2eced04 100644
--- a/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php
@@ -1,25 +1,14 @@
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from Open Hardware Monitor
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2014 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -38,25 +27,16 @@ class OHM extends Sensors
public function __construct()
{
parent::__construct();
- $_wmi = null;
- // don't set this params for local connection, it will not work
- $strHostname = '';
- $strUser = '';
- $strPassword = '';
- try {
- // initialize the wmi object
- $objLocator = new COM('WbemScripting.SWbemLocator');
- if ($strHostname == "") {
- $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor');
-
- } else {
- $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor', $strHostname.'\\'.$strUser, $strPassword);
+ if ((PSI_OS == 'WINNT') || (defined('PSI_EMU_HOSTNAME') && !defined('PSI_EMU_PORT'))) {
+ $_wmi = WINNT::initWMI('root\OpenHardwareMonitor', true);
+ if ($_wmi) {
+ $tmpbuf = WINNT::getWMI($_wmi, 'Sensor', array('Parent', 'Name', 'SensorType', 'Value'));
+ if ($tmpbuf) foreach ($tmpbuf as $buffer) {
+ if (!isset($this->_buf[$buffer['SensorType']]) || !isset($this->_buf[$buffer['SensorType']][$buffer['Parent'].' '.$buffer['Name']])) { // avoid duplicates
+ $this->_buf[$buffer['SensorType']][$buffer['Parent'].' '.$buffer['Name']] = $buffer['Value'];
+ }
+ }
}
- } catch (Exception $e) {
- $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for OpenHardwareMonitor data.");
- }
- if ($_wmi) {
- $this->_buf = CommonFunctions::getWMI($_wmi, 'Sensor', array('Parent', 'Name', 'SensorType', 'Value'));
}
}
@@ -67,13 +47,11 @@ class OHM extends Sensors
*/
private function _temperature()
{
- if ($this->_buf) foreach ($this->_buf as $buffer) {
- if ($buffer['SensorType'] == "Temperature") {
- $dev = new SensorDevice();
- $dev->setName($buffer['Parent'].' '.$buffer['Name']);
- $dev->setValue($buffer['Value']);
- $this->mbinfo->setMbTemp($dev);
- }
+ if (isset($this->_buf['Temperature'])) foreach ($this->_buf['Temperature'] as $name=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName($name);
+ $dev->setValue($value);
+ $this->mbinfo->setMbTemp($dev);
}
}
@@ -84,13 +62,11 @@ class OHM extends Sensors
*/
private function _voltage()
{
- if ($this->_buf) foreach ($this->_buf as $buffer) {
- if ($buffer['SensorType'] == "Voltage") {
- $dev = new SensorDevice();
- $dev->setName($buffer['Parent'].' '.$buffer['Name']);
- $dev->setValue($buffer['Value']);
- $this->mbinfo->setMbVolt($dev);
- }
+ if (isset($this->_buf['Voltage'])) foreach ($this->_buf['Voltage'] as $name=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName($name);
+ $dev->setValue($value);
+ $this->mbinfo->setMbVolt($dev);
}
}
@@ -101,13 +77,11 @@ class OHM extends Sensors
*/
private function _fans()
{
- if ($this->_buf) foreach ($this->_buf as $buffer) {
- if ($buffer['SensorType'] == "Fan") {
- $dev = new SensorDevice();
- $dev->setName($buffer['Parent'].' '.$buffer['Name']);
- $dev->setValue($buffer['Value']);
- $this->mbinfo->setMbFan($dev);
- }
+ if (isset($this->_buf['Fan'])) foreach ($this->_buf['Fan'] as $name=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName($name);
+ $dev->setValue($value);
+ $this->mbinfo->setMbFan($dev);
}
}
@@ -118,13 +92,11 @@ class OHM extends Sensors
*/
private function _power()
{
- if ($this->_buf) foreach ($this->_buf as $buffer) {
- if ($buffer['SensorType'] == "Power") {
- $dev = new SensorDevice();
- $dev->setName($buffer['Parent'].' '.$buffer['Name']);
- $dev->setValue($buffer['Value']);
- $this->mbinfo->setMbPower($dev);
- }
+ if (isset($this->_buf['Power'])) foreach ($this->_buf['Power'] as $name=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName($name);
+ $dev->setValue($value);
+ $this->mbinfo->setMbPower($dev);
}
}
@@ -133,7 +105,7 @@ class OHM extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php
index 1455ad5..ff55719 100644
--- a/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php
@@ -7,8 +7,10 @@
* @category PHP
* @package PSI_Sensor
* @author Marc Hillesheim
- * @copyright 2012 Marc Hillesheim
- * @link http://pi.no-ip.biz
+ * @copyright 2012 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
*/
class PiTemp extends Sensors
{
@@ -16,15 +18,15 @@ class PiTemp extends Sensors
{
$temp = null;
$temp_max = null;
- if (!CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input', $temp, 0, 4096, false)) { // Not Banana Pi
- CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/temp', $temp);
- CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/trip_point_0_temp', $temp_max, 0, 4096, PSI_DEBUG);
+ if (!CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input', $temp, 1, 4096, false)) { // Not Banana Pi
+ CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/temp', $temp, 1);
+ CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/trip_point_0_temp', $temp_max, 1, 4096, PSI_DEBUG);
}
- if (!is_null($temp) && (trim($temp) != "")) {
+ if (($temp !== null) && (($temp = trim($temp)) != "")) {
$dev = new SensorDevice();
$dev->setName("CPU 1");
$dev->setValue($temp / 1000);
- if (!is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) {
+ if (($temp_max !== null) && (($temp_max = trim($temp_max)) != "") && ($temp_max > 0)) {
$dev->setMax($temp_max / 1000);
}
$this->mbinfo->setMbTemp($dev);
@@ -34,7 +36,7 @@ class PiTemp extends Sensors
private function _voltage()
{
$volt = null;
- if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now', $volt, 0, 4096, false) && !is_null($volt) && (trim($volt) != "")) { // Banana Pi
+ if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now', $volt, 1, 4096, false) && ($volt !== null) && (($volt = trim($volt)) != "")) { // Banana Pi
$dev = new SensorDevice();
$dev->setName("Voltage 1");
$dev->setValue($volt / 1000000);
@@ -45,7 +47,7 @@ class PiTemp extends Sensors
private function _current()
{
$current = null;
- if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now', $current, 0, 4096, false) && !is_null($current) && (trim($current) != "")) { // Banana Pi
+ if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now', $current, 1, 4096, false) && ($current !== null) && (($current = trim($current)) != "")) { // Banana Pi
$dev = new SensorDevice();
$dev->setName("Current 1");
$dev->setValue($current / 1000000);
@@ -55,8 +57,10 @@ class PiTemp extends Sensors
public function build()
{
- $this->_temperature();
- $this->_voltage();
- $this->_current();
+ if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) {
+ $this->_temperature();
+ $this->_voltage();
+ $this->_current();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php b/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php
new file mode 100644
index 0000000..475831a
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.qtssnmp.inc.php
@@ -0,0 +1,93 @@
+
+ * @copyright 2016 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class QTSsnmp extends Sensors
+{
+ /**
+ * get temperature information
+ *
+ * @return void
+ */
+ private function _temperature()
+ {
+ if (!defined('PSI_EMU_PORT')) {
+ $address = '127.0.0.1';
+ } else {
+ $address = PSI_EMU_HOSTNAME;
+ }
+ if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.5.0", $buffer, PSI_DEBUG)
+ && preg_match('/^[\.\d]+ = STRING:\s\"?(\d+)\sC/', $buffer, $data)) {
+ $dev = new SensorDevice();
+ $dev->setName("CPU");
+ $dev->setValue($data[1]);
+ $this->mbinfo->setMbTemp($dev);
+ }
+
+ if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.6.0", $buffer, PSI_DEBUG)
+ && preg_match('/^[\.\d]+ = STRING:\s\"?(\d+)\sC/', $buffer, $data)) {
+ $dev = new SensorDevice();
+ $dev->setName("System");
+ $dev->setValue($data[1]);
+ $this->mbinfo->setMbTemp($dev);
+ }
+
+ if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.11.1.3", $buffer, PSI_DEBUG)) {
+ $lines = preg_split('/\r?\n/', $buffer);
+ foreach ($lines as $line) if (preg_match('/^[\.\d]+\.(\d+) = STRING:\s\"?(\d+)\sC/', $line, $data)) {
+ $dev = new SensorDevice();
+ $dev->setName("HDD ".$data[1]);
+ $dev->setValue($data[2]);
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @return void
+ */
+ private function _fans()
+ {
+ if (!defined('PSI_EMU_PORT')) {
+ $address = '127.0.0.1';
+ } else {
+ $address = PSI_EMU_HOSTNAME;
+ }
+ if (CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$address." .1.3.6.1.4.1.24681.1.2.15.1.3", $buffer, PSI_DEBUG)) {
+ $lines = preg_split('/\r?\n/', $buffer);
+ foreach ($lines as $line) if (preg_match('/^[\.\d]+\.(\d+) = STRING:\s\"?(\d+)\sRPM/', $line, $data)) {
+ $dev = new SensorDevice();
+ $dev->setName("Fan ".$data[1]);
+ $dev->setValue($data[2]);
+ $this->mbinfo->setMbFan($dev);
+ }
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ if ((PSI_OS == 'Linux') && (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT'))) {
+ $this->_temperature();
+ $this->_fans();
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php
index a37385b..dce90ac 100644
--- a/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php
@@ -8,7 +8,7 @@
* @package PSI sensors class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.sensors.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI sensors class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,7 +28,7 @@ abstract class Sensors implements PSI_Interface_Sensor
/**
* object for error handling
*
- * @var Error
+ * @var PSI_Error
*/
protected $error;
@@ -44,7 +44,7 @@ abstract class Sensors implements PSI_Interface_Sensor
*/
public function __construct()
{
- $this->error = Error::singleton();
+ $this->error = PSI_Error::singleton();
$this->mbinfo = new MBInfo();
}
diff --git a/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php b/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php
new file mode 100644
index 0000000..628d811
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.speedfan.inc.php
@@ -0,0 +1,125 @@
+
+ * @copyright 2016 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class SpeedFan extends Sensors
+{
+ /*
+ * variable, which holds the content of the command
+ * @var array
+ */
+ private $_filecontent = array();
+
+ public function __construct()
+ {
+ parent::__construct();
+ if ((PSI_OS == 'WINNT') && !defined('PSI_EMU_HOSTNAME')) switch (defined('PSI_SENSOR_SPEEDFAN_ACCESS')?strtolower(PSI_SENSOR_SPEEDFAN_ACCESS):'command') {
+ case 'command':
+ if (CommonFunctions::executeProgram("SpeedFanGet.exe", "", $buffer, PSI_DEBUG) && (strlen($buffer) > 0)) {
+ if (preg_match("/^Temperatures:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["temp"] = $out[1];
+ }
+ if (preg_match("/^Fans:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["fans"] = $out[1];
+ }
+ if (preg_match("/^Voltages:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["volt"] = $out[1];
+ }
+ }
+ break;
+ case 'data':
+ if (CommonFunctions::rftsdata('speedfan.tmp', $buffer) && (strlen($buffer) > 0)) {
+ if (preg_match("/^Temperatures:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["temp"] = $out[1];
+ }
+ if (preg_match("/^Fans:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["fans"] = $out[1];
+ }
+ if (preg_match("/^Voltages:\s+(.+)$/m", $buffer, $out)) {
+ $this->_filecontent["volt"] = $out[1];
+ }
+ }
+ break;
+ default:
+ $this->error->addConfigError('__construct()', '[sensor_speedfan] ACCESS');
+ }
+ }
+
+ /**
+ * get temperature information
+ *
+ * @return void
+ */
+ private function _temperature()
+ {
+ if (isset($this->_filecontent["temp"]) && (trim($this->_filecontent["temp"]) !== "")) {
+ $values = preg_split("/ /", trim($this->_filecontent["temp"]));
+ foreach ($values as $id=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName("temp".$id);
+ $dev->setValue($value);
+ $this->mbinfo->setMbTemp($dev);
+ }
+ }
+ }
+
+ /**
+ * get fan information
+ *
+ * @return void
+ */
+ private function _fans()
+ {
+ if (isset($this->_filecontent["fans"]) && (trim($this->_filecontent["fans"]) !== "")) {
+ $values = preg_split("/ /", trim($this->_filecontent["fans"]));
+ foreach ($values as $id=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName("fan".$id);
+ $dev->setValue($value);
+ $this->mbinfo->setMbFan($dev);
+ }
+ }
+ }
+
+ /**
+ * get voltage information
+ *
+ * @return void
+ */
+ private function _voltage()
+ {
+ if (isset($this->_filecontent["volt"]) && (trim($this->_filecontent["volt"]) !== "")) {
+ $values = preg_split("/ /", trim($this->_filecontent["volt"]));
+ foreach ($values as $id=>$value) {
+ $dev = new SensorDevice();
+ $dev->setName("in".$id);
+ $dev->setValue($value);
+ $this->mbinfo->setMbVolt($dev);
+ }
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->_temperature();
+ $this->_fans();
+ $this->_voltage();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php
index 6abd7c1..19ddcb6 100644
--- a/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php
+++ b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php
@@ -1,31 +1,20 @@
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $
- * @link http://phpsysinfo.sourceforge.net
- */
- /**
- * getting information from Thermal Zone WMI class
- *
- * @category PHP
- * @package PSI_Sensor
- * @author Michael Cramer
- * @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2014 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class ThermalZone extends Sensors
{
-/**
+ /**
* holds the COM object that we pull all the WMI data from
*
* @var Object
@@ -38,27 +27,39 @@ class ThermalZone extends Sensors
public function __construct()
{
parent::__construct();
- if (PSI_OS == 'WINNT') {
- $_wmi = null;
- // don't set this params for local connection, it will not work
- $strHostname = '';
- $strUser = '';
- $strPassword = '';
- try {
- // initialize the wmi object
- $objLocator = new COM('WbemScripting.SWbemLocator');
- if ($strHostname == "") {
- $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI');
-
+ switch (defined('PSI_SENSOR_THERMALZONE_ACCESS')?strtolower(PSI_SENSOR_THERMALZONE_ACCESS):'command') {
+ case 'command':
+ if ((PSI_OS == 'WINNT') || (defined('PSI_EMU_HOSTNAME') && !defined('PSI_EMU_PORT'))) {
+ if (defined('PSI_EMU_HOSTNAME') || WINNT::isAdmin()) {
+ $_wmi = WINNT::initWMI('root\WMI', true);
+ if ($_wmi) {
+ $this->_buf = WINNT::getWMI($_wmi, 'MSAcpi_ThermalZoneTemperature', array('InstanceName', 'CriticalTripPoint', 'CurrentTemperature'));
+ }
} else {
- $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI', $strHostname.'\\'.$strUser, $strPassword);
+ $_wmi = WINNT::getcimv2wmi();
+ if ($_wmi) {
+ $this->_buf = WINNT::getWMI($_wmi, 'Win32_PerfFormattedData_Counters_ThermalZoneInformation', array('Name', 'HighPrecisionTemperature', 'Temperature'));
+ }
+ if (!$this->_buf || PSI_DEBUG) {
+ $this->error->addError("Error reading data from thermalzone sensor", "Allowed only for systems with administrator privileges (run as administrator)");
+ }
}
- } catch (Exception $e) {
- $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for ThermalZone data.");
}
- if ($_wmi) {
- $this->_buf = CommonFunctions::getWMI($_wmi, 'MSAcpi_ThermalZoneTemperature', array('InstanceName', 'CriticalTripPoint', 'CurrentTemperature'));
+ break;
+ case 'data':
+ if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::rftsdata('thermalzone.tmp', $lines)) { //output of "wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CriticalTripPoint,CurrentTemperature,InstanceName"
+ $lines = trim(preg_replace('/[\x00-\x09\x0b-\x1F]/', '', $lines));
+ $lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY);
+ if ((($clines=count($lines)) > 1) && preg_match("/CriticalTripPoint\s+CurrentTemperature\s+InstanceName/i", $lines[0])) for ($i = 1; $i < $clines; $i++) {
+ $values = preg_split("/\s+/", trim($lines[$i]), -1, PREG_SPLIT_NO_EMPTY);
+ if (count($values)==3) {
+ $this->_buf[] = array('CriticalTripPoint'=>trim($values[0]), 'CurrentTemperature'=>trim($values[1]), 'InstanceName'=>trim($values[2]));
+ }
+ }
}
+ break;
+ default:
+ $this->error->addConfigError('__construct()', '[sensor_thermalzone] ACCESS');
}
}
@@ -69,7 +70,9 @@ class ThermalZone extends Sensors
*/
private function _temperature()
{
- if (PSI_OS == 'WINNT') {
+ $mode = defined('PSI_SENSOR_THERMALZONE_ACCESS')?strtolower(PSI_SENSOR_THERMALZONE_ACCESS):'command';
+ if ((($mode == 'command') && ((PSI_OS == 'WINNT') || defined('PSI_EMU_HOSTNAME')))
+ || (($mode == 'data') && !defined('PSI_EMU_HOSTNAME'))) {
if ($this->_buf) foreach ($this->_buf as $buffer) {
if (isset($buffer['CurrentTemperature']) && (($value = ($buffer['CurrentTemperature'] - 2732)/10) > -100)) {
$dev = new SensorDevice();
@@ -83,34 +86,73 @@ class ThermalZone extends Sensors
$dev->setMax($maxvalue);
}
$this->mbinfo->setMbTemp($dev);
+ } else {
+ if ((isset($buffer['HighPrecisionTemperature']) && (($value = ($buffer['HighPrecisionTemperature'] - 2732)/10) > -100))
+ || (isset($buffer['Temperature']) && (($value = ($buffer['Temperature'] - 273)) > -100))) {
+ $dev = new SensorDevice();
+ if (isset($buffer['Name']) && preg_match("/([^\\\\\. ]+)$/", $buffer['Name'], $outbuf)) {
+ $dev->setName('ThermalZone '.$outbuf[1]);
+ } else {
+ $dev->setName('ThermalZone THM0');
+ }
+ $dev->setValue($value);
+ $this->mbinfo->setMbTemp($dev);
+ }
}
}
- } else {
- foreach (glob('/sys/class/thermal/thermal_zone*/') as $thermalzone) {
+ } elseif (($mode == 'command') && (PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) {
+ $notwas = true;
+ $thermalzones = CommonFunctions::findglob('/sys/class/thermal/thermal_zone*/');
+ if (is_array($thermalzones) && (count($thermalzones) > 0)) foreach ($thermalzones as $thermalzone) {
$thermalzonetemp = $thermalzone.'temp';
$temp = null;
- if (CommonFunctions::rfts($thermalzonetemp, $temp, 0, 4096, false) && !is_null($temp) && (trim($temp) != "")) {
+ if (CommonFunctions::rfts($thermalzonetemp, $temp, 1, 4096, false) && ($temp !== null) && (($temp = trim($temp)) != "")) {
if ($temp >= 1000) {
- $temp = $temp / 1000;
+ $div = 1000;
+ } elseif ($temp >= 200) {
+ $div = 10;
+ } else {
+ $div = 1;
}
-
+ $temp = $temp / $div;
+
if ($temp > -40) {
$dev = new SensorDevice();
$dev->setValue($temp);
$temp_type = null;
- if (CommonFunctions::rfts($thermalzone.'type', $temp_type, 0, 4096, false) && !is_null($temp_type) && (trim($temp_type) != "")) {
+ if (CommonFunctions::rfts($thermalzone.'type', $temp_type, 1, 4096, false) && ($temp_type !== null) && (($temp_type = trim($temp_type)) != "")) {
$dev->setName($temp_type);
+ } else {
+ $dev->setName("ThermalZone");
}
$temp_max = null;
- if (CommonFunctions::rfts($thermalzone.'trip_point_0_temp', $temp_max, 0, 4096, false) && !is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) {
- if ($temp_max >= 1000) {
- $temp_max = $temp_max / 1000;
+ if (CommonFunctions::rfts($thermalzone.'trip_point_0_temp', $temp_max, 1, 4096, false) && ($temp_max !== null) && (($temp_max = trim($temp_max)) != "") && ($temp_max > -40)) {
+ $temp_max = $temp_max / $div;
+ if (($temp_max != 0) || ($temp != 0)) { // if non-zero values
+ $dev->setMax($temp_max);
+ $this->mbinfo->setMbTemp($dev);
}
- $dev->setMax($temp_max);
+ } else {
+ $this->mbinfo->setMbTemp($dev);
}
-
+ $notwas = false;
+ }
+ }
+ }
+ if ($notwas) {
+ $thermalzones = (PSI_ROOT_FILESYSTEM.'/proc/acpi/thermal_zone/TH*/temperature');
+ if (is_array($thermalzones) && (count($thermalzones) > 0)) foreach ($thermalzones as $thermalzone) {
+ $temp = null;
+ if (CommonFunctions::rfts($thermalzone, $temp, 1, 4096, false) && ($temp !== null) && (($temp = trim($temp)) != "")) {
+ $dev = new SensorDevice();
+ if (preg_match("/^\/proc\/acpi\/thermal_zone\/(.+)\/temperature$/", $thermalzone, $name)) {
+ $dev->setName("ThermalZone ".$name[1]);
+ } else {
+ $dev->setName("ThermalZone");
+ }
+ $dev->setValue(trim(substr($temp, 23, 4)));
$this->mbinfo->setMbTemp($dev);
}
}
@@ -123,7 +165,7 @@ class ThermalZone extends Sensors
*
* @see PSI_Interface_Sensor::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php b/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php
new file mode 100644
index 0000000..ee24091
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/mb/class.thinkpad.inc.php
@@ -0,0 +1,41 @@
+
+ * @copyright 2017 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class Thinkpad extends Hwmon
+{
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_Sensor::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ if ((PSI_OS == 'Linux') && !defined('PSI_EMU_HOSTNAME')) {
+ $hwpaths = CommonFunctions::findglob("/sys/devices/platform/thinkpad_hwmon/", GLOB_NOSORT);
+ if (is_array($hwpaths) && (count($hwpaths) == 1)) {
+ $hwpaths2 = CommonFunctions::findglob("/sys/devices/platform/thinkpad_hwmon/hwmon/hwmon*/", GLOB_NOSORT);
+ if (is_array($hwpaths2) && (count($hwpaths2) > 0)) {
+ $hwpaths = array_merge($hwpaths, $hwpaths2);
+ }
+ $totalh = count($hwpaths);
+ for ($h = 0; $h < $totalh; $h++) {
+ $this->_temperature($hwpaths[$h]);
+ $this->_fans($hwpaths[$h]);
+ }
+ }
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/os/class.AIX.inc.php b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php
index 61ce603..2bae924 100644
--- a/root/opt/phpsysinfo/includes/os/class.AIX.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php
@@ -8,7 +8,7 @@
* @package PSI AIX OS class
* @author Krzysztof Paz (kpaz@gazeta.pl) based on HPUX of Michael Cramer
* @copyright 2011 Krzysztof Paz
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.AIX.inc.php 287 2009-06-26 12:11:59Z Krzysztof Paz, IBM POLSKA
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,13 +20,20 @@
* @package PSI AIX OS class
* @author Krzysztof Paz (kpaz@gazeta.pl) based on Michael Cramer
* @copyright 2011 Krzysztof Paz
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class AIX extends OS
{
+ /**
+ * uptime command result.
+ */
+ private $_uptime = null;
+ /**
+ * prtconf command result.
+ */
private $_aixdata = array();
/**
@@ -35,34 +42,17 @@ class AIX extends OS
*/
private function _hostname()
{
- /* if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ /* if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('hostname', '', $ret)) {
$this->sys->setHostname($ret);
}
} */
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
}
- /**
- * IP of the Virtual Host Name
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* IBM AIX Version
* @return void
@@ -81,8 +71,8 @@ class AIX extends OS
*/
private function _uptime()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf) || preg_match("/up (\d+) day,\s*(\d+):(\d+),/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/up (\d+) day[s]?,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
$min = $ar_buf[3];
$hours = $ar_buf[2];
$days = $ar_buf[1];
@@ -91,17 +81,6 @@ class AIX extends OS
}
}
- /**
- * Number of Users
- * @return void
- */
- private function _users()
- {
- if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) {
- $this->sys->setUsers($buf);
- }
- }
-
/**
* Processor Load
* optionally create a loadbar
@@ -109,8 +88,8 @@ class AIX extends OS
*/
private function _loadavg()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) {
$this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
}
}
@@ -305,7 +284,7 @@ class AIX extends OS
$mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) {
$lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY);
- while (list(, $line) = each($lines)) {
+ foreach ($lines as $line) {
$a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY);
$fsdev[$a[0]] = $a[4];
}
@@ -339,7 +318,7 @@ class AIX extends OS
/**
* IBM AIX informations by K.PAZ
- * @return void
+ * @return array
*/
private function readaixdata()
{
@@ -357,25 +336,34 @@ class AIX extends OS
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->error->addError("WARN", "The AIX version of phpSysInfo is a work in progress, some things currently don't work");
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_loadavg();
- $this->_cpuinfo();
- $this->_pci();
- $this->_ide();
- $this->_scsi();
- $this->_usb();
- $this->_network();
- $this->_memory();
- $this->_filesystems();
+ $this->error->addWarning("The AIX version of phpSysInfo is a work in progress, some things currently don't work");
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_cpuinfo();
+ $this->_pci();
+ $this->_ide();
+ $this->_scsi();
+ $this->_usb();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.Android.inc.php b/root/opt/phpsysinfo/includes/os/class.Android.inc.php
index 04c88e4..3286a24 100644
--- a/root/opt/phpsysinfo/includes/os/class.Android.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.Android.inc.php
@@ -8,7 +8,7 @@
* @package PSI Android OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,18 +20,33 @@
* @package PSI Android OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class Android extends Linux
{
/**
- * call parent constructor
+ * holds the data from /system/build.prop file
+ *
+ * @var string
*/
- public function __construct()
+ private $_buildprop = null;
+
+ /**
+ * reads the data from /system/build.prop file
+ *
+ * @return string
+ */
+ private function _get_buildprop()
{
- parent::__construct();
+ if ($this->_buildprop === null) {
+ if (!CommonFunctions::rfts('/system/build.prop', $this->_buildprop, 0, 4096, false)) {
+ CommonFunctions::rfts('/system//build.prop', $this->_buildprop, 0, 4096, false); //fix some access issues
+ }
+ }
+
+ return $this->_buildprop;
}
/**
@@ -39,16 +54,25 @@ class Android extends Linux
*
* @return void
*/
- private function _kernel()
+ protected function _kernel()
{
- if (CommonFunctions::rfts('/proc/version', $strBuf, 1)) {
- if (preg_match('/version (.*?) /', $strBuf, $ar_buf)) {
- $result = $ar_buf[1];
+ if (CommonFunctions::executeProgram('uname', '-r', $strBuf, false)) {
+ $result = $strBuf;
+ if (CommonFunctions::executeProgram('uname', '-v', $strBuf, PSI_DEBUG)) {
if (preg_match('/SMP/', $strBuf)) {
$result .= ' (SMP)';
}
- $this->sys->setKernel($result);
}
+ if (CommonFunctions::executeProgram('uname', '-m', $strBuf, PSI_DEBUG)) {
+ $result .= ' '.$strBuf;
+ }
+ $this->sys->setKernel($result);
+ } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) && preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) {
+ $result = $ar_buf[1];
+ if (preg_match('/SMP/', $strBuf)) {
+ $result .= ' (SMP)';
+ }
+ $this->sys->setKernel($result);
}
}
@@ -57,7 +81,7 @@ class Android extends Linux
*
* @return void
*/
- private function _users()
+ protected function _users()
{
$this->sys->setUsers(1);
}
@@ -67,9 +91,10 @@ class Android extends Linux
*
* @return void
*/
- private function _filesystems()
+ protected function _filesystems()
{
- if (CommonFunctions::executeProgram('df', '2>/dev/null ', $df, PSI_DEBUG)) {
+ $notwas = true;
+ if (CommonFunctions::executeProgram('df', '2>/dev/null ', $df, PSI_DEBUG) && preg_match("/\s+[0-9\.]+[KMGT]\s+/", $df)) {
$df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) {
$mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY);
@@ -130,10 +155,17 @@ class Android extends Linux
}
}
$this->sys->setDiskDevices($dev);
+ $notwas = false;
}
}
}
}
+ if ($notwas) { // try Linux df style
+ $arrResult = Parser::df("-P 2>/dev/null", false);
+ foreach ($arrResult as $dev) {
+ $this->sys->setDiskDevices($dev);
+ }
+ }
}
/**
@@ -141,18 +173,17 @@ class Android extends Linux
*
* @return void
*/
- private function _distro()
+ protected function _distro()
{
$buf = "";
- if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false)
- && preg_match('/^ro\.build\.version\.release=([^\n]+)/m', $lines, $ar_buf)) {
+ if (($lines = $this->_get_buildprop()) && preg_match('/^ro\.build\.version\.release=([^\n]+)/m', $lines, $ar_buf)) {
$buf = trim($ar_buf[1]);
}
- if (is_null($buf) || ($buf == "")) {
+ if (($buf === null) || ($buf == "")) {
$this->sys->setDistribution('Android');
} else {
if (preg_match('/^(\d+\.\d+)/', $buf, $ver)
- && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true))
+ && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))
&& isset($list['Android'][$ver[1]])) {
$buf.=' '.$list['Android'][$ver[1]];
}
@@ -166,14 +197,14 @@ class Android extends Linux
*
* @return void
*/
- private function _machine()
+ protected function _machine()
{
- if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false)) {
+ if ($lines = $this->_get_buildprop()) {
$buf = "";
- if (preg_match('/^ro\.product\.manufacturer=([^\n]+)/m', $lines, $ar_buf)) {
+ if (preg_match('/^ro\.product\.manufacturer=([^\n]+)/m', $lines, $ar_buf) && (trim($ar_buf[1]) !== "unknown")) {
$buf .= ' '.trim($ar_buf[1]);
}
- if (preg_match('/^ro\.product\.model=([^\n]+)/m', $lines, $ar_buf) && (trim($buf) !== trim($ar_buf[1]))) {
+ if (preg_match('/^ro\.product\.model=([^\n]+)/m', $lines, $ar_buf) && (trim($ar_buf[1]) !== trim($buf))) {
$buf .= ' '.trim($ar_buf[1]);
}
if (preg_match('/^ro\.semc\.product\.name=([^\n]+)/m', $lines, $ar_buf)) {
@@ -188,7 +219,7 @@ class Android extends Linux
/**
* PCI devices
*
- * @return array
+ * @return void
*/
private function _pci()
{
@@ -205,50 +236,40 @@ class Android extends Linux
}
}
- /**
- * USB devices
- *
- * @return array
- */
- private function _usb()
- {
- if (file_exists('/dev/bus/usb') && CommonFunctions::executeProgram('lsusb', '', $bufr, false)) {
- $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($bufe as $buf) {
- $device = preg_split("/ /", $buf, 6);
- if (isset($device[5]) && trim($device[5]) != "") {
- $dev = new HWDevice();
- $dev->setName(trim($device[5]));
- $this->sys->setUsbDevices($dev);
- }
- }
- }
- }
-
/**
* get the information
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_machine();
- $this->_uptime();
- $this->_users();
- $this->_cpuinfo();
- $this->_pci();
- $this->_usb();
- $this->_i2c();
- $this->_network();
- $this->_memory();
- $this->_filesystems();
- $this->_loadavg();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_machine();
+ $this->_cpuinfo();
+ $this->_virtualizer();
+ $this->_pci();
+ $this->_usb();
+ $this->_i2c();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php
index 50bc2cf..7db0296 100644
--- a/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php
@@ -8,7 +8,7 @@
* @package PSI BSDCommon OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.BSDCommon.inc.php 621 2012-07-29 18:49:04Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,68 +21,72 @@
* @package PSI BSDCommon OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
abstract class BSDCommon extends OS
{
+ /**
+ * Assoc array of all CPUs loads.
+ */
+ private $_cpu_loads = null;
+
/**
* content of the syslog
*
* @var array
*/
- private $_dmesg = array();
+ private $_dmesg = null;
/**
* regexp1 for cpu information out of the syslog
*
* @var string
*/
- private $_CPURegExp1 = "";
+ private $_CPURegExp1 = "//";
/**
* regexp2 for cpu information out of the syslog
*
* @var string
*/
- private $_CPURegExp2 = "";
+ private $_CPURegExp2 = "//";
/**
* regexp1 for scsi information out of the syslog
*
* @var string
*/
- private $_SCSIRegExp1 = "";
+ private $_SCSIRegExp1 = "//";
/**
* regexp2 for scsi information out of the syslog
*
* @var string
*/
- private $_SCSIRegExp2 = "";
+ private $_SCSIRegExp2 = "//";
+
+ /**
+ * regexp3 for scsi information out of the syslog
+ *
+ * @var string
+ */
+ private $_SCSIRegExp3 = "//";
/**
* regexp1 for pci information out of the syslog
*
* @var string
*/
- private $_PCIRegExp1 = "";
+ private $_PCIRegExp1 = "//";
/**
* regexp1 for pci information out of the syslog
*
* @var string
*/
- private $_PCIRegExp2 = "";
-
- /**
- * call parent constructor
- */
- public function __construct()
- {
- parent::__construct();
- }
+ private $_PCIRegExp2 = "//";
/**
* setter for cpuregexp1
@@ -132,6 +136,18 @@ abstract class BSDCommon extends OS
$this->_SCSIRegExp2 = $value;
}
+ /**
+ * setter for scsiregexp3
+ *
+ * @param string $value value to set
+ *
+ * @return void
+ */
+ protected function setSCSIRegExp3($value)
+ {
+ $this->_SCSIRegExp3 = $value;
+ }
+
/**
* setter for pciregexp1
*
@@ -163,12 +179,12 @@ abstract class BSDCommon extends OS
*/
protected function readdmesg()
{
- if (count($this->_dmesg) === 0) {
- if (PSI_OS != "Darwin") {
- if (CommonFunctions::rfts('/var/run/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/log/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/run/dmesg.boot', $buf)) { // Once again but with debug
- $parts = preg_split("/rebooting|Uptime/", $buf, -1, PREG_SPLIT_NO_EMPTY);
- $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY);
- }
+ if ($this->_dmesg === null) {
+ if ((PSI_OS != 'Darwin') && (CommonFunctions::rfts('/var/run/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/log/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/run/dmesg.boot', $buf))) { // Once again but with debug
+ $parts = preg_split("/rebooting|Uptime/", $buf, -1, PREG_SPLIT_NO_EMPTY);
+ $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY);
+ } else {
+ $this->_dmesg = array();
}
}
@@ -199,8 +215,8 @@ abstract class BSDCommon extends OS
*/
protected function hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('hostname', '', $buf, PSI_DEBUG)) {
$this->sys->setHostname($buf);
@@ -208,24 +224,6 @@ abstract class BSDCommon extends OS
}
}
- /**
- * IP of the Canonical Host Name
- *
- * @return void
- */
- protected function ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* Kernel Version
*
@@ -234,19 +232,98 @@ abstract class BSDCommon extends OS
protected function kernel()
{
$s = $this->grabkey('kern.version');
- $a = preg_split('/:/', $s);
- $this->sys->setKernel($a[0].$a[1].':'.$a[2]);
+ $a = preg_split('/:/', $s, 4);
+ if (isset($a[3])) {
+ if (preg_match('/^(\d{2} [A-Z]{3});/', $a[3], $abuf) // eg. 19:58 GMT;...
+ || preg_match('/^(\d{2} [A-Z]{3} \d{4})/', $a[3], $abuf)) { // eg. 26:31 PDT 2019...
+ $this->sys->setKernel($a[0].$a[1].':'.$a[2].':'.$abuf[1]);
+ } else {
+ $this->sys->setKernel($a[0].$a[1].':'.$a[2]);
+ }
+ } elseif (isset($a[2])) {
+ $this->sys->setKernel($a[0].$a[1].':'.$a[2]);
+ } else {
+ $this->sys->setKernel($s);
+ }
}
/**
- * Number of Users
+ * Virtualizer info
*
* @return void
*/
- protected function users()
+ private function virtualizer()
{
- if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) {
- $this->sys->setUsers($buf);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $testvirt = $this->sys->getVirtualizer();
+ $novm = true;
+ foreach ($testvirt as $virtkey=>$virtvalue) if ($virtvalue) {
+ $novm = false;
+ break;
+ }
+ // Detect QEMU cpu
+ if ($novm && isset($testvirt["cpuid:QEMU"])) {
+ $this->sys->setVirtualizer('qemu'); // QEMU
+ $novm = false;
+ }
+
+ if ($novm && isset($testvirt["hypervisor"])) {
+ $this->sys->setVirtualizer('unknown');
+ }
+ }
+ }
+
+ /**
+ * CPU usage
+ *
+ * @return void
+ */
+ protected function cpuusage()
+ {
+ if (($this->_cpu_loads === null)) {
+ $this->_cpu_loads = array();
+ if (PSI_OS != 'Darwin') {
+ if ($fd = $this->grabkey('kern.cp_time')) {
+ // Find out the CPU load
+ // user + sys = load
+ // total = total
+ if (preg_match($this->_CPURegExp2, $fd, $res) && (sizeof($res) > 4)) {
+ $load = $res[2] + $res[3] + $res[4]; // cpu.user + cpu.sys
+ $total = $res[2] + $res[3] + $res[4] + $res[5]; // cpu.total
+ // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
+ sleep(1);
+ $fd = $this->grabkey('kern.cp_time');
+ if (preg_match($this->_CPURegExp2, $fd, $res) && (sizeof($res) > 4)) {
+ $load2 = $res[2] + $res[3] + $res[4];
+ $total2 = $res[2] + $res[3] + $res[4] + $res[5];
+ if ($total2 != $total) {
+ $this->_cpu_loads['cpu'] = (100 * ($load2 - $load)) / ($total2 - $total);
+ } else {
+ $this->_cpu_loads['cpu'] = 0;
+ }
+ }
+ }
+ }
+ } else {
+ $ncpu = $this->grabkey('hw.ncpu');
+ if (($ncpu !== "") && ($ncpu >= 1) && CommonFunctions::executeProgram('ps', "-A -o %cpu", $pstable, false) && !empty($pstable)) {
+ $pslines = preg_split("/\n/", $pstable, -1, PREG_SPLIT_NO_EMPTY);
+ if (!empty($pslines) && (count($pslines)>1) && (trim($pslines[0])==="%CPU")) {
+ array_shift($pslines);
+ $sum = 0;
+ foreach ($pslines as $psline) {
+ $sum+=str_replace(',', '.', trim($psline));
+ }
+ $this->_cpu_loads['cpu'] = min($sum/$ncpu, 100);
+ }
+ }
+ }
+ }
+
+ if (isset($this->_cpu_loads['cpu'])) {
+ return $this->_cpu_loads['cpu'];
+ } else {
+ return null;
}
}
@@ -261,23 +338,11 @@ abstract class BSDCommon extends OS
$s = $this->grabkey('vm.loadavg');
$s = preg_replace('/{ /', '', $s);
$s = preg_replace('/ }/', '', $s);
+ $s = str_replace(',', '.', $s);
$this->sys->setLoad($s);
- if (PSI_LOAD_BAR && (PSI_OS != "Darwin")) {
- if ($fd = $this->grabkey('kern.cp_time')) {
- // Find out the CPU load
- // user + sys = load
- // total = total
- preg_match($this->_CPURegExp2, $fd, $res);
- $load = $res[2] + $res[3] + $res[4]; // cpu.user + cpu.sys
- $total = $res[2] + $res[3] + $res[4] + $res[5]; // cpu.total
- // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
- sleep(1);
- $fd = $this->grabkey('kern.cp_time');
- preg_match($this->_CPURegExp2, $fd, $res);
- $load2 = $res[2] + $res[3] + $res[4];
- $total2 = $res[2] + $res[3] + $res[4] + $res[5];
- $this->sys->setLoadPercent((100 * ($load2 - $load)) / ($total2 - $total));
- }
+
+ if (PSI_LOAD_BAR) {
+ $this->sys->setLoadPercent($this->cpuusage());
}
}
@@ -289,37 +354,153 @@ abstract class BSDCommon extends OS
protected function cpuinfo()
{
$dev = new CpuDevice();
- $dev->setModel($this->grabkey('hw.model'));
+ $cpumodel = $this->grabkey('hw.model');
+ $dev->setModel($cpumodel);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^QEMU Virtual CPU version /', $cpumodel)) {
+ $this->sys->setVirtualizer("cpuid:QEMU", false);
+ }
+
$notwas = true;
foreach ($this->readdmesg() as $line) {
if ($notwas) {
- if (preg_match("/".$this->_CPURegExp1."/", $line, $ar_buf)) {
- $dev->setCpuSpeed(round($ar_buf[2]));
- $notwas = false;
+ $regexps = preg_split("/\n/", $this->_CPURegExp1, -1, PREG_SPLIT_NO_EMPTY); // multiple regexp separated by \n
+ foreach ($regexps as $regexp) {
+ if (preg_match($regexp, $line, $ar_buf) && (sizeof($ar_buf) > 2)) {
+ if ($dev->getCpuSpeed() == 0) {
+ $dev->setCpuSpeed(round($ar_buf[2]));
+ }
+ $notwas = false;
+ break;
+ }
}
} else {
- if (preg_match("/ Origin| Features/", $line, $ar_buf)) {
- if (preg_match("/ Features2[ ]*=.*<(.*)>/", $line, $ar_buf)) {
+ if (preg_match("/^\s+Origin| Features/", $line, $ar_buf)) {
+ if (preg_match("/^\s+Origin[ ]*=[ ]*\"(.+)\"/", $line, $ar_buf)) {
+ $dev->setVendorId($ar_buf[1]);
+ } elseif (preg_match("/ Features2[ ]*=.*<(.+)>/", $line, $ar_buf)) {
$feats = preg_split("/,/", strtolower(trim($ar_buf[1])), -1, PREG_SPLIT_NO_EMPTY);
foreach ($feats as $feat) {
if (($feat=="vmx") || ($feat=="svm")) {
$dev->setVirt($feat);
- break 2;
+ } elseif ($feat=="hv") {
+ if ($dev->getVirt() === null) {
+ $dev->setVirt('hypervisor');
+ }
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $this->sys->setVirtualizer("hypervisor", false);
+ }
}
}
- break;
}
} else break;
}
}
+
$ncpu = $this->grabkey('hw.ncpu');
- if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1)))
+ if (($ncpu === "") || !($ncpu >= 1)) {
$ncpu = 1;
+ }
+ if (($ncpu == 1) && PSI_LOAD_BAR) {
+ $dev->setLoad($this->cpuusage());
+ }
for ($ncpu ; $ncpu > 0 ; $ncpu--) {
$this->sys->setCpus($dev);
}
}
+ /**
+ * Machine information
+ *
+ * @return void
+ */
+ private function machine()
+ {
+ if ((PSI_OS == 'NetBSD') || (PSI_OS == 'OpenBSD')) {
+ $buffer = array();
+ if (PSI_OS == 'NetBSD') { // NetBSD
+ $buffer['Manufacturer'] = $this->grabkey('machdep.dmi.system-vendor');
+ $buffer['Model'] = $this->grabkey('machdep.dmi.system-product');
+ $buffer['Product'] = $this->grabkey('machdep.dmi.board-product');
+ $buffer['SMBIOSBIOSVersion'] = $this->grabkey('machdep.dmi.bios-version');
+ $buffer['ReleaseDate'] = $this->grabkey('machdep.dmi.bios-date');
+ } else { // OpenBSD
+ $buffer['Manufacturer'] = $this->grabkey('hw.vendor');
+ $buffer['Model'] = $this->grabkey('hw.product');
+ $buffer['Product'] = "";
+ $buffer['SMBIOSBIOSVersion'] = "";
+ $buffer['ReleaseDate'] = "";
+ }
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $vendor_array = array();
+ $vendor_array[] = $buffer['Model'];
+ $vendor_array[] = trim($buffer['Manufacturer']." ".$buffer['Model']);
+ if (PSI_OS == 'NetBSD') { // NetBSD
+ $vendor_array[] = $this->grabkey('machdep.dmi.board-vendor');
+ $vendor_array[] = $this->grabkey('machdep.dmi.bios-vendor');
+ }
+ $virt = CommonFunctions::decodevirtualizer($vendor_array);
+ if ($virt !== null) {
+ $this->sys->setVirtualizer($virt);
+ }
+ }
+
+ $buf = "";
+ if (($buffer['Manufacturer'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^System manufacturer$|^Not Specified$/i", $buf2=trim($buffer['Manufacturer'])) && ($buf2 !== "")) {
+ $buf .= ' '.$buf2;
+ }
+
+ if (($buffer['Model'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^System Product Name$|^Not Specified$/i", $buf2=trim($buffer['Model'])) && ($buf2 !== "")) {
+ $model = $buf2;
+ $buf .= ' '.$buf2;
+ }
+ if (($buffer['Product'] !== "") && !preg_match("/^To be filled by O\.E\.M\.$|^BaseBoard Product Name$|^Not Specified$|^Default string$/i", $buf2=trim($buffer['Product'])) && ($buf2 !== "")) {
+ if ($buf2 !== $model) {
+ $buf .= '/'.$buf2;
+ } elseif (isset($buffer['SystemFamily']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Family$|^Not Specified$/i", $buf2=trim($buffer['SystemFamily'])) && ($buf2 !== "")) {
+ $buf .= '/'.$buf2;
+ }
+ }
+
+ $bver = "";
+ $brel = "";
+ if (($buf2=trim($buffer['SMBIOSBIOSVersion'])) !== "") {
+ $bver .= ' '.$buf2;
+ }
+ if ($buffer['ReleaseDate'] !== "") {
+ if (preg_match("/^(\d{4})(\d{2})(\d{2})$/", $buffer['ReleaseDate'], $dateout)) {
+ $brel .= ' '.$dateout[2].'/'.$dateout[3].'/'.$dateout[1];
+ } elseif (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $buffer['ReleaseDate'])) {
+ $brel .= ' '.$buffer['ReleaseDate'];
+ }
+ }
+ if ((trim($bver) !== "") || (trim($brel) !== "")) {
+ $buf .= ', BIOS'.$bver.$brel;
+ }
+
+ if (trim($buf) !== "") {
+ $this->sys->setMachine(trim($buf));
+ }
+ } elseif ((PSI_OS == 'FreeBSD') && defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $vendorid = $this->grabkey('hw.hv_vendor');
+ if (trim($vendorid) === "") {
+ foreach ($this->readdmesg() as $line) if (preg_match("/^Hypervisor: Origin = \"(.+)\"/", $line, $ar_buf)) {
+ if (trim($ar_buf[1]) !== "") {
+ $vendorid = $ar_buf[1];
+ }
+ break;
+ }
+ }
+ if (trim($vendorid) !== "") {
+ $virt = CommonFunctions::decodevirtualizer($vendorid);
+ if ($virt !== null) {
+ $this->sys->setVirtualizer($virt);
+ } else {
+ $this->sys->setVirtualizer('unknown');
+ }
+ }
+ }
+ }
+
/**
* SCSI devices
* get the scsi device information out of dmesg
@@ -329,16 +510,22 @@ abstract class BSDCommon extends OS
protected function scsi()
{
foreach ($this->readdmesg() as $line) {
- if (preg_match("/".$this->_SCSIRegExp1."/", $line, $ar_buf)) {
+ if (preg_match($this->_SCSIRegExp1, $line, $ar_buf) && (sizeof($ar_buf) > 2)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[1].": ".$ar_buf[2]);
+ $dev->setName($ar_buf[1].": ".trim($ar_buf[2]));
$this->sys->setScsiDevices($dev);
- } elseif (preg_match("/".$this->_SCSIRegExp2."/", $line, $ar_buf)) {
+ } elseif (preg_match($this->_SCSIRegExp2, $line, $ar_buf) && (sizeof($ar_buf) > 1)) {
/* duplication security */
$notwas = true;
foreach ($this->sys->getScsiDevices() as $finddev) {
if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) {
- $finddev->setCapacity($ar_buf[2] * 2048 * 1.049);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($ar_buf[3]) && ($ar_buf[3]==="G")) {
+ $finddev->setCapacity($ar_buf[2] * 1024 * 1024 * 1024);
+ } elseif (isset($ar_buf[2])) {
+ $finddev->setCapacity($ar_buf[2] * 1024 * 1024);
+ }
+ }
$notwas = false;
break;
}
@@ -346,15 +533,43 @@ abstract class BSDCommon extends OS
if ($notwas) {
$dev = new HWDevice();
$dev->setName($ar_buf[1]);
- $dev->setCapacity($ar_buf[2] * 2048 * 1.049);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($ar_buf[3]) && ($ar_buf[3]==="G")) {
+ $dev->setCapacity($ar_buf[2] * 1024 * 1024 * 1024);
+ } elseif (isset($ar_buf[2])) {
+ $dev->setCapacity($ar_buf[2] * 1024 * 1024);
+ }
+ }
+ $this->sys->setScsiDevices($dev);
+ }
+ } elseif (preg_match($this->_SCSIRegExp3, $line, $ar_buf) && (sizeof($ar_buf) > 1)) {
+ /* duplication security */
+ $notwas = true;
+ foreach ($this->sys->getScsiDevices() as $finddev) {
+ if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) {
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ if (isset($ar_buf[2])) $finddev->setSerial(trim($ar_buf[2]));
+ }
+ $notwas = false;
+ break;
+ }
+ }
+ if ($notwas) {
+ $dev = new HWDevice();
+ $dev->setName($ar_buf[1]);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ if (isset($ar_buf[2])) $dev->setSerial(trim($ar_buf[2]));
+ }
$this->sys->setScsiDevices($dev);
}
}
}
/* cleaning */
foreach ($this->sys->getScsiDevices() as $finddev) {
- if (strpos($finddev->getName(), ': ') !== false)
- $finddev->setName(substr(strstr($finddev->getName(), ': '), 2));
+ if (strpos($finddev->getName(), ': ') !== false)
+ $finddev->setName(substr(strstr($finddev->getName(), ': '), 2));
}
}
@@ -412,13 +627,13 @@ abstract class BSDCommon extends OS
*/
protected function pci()
{
- if (!is_array($results = Parser::lspci(false)) || !is_array($results = $this->pciconf())) {
+ if ((!$results = Parser::lspci(false)) && (!$results = $this->pciconf())) {
foreach ($this->readdmesg() as $line) {
- if (preg_match("/".$this->_PCIRegExp1."/", $line, $ar_buf)) {
+ if (preg_match($this->_PCIRegExp1, $line, $ar_buf) && (sizeof($ar_buf) > 2)) {
$dev = new HWDevice();
$dev->setName($ar_buf[1].": ".$ar_buf[2]);
$results[] = $dev;
- } elseif (preg_match("/".$this->_PCIRegExp2."/", $line, $ar_buf)) {
+ } elseif (preg_match($this->_PCIRegExp2, $line, $ar_buf) && (sizeof($ar_buf) > 2)) {
$dev = new HWDevice();
$dev->setName($ar_buf[1].": ".$ar_buf[2]);
$results[] = $dev;
@@ -441,23 +656,27 @@ abstract class BSDCommon extends OS
foreach ($this->readdmesg() as $line) {
if (preg_match('/^(ad[0-9]+): (.*)MB <(.*)> (.*) (.*)/', $line, $ar_buf)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[1].": ".$ar_buf[3]);
- $dev->setCapacity($ar_buf[2] * 1024);
+ $dev->setName($ar_buf[1].": ".trim($ar_buf[3]));
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setCapacity($ar_buf[2] * 1024 * 1024);
+ }
$this->sys->setIdeDevices($dev);
} elseif (preg_match('/^(acd[0-9]+): (.*) <(.*)> (.*)/', $line, $ar_buf)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[1].": ".$ar_buf[3]);
+ $dev->setName($ar_buf[1].": ".trim($ar_buf[3]));
$this->sys->setIdeDevices($dev);
} elseif (preg_match('/^(ada[0-9]+): <(.*)> (.*)/', $line, $ar_buf)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[1].": ".$ar_buf[2]);
+ $dev->setName($ar_buf[1].": ".trim($ar_buf[2]));
$this->sys->setIdeDevices($dev);
} elseif (preg_match('/^(ada[0-9]+): (.*)MB \((.*)\)/', $line, $ar_buf)) {
/* duplication security */
$notwas = true;
foreach ($this->sys->getIdeDevices() as $finddev) {
if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) {
- $finddev->setCapacity($ar_buf[2] * 1024);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $finddev->setCapacity($ar_buf[2] * 1024 * 1024);
+ }
$notwas = false;
break;
}
@@ -465,7 +684,31 @@ abstract class BSDCommon extends OS
if ($notwas) {
$dev = new HWDevice();
$dev->setName($ar_buf[1]);
- $dev->setCapacity($ar_buf[2] * 1024);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setCapacity($ar_buf[2] * 1024 * 1024);
+ }
+ $this->sys->setIdeDevices($dev);
+ }
+ } elseif (preg_match('/^(ada[0-9]+): Serial Number (.*)/', $line, $ar_buf)) {
+ /* duplication security */
+ $notwas = true;
+ foreach ($this->sys->getIdeDevices() as $finddev) {
+ if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) {
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $finddev->setSerial(trim($ar_buf[2]));
+ }
+ $notwas = false;
+ break;
+ }
+ }
+ if ($notwas) {
+ $dev = new HWDevice();
+ $dev->setName($ar_buf[1]);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $finddev->setSerial(trim($ar_buf[2]));
+ }
$this->sys->setIdeDevices($dev);
}
}
@@ -530,7 +773,19 @@ abstract class BSDCommon extends OS
*/
protected function usb()
{
- foreach ($this->readdmesg() as $line) {
+ $notwas = true;
+ if ((PSI_OS == 'FreeBSD') && CommonFunctions::executeProgram('usbconfig', '', $bufr, false)) {
+ $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) {
+ if (preg_match('/^(ugen[0-9]+\.[0-9]+): <([^,]*)(.*)> at (usbus[0-9]+)/', $line, $ar_buf)) {
+ $notwas = false;
+ $dev = new HWDevice();
+ $dev->setName($ar_buf[2]);
+ $this->sys->setUSBDevices($dev);
+ }
+ }
+ }
+ if ($notwas) foreach ($this->readdmesg() as $line) {
// if (preg_match('/^(ugen[0-9\.]+): <(.*)> (.*) (.*)/', $line, $ar_buf)) {
// $dev->setName($ar_buf[1].": ".$ar_buf[2]);
if (preg_match('/^(u[a-z]+[0-9]+): <([^,]*)(.*)> on (usbus[0-9]+)/', $line, $ar_buf)) {
@@ -566,27 +821,60 @@ abstract class BSDCommon extends OS
}
}
+ /**
+ * UpTime
+ * time the system is running
+ *
+ * @return void
+ */
+ private function uptime()
+ {
+ if ($kb = $this->grabkey('kern.boottime')) {
+ if (preg_match("/sec = ([0-9]+)/", $kb, $buf)) { // format like: { sec = 1096732600, usec = 885425 } Sat Oct 2 10:56:40 2004
+ $this->sys->setUptime(time() - $buf[1]);
+ } else {
+ date_default_timezone_set('UTC');
+ $kbt = strtotime($kb);
+ if (($kbt !== false) && ($kbt != -1)) {
+ $this->sys->setUptime(time() - $kbt); // format like: Sat Oct 2 10:56:40 2004
+ } else {
+ $this->sys->setUptime(time() - $kb); // format like: 1096732600
+ }
+ }
+ }
+ }
+
/**
* get the information
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->distro();
- $this->memory();
- $this->ide();
- $this->pci();
- $this->cpuinfo();
- $this->filesystems();
- $this->kernel();
- $this->users();
- $this->loadavg();
- $this->hostname();
- $this->ip();
- $this->scsi();
- $this->usb();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->distro();
+ $this->hostname();
+ $this->kernel();
+ $this->_users();
+ $this->loadavg();
+ $this->uptime();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->machine();
+ $this->cpuinfo();
+ $this->virtualizer();
+ $this->pci();
+ $this->ide();
+ $this->scsi();
+ $this->usb();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->filesystems();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php
index 1ee9dd8..c84d8a5 100644
--- a/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php
@@ -8,7 +8,7 @@
* @package PSI Darwin OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Darwin.inc.php 638 2012-08-24 09:40:48Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,7 +21,7 @@
* @package PSI Darwin OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,13 +30,13 @@ class Darwin extends BSDCommon
/**
* define the regexp for log parser
*/
- /* public function __construct()
+ /* public function __construct($blockname = false)
{
- parent::__construct();
+ parent::__construct($blockname);
$this->error->addWarning("The Darwin version of phpSysInfo is a work in progress, some things currently don't work!");
- $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)");
+ $this->setCPURegExp1("/CPU: (.*) \((.*)-MHz (.*)\)/");
$this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/");
- $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device");
+ $this->setSCSIRegExp1("/^(.*): <(.*)> .*SCSI.*device/");
} */
/**
@@ -89,25 +89,6 @@ class Darwin extends BSDCommon
}
}
- /**
- * UpTime
- * time the system is running
- *
- * @return void
- */
- private function _uptime()
- {
- if (CommonFunctions::executeProgram('sysctl', '-n kern.boottime', $a, PSI_DEBUG)) {
- $tmp = explode(" ", $a);
- if ($tmp[0]=="{") { /* kern.boottime= { sec = 1096732600, usec = 885425 } Sat Oct 2 10:56:40 2004 */
- $data = trim($tmp[3], ",");
- $this->sys->setUptime(time() - $data);
- } else { /* kern.boottime= 1096732600 */
- $this->sys->setUptime(time() - $a);
- }
- }
- }
-
/**
* get CPU information
*
@@ -116,12 +97,12 @@ class Darwin extends BSDCommon
protected function cpuinfo()
{
$dev = new CpuDevice();
- if (CommonFunctions::executeProgram('hostinfo', '| grep "Processor type"', $buf, PSI_DEBUG)) {
- $dev->setModel(preg_replace('/Processor type: /', '', $buf));
+ if (CommonFunctions::executeProgram('hostinfo', '', $buf, PSI_DEBUG) && ($buf !== '') && preg_match('/^Processor type:[ ]+(.+)$/m', $buf, $proc) && (($proc[1] = trim($proc[1])) !== '')) {
+ $dev->setModel($proc[1]);
$buf=$this->grabkey('hw.model');
- if (!is_null($buf) && (trim($buf) != "")) {
+ if (($buf !== null) && (trim($buf) != "")) {
$this->sys->setMachine(trim($buf));
- if (CommonFunctions::rfts(APP_ROOT.'/data/ModelTranslation.txt', $buffer)) {
+ if (CommonFunctions::rftsdata('ModelTranslation.txt', $buffer)) {
$buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY);
foreach ($buffer as $line) {
$ar_buf = preg_split("/:/", $line, 3);
@@ -134,12 +115,12 @@ class Darwin extends BSDCommon
}
}
$buf=$this->grabkey('machdep.cpu.brand_string');
- if (!is_null($buf) && (trim($buf) != "") &&
+ if (($buf !== null) && (trim($buf) != "") &&
((trim($buf) != "i486 (Intel 80486)") || ($dev->getModel() == ""))) {
$dev->setModel(trim($buf));
}
$buf=$this->grabkey('machdep.cpu.features');
- if (!is_null($buf) && (trim($buf) != "")) {
+ if (($buf !== null) && (trim($buf) != "")) {
if (preg_match("/ VMX/", $buf)) {
$dev->setVirt("vmx");
} elseif (preg_match("/ SVM/", $buf)) {
@@ -151,17 +132,21 @@ class Darwin extends BSDCommon
$dev->setBusSpeed(round($this->grabkey('hw.busfrequency') / 1000000));
$bufn=$this->grabkey('hw.cpufrequency_min');
$bufx=$this->grabkey('hw.cpufrequency_max');
- if (!is_null($bufn) && (trim($bufn) != "") && !is_null($bufx) && (trim($bufx) != "") && ($bufn != $bufx)) {
+ if (($bufn !== null) && (trim($bufn) != "") && ($bufx !== null) && (trim($bufx) != "") && ($bufn != $bufx)) {
$dev->setCpuSpeedMin(round($bufn / 1000000));
$dev->setCpuSpeedMax(round($bufx / 1000000));
}
$buf=$this->grabkey('hw.l2cachesize');
- if (!is_null($buf) && (trim($buf) != "")) {
+ if ($buf !== "") {
$dev->setCache(round($buf));
}
$ncpu = $this->grabkey('hw.ncpu');
- if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1)))
+ if (($ncpu === "") || !($ncpu >= 1)) {
$ncpu = 1;
+ }
+ if (($ncpu == 1) && PSI_LOAD_BAR) {
+ $dev->setLoad($this->cpuusage());
+ }
for ($ncpu ; $ncpu > 0 ; $ncpu--) {
$this->sys->setCpus($dev);
}
@@ -238,6 +223,18 @@ class Darwin extends BSDCommon
if (!preg_match('/"USB Product Name" = "([^"]*)"/', $line, $ar_buf))
$ar_buf = preg_split("/[\s@]+/", $line, 19);
$dev->setName(trim($ar_buf[1]));
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (preg_match('/"USB Vendor Name" = "([^"]*)"/', $line, $ar_buf)) {
+ $dev->setManufacturer(trim($ar_buf[1]));
+ }
+ if (preg_match('/"USB Product Name" = "([^"]*)"/', $line, $ar_buf)) {
+ $dev->setProduct(trim($ar_buf[1]));
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
+ && preg_match('/"USB Serial Number" = "([^"]*)"/', $line, $ar_buf)) {
+ $dev->setSerial(trim($ar_buf[1]));
+ }
+ }
$this->sys->setUsbDevices($dev);
}
}
@@ -267,60 +264,63 @@ class Darwin extends BSDCommon
*/
protected function memory()
{
- $s = $this->grabkey('hw.memsize');
- if (CommonFunctions::executeProgram('vm_stat', '', $pstat, PSI_DEBUG)) {
- // calculate free memory from page sizes (each page = 4096)
- if (preg_match('/^Pages free:\s+(\S+)/m', $pstat, $free_buf)) {
- if (preg_match('/^Anonymous pages:\s+(\S+)/m', $pstat, $anon_buf)
- && preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)
- && preg_match('/^File-backed pages:\s+(\S+)/m', $pstat, $fileb_buf)) {
- // OS X 10.9 or never
- $this->sys->setMemFree($free_buf[1] * 4 * 1024);
- $this->sys->setMemApplication(($anon_buf[1]+$wire_buf[1]) * 4 * 1024);
- $this->sys->setMemCache($fileb_buf[1] * 4 * 1024);
- if (preg_match('/^Pages occupied by compressor:\s+(\S+)/m', $pstat, $compr_buf)) {
- $this->sys->setMemBuffer($compr_buf[1] * 4 * 1024);
- }
- } else {
- if (preg_match('/^Pages speculative:\s+(\S+)/m', $pstat, $spec_buf)) {
- $this->sys->setMemFree(($free_buf[1]+$spec_buf[1]) * 4 * 1024);
+ if (($s = $this->grabkey('hw.memsize')) > 0) {
+ $this->sys->setMemTotal($s);
+ if (CommonFunctions::executeProgram('vm_stat', '', $pstat, PSI_DEBUG)) {
+ // calculate free memory from page sizes (each page = 4096)
+ if (preg_match('/^Pages free:\s+(\S+)/m', $pstat, $free_buf)) {
+ if (preg_match('/^Anonymous pages:\s+(\S+)/m', $pstat, $anon_buf)
+ && preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)
+ && preg_match('/^File-backed pages:\s+(\S+)/m', $pstat, $fileb_buf)) {
+ // OS X 10.9 or never
+ $this->sys->setMemFree($free_buf[1] * 4 * 1024);
+ $this->sys->setMemApplication(($anon_buf[1]+$wire_buf[1]) * 4 * 1024);
+ $this->sys->setMemCache($fileb_buf[1] * 4 * 1024);
+ if (preg_match('/^Pages occupied by compressor:\s+(\S+)/m', $pstat, $compr_buf)) {
+ $this->sys->setMemBuffer($compr_buf[1] * 4 * 1024);
+ }
} else {
- $this->sys->setMemFree($free_buf[1] * 4 * 1024);
- }
- $appMemory = 0;
- if (preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)) {
- $appMemory += $wire_buf[1] * 4 * 1024;
- }
- if (preg_match('/^Pages active:\s+(\S+)/m', $pstat, $active_buf)) {
- $appMemory += $active_buf[1] * 4 * 1024;
- }
- $this->sys->setMemApplication($appMemory);
+ if (preg_match('/^Pages speculative:\s+(\S+)/m', $pstat, $spec_buf)) {
+ $this->sys->setMemFree(($free_buf[1]+$spec_buf[1]) * 4 * 1024);
+ } else {
+ $this->sys->setMemFree($free_buf[1] * 4 * 1024);
+ }
+ $appMemory = 0;
+ if (preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)) {
+ $appMemory += $wire_buf[1] * 4 * 1024;
+ }
+ if (preg_match('/^Pages active:\s+(\S+)/m', $pstat, $active_buf)) {
+ $appMemory += $active_buf[1] * 4 * 1024;
+ }
+ $this->sys->setMemApplication($appMemory);
- if (preg_match('/^Pages inactive:\s+(\S+)/m', $pstat, $inactive_buf)) {
- $this->sys->setMemCache($inactive_buf[1] * 4 * 1024);
+ if (preg_match('/^Pages inactive:\s+(\S+)/m', $pstat, $inactive_buf)) {
+ $this->sys->setMemCache($inactive_buf[1] * 4 * 1024);
+ }
}
+ } else {
+ $lines = preg_split("/\n/", $pstat, -1, PREG_SPLIT_NO_EMPTY);
+ $ar_buf = preg_split("/\s+/", $lines[1], 19);
+ $this->sys->setMemFree($ar_buf[2] * 4 * 1024);
}
- } else {
- $lines = preg_split("/\n/", $pstat, -1, PREG_SPLIT_NO_EMPTY);
- $ar_buf = preg_split("/\s+/", $lines[1], 19);
- $this->sys->setMemFree($ar_buf[2] * 4 * 1024);
+ $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
}
- $this->sys->setMemTotal($s);
- $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
-
- if (CommonFunctions::executeProgram('sysctl', 'vm.swapusage | colrm 1 22', $swapBuff, PSI_DEBUG)) {
- $swap1 = preg_split('/M/', $swapBuff);
- $swap2 = preg_split('/=/', $swap1[1]);
- $swap3 = preg_split('/=/', $swap1[2]);
- $dev = new DiskDevice();
- $dev->setName('SWAP');
- $dev->setMountPoint('SWAP');
- $dev->setFsType('swap');
- $dev->setTotal($swap1[0] * 1024 * 1024);
- $dev->setUsed($swap2[1] * 1024 * 1024);
- $dev->setFree($swap3[1] * 1024 * 1024);
- $this->sys->setSwapDevices($dev);
+ if (($swap = $this->grabkey("vm.swapusage")) > 0) {
+ $swap0 = preg_split('/M/', $swap);
+ $swap1 = preg_split('/=/', $swap0[0]);
+ $swap2 = preg_split('/=/', $swap0[1]);
+ $swap3 = preg_split('/=/', $swap0[2]);
+ if (($swap=str_replace(',', '.', trim($swap1[1]))) > 0) {
+ $dev = new DiskDevice();
+ $dev->setName('SWAP');
+ $dev->setMountPoint('SWAP');
+ $dev->setFsType('swap');
+ $dev->setTotal($swap * 1024 * 1024);
+ $dev->setUsed(str_replace(',', '.', trim($swap2[1])) * 1024 * 1024);
+ $dev->setFree(str_replace(',', '.', trim($swap3[1])) * 1024 * 1024);
+ $this->sys->setSwapDevices($dev);
+ }
}
}
}
@@ -354,7 +354,7 @@ class Darwin extends BSDCommon
$lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY);
foreach ($lines as $line) {
$ar_buf = preg_split("/\s+/", $line, 10);
- if (! empty($ar_buf[0])) {
+ if (!empty($ar_buf[0])) {
$dev = new NetDevice();
$dev->setName($ar_buf[0]);
$dev->setTxBytes($ar_buf[8]);
@@ -366,14 +366,25 @@ class Darwin extends BSDCommon
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) {
$bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe2 as $buf2) {
- if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2))
+ if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) {
$dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
- elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
+ } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
|| preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2))
- && !preg_match('/^fe80::/i', $ar_buf2[1]))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) {
+ if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") {
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (preg_match('/[<\s]([^\s<]+)-duplex/i', $buf2, $ar_buf3))
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]));
+ else
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s');
+ }
}
}
$this->sys->setNetDevices($dev);
@@ -390,28 +401,37 @@ class Darwin extends BSDCommon
protected function distro()
{
$this->sys->setDistributionIcon('Darwin.png');
- if (!CommonFunctions::executeProgram('system_profiler', 'SPSoftwareDataType', $buffer, PSI_DEBUG)) {
+ if ((!CommonFunctions::executeProgram('system_profiler', 'SPSoftwareDataType', $buffer, PSI_DEBUG) || !preg_match('/\n\s*System Version:/', $buffer))
+ && (!CommonFunctions::executeProgram('sw_vers', '', $buffer, PSI_DEBUG) || !preg_match('/^ProductName:/', $buffer))) {
parent::distro();
} else {
- $arrBuff = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($arrBuff as $line) {
- $arrLine = preg_split("/:/", $line, -1, PREG_SPLIT_NO_EMPTY);
- if (trim($arrLine[0]) === "System Version") {
- $distro = trim($arrLine[1]);
-
- if (preg_match('/(^Mac OS)|(^OS X)/', $distro)) {
- $this->sys->setDistributionIcon('Apple.png');
- if (preg_match('/((^Mac OS X Server)|(^Mac OS X)|(^OS X Server)|(^OS X)) (\d+\.\d+)/', $distro, $ver)
- && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true))
- && isset($list['OS X'][$ver[6]])) {
- $distro.=' '.$list['OS X'][$ver[6]];
+ $distro_tmp = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($distro_tmp as $info) {
+ $info_tmp = preg_split('/:/', $info, 2);
+ if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "") &&
+ isset($distro_tmp[1]) && ($distro_tmp[1] !== null) && (trim($distro_tmp[1]) != "")) {
+ $distro_arr[trim($info_tmp[0])] = trim($info_tmp[1]);
+ }
+ }
+ if (isset($distro_arr['ProductName']) && isset($distro_arr['ProductVersion']) && isset($distro_arr['BuildVersion'])) {
+ $distro_arr['System Version'] = $distro_arr['ProductName'].' '.$distro_arr['ProductVersion'].' ('.$distro_arr['BuildVersion'].')';
+ }
+ if (isset($distro_arr['System Version'])) {
+ $distro = $distro_arr['System Version'];
+ if (preg_match('/^Mac OS |^OS X |^macOS |^iPhone OS |^Mac OS$|^OS X$|^macOS$|^iPhone OS$/', $distro)) {
+ $this->sys->setDistributionIcon('Apple.png');
+ if (preg_match('/(^Mac OS X Server|^Mac OS X|^OS X Server|^OS X|^macOS Server|^macOS) ((\d+)\.\d+)/', $distro, $ver)
+ && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) {
+ if (isset($list['macOS'][$ver[2]])) {
+ $distro.=' '.$list['macOS'][$ver[2]];
+ } elseif (isset($list['macOS'][$ver[3]])) {
+ $distro.=' '.$list['macOS'][$ver[3]];
}
}
-
- $this->sys->setDistribution($distro);
-
- return;
}
+ $this->sys->setDistribution($distro);
+ } else {
+ parent::distro();
}
}
}
@@ -451,14 +471,19 @@ class Darwin extends BSDCommon
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
parent::build();
- $this->_uptime();
- $this->_network();
- $this->_processes();
- $this->_tb();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_tb();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php
index 9e9f946..9c0ac7a 100644
--- a/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php
@@ -8,7 +8,7 @@
* @package PSI DragonFly OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.DragonFly.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI DragonFly OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -29,33 +29,20 @@ class DragonFly extends BSDCommon
/**
* define the regexp for log parser
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- parent::__construct();
- $this->setCPURegExp1("^cpu(.*)\, (.*) MHz");
- $this->setCPURegExp2("^(.*) at scsibus.*: <(.*)> .*");
- $this->setSCSIRegExp2("^(da[0-9]): (.*)MB ");
- $this->setPCIRegExp1("/(.*): <(.*)>(.*) (pci|legacypci)[0-9]$/");
+ parent::__construct($blockname);
+ $this->setCPURegExp1("/^cpu(.*)\, (.*) MHz/\n/^CPU: (.*) \((.*)-MHz (.*)\)/"); // multiple regexp separated by \n
+ $this->setCPURegExp2("/^(.*) at scsibus.*: <(.*)> .*/");
+ $this->setSCSIRegExp2("/^(da[0-9]+): (.*)MB /");
+ $this->setPCIRegExp1("/(.*): <(.*)>(.*) (pci|legacypci)[0-9]+$/");
$this->setPCIRegExp2("/(.*): <(.*)>.* at [0-9\.]+$/");
}
- /**
- * UpTime
- * time the system is running
- *
- * @return void
- */
- private function _uptime()
- {
- $a = $this->grab_key('kern.boottime');
- preg_match("/sec = ([0-9]+)/", $a, $buf);
- $this->sys->setUptime(time() - $buf[1]);
- }
-
/**
* get network information
*
- * @return array
+ * @return void
*/
private function _network()
{
@@ -66,7 +53,7 @@ class DragonFly extends BSDCommon
for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) {
$ar_buf_b = preg_split("/\s+/", $lines_b[$i]);
$ar_buf_n = preg_split("/\s+/", $lines_n[$i]);
- if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) {
+ if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[5]) || ($ar_buf_n[5] === "0"))) {
$dev = new NetDevice();
$dev->setName($ar_buf_b[0]);
$dev->setTxBytes($ar_buf_b[8]);
@@ -81,16 +68,16 @@ class DragonFly extends BSDCommon
/**
* get the ide information
*
- * @return array
+ * @return void
*/
protected function ide()
{
foreach ($this->readdmesg() as $line) {
- if (preg_match('/^(.*): (.*) <(.*)> at (ata[0-9]\-(.*)) (.*)/', $line, $ar_buf)) {
+ if (preg_match('/^(.*): (.*) <(.*)> at (ata[0-9]+\-(.*)) (.*)/', $line, $ar_buf)) {
$dev = new HWDevice();
$dev->setName($ar_buf[1]);
- if (!preg_match("/^acd[0-9](.*)/", $ar_buf[1])) {
- $dev->setCapacity($ar_buf[2] * 1024);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && !preg_match("/^acd[0-9]+(.*)/", $ar_buf[1])) {
+ $dev->setCapacity($ar_buf[2] * 1024 * 1024);
}
$this->sys->setIdeDevices($dev);
}
@@ -140,14 +127,17 @@ class DragonFly extends BSDCommon
*
* @see BSDCommon::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
parent::build();
- $this->_distroicon();
- $this->_network();
- $this->_uptime();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distroicon();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php
index d602a60..01ba0c3 100644
--- a/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php
@@ -8,7 +8,7 @@
* @package PSI FreeBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.FreeBSD.inc.php 696 2012-09-09 11:24:04Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI FreeBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -29,30 +29,18 @@ class FreeBSD extends BSDCommon
/**
* define the regexp for log parser
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- parent::__construct();
- $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)");
+ parent::__construct($blockname);
+ $this->setCPURegExp1("/CPU: (.*) \((.*)-MHz (.*)\)/");
$this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/");
- $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device");
- $this->setSCSIRegExp2("^(da[0-9]): (.*)MB ");
- $this->setPCIRegExp1("/(.*): <(.*)>(.*) pci[0-9]$/");
+ $this->setSCSIRegExp1("/^(.*): <(.*)> .*SCSI.*device/");
+ $this->setSCSIRegExp2("/^(da[0-9]+): (.*)MB /");
+ $this->setSCSIRegExp3("/^(da[0-9]+|cd[0-9]+): Serial Number (.*)/");
+ $this->setPCIRegExp1("/(.*): <(.*)>(.*) pci[0-9]+$/");
$this->setPCIRegExp2("/(.*): <(.*)>.* at [.0-9]+ irq/");
}
- /**
- * UpTime
- * time the system is running
- *
- * @return void
- */
- private function _uptime()
- {
- $s = preg_split('/ /', $this->grabkey('kern.boottime'));
- $a = preg_replace('/,/', '', $s[3]);
- $this->sys->setUptime(time() - $a);
- }
-
/**
* get network information
*
@@ -65,11 +53,11 @@ class FreeBSD extends BSDCommon
$lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY);
foreach ($lines as $line) {
$ar_buf = preg_split("/\s+/", $line);
- if (! empty($ar_buf[0])) {
+ if (!empty($ar_buf[0])) {
if (preg_match('/^ setName($ar_buf[0]);
- if (strlen($ar_buf[3]) < 17) { /* no Address */
+ if ((strlen($ar_buf[3]) < 17) && ($ar_buf[0] != $ar_buf[3])) { /* no MAC or dev name*/
if (isset($ar_buf[11]) && (trim($ar_buf[11]) != '')) { /* Idrop column exist*/
$dev->setTxBytes($ar_buf[9]);
$dev->setRxBytes($ar_buf[6]);
@@ -97,14 +85,25 @@ class FreeBSD extends BSDCommon
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) {
$bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe2 as $buf2) {
- if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2))
+ if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) {
$dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
- elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
+ } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
|| preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2))
- && !preg_match('/^fe80::/i', $ar_buf2[1]))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) {
+ if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") {
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (preg_match('/[<\s]([^\s<]+)-duplex/i', $buf2, $ar_buf3))
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]));
+ else
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].$unit.'b/s');
+ }
}
}
$this->sys->setNetDevices($dev);
@@ -121,9 +120,19 @@ class FreeBSD extends BSDCommon
*/
private function _distroicon()
{
- if (extension_loaded('pfSense') && CommonFunctions::rfts('/etc/version', $version, 1, 4096, false) && (trim($version) != '')) { // pfSense detection
- $this->sys->setDistribution('pfSense '. trim($version));
- $this->sys->setDistributionIcon('pfSense.png');
+ if (CommonFunctions::rfts('/etc/version', $version, 1, 4096, false) && (($version=trim($version)) != '')) {
+ if (extension_loaded('pfSense')) { // pfSense detection
+ $this->sys->setDistribution('pfSense '. $version);
+ $this->sys->setDistributionIcon('pfSense.png');
+ } elseif (preg_match('/^FreeNAS/i', $version)) { // FreeNAS detection
+ $this->sys->setDistribution($version);
+ $this->sys->setDistributionIcon('FreeNAS.png');
+ } elseif (preg_match('/^TrueNAS/i', $version)) { // TrueNAS detection
+ $this->sys->setDistribution($version);
+ $this->sys->setDistributionIcon('TrueNAS.png');
+ } else {
+ $this->sys->setDistributionIcon('FreeBSD.png');
+ }
} else {
$this->sys->setDistributionIcon('FreeBSD.png');
}
@@ -176,15 +185,20 @@ class FreeBSD extends BSDCommon
*
* @see BSDCommon::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
parent::build();
- $this->_memoryadditional();
- $this->_distroicon();
- $this->_network();
- $this->_uptime();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distroicon();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memoryadditional();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.GNU.inc.php b/root/opt/phpsysinfo/includes/os/class.GNU.inc.php
new file mode 100644
index 0000000..3d42959
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/os/class.GNU.inc.php
@@ -0,0 +1,118 @@
+
+ * @copyright 2012 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version SVN: $Id: class.GNU.inc.php 687 2012-09-06 20:54:49Z namiltd $
+ * @link http://phpsysinfo.sourceforge.net
+ */
+ /**
+ * GNU sysinfo class
+ * get all the required information from GNU
+ *
+ * @category PHP
+ * @package PSI GNU class
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2022 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class GNU extends Linux
+{
+ /**
+ * Network devices
+ * includes also rx/tx bytes
+ *
+ * @return void
+ */
+ protected function _network($bufr = null)
+ {
+ if ($this->sys->getOS() == 'GNU') {
+ if (CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) {
+ $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ $was = false;
+ $macaddr = "";
+ $dev = null;
+ foreach ($lines as $line) {
+ if (preg_match("/^\/dev\/([^\s:]+)/", $line, $ar_buf) || preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
+ if ($was) {
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ $this->sys->setNetDevices($dev);
+ }
+ $macaddr = "";
+ $dev = new NetDevice();
+ $dev->setName($ar_buf[1]);
+ $was = true;
+ } else {
+ if ($was) {
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ if (preg_match('/^\s+inet address\s+(\S+)$/', $line, $ar_buf)) {
+ $dev->setInfo($ar_buf[1]);
+ } elseif (preg_match('/^\s+hardware addr\s+(\S+)$/', $line, $ar_buf)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
+ $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf[1]));
+ if ($macaddr === '00-00-00-00-00-00') { // empty
+ $macaddr = "";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if ($was) {
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ $this->sys->setNetDevices($dev);
+ }
+ }
+ } else {
+ parent::_network($bufr);
+ }
+ }
+
+ /**
+ * Number of Users
+ *
+ * @return void
+ */
+ protected function _users()
+ {
+ if ($this->sys->getOS() == 'GNU') {
+ if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) {
+ if (strlen($strBuf) > 0) {
+ $lines = preg_split('/\n/', $strBuf);
+ preg_match_all('/^login\s+/m', $strBuf, $ttybuf);
+ if (($who = count($lines)-count($ttybuf[0])) > 0) {
+ $this->sys->setUsers($who);
+ }
+ }
+ }
+ } else {
+ parent::_users();
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @return void
+ */
+ public function build()
+ {
+ if ($this->sys->getOS() == 'GNU') {
+ $this->error->addWarning("The GNU Hurd version of phpSysInfo is a work in progress, some things currently don't work");
+ }
+ parent::build();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php
index 02626ca..5d1a551 100644
--- a/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php
@@ -8,7 +8,7 @@
* @package PSI HPUX OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.HPUX.inc.php 596 2012-07-05 19:37:48Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,12 +20,17 @@
* @package PSI HPUX OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class HPUX extends OS
{
+ /**
+ * uptime command result.
+ */
+ private $_uptime = null;
+
/**
* Virtual Host Name
*
@@ -33,8 +38,8 @@ class HPUX extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('hostname', '', $ret)) {
$this->sys->setHostname($ret);
@@ -42,24 +47,6 @@ class HPUX extends OS
}
}
- /**
- * IP of the Virtual Host Name
- *
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* HP-UX Version
*
@@ -80,8 +67,8 @@ class HPUX extends OS
*/
private function _uptime()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
$min = $ar_buf[3];
$hours = $ar_buf[2];
$days = $ar_buf[1];
@@ -90,19 +77,6 @@ class HPUX extends OS
}
}
- /**
- * Number of Users
- *
- * @return void
- */
- private function _users()
- {
- if (CommonFunctions::executeProgram('who', '-q', $ret)) {
- $who = preg_split('/=/', $ret, -1, PREG_SPLIT_NO_EMPTY);
- $this->sys->setUsers($who[1]);
- }
- }
-
/**
* Processor Load
* optionally create a loadbar
@@ -111,8 +85,8 @@ class HPUX extends OS
*/
private function _loadavg()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) {
$this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
}
}
@@ -132,31 +106,29 @@ class HPUX extends OS
$dev = new CpuDevice();
$details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
foreach ($details as $detail) {
- $arrBuff = preg_split('/\s+:\s+/', trim($detail));
- if (count($arrBuff) == 2) {
- switch (strtolower($arrBuff[0])) {
+ if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) {
+ switch (strtolower(trim($arrBuff[1]))) {
case 'model name':
case 'cpu':
- $dev->setModel($arrBuff[1]);
+ $dev->setModel($arrBuff2);
break;
case 'cpu mhz':
case 'clock':
- $dev->setCpuSpeed($arrBuff[1]);
+ $dev->setCpuSpeed($arrBuff2);
break;
case 'cycle frequency [hz]':
- $dev->setCpuSpeed($arrBuff[1] / 1000000);
+ $dev->setCpuSpeed($arrBuff2 / 1000000);
break;
case 'cpu0clktck':
- $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64
+ $dev->setCpuSpeed(hexdec($arrBuff2) / 1000000); // Linux sparc64
break;
case 'l2 cache':
case 'cache size':
- $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024);
+ $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff2) * 1024);
break;
case 'bogomips':
case 'cpu0bogo':
- $dev->setBogomips($arrBuff[1]);
- break;
+ $dev->setBogomips($arrBuff2);
}
}
}
@@ -172,19 +144,25 @@ class HPUX extends OS
private function _pci()
{
if (CommonFunctions::rfts('/proc/pci', $bufr)) {
+ $device = false;
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
- if (preg_match('/Bus/', $buf)) {
+ if (preg_match('/^\s*Bus\s/', $buf)) {
$device = true;
continue;
}
if ($device) {
+ $dev = new HWDevice();
+ $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($buf)));
+ $this->sys->setPciDevices($dev);
+/*
list($key, $value) = preg_split('/: /', $buf, 2);
if (!preg_match('/bridge/i', $key) && !preg_match('/USB/i', $key)) {
$dev = new HWDevice();
$dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($value)));
$this->sys->setPciDevices($dev);
}
+*/
$device = false;
}
}
@@ -203,10 +181,10 @@ class HPUX extends OS
if (preg_match('/^hd/', $file)) {
$dev = new HWDevice();
$dev->setName(trim($file));
- if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
if (trim($buf) == 'disk') {
if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false)) {
- $dev->setCapacity(trim($buf) * 512 / 1024);
+ $dev->setCapacity(trim($buf) * 512);
}
}
}
@@ -250,9 +228,11 @@ class HPUX extends OS
{
if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) {
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ $devnum = -1;
+ $results = array();
foreach ($bufe as $buf) {
if (preg_match('/^T/', $buf)) {
- $devnum += 1;
+ $devnum++;
$results[$devnum] = "";
} elseif (preg_match('/^S:/', $buf)) {
list($key, $value) = preg_split('/: /', $buf, 2);
@@ -344,7 +324,7 @@ class HPUX extends OS
$mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) {
$lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY);
- while (list(, $line) = each($lines)) {
+ foreach ($lines as $line) {
$a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY);
$fsdev[$a[0]] = $a[4];
}
@@ -381,24 +361,33 @@ class HPUX extends OS
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_loadavg();
- $this->_cpuinfo();
- $this->_pci();
- $this->_ide();
- $this->_scsi();
- $this->_usb();
- $this->_network();
- $this->_memory();
- $this->_filesystems();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_cpuinfo();
+ $this->_pci();
+ $this->_ide();
+ $this->_scsi();
+ $this->_usb();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php
index c803156..fe0bbe2 100644
--- a/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php
@@ -8,7 +8,7 @@
* @package PSI Haiku OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Haiku.inc.php 687 2012-09-06 20:54:49Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,24 +20,16 @@
* @package PSI Haiku OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class Haiku extends OS
{
- /**
- * call parent constructor
- */
- public function __construct()
- {
- parent::__construct();
- }
-
/**
* get the cpu information
*
- * @return array
+ * @return void
*/
protected function _cpuinfo()
{
@@ -53,21 +45,22 @@ class Haiku extends OS
$dev->setModel($ar_buf[1]);
$arrLines = preg_split("/\n/", $cpu, -1, PREG_SPLIT_NO_EMPTY);
foreach ($arrLines as $Line) {
- if (preg_match("/^\s+Data TLB:\s+(.*)K-byte/", $Line, $Line_buf)) {
- $dev->setCache(max($Line_buf[1]*1024, $dev->getCache()));
- } elseif (preg_match("/^\s+Data TLB:\s+(.*)M-byte/", $Line, $Line_buf)) {
- $dev->setCache(max($Line_buf[1]*1024*1024, $dev->getCache()));
- } elseif (preg_match("/^\s+Data TLB:\s+(.*)G-byte/", $Line, $Line_buf)) {
- $dev->setCache(max($Line_buf[1]*1024*1024*1024, $dev->getCache()));
+ if (preg_match("/^\s+Data TLB:\s+(.*)K-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)K-byte/", $Line, $Line_buf)) {
+ $dev->setCache(max(intval($Line_buf[1])*1024, $dev->getCache()));
+ } elseif (preg_match("/^\s+Data TLB:\s+(.*)M-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)M-byte/", $Line, $Line_buf)) {
+ $dev->setCache(max(intval($Line_buf[1])*1024*1024, $dev->getCache()));
+ } elseif (preg_match("/^\s+Data TLB:\s+(.*)G-byte/", $Line, $Line_buf) || preg_match("/^\s+L0 Data TLB:\s+(.*)G-byte/", $Line, $Line_buf)) {
+ $dev->setCache(max(intval($Line_buf[1])*1024*1024*1024, $dev->getCache()));
} elseif (preg_match("/\s+VMX/", $Line, $Line_buf)) {
$dev->setVirt("vmx");
} elseif (preg_match("/\s+SVM/", $Line, $Line_buf)) {
$dev->setVirt("svm");
}
}
- if ($cpuspeed != "")$dev->setCpuSpeed($cpuspeed);
+ if ($cpuspeed != "") {
+ $dev->setCpuSpeed($cpuspeed);
+ }
$this->sys->setCpus($dev);
- //echo ">>>>>".$cpu;
}
}
}
@@ -136,7 +129,7 @@ class Haiku extends OS
private function _kernel()
{
if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) {
- $this->sys->setKernel($ret);
+ $this->sys->setKernel($ret);
}
}
@@ -163,19 +156,28 @@ class Haiku extends OS
*/
private function _uptime()
{
- if (CommonFunctions::executeProgram('uptime', '-u', $buf)) {
- if (preg_match("/^up (\d+) minute[s]?/", $buf, $ar_buf)) {
- $min = $ar_buf[1];
- $this->sys->setUptime($min * 60);
- } elseif (preg_match("/^up (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) {
- $min = $ar_buf[2];
- $hours = $ar_buf[1];
- $this->sys->setUptime($hours * 3600 + $min * 60);
- } elseif (preg_match("/^up (\d+) day[s]?, (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) {
+ if (CommonFunctions::executeProgram('uptime', '', $buf)) {
+ if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $buf, $ar_buf)) {
$min = $ar_buf[3];
$hours = $ar_buf[2];
$days = $ar_buf[1];
$this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
+ } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $buf, $ar_buf)) {
+ $min = $ar_buf[2];
+ $hours = $ar_buf[1];
+ $this->sys->setUptime($hours * 3600 + $min * 60);
+ } elseif (preg_match("/up (\d+) day[s]?, (\d+) hour[s]?, (\d+) minute[s]?$/", $buf, $ar_buf)) {
+ $min = $ar_buf[3];
+ $hours = $ar_buf[2];
+ $days = $ar_buf[1];
+ $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
+ } elseif (preg_match("/up (\d+) hour[s]?, (\d+) minute[s]?$/", $buf, $ar_buf)) {
+ $min = $ar_buf[2];
+ $hours = $ar_buf[1];
+ $this->sys->setUptime($hours * 3600 + $min * 60);
+ } elseif (preg_match("/up (\d+) minute[s]?$/", $buf, $ar_buf)) {
+ $min = $ar_buf[1];
+ $this->sys->setUptime($min * 60);
}
}
}
@@ -203,7 +205,7 @@ class Haiku extends OS
*
* @return void
*/
- private function _users()
+ protected function _users()
{
$this->sys->setUsers(1);
}
@@ -215,8 +217,8 @@ class Haiku extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) {
$ip = gethostbyname($result);
@@ -227,24 +229,6 @@ class Haiku extends OS
}
}
- /**
- * IP of the Virtual Host Name
- *
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* Physical memory information and Swap Space information
*
@@ -256,7 +240,7 @@ class Haiku extends OS
if (preg_match("/(.*)bytes free\s+\(used\/max\s+(.*)\s+\/\s+(.*)\)\s*\n\s+\(cached\s+(.*)\)/", $bufr, $ar_buf)) {
$this->sys->setMemTotal($ar_buf[3]);
$this->sys->setMemFree($ar_buf[1]);
- $this->sys->setMemCache($ar_buf[4]);
+ $this->sys->setMemCache(min($ar_buf[4], $ar_buf[2]));
$this->sys->setMemUsed($ar_buf[2]);
}
}
@@ -310,10 +294,13 @@ class Haiku extends OS
{
if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) {
$lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
- $notwas = true;
+ $was = false;
+ $errors = 0;
+ $drops = 0;
+ $dev = null;
foreach ($lines as $line) {
if (preg_match("/^(\S+)/", $line, $ar_buf)) {
- if (!$notwas) {
+ if ($was) {
$dev->setErrors($errors);
$dev->setDrops($drops);
$this->sys->setNetDevices($dev);
@@ -322,9 +309,9 @@ class Haiku extends OS
$drops = 0;
$dev = new NetDevice();
$dev->setName($ar_buf[1]);
- $notwas = false;
+ $was = true;
} else {
- if (!$notwas) {
+ if ($was) {
if (preg_match('/\sReceive:\s\d+\spackets,\s(\d+)\serrors,\s(\d+)\sbytes,\s\d+\smcasts,\s(\d+)\sdropped/i', $line, $ar_buf2)) {
$errors +=$ar_buf2[1];
$drops +=$ar_buf2[3];
@@ -336,18 +323,19 @@ class Haiku extends OS
}
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
- if (preg_match('/\sEthernet,\s+Address:\s(\S*)/i', $line, $ar_buf2))
- $dev->setInfo(preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\saddr:\s(\S*),/i', $line, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
- elseif (preg_match('/^\s+inet6\saddr:\s(\S*),/i', $line, $ar_buf2))
- if (!preg_match('/^fe80::/i', $ar_buf2[1]))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ if (preg_match('/\sEthernet,\s+Address:\s(\S*)/i', $line, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\saddr:\s(\S*),/i', $line, $ar_buf2)) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ } elseif (preg_match('/^\s+inet6\saddr:\s(\S*),/i', $line, $ar_buf2)
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ }
}
}
}
}
- if (!$notwas) {
+ if ($was) {
$dev->setErrors($errors);
$dev->setDrops($drops);
$this->sys->setNetDevices($dev);
@@ -380,24 +368,33 @@ class Haiku extends OS
/**
* get the information
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->error->addError("WARN", "The Haiku version of phpSysInfo is a work in progress, some things currently don't work");
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_loadavg();
- $this->_pci();
- $this->_usb();
- $this->_cpuinfo();
- $this->_memory();
- $this->_filesystems();
- $this->_network();
- $this->_processes();
+ $this->error->addWarning("The Haiku version of phpSysInfo is a work in progress, some things currently don't work");
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_cpuinfo();
+ $this->_pci();
+ $this->_usb();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.Linux.inc.php b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php
index 96abbbf..d9d35bd 100644
--- a/root/opt/phpsysinfo/includes/os/class.Linux.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php
@@ -8,7 +8,7 @@
* @package PSI Linux OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,23 +20,250 @@
* @package PSI Linux OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class Linux extends OS
{
/**
- * Assoc array of all CPUs loads.
+ * Uptime command result.
*/
- protected $_cpu_loads;
+ private $_uptime = null;
/**
- * call parent constructor
+ * Assoc array of all CPUs loads.
*/
- public function __construct()
+ protected $_cpu_loads = null;
+
+ /**
+ * Version string.
+ */
+ private $_kernel_string = null;
+
+ /**
+ * Array of info from Bios.
+ */
+ private $_machine_info = null;
+
+ /**
+ * Content of dmesg file.
+ */
+ private $_dmesg_f = null;
+
+ /**
+ * Result of executing dmesg command.
+ */
+ private $_dmesg_c = null;
+
+ /**
+ * Result of systemd-detect-virt.
+ */
+ private $system_detect_virt = null;
+
+ /**
+ * Read contents of the dmesg file.
+ *
+ * @return string
+ */
+ private function _get_dmesg_f()
{
- parent::__construct();
+ if ($this->_dmesg_f === null) {
+ $this->_dmesg_f = "";
+ if (CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false)) {
+ $this->_dmesg_f = trim($result);
+ }
+ }
+
+ return $this->_dmesg_f;
+ }
+
+ /**
+ * Save output of the dmesg command.
+ *
+ * @return string
+ */
+ private function _get_dmesg_c()
+ {
+ if ($this->_dmesg_c === null) {
+ $this->_dmesg_c = "";
+ if (CommonFunctions::executeProgram('dmesg', '', $result, false)) {
+ $this->_dmesg_c = trim($result);
+ }
+ }
+
+ return $this->_dmesg_c;
+ }
+
+ /**
+ * Get machine info
+ *
+ * @return string
+ */
+ private function _get_machine_info()
+ {
+ if ($this->_machine_info === null) {
+ $this->_machine_info = array();
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ if (CommonFunctions::executeProgram('systemd-detect-virt', '-v', $resultv, false)) {
+ $this->system_detect_virt = $resultv;
+ }
+ }
+ $vendor_array = array();
+ if (((($dmesg = $this->_get_dmesg_f()) !== null) && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $dmesg, $ar_buf)) ||
+ ((($dmesg = $this->_get_dmesg_c()) !== null) && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $dmesg, $ar_buf))) {
+ $this->_machine_info['machine'] = trim($ar_buf[1]);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
+ /* Test this before sys_vendor to detect KVM over QEMU */
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = $product_name = trim($buf);
+ } else {
+ $product_name = '';
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ if ($product_name != "") {
+ $vendor_array[] = trim($buf)." ".$product_name;
+ } else {
+ $vendor_array[] = trim($buf);
+ }
+ } else {
+ $vendor_array[] = $this->_machine_info['machine'];
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ }
+ } else { // 'machine' data from /sys/devices/virtual/dmi/id/
+ $bios = "";
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
+ // Test this before sys_vendor to detect KVM over QEMU
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = $product_name = trim($buf);
+ } else {
+ $product_name = '';
+ }
+
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ if ($product_name != "") {
+ $this->_machine_info['machine'] = trim($buf)." ".$product_name;
+ } else {
+ $this->_machine_info['machine'] = trim($buf);
+ }
+ $vendor_array[] = $this->_machine_info["machine"];
+ } elseif ($product_name != "") {
+ $this->_machine_info['machine'] = $product_name;
+ }
+
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $vendor_array[] = trim($buf);
+ }
+ } else {
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $this->_machine_info['machine'] = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ if (isset($this->_machine_info['machine'])) {
+ $this->_machine_info['machine'] .= " ".trim($buf);
+ } else {
+ $this->_machine_info['machine'] = trim($buf);
+ }
+ }
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ if (isset($this->_machine_info['machine'])) {
+ $this->_machine_info['machine'] .= "/".trim($buf);
+ } else {
+ $this->_machine_info['machine'] = trim($buf);
+ }
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $bios = trim($buf);
+ }
+ if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $bios = trim($bios." ".trim($buf));
+ }
+ if ($bios != "") {
+ if (isset($this->_machine_info['machine'])) {
+ $this->_machine_info['machine'] .= ", BIOS ".$bios;
+ } else {
+ $this->_machine_info['machine'] = "BIOS ".$bios;
+ }
+ }
+ }
+ if (isset($this->_machine_info['machine'])) {
+ $this->_machine_info['machine'] = trim(preg_replace("/^\/,?/", "", preg_replace("/ ?(To be filled by O\.E\.M\.|System manufacturer|System Product Name|Not Specified|Default string) ?/i", "", $this->_machine_info['machine'])));
+ }
+
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && count($vendor_array) > 0) {
+ $virt = CommonFunctions::decodevirtualizer($vendor_array);
+ if ($virt !== null) {
+ $this->_machine_info['hypervisor'] = $virt;
+ }
+ }
+ }
+
+ return $this->_machine_info;
+ }
+
+ /**
+ * Get kernel string
+ *
+ * @return string
+ */
+ private function _get_kernel_string()
+ {
+ if ($this->_kernel_string === null) {
+ $this->_kernel_string = "";
+ if ($this->sys->getOS() !== 'SSH') {
+ if ((CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) && ($strBuf !== '')) || // show effective kernel if ksplice uptrack is installed
+ (CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG) && ($strBuf !== ''))) {
+ $this->_kernel_string = $strBuf;
+ if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG) && ($strBuf !== '')) {
+ if (preg_match('/ SMP /', $strBuf)) {
+ $this->_kernel_string .= ' (SMP)';
+ }
+ }
+ if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG) && ($strBuf !== '')) {
+ $this->_kernel_string .= ' '.$strBuf;
+ }
+ } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1)) {
+ if (preg_match('/\/Hurd-([^\)]+)/', $strBuf, $ar_buf)) {
+ $this->_kernel_string = $ar_buf[1];
+ } elseif (preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) {
+ $this->_kernel_string = $ar_buf[1];
+ if (preg_match('/ SMP /', $strBuf)) {
+ $this->_kernel_string .= ' (SMP)';
+ }
+ }
+ }
+ }
+ }
+
+ return $this->_kernel_string;
+ }
+
+ /**
+ * check OS type
+ */
+ public function __construct($blockname = false)
+ {
+ parent::__construct($blockname);
+
+ if (($this->sys->getOS() == 'SSH') && CommonFunctions::executeProgram('uname', '-s', $strBuf, false) && ($strBuf !== '')) {
+ $this->sys->setOS($strBuf);
+ }
}
/**
@@ -44,47 +271,31 @@ class Linux extends OS
*
* @return void
*/
- private function _machine()
+ protected function _machine()
{
- if ((CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false)
- && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))
- ||(CommonFunctions::executeProgram('dmesg', '', $result, false)
- && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))) {
- $this->sys->setMachine(trim($ar_buf[1]));
- } else { //data from /sys/devices/virtual/dmi/id/
+ $machine_info = $this->_get_machine_info();
+ if (isset($machine_info['machine'])) {
+ $machine = $machine_info['machine'];
+ } else {
$machine = "";
- $product = "";
- $board = "";
- $bios = "";
- if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
- $machine = trim($buf);
- }
- if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
- $product = trim($buf);
- }
- if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
- $board = trim($buf);
- }
- if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
- $bios = trim($buf);
- }
- if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) {
- $bios = trim($bios." ".trim($buf));
- }
- if ($product != "") {
- $machine .= " ".$product;
- }
- if ($board != "") {
- $machine .= "/".$board;
- }
- if ($bios != "") {
- $machine .= ", BIOS ".$bios;
- }
+ }
- if ($machine != "") {
- $this->sys->setMachine(trim($machine));
+ if (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf") // QNAP detection
+ && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
+ && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
+ && CommonFunctions::fileexists($filename="/etc/platform.conf") // Platform detection
+ && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
+ && preg_match("/^DISPLAY_NAME\s*=\s*(\S+)/m", $buf, $mach_buf) && ($mach_buf[1]!=="")) {
+ if ($machine !== "") {
+ $machine = "QNAP ".$mach_buf[1].' - '.$machine;
+ } else {
+ $machine = "QNAP ".$mach_buf[1];
}
}
+
+ if ($machine !== "") {
+ $this->sys->setMachine($machine);
+ }
}
/**
@@ -94,34 +305,21 @@ class Linux extends OS
*/
protected function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST && !defined('PSI_EMU_PORT')) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
- if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1)) {
+ if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) {
$result = trim($result);
$ip = gethostbyname($result);
if ($ip != $result) {
- $this->sys->setHostname(gethostbyaddr($ip));
+ $this->sys->setHostname(trim(gethostbyaddr($ip), "."));
}
+ } elseif (CommonFunctions::executeProgram('hostname', '', $ret, false)) {
+ $this->sys->setHostname($ret);
+ } elseif (CommonFunctions::executeProgram('uname', '-n', $ret, false)) {
+ $this->sys->setHostname($ret);
}
- }
- }
- /**
- * IP
- *
- * @return void
- */
- protected function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!isset($_SERVER['SERVER_ADDR']) || !($result = $_SERVER['SERVER_ADDR'])) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
}
}
@@ -130,37 +328,224 @@ class Linux extends OS
*
* @return void
*/
- private function _kernel()
+ protected function _kernel()
{
- $result = "";
- if (CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) || // show effective kernel if ksplice uptrack is installed
- CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG)) {
- $result = trim($strBuf);
- if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG)) {
- if (preg_match('/SMP/', $strBuf)) {
- $result .= ' (SMP)';
- }
- }
- if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG)) {
- $result .= ' '.trim($strBuf);
- }
- } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) && preg_match('/version (.*?) /', $strBuf, $ar_buf)) {
- $result = $ar_buf[1];
- if (preg_match('/SMP/', $strBuf)) {
- $result .= ' (SMP)';
- }
+ if (($verBuf = $this->_get_kernel_string()) != "") {
+ $this->sys->setKernel($verBuf);
}
- if ($result != "") {
- if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) {
- if (preg_match('/:\/lxc\//m', $strBuf2)) {
- $result .= ' [lxc]';
- } elseif (preg_match('/:\/docker\//m', $strBuf2)) {
- $result .= ' [docker]';
- } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) {
- $result .= ' [docker]';
+ }
+
+ /**
+ * Virtualizer info
+ *
+ * @return void
+ */
+ protected function _virtualizer()
+ {
+ if (!defined('PSI_SHOW_VIRTUALIZER_INFO') || !PSI_SHOW_VIRTUALIZER_INFO) {
+ return;
+ }
+ if ($this->system_detect_virt !== null) {
+ if (($this->system_detect_virt !== "") && ($this->system_detect_virt !== "none")) {
+ $this->sys->setVirtualizer($this->system_detect_virt);
+ }
+ if (($verBuf = $this->_get_kernel_string()) !== "") {
+ if (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) {
+ $this->sys->setVirtualizer('wsl2', 'wsl'); // Windows Subsystem for Linux 2
+ }
+ }
+ if (CommonFunctions::executeProgram('systemd-detect-virt', '-c', $resultc, false) && ($resultc !== "") && ($resultc !== "none")) {
+ $this->sys->setVirtualizer($resultc);
+ }
+ } else {
+ $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo()
+
+ $novm = true;
+ // code based on src/basic/virt.c from systemd-detect-virt source code (https://github.com/systemd/systemd)
+
+ // First, try to detect Oracle Virtualbox, Amazon EC2 Nitro and Parallels, even if they use KVM,
+ // as well as Xen even if it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also
+ // since it runs as a user-process nested inside other VMs. Also check for Xen now, because Xen PV
+ // mode does not override CPUID when nested inside another hypervisor.
+ $machine_info = $this->_get_machine_info();
+ if (isset($machine_info['hypervisor'])) {
+ $hypervisor = $machine_info['hypervisor'];
+ if (($hypervisor === 'oracle') || ($hypervisor === 'amazon') || ($hypervisor === 'xen') || ($hypervisor === 'parallels')) {
+ $this->sys->setVirtualizer($hypervisor);
+ $novm = false;
+ }
+ }
+
+ // Detect UML
+ if ($novm) {
+ if (isset($cpuvirt["cpuid:UserModeLinux"])) {
+ $this->sys->setVirtualizer('uml'); // User-mode Linux
+ $novm = false;
+ }
+ }
+
+ // Detect Xen
+ if ($novm && is_dir('/proc/xen')) {
+ // xen Dom0 is detected as XEN in hypervisor and maybe others.
+ // In order to detect the Dom0 as not virtualization we need to
+ // double-check it
+ if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) {
+ if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
+ $novm = false;
+ }
+ } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
+ $novm = false;
+ }
+ }
+
+ // Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is overwritten.
+ // Since the vendor_id in /proc/cpuinfo is overwritten on virtualization we use values from msr-cpuid.
+ if ($novm && CommonFunctions::executeProgram('msr-cpuid', '', $bufr, false)
+ && (preg_match('/^40000000 00000000: [0-9a-f]{8} \S{4} [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4})/m', $bufr, $cpuid))) {
+ $virt = CommonFunctions::decodevirtualizer($cpuid[1].$cpuid[2].$cpuid[3]);
+ if ($virt !== null) {
+ $this->sys->setVirtualizer($virt);
+ }
+ }
+
+ // Third, try to detect from DMI.
+ if ($novm && isset($hypervisor)) {
+ $this->sys->setVirtualizer($hypervisor);
+ $novm = false;
+ }
+
+ // Check high-level hypervisor sysfs file
+ if ($novm && CommonFunctions::rfts('/sys/hypervisor/type', $type, 1, 4096, false) && ($type === "xen")) {
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor
+ $novm = false;
+ }
+
+ if ($novm) {
+ if (CommonFunctions::rfts('/proc/device-tree/hypervisor/compatible', $compatible, 1, 4096, false)) {
+ switch ($compatible) {
+ case 'linux,kvm':
+ $this->sys->setVirtualizer('kvm'); // KVM
+ $novm = false;
+ break;
+ case 'vmware':
+ $this->sys->setVirtualizer('vmware'); // VMware
+ $novm = false;
+ break;
+ case 'xen':
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor
+ $novm = false;
+ }
+ } else {
+ if (CommonFunctions::fileexists('/proc/device-tree/ibm,partition-name')
+ && CommonFunctions::fileexists('/proc/device-tree/hmc-managed?')
+ && CommonFunctions::fileexists('/proc/device-tree/chosen/qemu,graphic-width')) {
+ $this->sys->setVirtualizer('powervm'); // IBM PowerVM hypervisor
+ $novm = false;
+ } else {
+ $names = CommonFunctions::findglob('/proc/device-tree', GLOB_NOSORT);
+ if (is_array($names) && (($total = count($names)) > 0)) {
+ for ($i = 0; $i < $total; $i++) {
+ if (preg_match('/fw-cfg/', $names[$i])) {
+ $this->sys->setVirtualizer('qemu'); // QEMU
+ $novm = false;
+ break;
+ }
+ }
+ }
+ if (CommonFunctions::rfts('/proc/device-tree/compatible', $compatible, 1, 4096, false) && ($compatible === "qemu,pseries")) {
+ $this->sys->setVirtualizer('qemu'); // QEMU
+ $novm = false;
+ }
+ }
+ }
+ }
+
+ if ($novm && CommonFunctions::rfts('/proc/sysinfo', $sysinfo, 0, 4096, false) && preg_match('//VM00 Control Program:\s*(\S+)/m', $sysinfo, $vcp)) {
+ if ($vcp[1] === 'z/VM') {
+ $this->sys->setVirtualizer('zvm'); // s390 z/VM
+ } else {
+ $this->sys->setVirtualizer('kvm'); // KVM
+ }
+ $novm = false;
+ }
+
+ // Additional tests outside of the systemd-detect-virt source code
+ if ($novm && (
+ ((($dmesg = $this->_get_dmesg_f()) !== null) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $dmesg, $ar_buf)) ||
+ ((($dmesg = $this->_get_dmesg_c()) !== null) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $dmesg, $ar_buf)))) {
+ switch (trim($ar_buf[1])) {
+ case 'VMware':
+ $this->sys->setVirtualizer('vmware'); // VMware
+ $novm = false;
+ break;
+ case 'KVM':
+ $this->sys->setVirtualizer('kvm'); // KVM
+ $novm = false;
+ break;
+ case 'Microsoft HyperV':
+ case 'Microsoft Hyper-V':
+ $this->sys->setVirtualizer('microsoft'); // Hyper-V
+ $novm = false;
+ break;
+ case 'ACRN':
+ $this->sys->setVirtualizer('acrn'); // ACRN hypervisor
+ $novm = false;
+ break;
+ case 'Jailhouse':
+ $this->sys->setVirtualizer('jailhouse'); // Jailhouse
+ $novm = false;
+ break;
+ case 'Xen':
+ case 'Xen PV':
+ case 'Xen HVM':
+ // xen Dom0 is detected as XEN in hypervisor and maybe others.
+ // In order to detect the Dom0 as not virtualization we need to
+ // double-check it
+ if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) {
+ if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
+ $novm = false;
+ }
+ } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities
+ $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
+ $novm = false;
+ }
+ }
+ }
+
+ // Detect QEMU cpu
+ if ($novm && isset($cpuvirt["cpuid:QEMU"])) {
+ $this->sys->setVirtualizer('qemu'); // QEMU
+ $novm = false;
+ }
+
+ if ($novm && isset($cpuvirt["hypervisor"])) {
+ $this->sys->setVirtualizer('unknown');
+ }
+
+ if ((count(CommonFunctions::gdc('/proc/vz', false)) == 0) && (count(CommonFunctions::gdc('/proc/bc', false)) > 0)) {
+ $this->sys->setVirtualizer('openvz'); // OpenVZ/Virtuozzo
+ }
+
+ if (($verBuf = $this->_get_kernel_string()) !== "") {
+ if (preg_match('/^[\d\.-]+-Microsoft/', $verBuf)) {
+ $this->sys->setVirtualizer('wsl'); // Windows Subsystem for Linux
+ } elseif (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) {
+ $this->sys->setVirtualizer('wsl2'); // Windows Subsystem for Linux 2
+ }
+ }
+
+ if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) {
+ if (preg_match('/:\/lxc\//m', $strBuf2)) {
+ $this->sys->setVirtualizer('lxc'); // Linux container
+ } elseif (preg_match('/:\/docker\//m', $strBuf2)) {
+ $this->sys->setVirtualizer('docker'); // Docker
+ } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) {
+ $this->sys->setVirtualizer('docker'); // Docker
}
}
- $this->sys->setKernel($result);
}
}
@@ -170,24 +555,41 @@ class Linux extends OS
*
* @return void
*/
- protected function _uptime()
+ protected function _uptime($bufu = null)
{
- CommonFunctions::rfts('/proc/uptime', $buf, 1);
- $ar_buf = preg_split('/ /', $buf);
- $this->sys->setUptime(trim($ar_buf[0]));
- }
-
- /**
- * Number of Users
- *
- * @return void
- */
- private function _users()
- {
- if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) {
- if (strlen(trim($strBuf)) > 0) {
- $lines = preg_split('/\n/', $strBuf);
- $this->sys->setUsers(count($lines));
+ if (CommonFunctions::rfts('/proc/uptime', $buf, 1, 4096, PSI_OS != 'Android')) {
+ $ar_buf = preg_split('/ /', $buf);
+ $this->sys->setUptime(trim($ar_buf[0]));
+ } elseif (($this->_uptime !== null) || ($bufu !== null) || CommonFunctions::executeProgram('uptime', '', $bufu)) {
+ if (($this->_uptime === null) && ($bufu !== null)) {
+ $this->_uptime = $bufu;
+ }
+ if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
+ $min = $ar_buf[3];
+ $hours = $ar_buf[2];
+ $days = $ar_buf[1];
+ $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
+ } elseif (preg_match("/up (\d+) day[s]?,[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) {
+ $min = $ar_buf[2];
+ $days = $ar_buf[1];
+ $this->sys->setUptime($days * 86400 + $min * 60);
+ } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
+ $min = $ar_buf[2];
+ $hours = $ar_buf[1];
+ $this->sys->setUptime($hours * 3600 + $min * 60);
+ } elseif (preg_match("/up[ ]+(\d+):(\d+):(\d+)/", $this->_uptime, $ar_buf)) {
+ $sec = $ar_buf[3];
+ $min = $ar_buf[2];
+ $hours = $ar_buf[1];
+ $this->sys->setUptime($hours * 3600 + $min * 60 + $sec);
+ } elseif (preg_match("/up[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) {
+ $min = $ar_buf[1];
+ $this->sys->setUptime($min * 60);
+ } elseif (preg_match("/up[ ]+(\d+) day[s]?,[ ]+(\d+) hour[s]?,[ ]+(\d+) minute[s]?/", $this->_uptime, $ar_buf)) {
+ $min = $ar_buf[3];
+ $hours = $ar_buf[2];
+ $days = $ar_buf[1];
+ $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
}
}
}
@@ -198,13 +600,15 @@ class Linux extends OS
*
* @return void
*/
- protected function _loadavg()
+ protected function _loadavg($buf = null)
{
- if (CommonFunctions::rfts('/proc/loadavg', $buf)) {
+ if ((($buf !== null) || CommonFunctions::rfts('/proc/loadavg', $buf, 1, 4096, PSI_OS != 'Android')) && preg_match("/^\d/", trim($buf))) {
$result = preg_split("/\s/", $buf, 4);
// don't need the extra values, only first three
unset($result[3]);
$this->sys->setLoad(implode(' ', $result));
+ } elseif (($buf === null) && ((($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) && preg_match("/load average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf))) {
+ $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
}
if (PSI_LOAD_BAR) {
$this->sys->setLoadPercent($this->_parseProcStat('cpu'));
@@ -216,53 +620,56 @@ class Linux extends OS
*
* @param String $cpuline cpu for which load should be meassured
*
- * @return Integer
+ * @return int
*/
protected function _parseProcStat($cpuline)
{
- if (is_null($this->_cpu_loads)) {
+ if ($this->_cpu_loads === null) {
$this->_cpu_loads = array();
- if (CommonFunctions::rfts('/proc/stat', $buf)) {
+ $cpu_tmp = array();
+ if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) {
if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
foreach ($matches as $line) {
$cpu = $line[1];
$buf2 = $line[2];
- $this->_cpu_loads[$cpu] = array();
+ $cpu_tmp[$cpu] = array();
$ab = 0;
$ac = 0;
$ad = 0;
$ae = 0;
sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
- $this->_cpu_loads[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys
- $this->_cpu_loads[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total
+ $cpu_tmp[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys
+ $cpu_tmp[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total
}
}
- }
- // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
- if (PSI_LOAD_BAR) {
- sleep(1);
- }
- if (CommonFunctions::rfts('/proc/stat', $buf)) {
- if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
- foreach ($matches as $line) {
- $cpu = $line[1];
- $buf2 = $line[2];
- $ab = 0;
- $ac = 0;
- $ad = 0;
- $ae = 0;
- sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
- $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys
- $total2 = $ab + $ac + $ad + $ae; // cpu.total
- $total = $this->_cpu_loads[$cpu]['total'];
- $load = $this->_cpu_loads[$cpu]['load'];
- $this->_cpu_loads[$cpu] = 0;
- if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) {
- $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total);
+ // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
+ sleep(1);
+
+ if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG)) {
+ if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $line) {
+ $cpu = $line[1];
+ if (isset($cpu_tmp[$cpu])) {
+ $buf2 = $line[2];
+
+ $ab = 0;
+ $ac = 0;
+ $ad = 0;
+ $ae = 0;
+ sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
+ $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys
+ $total2 = $ab + $ac + $ad + $ae; // cpu.total
+ $total = $cpu_tmp[$cpu]['total'];
+ $load = $cpu_tmp[$cpu]['load'];
+ $this->_cpu_loads[$cpu] = 0;
+ if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) {
+ $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total);
+ }
+ }
}
}
}
@@ -271,9 +678,9 @@ class Linux extends OS
if (isset($this->_cpu_loads[$cpuline])) {
return $this->_cpu_loads[$cpuline];
+ } else {
+ return null;
}
-
- return 0;
}
/**
@@ -282,24 +689,116 @@ class Linux extends OS
*
* @return void
*/
- protected function _cpuinfo()
+ protected function _cpuinfo($bufr = null)
{
- if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) {
+ if (($bufr !== null) || CommonFunctions::rfts('/proc/cpuinfo', $bufr)) {
+ $cpulist = null;
+ $raslist = null;
+
+ // sparc
+ if (preg_match('/\nCpu(\d+)Bogo\s*:/i', $bufr)) {
+ $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\nCpu0ClkTck:", preg_replace('/\nCpu(\d+)Bogo\s*:/i', "\n\nprocessor: $1\nCpu0Bogo:", $bufr));
+ } else {
+ $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\n\nprocessor: $1\nCpu0ClkTck:", $bufr);
+ }
+
+ if (preg_match('/\nprocessor\s*:\s*\d+\r?\nprocessor\s*:\s*\d+/', $bufr)) {
+ $bufr = preg_replace('/^(processor\s*:\s*\d+)\r?$/m', "$1\n", $bufr);
+ }
+
+ // IBM/S390
+ $bufr = preg_replace('/\ncpu number\s*:\s*(\d+)\r?\ncpu MHz dynamic\s*:\s*(\d+)/m', "\nprocessor:$1\nclock:$2", $bufr);
+
+ // machine
+ $bufr = preg_replace('/(\nmachine\s*:\s*[^\r\n]+)/m', "$1\n", $bufr);
+
$processors = preg_split('/\s?\n\s?\n/', trim($bufr));
+
+ //first stage
+ $_arch = null;
+ $_impl = null;
+ $_part = null;
+ $_vari = null;
+ $_hard = null;
+ $_revi = null;
+ $_cpus = null;
+ $_buss = null;
+ $_bogo = null;
+ $_vend = null;
+ $_system = null;
$procname = null;
- foreach ($processors as $processor) {
+ foreach ($processors as $processor) if (!preg_match('/^\s*processor\s*:/mi', $processor)) {
+ $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($details as $detail) {
+ if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) {
+ switch (strtolower(trim($arrBuff[1]))) {
+ case 'cpu architecture':
+ $_arch = $arrBuff2;
+ break;
+ case 'cpu implementer':
+ $_impl = $arrBuff2;
+ break;
+ case 'cpu part':
+ $_part = $arrBuff2;
+ break;
+ case 'cpu variant':
+ $_vari = $arrBuff2;
+ break;
+ case 'system type':
+ $_system = $arrBuff2;
+ break;
+ case 'machine':
+ case 'hardware':
+ $_hard = $arrBuff2;
+ break;
+ case 'revision':
+ $_revi = $arrBuff2;
+ break;
+ case 'cpu frequency':
+ if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) {
+ $_cpus = round($bufr2[1]/1000000);
+ } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) {
+ $_cpus = $bufr2[1];
+ }
+ break;
+ case 'system bus frequency':
+ if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) {
+ $_buss = round($bufr2[1]/1000000);
+ } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) {
+ $_buss = $bufr2[1];
+ }
+ break;
+ case 'bogomips per cpu':
+ $_bogo = round($arrBuff2);
+ break;
+ case 'vendor_id':
+ $_vend = $arrBuff2;
+ break;
+ case 'cpu':
+ $procname = $arrBuff2;
+ }
+ }
+ }
+ }
+
+ //second stage
+ $cpucount = 0;
+ $speedset = false;
+ foreach ($processors as $processor) if (preg_match('/^\s*processor\s*:/mi', $processor)) {
$proc = null;
$arch = null;
+ $impl = null;
+ $part = null;
+ $vari = null;
$dev = new CpuDevice();
$details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
foreach ($details as $detail) {
- $arrBuff = preg_split('/\s*:\s*/', trim($detail));
- if (count($arrBuff) == 2) {
- switch (strtolower($arrBuff[0])) {
+ if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) {
+ switch (strtolower(trim($arrBuff[1]))) {
case 'processor':
- $proc = trim($arrBuff[1]);
+ $proc = $arrBuff2;
if (is_numeric($proc)) {
- if (strlen($procname)>0) {
+ if (($procname !== null) && (strlen($procname) > 0)) {
$dev->setModel($procname);
}
} else {
@@ -311,52 +810,100 @@ class Linux extends OS
case 'cpu model':
case 'cpu type':
case 'cpu':
- $dev->setModel($arrBuff[1]);
+ $dev->setModel($arrBuff2);
+ break;
+ case 'cpu frequency':
+ if (preg_match('/^(\d+)\s+Hz/i', $arrBuff2, $bufr2)) {
+ if (($tmpsp = round($bufr2[1]/1000000)) > 0) {
+ $dev->setCpuSpeed($tmpsp);
+ $speedset = true;
+ }
+ } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff2, $bufr2)) {
+ if ($bufr2[1] > 0) {
+ $dev->setCpuSpeed($bufr2[1]);
+ $speedset = true;
+ }
+ }
break;
case 'cpu mhz':
case 'clock':
- if ($arrBuff[1] > 0) { //openSUSE fix
- $dev->setCpuSpeed($arrBuff[1]);
+ if ($arrBuff2 > 0) {
+ $dev->setCpuSpeed($arrBuff2);
+ $speedset = true;
}
break;
+ case 'cpu mhz static':
+ $dev->setCpuSpeedMax($arrBuff2);
+ break;
case 'cycle frequency [hz]':
- $dev->setCpuSpeed($arrBuff[1] / 1000000);
+ if (($tmpsp = round($arrBuff2/1000000)) > 0) {
+ $dev->setCpuSpeed($tmpsp);
+ $speedset = true;
+ }
break;
- case 'cpu0clktck':
- $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64
+ case 'cpu0clktck': // Linux sparc64
+ if (($tmpsp = round(hexdec($arrBuff2)/1000000)) > 0) {
+ $dev->setCpuSpeed($tmpsp);
+ $speedset = true;
+ }
break;
- case 'l2 cache':
+ case 'l3 cache':
case 'cache size':
- $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024);
+ $dev->setCache(trim(preg_replace("/[a-zA-Z]/", "", $arrBuff2)) * 1024);
break;
case 'initial bogomips':
case 'bogomips':
case 'cpu0bogo':
- $dev->setBogomips($arrBuff[1]);
+ $dev->setBogomips(round($arrBuff2));
break;
case 'flags':
- if (preg_match("/ vmx/", $arrBuff[1])) {
+ if (preg_match("/ vmx/", $arrBuff2)) {
$dev->setVirt("vmx");
- } elseif (preg_match("/ svm/", $arrBuff[1])) {
+ } elseif (preg_match("/ svm/", $arrBuff2)) {
$dev->setVirt("svm");
- } elseif (preg_match("/ hypervisor/", $arrBuff[1])) {
- $dev->setVirt("hypervisor");
+ }
+ if (preg_match("/ hypervisor/", $arrBuff2)) {
+ if ($dev->getVirt() === null) {
+ $dev->setVirt("hypervisor");
+ }
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
+ $this->sys->setVirtualizer("hypervisor", false);
+ }
}
break;
case 'i size':
case 'd size':
if ($dev->getCache() === null) {
- $dev->setCache($arrBuff[1] * 1024);
+ $dev->setCache($arrBuff2 * 1024);
} else {
- $dev->setCache($dev->getCache() + ($arrBuff[1] * 1024));
+ $dev->setCache($dev->getCache() + ($arrBuff2 * 1024));
}
break;
case 'cpu architecture':
- $arch = trim($arrBuff[1]);
+ $arch = $arrBuff2;
break;
+ case 'cpu implementer':
+ $impl = $arrBuff2;
+ break;
+ case 'cpu part':
+ $part = $arrBuff2;
+ break;
+ case 'cpu variant':
+ $vari = $arrBuff2;
+ break;
+ case 'vendor_id':
+ $dev->setVendorId($arrBuff2);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $arrBuff2)) {
+ $this->sys->setVirtualizer("cpuid:UserModeLinux", false);
+ }
}
}
}
+ if ($arch === null) $arch = $_arch;
+ if ($impl === null) $impl = $_impl;
+ if ($part === null) $part = $_part;
+ if ($vari === null) $vari = $_vari;
+
// sparc64 specific code follows
// This adds the ability to display the cache that a CPU has
// Originally made by Sven Blumenstein in 2004
@@ -364,43 +911,157 @@ class Linux extends OS
$sparclist = array('SUNW,UltraSPARC@0,0', 'SUNW,UltraSPARC-II@0,0', 'SUNW,UltraSPARC@1c,0', 'SUNW,UltraSPARC-IIi@1c,0', 'SUNW,UltraSPARC-II@1c,0', 'SUNW,UltraSPARC-IIe@0,0');
foreach ($sparclist as $name) {
if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) {
- $dev->setCache(base_convert($buf, 16, 10));
+ $dev->setCache(base_convert(trim($buf), 16, 10));
}
}
// sparc64 specific code ends
// XScale detection code
- if (($arch === "5TE") && ($dev->getBogomips() != null)) {
- $dev->setCpuSpeed($dev->getBogomips()); //BogoMIPS are not BogoMIPS on this CPU, it's the speed
+ if (($arch === "5TE") && (($bogo = $dev->getBogomips()) !== null) && ($bogo > 0)) {
+ $dev->setCpuSpeed($bogo); // BogoMIPS are not BogoMIPS on this CPU, it's the speed
+ $speedset = true;
$dev->setBogomips(null); // no BogoMIPS available, unset previously set BogoMIPS
}
- if ($proc != null) {
+ if (($dev->getBusSpeed() == 0) && ($_buss !== null)) {
+ $dev->setBusSpeed($_buss);
+ }
+ if (($dev->getCpuSpeed() == 0) && ($_cpus !== null) && ($_cpus > 0)) {
+ $dev->setCpuSpeed($_cpus);
+ $speedset = true;
+ }
+ if (($dev->getBogomips() == 0) && ($_bogo !== null)) {
+ $dev->setBogomips($_bogo);
+ }
+ if (($dev->getVendorId() === null) && ($_vend !== null)) {
+ $dev->setVendorId($_vend);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $_vend)) {
+ $this->sys->setVirtualizer("cpuid:UserModeLinux", false);
+ }
+ }
+
+ if ($proc !== null) {
if (!is_numeric($proc)) {
$proc = 0;
}
// variable speed processors specific code follows
- if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)) {
- $dev->setCpuSpeed($buf / 1000);
- } elseif (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) {
- $dev->setCpuSpeed($buf / 1000);
+ if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)
+ || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) {
+ if (round(trim($buf)/1000) > 0) {
+ $dev->setCpuSpeed(round(trim($buf)/1000));
+ $speedset = true;
+ }
}
- if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)) {
- $dev->setCpuSpeedMax($buf / 1000);
+ if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)
+ || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_max_freq', $buf, 1, 4096, false)) {
+ $dev->setCpuSpeedMax(round(trim($buf)/1000));
}
- if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)) {
- $dev->setCpuSpeedMin($buf / 1000);
+ if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)
+ || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_min_freq', $buf, 1, 4096, false)) {
+ $dev->setCpuSpeedMin(round(trim($buf)/1000));
}
// variable speed processors specific code ends
if (PSI_LOAD_BAR) {
$dev->setLoad($this->_parseProcStat('cpu'.$proc));
}
-
- if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)) {
- $dev->setTemp(substr($buf, 25, 2));
+/*
+ if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)
+ && preg_match("/(\S+)\sC$/", $buf, $value)) {
+ $dev->setTemp(value[1]);
}
- if ($dev->getModel() === "") {
- $dev->setModel("unknown");
+*/
+ if (($arch !== null) && ($impl !== null) && ($part !== null)) {
+ if (($impl === '0x41')
+ && (($_hard === 'BCM2708') || ($_hard === 'BCM2709') || ($_hard === 'BCM2710') || ($_hard === 'BCM2711') || ($_hard === 'BCM2712') || ($_hard === 'BCM2835') || ($_hard === 'BCM2836') || ($_hard === 'BCM2837') || ($_hard === 'BCM2838'))
+ && ($_revi !== null)) { // Raspberry Pi detection (instead of 'cat /proc/device-tree/model')
+ if ($raslist === null) $raslist = @parse_ini_file(PSI_APP_ROOT."/data/raspberry.ini", true);
+ $oldmach = $this->sys->getMachine();
+ if (($oldmach !== '') && preg_match("/^raspberrypi rpi(,.+)/", $oldmach, $machbuf)) {
+ $oldmachend = $machbuf[1];
+ } else {
+ $oldmachend = '';
+ }
+ if ($raslist && !preg_match('/[^0-9a-f]/', $_revi)) {
+ if (($revidec = hexdec($_revi)) & 0x800000) {
+ if (($oldmach === '') || ($oldmachend !== '')) {
+ $manufacturer = ($revidec >> 16) & 15;
+ if (isset($raslist['manufacturer'][$manufacturer])) {
+ $manuf = ' '.$raslist['manufacturer'][$manufacturer];
+ } else {
+ $manuf = '';
+ }
+ $model = ($revidec >> 4) & 255;
+ if (isset($raslist['model'][$model])) {
+ $this->sys->setMachine('Raspberry Pi '.$raslist['model'][$model].' (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend);
+ } else {
+ $this->sys->setMachine('Raspberry Pi (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend);
+ }
+ }
+ } else {
+ if (($oldmach === '') || ($oldmachend !== '')) {
+ if (isset($raslist['old'][$revidec & 0x7fffff])) {
+ $this->sys->setMachine('Raspberry Pi '.$raslist['old'][$revidec & 0x7fffff].$oldmachend);
+ } else {
+ $this->sys->setMachine('Raspberry Pi'.$oldmachend);
+ }
+ }
+ }
+ }
+ } elseif ($this->sys->getMachine() === '') { // other ARM hardware
+ if ($_hard !== null) {
+ if ($_system !== null) {
+ $this->sys->setMachine($_hard." - ".$_system);
+ } else {
+ $this->sys->setMachine($_hard);
+ }
+ } elseif ($_system !== null) {
+ $this->sys->setMachine($_system);
+ }
+ }
+ if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
+ if ($cpulist && (((($vari !== null) && isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part.','.$vari)]))
+ || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part)])))) {
+ if (($cpumodel = $dev->getModel()) !== '') {
+ $dev->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]);
+ } else {
+ $dev->setModel($cpulist['cpu'][$cpufromlist]);
+ }
+ }
+ } elseif ($this->sys->getMachine() === '') { // other hardware
+ if ($_hard !== null) {
+ if ($_system !== null) {
+ $this->sys->setMachine($_hard." - ".$_system);
+ } else {
+ $this->sys->setMachine($_hard);
+ }
+ } elseif ($_system !== null) {
+ $this->sys->setMachine($_system);
+ }
+ }
+
+ $cpumodel = $dev->getModel();
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && preg_match('/^QEMU Virtual CPU version /', $cpumodel)) {
+ $this->sys->setVirtualizer("cpuid:QEMU", false);
+ }
+ if ($cpumodel === "") {
+ if (($vendid = $dev->getVendorId()) !== "") {
+ $dev->setModel($vendid);
+ } else {
+ $dev->setModel("unknown");
+ }
+ }
+ $cpucount++;
+ $this->sys->setCpus($dev);
+ }
+ }
+
+ $cpudevices = CommonFunctions::findglob('/sys/devices/system/cpu/cpu[0-9]*/uevent', GLOB_NOSORT);
+ if (is_array($cpudevices) && (($cpustopped = count($cpudevices)-$cpucount) > 0)) {
+ for (; $cpustopped > 0; $cpustopped--) {
+ $dev = new CpuDevice();
+ $dev->setModel("stopped");
+ if ($speedset) {
+ $dev->setCpuSpeed(-1);
}
$this->sys->setCpus($dev);
}
@@ -415,29 +1076,67 @@ class Linux extends OS
*/
private function _pci()
{
- if (!$arrResults = Parser::lspci()) {
- if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
- $booDevice = false;
- $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($arrBuf as $strLine) {
- if (preg_match('/Bus/', $strLine)) {
- $booDevice = true;
- continue;
- }
- if ($booDevice) {
- list($strKey, $strValue) = preg_split('/: /', $strLine, 2);
- if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) {
- $dev = new HWDevice();
- $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strValue)));
- $this->sys->setPciDevices($dev);
- }
- $booDevice = false;
+ if ($arrResults = Parser::lspci()) {
+ foreach ($arrResults as $dev) {
+ $this->sys->setPciDevices($dev);
+ }
+ } elseif (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
+ $booDevice = false;
+ $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($arrBuf as $strLine) {
+ if (preg_match('/^\s*Bus\s/', $strLine)) {
+ $booDevice = true;
+ continue;
+ }
+ if ($booDevice) {
+ $dev = new HWDevice();
+ $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strLine)));
+ $this->sys->setPciDevices($dev);
+/*
+ list($strKey, $strValue) = preg_split('/: /', $strLine, 2);
+ if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) {
+ $dev = new HWDevice();
+ $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strValue)));
+ $this->sys->setPciDevices($dev);
}
+*/
+ $booDevice = false;
}
}
} else {
- foreach ($arrResults as $dev) {
- $this->sys->setPciDevices($dev);
+ $pcidevices = CommonFunctions::findglob('/sys/bus/pci/devices/*/uevent', GLOB_NOSORT);
+ if (is_array($pcidevices) && (($total = count($pcidevices)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) {
+ if (CommonFunctions::rfts($pcidevices[$i], $buf, 0, 4096, false) && (trim($buf) != "")) {
+ $pcibuf = "";
+ if (preg_match("/^PCI_CLASS=(\S+)/m", trim($buf), $subbuf)) {
+ $pcibuf = "Class ".$subbuf[1].":";
+ }
+ if (preg_match("/^PCI_ID=(\S+)/m", trim($buf), $subbuf)) {
+ $pcibuf .= " Device ".$subbuf[1];
+ }
+ if (preg_match("/^DRIVER=(\S+)/m", trim($buf), $subbuf)) {
+ $pcibuf .= " Driver ".$subbuf[1];
+ }
+ $dev = new HWDevice();
+ if (trim($pcibuf) != "") {
+ $dev->setName(trim($pcibuf));
+ } else {
+ $dev->setName("unknown");
+ }
+ $this->sys->setPciDevices($dev);
+ }
+ }
+ } elseif (($dmesg = $this->_get_dmesg_c()) !== null) {
+ $arrBuf = preg_split("/\n/", $dmesg, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($arrBuf as $strLine) {
+ if (preg_match('/^[\s\[\]\.\d]*pci\s+\d\d\d\d:\d\d:\d\d.\d: (\[[^\]]+\].*)/', $strLine, $ar_buf)) {
+ $dev = new HWDevice();
+ $dev->setName(trim($ar_buf[1]));
+ $this->sys->setPciDevices($dev);
+ }
+ }
}
}
}
@@ -454,10 +1153,10 @@ class Linux extends OS
if (preg_match('/^hd/', $file)) {
$dev = new HWDevice();
$dev->setName(trim($file));
- if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
if (trim($buf) == 'disk') {
if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) {
- $dev->setCapacity(trim($buf) * 512 / 1024);
+ $dev->setCapacity(trim($buf) * 512);
}
}
}
@@ -476,22 +1175,45 @@ class Linux extends OS
*/
private function _scsi()
{
- $get_type = false;
+ $getline = 0;
$device = null;
+ $scsiid = null;
if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) {
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
- if (preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices)) {
- $get_type = true;
+ if (preg_match('/Host: scsi(\d+) Channel: (\d+) Target: (\d+) Lun: (\d+)/i', $buf, $scsiids)
+ || preg_match('/Host: scsi(\d+) Channel: (\d+) Id: (\d+) Lun: (\d+)/i', $buf, $scsiids)) {
+ $scsiid = $scsiids;
+ $getline = 1;
+ continue;
+ }
+ if ($getline == 1) {
+ preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices);
+ $getline = 2;
$device = $devices;
continue;
}
- if ($get_type) {
+ if ($getline == 2) {
preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
+
$dev = new HWDevice();
$dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')');
+
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && ($dev_type[1]==='Direct-Access')) {
+ $sizelist = CommonFunctions::findglob('/sys/bus/scsi/devices/'.intval($scsiid[1]).':'.intval($scsiid[2]).':'.intval($scsiid[3]).':'.intval($scsiid[4]).'/*/*/size', GLOB_NOSORT);
+ if (is_array($sizelist) && (($total = count($sizelist)) > 0)) {
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) {
+ if (CommonFunctions::rfts($sizelist[$i], $buf, 1, 4096, false) && (($buf=trim($buf)) != "") && ($buf > 0)) {
+ $dev->setCapacity($buf * 512);
+ break;
+ }
+ }
+ }
+ }
$this->sys->setScsiDevices($dev);
- $get_type = false;
+ $getline = 0;
}
}
}
@@ -500,47 +1222,161 @@ class Linux extends OS
/**
* USB devices
*
- * @return array
+ * @return void
*/
- private function _usb()
+ protected function _usb($bufu = null)
{
- $devnum = -1;
- if (!CommonFunctions::executeProgram('lsusb', '', $bufr, PSI_DEBUG)) {
- if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) {
+ $usbarray = array();
+ if ($nobufu = ($bufu === null)) {
+ if (CommonFunctions::executeProgram('lsusb', (PSI_OS != 'Android')?'':'2>/dev/null', $bufr, PSI_DEBUG && (PSI_OS != 'Android'), 5) && ($bufr !== "")) {
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
- if (preg_match('/^T/', $buf)) {
- $devnum += 1;
- $results[$devnum] = "";
- } elseif (preg_match('/^S:/', $buf)) {
- list($key, $value) = preg_split('/: /', $buf, 2);
- list($key, $value2) = preg_split('/=/', $value, 2);
- if (trim($key) != "SerialNumber") {
- $results[$devnum] .= " ".trim($value2);
+ $device = preg_split("/ /", $buf, 7);
+ if (((isset($device[6]) && trim($device[6]) != "")) ||
+ ((isset($device[5]) && trim($device[5]) != ""))) {
+ $usbid = intval($device[1]).'-'.intval(trim($device[3], ':')).' '.$device[5];
+ if ((isset($device[6]) && trim($device[6]) != "")) {
+ $usbarray[$usbid]['name'] = trim($device[6]);
+ } else {
+ $usbarray[$usbid]['name'] = 'unknown';
}
}
}
- foreach ($results as $var) {
- $dev = new HWDevice();
- $dev->setName($var);
- $this->sys->setUsbDevices($dev);
+ }
+
+ $usbdevices = CommonFunctions::findglob('/sys/bus/usb/devices/*/idProduct', GLOB_NOSORT);
+ if (is_array($usbdevices) && (($total = count($usbdevices)) > 0)) {
+ for ($i = 0; $i < $total; $i++) {
+ if (CommonFunctions::rfts($usbdevices[$i], $idproduct, 1, 4096, false) && (($idproduct=trim($idproduct)) != "")) { // is readable
+ $busnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/busnum');
+ $devnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/devnum');
+ $idvendor = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/idVendor');
+ if (($busnum!==null) && ($devnum!==null) && ($idvendor!==null)) {
+ $usbid = intval($busnum).'-'.intval($devnum).' '.$idvendor.':'.$idproduct;
+ $manufacturer = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/manufacturer');
+ if ($manufacturer!==null) {
+ $usbarray[$usbid]['manufacturer'] = $manufacturer;
+ }
+ $product = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/product');
+ if ($product!==null) {
+ $usbarray[$usbid]['product'] = $product;
+ }
+ $speed = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/speed');
+ if ($product!==null) {
+ $usbarray[$usbid]['speed'] = $speed;
+ }
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $serial = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/serial');
+ if (($serial!==null) && !preg_match('/\W/', $serial)) {
+ $usbarray[$usbid]['serial'] = $serial;
+ }
+ }
+ }
+ }
}
}
- } else {
+ }
+
+ if (!$nobufu || ((count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/usb/devices', $bufu, 0, 4096, false))) { // usb-devices
+ $devnum = -1;
+ $bufe = preg_split("/\n/", $bufu, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($bufe as $buf) {
+ if (preg_match('/^T/', $buf)) {
+ $devnum++;
+ if (preg_match('/\sSpd=([\d\.]+)/', $buf, $bufr)
+ && isset($bufr[1]) && ($bufr[1]!=="")) {
+ $usbarray[$devnum]['speed'] = $bufr[1];
+ }
+ } elseif (preg_match('/^S:/', $buf)) {
+ list($key, $value) = preg_split('/: /', $buf, 2);
+ list($key, $value2) = preg_split('/=/', $value, 2);
+ switch (trim($key)) {
+ case 'Manufacturer':
+ $usbarray[$devnum]['manufacturer'] = trim($value2);
+ break;
+ case 'Product':
+ $usbarray[$devnum]['product'] = trim($value2);
+ break;
+ case 'SerialNumber':
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
+ && !preg_match('/\W/', trim($value2))) {
+ $usbarray[$devnum]['serial'] = trim($value2);
+ }
+ }
+ }
+ }
+ }
+
+ if ($nobufu && (count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/input/devices', $bufr, 0, 4096, false)) {
+ $devnam = "unknown";
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
- $device = preg_split("/ /", $buf, 7);
- if (isset($device[6]) && trim($device[6]) != "") {
- $dev = new HWDevice();
- $dev->setName(trim($device[6]));
- $this->sys->setUsbDevices($dev);
- } elseif (isset($device[5]) && trim($device[5]) != "") {
- $dev = new HWDevice();
- $dev->setName("unknown");
- $this->sys->setUsbDevices($dev);
+ if (preg_match('/^I:\s+(.+)/', $buf, $bufr)
+ && isset($bufr[1]) && (trim($bufr[1])!=="")) {
+ $devnam = trim($bufr[1]);
+ $usbarray[$devnam]['phys'] = 'unknown';
+ } elseif (preg_match('/^N:\s+Name="([^"]+)"/', $buf, $bufr2)
+ && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
+ $usbarray[$devnam]['name'] = trim($bufr2[1]);
+ } elseif (preg_match('/^P:\s+Phys=(.*)/', $buf, $bufr2)
+ && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
+ $usbarray[$devnam]['phys'] = trim($bufr2[1]);
+ } elseif (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
+ && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
+ && preg_match('/^U:\s+Uniq=(.+)/', $buf, $bufr2)
+ && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
+ $usbarray[$devnam]['serial'] = trim($bufr2[1]);
}
}
}
+
+ foreach ($usbarray as $usbdev) if (!isset($usbdev['phys']) || preg_match('/^usb-/', $usbdev['phys'])) {
+ $dev = new HWDevice();
+
+ if (isset($usbdev['manufacturer']) && (($manufacturer=$usbdev['manufacturer']) !== 'no manufacturer')) {
+ if (preg_match("/^linux\s/i", $manufacturer)) {
+ $manufacturer = 'Linux Foundation';
+ }
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setManufacturer($manufacturer);
+ }
+ } else {
+ $manufacturer = '';
+ }
+
+ if (isset($usbdev['product'])) {
+ $product = $usbdev['product'];
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setProduct($product);
+ }
+ } else {
+ $product = '';
+ }
+
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($usbdev['speed'])) {
+ $dev->setSpeed($usbdev['speed']);
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
+ && isset($usbdev['serial'])) {
+ $dev->setSerial($usbdev['serial']);
+ }
+ }
+
+ if (isset($usbdev['name']) && (($name=$usbdev['name']) !== 'unknown')) {
+ $dev->setName($name);
+ } else {
+ if (($newname = trim($manufacturer.' '.$product)) !== '') {
+ $dev->setName($newname);
+ } else {
+ $dev->setName('unknown');
+ }
+ }
+
+ $this->sys->setUsbDevices($dev);
+ }
}
/**
@@ -550,17 +1386,92 @@ class Linux extends OS
*/
protected function _i2c()
{
- $i2cdevices = glob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT);
- if (($total = count($i2cdevices)) > 0) {
+ $i2cdevices = CommonFunctions::findglob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT);
+ if (is_array($i2cdevices) && (($total = count($i2cdevices)) > 0)) {
$buf = "";
for ($i = 0; $i < $total; $i++) {
- if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false)) {
- if (trim($buf) != "") {
+ if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false) && (trim($buf) != "")) {
+ $dev = new HWDevice();
+ $dev->setName(trim($buf, ": \n\r\t\v\x00"));
+ $this->sys->setI2cDevices($dev);
+ }
+ }
+ }
+ }
+
+ /**
+ * NVMe devices
+ *
+ * @return void
+ */
+ protected function _nvme()
+ {
+ if (CommonFunctions::executeProgram('nvme', 'list', $bufr, PSI_DEBUG) && ($bufr!="")) {
+ $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ $count = 0;
+ $nlocate = array();
+ $nsize = array();
+ foreach ($bufe as $buf) {
+ if ($count == 1) {
+ $locid = 0;
+ $nlocate[0] = 0;
+ $total = strlen($buf);
+ $begin = true;
+ for ($i = 0; $i < $total; $i++) {
+ if ($begin) {
+ if ($buf[$i] !== '-') {
+ $nsize[$locid] = $i - $nlocate[$locid];
+ $locid++;
+ $begin = false;
+ }
+ } else {
+ if ($buf[$i] === '-') {
+ $nlocate[$locid] = $i;
+ $begin = true;
+ }
+ }
+ }
+ if ($begin) {
+ $nsize[$locid] = $i - $nlocate[$locid];
+ }
+ } elseif ($count > 1) {
+ if (isset($nlocate[2]) && isset($nsize[2]) && (($nvname=trim(substr($buf, $nlocate[2], $nsize[2]))) !== '')) {
$dev = new HWDevice();
- $dev->setName(trim($buf));
- $this->sys->setI2cDevices($dev);
+ $dev->setName($nvname);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && (PSI_SHOW_DEVICES_INFOS)) {
+ if (isset($nlocate[4]) && isset($nsize[4])) {
+ if (preg_match('/\/\s*([0-9\.]+)\s*(B|KB|MB|GB|TB|PB)$/', str_replace(',', '.', trim(substr($buf, $nlocate[4], $nsize[4]))), $tmpbuf)) {
+ switch ($tmpbuf[2]) {
+ case 'B':
+ $dev->setCapacity($tmpbuf[1]);
+ break;
+ case 'KB':
+ $dev->setCapacity(1000*$tmpbuf[1]);
+ break;
+ case 'MB':
+ $dev->setCapacity(1000*1000*$tmpbuf[1]);
+ break;
+ case 'GB':
+ $dev->setCapacity(1000*1000*1000*$tmpbuf[1]);
+ break;
+ case 'TB':
+ $dev->setCapacity(1000*1000*1000*1000*$tmpbuf[1]);
+ break;
+ case 'PB':
+ $dev->setCapacity(1000*1000*1000*1000*1000*$tmpbuf[1]);
+ }
+ }
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ if (isset($nlocate[1]) && isset($nsize[1])) {
+ $dev->setSerial(trim(substr($buf, $nlocate[1], $nsize[1])));
+ }
+ }
+ }
+ $this->sys->setNvmeDevices($dev);
}
}
+ $count++;
}
}
}
@@ -571,9 +1482,9 @@ class Linux extends OS
*
* @return void
*/
- protected function _network()
+ protected function _network($bufr = null)
{
- if (CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) {
+ if (($bufr === null) && CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) {
$bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
if (preg_match('/:/', $buf)) {
@@ -585,54 +1496,232 @@ class Linux extends OS
$dev->setTxBytes($stats[8]);
$dev->setErrors($stats[2] + $stats[10]);
$dev->setDrops($stats[3] + $stats[11]);
- if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG))) {
- $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($bufe2 as $buf2) {
-// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
- if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
- || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2)
- || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)) {
- if ($ar_buf2[1] != $ar_buf2[2]) {
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
- } else {
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ if (((defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) || (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE))
+ && CommonFunctions::executeProgram('ip', 'addr show '.trim($dev_name), $bufr2, PSI_DEBUG) && (trim($bufr2)!="")) {
+ if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE && preg_match("/^\d+:\s+([^\s:@]+).+\s+master\s+(\S+)/", $bufr2, $brbufr)) {
+ $dev->setBridge($brbufr[2]);
+ }
+ } else {
+ $bufr2 = "";
+ }
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ $macaddr = "";
+ if (($bufr2!="") || CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG)) {
+ $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($bufe2 as $buf2) {
+// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
+ if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
+ || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
+ $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
+ if (($macaddr === '00-00-00-00-00-00') || ($macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') || ($macaddr === '--') || ($macaddr === '0.0.0.0')) { // empty
+ $macaddr = "";
+ }
}
- } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2)
- || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)
- || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2)
- || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2)
- || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $buf2, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2)
+ /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $buf2, $ar_buf2)*/) {
+ if ($ar_buf2[1] != $ar_buf2[2]) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
+ } else {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ }
+ } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)
+ || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $buf2, $ar_buf2))
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ }
+ }
+ }
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ if ((!CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
+ (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
+ if ($speed > 1000) {
+ $speed = $speed/1000;
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s '.$duplex);
+ } else {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s');
+ }
}
}
$this->sys->setNetDevices($dev);
}
}
- } elseif (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) {
+ } elseif (($bufr === null) && CommonFunctions::executeProgram('ip', 'addr show', $bufr, PSI_DEBUG) && ($bufr!="")) {
$lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
- $notwas = true;
+ $was = false;
+ $macaddr = "";
+ $speedinfo = "";
+ $dev = null;
foreach ($lines as $line) {
- if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
- if (!$notwas) {
+ if (preg_match("/^\d+:\s+([^\s:@]+)(.*)/", $line, $ar_buf)) {
+ if ($was) {
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ if ($speedinfo != "") {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
+ $this->sys->setNetDevices($dev);
+ }
+ $speedinfo = "";
+ $macaddr = "";
+ $dev = new NetDevice();
+ $dev->setName($ar_buf[1]);
+ if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE
+ && isset($ar_buf[2]) && (($ar_buf[2] = trim($ar_buf[2])) !=="") && preg_match("/\s+master\s+(\S+)/", $ar_buf[2], $bufr2)) {
+ $dev->setBridge($bufr2[1]);
+ }
+ if (CommonFunctions::executeProgram('ip', '-s link show '.$ar_buf[1], $bufr2, false) && ($bufr2!="")
+ && preg_match("/\n\s+RX:\s[^\n]+\n\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)[^\n]+\n\s+TX:\s[^\n]+\n\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)/m", $bufr2, $ar_buf2)) {
+ $dev->setRxBytes($ar_buf2[1]);
+ $dev->setTxBytes($ar_buf2[4]);
+ $dev->setErrors($ar_buf2[2]+$ar_buf2[5]);
+ $dev->setDrops($ar_buf2[3]+$ar_buf2[6]);
+ } elseif (CommonFunctions::executeProgram('ifconfig', $ar_buf[1], $bufr2, false) && ($bufr2!="")) {
+ if (preg_match('/\sRX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) {
+ $dev->setRxBytes($ar_buf2[1]);
+ }
+ if (preg_match('/\sTX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) {
+ $dev->setTxBytes($ar_buf2[1]);
+ }
+ $errors = 0;
+ $drops = 0;
+ if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) {
+ $errors +=$ar_buf2[1];
+ $drops +=$ar_buf2[2];
+ }
+ if (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) {
+ $errors +=$ar_buf2[1];
+ $drops +=$ar_buf2[2];
+ }
$dev->setErrors($errors);
$dev->setDrops($drops);
+ }
+ $was = true;
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
+ (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
+ if ($speed > 1000) {
+ $speed = $speed/1000;
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
+ $speedinfo = $speed.$unit.'b/s '.$duplex;
+ } else {
+ $speedinfo = $speed.$unit.'b/s';
+ }
+ }
+ }
+ } else {
+ if ($was) {
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ if (preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $line, $ar_buf2)
+ || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $line, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
+ $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
+ if (($macaddr === '00-00-00-00-00-00') || ($macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00') || ($macaddr === '--') || ($macaddr === '0.0.0.0')) { // empty
+ $macaddr = "";
+ }
+ }
+ } elseif (preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)
+ /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $line, $ar_buf2)*/) {
+ if ($ar_buf2[1] != $ar_buf2[2]) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
+ } else {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ }
+ } elseif (preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ }
+ }
+ }
+ }
+ }
+ if ($was) {
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ if ($speedinfo != "") {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
+ $this->sys->setNetDevices($dev);
+ }
+ } elseif (($bufr !== null) || CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) {
+ $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ $was = false;
+ $errors = 0;
+ $drops = 0;
+ $macaddr = "";
+ $speedinfo = "";
+ $dev = null;
+ foreach ($lines as $line) {
+ if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
+ if ($was) {
+ $dev->setErrors($errors);
+ $dev->setDrops($drops);
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ if ($speedinfo != "") {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
$this->sys->setNetDevices($dev);
}
$errors = 0;
$drops = 0;
+ $speedinfo = "";
+ $macaddr = "";
$dev = new NetDevice();
$dev->setName($ar_buf[1]);
- $notwas = false;
+ $was = true;
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
- if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2))
+ if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
+ (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
+ if ($speed > 1000) {
+ $speed = $speed/1000;
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
+ $speedinfo = $speed.$unit.'b/s '.$duplex;
+ } else {
+ $speedinfo = $speed.$unit.'b/s';
+ }
+ }
+ if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)
+ || preg_match('/^'.$ar_buf[1].'\s+Link\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $line, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
+ $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
+ if ($macaddr === '00-00-00-00-00-00') { // empty
+ $macaddr = "";
+ }
+ }
+ } elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2))
$dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
}
} else {
- if (!$notwas) {
+ if ($was) {
if (preg_match('/\sRX bytes:(\d+)\s/i', $line, $ar_buf2)) {
$dev->setRxBytes($ar_buf2[1]);
}
@@ -650,28 +1739,42 @@ class Linux extends OS
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)
- || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2)
- || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) {
- if ($ar_buf2[1] != $ar_buf2[2]) {
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
- } else {
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $line, $ar_buf2)
+ || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
+ $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
+ if ($macaddr === '00-00-00-00-00-00') { // empty
+ $macaddr = "";
}
- } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2)
+ }
+ } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2)
+ || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) {
+ if ($ar_buf2[1] != $ar_buf2[2]) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
+ } else {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ }
+ } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2)
|| preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2)
- || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2)
- || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $line, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
-
+ || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2)
+ || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $line, $ar_buf2)
+ || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $line, $ar_buf2))
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ }
}
}
}
}
- if (!$notwas) {
+ if ($was) {
$dev->setErrors($errors);
$dev->setDrops($drops);
+ if ($macaddr != "") {
+ $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
+ }
+ if ($speedinfo != "") {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
$this->sys->setNetDevices($dev);
}
}
@@ -682,27 +1785,33 @@ class Linux extends OS
*
* @return void
*/
- protected function _memory()
+ protected function _memory($mbuf = null, $sbuf = null)
{
- if (CommonFunctions::rfts('/proc/meminfo', $mbuf)) {
+ if (($mbuf !== null) || CommonFunctions::rfts('/proc/meminfo', $mbuf)) {
+ $swaptotal = null;
+ $swapfree = null;
$bufe = preg_split("/\n/", $mbuf, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe as $buf) {
- if (preg_match('/^MemTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+ if (preg_match('/^MemTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
$this->sys->setMemTotal($ar_buf[1] * 1024);
- } elseif (preg_match('/^MemFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+ } elseif (preg_match('/^MemFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
$this->sys->setMemFree($ar_buf[1] * 1024);
- } elseif (preg_match('/^Cached:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+ } elseif (preg_match('/^Cached:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
$this->sys->setMemCache($ar_buf[1] * 1024);
- } elseif (preg_match('/^Buffers:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
+ } elseif (preg_match('/^Buffers:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
$this->sys->setMemBuffer($ar_buf[1] * 1024);
+ } elseif (preg_match('/^SwapTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
+ $swaptotal = $ar_buf[1] * 1024;
+ } elseif (preg_match('/^SwapFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
+ $swapfree = $ar_buf[1] * 1024;
}
}
$this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
// values for splitting memory usage
- if ($this->sys->getMemCache() !== null && $this->sys->getMemBuffer() !== null) {
+ if (($this->sys->getMemCache() !== null) && ($this->sys->getMemBuffer() !== null)) {
$this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer());
}
- if (CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) {
+ if (($sbuf !== null) || CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) {
$swaps = preg_split("/\n/", $sbuf, -1, PREG_SPLIT_NO_EMPTY);
unset($swaps[0]);
foreach ($swaps as $swap) {
@@ -715,6 +1824,13 @@ class Linux extends OS
$dev->setFree($dev->getTotal() - $dev->getUsed());
$this->sys->setSwapDevices($dev);
}
+ } elseif (($swaptotal !== null) && ($swapfree !== null) && ($swaptotal > 0)) {
+ $dev = new DiskDevice();
+ $dev->setName("SWAP");
+ $dev->setTotal($swaptotal);
+ $dev->setFree($swapfree);
+ $dev->setUsed($dev->getTotal() - $dev->getFree());
+ $this->sys->setSwapDevices($dev);
}
}
}
@@ -724,7 +1840,7 @@ class Linux extends OS
*
* @return void
*/
- private function _filesystems()
+ protected function _filesystems()
{
$df_args = "";
$hideFstypes = array();
@@ -739,7 +1855,7 @@ class Linux extends OS
$df_args .= "-x $Fstype ";
}
if ($df_args !== "") {
- $df_args = trim($df_args); //trim spaces
+ $df_args = trim($df_args); // trim spaces
$arrResult = Parser::df("-P $df_args 2>/dev/null");
} else {
$arrResult = Parser::df("-P 2>/dev/null");
@@ -754,60 +1870,120 @@ class Linux extends OS
*
* @return void
*/
- private function _distro()
+ protected function _distro()
{
$this->sys->setDistribution("Linux");
- $list = @parse_ini_file(APP_ROOT."/data/distros.ini", true);
+ $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true);
if (!$list) {
return;
}
+ $_ignore_lsb_release = false;
+ $_Distrib = "";
+ $_DistribIcon = "";
// We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown
- if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && (strlen(trim($distro_info)) > 0)) {
- $distro_tmp = preg_split("/\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY);
+ if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && strlen($distro_info) > 0) {
+ $distro_tmp = preg_split("/\r?\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY);
foreach ($distro_tmp as $info) {
$info_tmp = preg_split('/:/', $info, 2);
- if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "") &&
- isset($distro_tmp[1]) && !is_null($distro_tmp[1]) && (trim($distro_tmp[1]) != "")) {
+ if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "") &&
+ isset($distro_tmp[1]) && ($distro_tmp[1] !== null) && (trim($distro_tmp[1]) != "")) {
$distro[trim($info_tmp[0])] = trim($info_tmp[1]);
}
}
+
if (!isset($distro['Distributor ID']) && !isset($distro['Description'])) { // Systems like StartOS
- if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "")) {
- $this->sys->setDistribution(trim($distro_tmp[0]));
+ if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "")) {
+ $_Distrib = trim($distro_tmp[0]);
if (preg_match('/^(\S+)\s*/', $distro_tmp[0], $id_buf)
- && isset($list[trim($id_buf[1])]['Image'])) {
- $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
+ && isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
+ $_DistribIcon = $list[strtolower(trim($id_buf[1]))]['Image'];
+ // set ignore lsb_release for some distributions
+ if (isset($list[strtolower(trim($id_buf[1]))]['Test']) && ($list[strtolower(trim($id_buf[1]))]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
}
}
} else {
- if (isset($distro['Description'])
- && preg_match('/^NAME=\s*(.+)\s*$/', $distro['Description'], $name_tmp)) {
- $distro['Description'] = $name_tmp[1];
+ if (isset($distro['Description'])) {
+ if (preg_match('/^NAME=\s*"?([^"\r\n]+)"?\s*$/', $distro['Description'], $name_tmp)) {
+ $distro['Description'] = trim($name_tmp[1]);
+ } elseif (($distro['Description']==="Rolling Release") && isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) {
+ $distro['Description'] = $distro['Distributor ID']." ".$distro['Description'];
+ }
}
if (isset($distro['Description'])
&& ($distro['Description'] != "n/a")
- && !isset($distro['Distributor ID'])) {
- $this->sys->setDistribution($distro['Description']);
- } elseif (isset($distro['Description'])
- && ($distro['Description'] != "n/a")
- && isset($distro['Distributor ID'])
- && ($distro['Distributor ID'] != "n/a")
- && ($distro['Description'] != $distro['Distributor ID'])) {
- $this->sys->setDistribution($distro['Description']);
- } elseif (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) {
- $this->sys->setDistribution($distro['Distributor ID']);
- if (isset($distro['Release']) && ($distro['Release'] != "n/a")) {
- $this->sys->setDistribution($this->sys->getDistribution()." ".$distro['Release']);
+ && (!isset($distro['Distributor ID'])
+ || (($distro['Distributor ID'] != "n/a")
+ && ($distro['Description'] != $distro['Distributor ID'])))) {
+ $_Distrib = $distro['Description'];
+ if (isset($distro['Release']) && ($distro['Release'] != "n/a")
+ && ($distro['Release'] != $distro['Description']) && strstr($distro['Release'], ".")){
+ if (preg_match("/^(\d+)\.[0]+$/", $distro['Release'], $match_buf)) {
+ $tofind = $match_buf[1];
+ } else {
+ $tofind = $distro['Release'];
+ }
+ if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", $distro['Description'])) {
+ $_Distrib .= " ".$distro['Release'];
+ }
}
- if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) {
- $this->sys->setDistribution($this->sys->getDistribution()." (".$distro['Codename'].")");
+ } elseif (isset($distro['Distributor ID'])) {
+ if ($distro['Distributor ID'] != "n/a") {
+ $_Distrib = $distro['Distributor ID'];
+ if (isset($distro['Release']) && ($distro['Release'] != "n/a")) {
+ $_Distrib .= " ".$distro['Release'];
+ }
+ if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) {
+ $_Distrib .= " (".$distro['Codename'].")";
+ }
+ } elseif (isset($distro['Description']) && ($distro['Description'] != "n/a")) {
+ $_Distrib = $distro['Description'];
}
}
- if (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a") && isset($list[$distro['Distributor ID']]['Image'])) {
- $this->sys->setDistributionIcon($list[$distro['Distributor ID']]['Image']);
+ if (isset($distro['Distributor ID'])) {
+ $distrib = $distro['Distributor ID'];
+ $distrib2 = $distrib;
+ $distrib3 = $distrib;
+ if (isset($distro['Description'])) {
+ $distarr = preg_split("/\s/", $distro['Description'], -1, PREG_SPLIT_NO_EMPTY);
+ if (isset($distarr[0])) {
+ if ($distrib != "n/a") {
+ $distrib2 .= ' '.$distarr[0];
+ } else {
+ $distrib2 = $distarr[0];
+ }
+ }
+ if (isset($distarr[1])) {
+ if ($distrib != "n/a") {
+ $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
+ } else {
+ $distrib3 = $distarr[0].' '.$distarr[1];
+ }
+ }
+ }
+ if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
+ $_DistribIcon = $list[strtolower($distrib3)]['Image'];
+ // set ignore lsb_release for some distributions
+ if (isset($list[strtolower($distrib3)]['Test']) && ($list[strtolower($distrib3)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
+ } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
+ $_DistribIcon = $list[strtolower($distrib2)]['Image'];
+ // set ignore lsb_release for some distributions
+ if (isset($list[strtolower($distrib2)]['Test']) && ($list[strtolower($distrib2)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
+ } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
+ $_DistribIcon = $list[strtolower($distrib)]['Image'];
+ // set ignore lsb_release for some distributions
+ if (isset($list[strtolower($distrib)]['Test']) && ($list[strtolower($distrib)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
+ }
}
}
- } else {
+ }
+
+ if (!$_ignore_lsb_release) { // don't ignore lsb_release
+ if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib));
+ if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon);
+ }
+
+ // if the distribution is still unknown
+ if ($this->sys->getDistribution() == "Linux") {
/* default error handler */
if (function_exists('errorHandlerPsi')) {
restore_error_handler();
@@ -819,25 +1995,56 @@ class Linux extends OS
// Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release
if (CommonFunctions::fileexists($filename="/etc/lsb-release")
&& CommonFunctions::rfts($filename, $buf, 0, 4096, false)
- && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) {
- if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf)
+ && (preg_match('/^DISTRIB_ID="?([^"\r\n]+)/m', $buf, $id_buf) || preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $id_buf))) {
+ if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf)
&& (trim($desc_buf[1])!=trim($id_buf[1]))) {
- $this->sys->setDistribution(trim($desc_buf[1]));
+ if ($desc_buf[1]==="Rolling Release") {
+ $desc_buf[1] = $id_buf[1]." ".$desc_buf[1];
+ }
+ $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
+ if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf)
+ && (trim($vers_buf[1])!=trim($desc_buf[1])) && strstr($vers_buf[1], ".")){
+ if (preg_match("/^(\d+)\.[0]+$/", trim($vers_buf[1]), $match_buf)) {
+ $tofind = $match_buf[1];
+ } else {
+ $tofind = trim($vers_buf[1]);
+ }
+ if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", trim($desc_buf[1]))) {
+ $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
+ }
+ }
+ $distrib = trim($id_buf[1]);
+ $distrib2 = $distrib;
+ $distrib3 = $distrib;
+ $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY);
+ if (isset($distarr[0])) {
+ $distrib2 .= ' '.$distarr[0];
+ }
+ if (isset($distarr[1])) {
+ $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
+ }
+ if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']);
+ } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']);
+ } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
+ }
} else {
- if (isset($list[trim($id_buf[1])]['Name'])) {
- $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
+ if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
+ $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name']));
} else {
$this->sys->setDistribution(trim($id_buf[1]));
}
- if (preg_match('/^DISTRIB_RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) {
+ if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf)) {
$this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
}
- if (preg_match('/^DISTRIB_CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) {
+ if (preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) {
$this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
}
- }
- if (isset($list[trim($id_buf[1])]['Image'])) {
- $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
+ if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']);
+ }
}
} else { // otherwise find files specific for distribution
foreach ($list as $section=>$distribution) {
@@ -852,29 +2059,37 @@ class Linux extends OS
} elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="execute")) {
if (!CommonFunctions::executeProgram($filename, '2>/dev/null', $buf, PSI_DEBUG)) {
$buf = "";
+ } elseif (preg_match('/^pve-manager\/([\d.]+)\//', $buf, $vers_buf)) { // Proxmox version
+ $buf = $vers_buf[1];
}
} else {
if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
$buf = "";
+ if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) {
+ break;
+ }
} elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) {
- if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf)
+ if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf)
&& isset($list[trim($id_buf[1])]['Image'])) {
$distro = $list[trim($id_buf[1])];
}
}
}
+ if (($buf !== null) && (trim($buf) !== "")) {
+ $buf = preg_replace("/ - Version:| Build:| Release| version| build/i", "", $buf);
+ }
if (isset($distro['Image'])) {
$this->sys->setDistributionIcon($distro['Image']);
}
if (isset($distribution['Name'])) {
- if (is_null($buf) || (trim($buf) == "")) {
+ if (($buf === null) || (trim($buf) == "")) {
$this->sys->setDistribution($distribution['Name']);
} else {
$this->sys->setDistribution($distribution['Name']." ".trim($buf));
}
} else {
- if (is_null($buf) || (trim($buf) == "")) {
- $this->sys->setDistribution($section);
+ if (($buf === null) || (trim($buf) == "")) {
+ $this->sys->setDistribution(preg_replace('/linux/', 'Linux', ucwords($section)));
} else {
$this->sys->setDistribution(trim($buf));
}
@@ -882,22 +2097,45 @@ class Linux extends OS
if (isset($distribution['Files2'])) {
foreach (preg_split("/;/", $distribution['Files2'], -1, PREG_SPLIT_NO_EMPTY) as $filename2) {
if (CommonFunctions::fileexists($filename2) && CommonFunctions::rfts($filename2, $buf, 0, 4096, false)) {
- if (preg_match('/^majorversion="?([^"\n]+)"?/m', $buf, $maj_buf)
- && preg_match('/^minorversion="?([^"\n]+)"?/m', $buf, $min_buf)) {
+ if (preg_match('/^majorversion="?([^"\r\n]+)/m', $buf, $maj_buf)
+ && preg_match('/^minorversion="?([^"\r\n]+)/m', $buf, $min_buf)) {
$distr2=$maj_buf[1].'.'.$min_buf[1];
- if (preg_match('/^buildphase="?([^"\n]+)"?/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) {
+ if (preg_match('/^buildphase="?([^"\r\n]+)/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) {
$distr2.='.'.$pha_buf[1];
}
- if (preg_match('/^buildnumber="?([^"\n]+)"?/m', $buf, $num_buf)) {
+ if (preg_match('/^buildnumber="?([^"\r\n]+)/m', $buf, $num_buf)) {
$distr2.='-'.$num_buf[1];
}
- if (preg_match('/^builddate="?([^"\n]+)"?/m', $buf, $dat_buf)) {
+ if (preg_match('/^builddate="?([^"\r\n]+)/m', $buf, $dat_buf)) {
$distr2.=' ('.$dat_buf[1].')';
}
$this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
+ } elseif (preg_match('/^elive-codename:\s*([^\r\n]+)/m', $buf, $cod_buf)
+ && preg_match('/^elive-version:\s*([^\r\n]+)/m', $buf, $ver_buf)) {
+ $this->sys->setDistribution($this->sys->getDistribution()." ".trim($cod_buf[1])." ".trim($ver_buf[1]));
+ } elseif (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/im', $buf, $vers_buf)
+ || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) {
+ $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
+ } elseif (preg_match('/^DISTRIB_ID=[\'"]?([^\'"\r\n]+)/m', $buf, $id_buf)) {
+ if (preg_match('/^DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf)
+ && (trim($desc_buf[1])!=trim($id_buf[1]))) {
+ $this->sys->setDistribution(trim($desc_buf[1]));
+ } else {
+ if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
+ $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name']));
+ } else {
+ $this->sys->setDistribution(trim($id_buf[1]));
+ }
+ if (preg_match('/^RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf) || preg_match('/^DISTRIB_RELEASE=[\'"]?([^\'"\r\n]+)/m', $buf, $vers_buf)) {
+ $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
+ }
+ if (preg_match('/^CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) {
+ $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
+ }
+ }
} else {
$distr2=trim(substr($buf, 0, strpos($buf, "\n")));
- if (!is_null($distr2) && ($distr2 != "")) {
+ if (($distr2 !== null) && ($distr2 != "")) {
$this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
}
}
@@ -913,116 +2151,171 @@ class Linux extends OS
}
// if the distribution is still unknown
if ($this->sys->getDistribution() == "Linux") {
- if (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS")
- && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
- && preg_match('/^DISTRO_NAME=\'(.+)\'/m', $buf, $id_buf)) {
- if (isset($list[trim($id_buf[1])]['Name'])) {
- $dist = trim($list[trim($id_buf[1])]['Name']);
- } else {
- $dist = trim($id_buf[1]);
- }
- if (preg_match('/^DISTRO_VERSION=(.+)/m', $buf, $vers_buf)) {
- $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1])));
- } else {
- $this->sys->setDistribution($dist);
- }
- if (isset($list[trim($id_buf[1])]['Image'])) {
- $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
- } else {
- if (isset($list['Puppy']['Image'])) {
- $this->sys->setDistributionIcon($list['Puppy']['Image']);
- }
- }
- } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release")
- && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
- && !is_null($buf) && (trim($buf) != ""))
- || (CommonFunctions::fileexists($filename="/etc/system-release")
- && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
- && !is_null($buf) && (trim($buf) != ""))) {
- $this->sys->setDistribution(trim($buf));
- if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf)
- && isset($list[trim($id_buf[1])]['Image'])) {
- $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
- }
- } elseif (CommonFunctions::fileexists($filename="/etc/solydxk/info")
- && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
- && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) {
- if (preg_match('/^DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf)
- && (trim($desc_buf[1])!=trim($id_buf[1]))) {
- $this->sys->setDistribution(trim($desc_buf[1]));
- } else {
- if (isset($list[trim($id_buf[1])]['Name'])) {
- $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
- } else {
- $this->sys->setDistribution(trim($id_buf[1]));
- }
- if (preg_match('/^RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) {
- $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
- }
- if (preg_match('/^CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) {
- $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
- }
- }
- if (isset($list[trim($id_buf[1])]['Image'])) {
- $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
- } else {
- $this->sys->setDistributionIcon($list['SolydXK']['Image']);
- }
- } elseif (CommonFunctions::fileexists($filename="/etc/os-release")
- && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
- && (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)
- || preg_match('/^NAME="?([^"\n]+)"?/m', $buf, $id_buf))) {
- if (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)) {
- if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)) {
+ if ($_ignore_lsb_release) { // if lsb_release was ignored
+ if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib));
+ if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon);
+ }
+ }
+ // if the distribution is still unknown
+ if ($this->sys->getDistribution() == "Linux") {
+ if (((defined('PSI_EMU_PORT') && CommonFunctions::executeProgram('cat', '/etc/os-release', $buf, false))
+ || (!defined('PSI_EMU_PORT') && CommonFunctions::fileexists($filename="/etc/os-release") && CommonFunctions::rfts($filename, $buf, 0, 4096, false)))
+ && (preg_match('/^TAILS_VERSION_ID="?([^"\r\n]+)/m', $buf, $tid_buf) || preg_match('/^NAME=["\']?([^"\'\r\n]+)/m', $buf, $id_buf) || preg_match('/^DISTRIB_ID=["\']?([^"\'\r\n]+)/m', $buf, $id_buf))) {
+ if (preg_match('/^TAILS_VERSION_ID="?([^"\r\n]+)/m', $buf, $tid_buf)) {
+ if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\r\n]+)/m', $buf, $desc_buf)) {
$this->sys->setDistribution(trim($desc_buf[1])." ".trim($tid_buf[1]));
} else {
- if (isset($list['Tails']['Name'])) {
- $this->sys->setDistribution(trim($list['Tails']['Name'])." ".trim($tid_buf[1]));
+ if (isset($list['tails']['Name'])) {
+ $this->sys->setDistribution(trim($list['tails']['Name'])." ".trim($tid_buf[1]));
} else {
$this->sys->setDistribution('Tails'." ".trim($tid_buf[1]));
}
}
- $this->sys->setDistributionIcon($list['Tails']['Image']);
+ $this->sys->setDistributionIcon($list['tails']['Image']);
} else {
- if (preg_match('/^PRETTY_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)
- && !preg_match('/\$/', $desc_buf[1])) { //if is not defined by variable
- $this->sys->setDistribution(trim($desc_buf[1]));
- } else {
- if (isset($list[trim($id_buf[1])]['Name'])) {
- $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
+ $addversion = false;
+ $distrib = trim($id_buf[1]);
+ if (preg_match('/^PRETTY_NAME=["\']?([^"\'\r\n]+)/m', $buf, $desc_buf)
+ && !preg_match('/\$/', $desc_buf[1]) // if is not defined by variable
+ && ($distrib!==trim($desc_buf[1]))) {
+ if (isset($list[strtolower($distrib)]['Name']) && !preg_match("/".$list[strtolower($distrib)]['Name']."/i", trim($desc_buf[1]))) {
+ $this->sys->setDistribution($list[strtolower($distrib)]['Name'] ." ". preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
} else {
- $this->sys->setDistribution(trim($id_buf[1]));
+ $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
}
- if (preg_match('/^VERSION="?([^"\n]+)"?/m', $buf, $vers_buf)) {
- $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
- } elseif (preg_match('/^VERSION_ID="?([^"\n]+)"?/m', $buf, $vers_buf)) {
+ $distrib2 = $distrib;
+ $distrib3 = $distrib;
+ $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY);
+ if (isset($distarr[0])) {
+ $distrib2 .= ' '.$distarr[0];
+ }
+ if (isset($distarr[1])) {
+ $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
+ }
+ if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']);
+ if (count($distarr) == 2) {
+ $addversion = true;
+ }
+ } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']);
+ if (count($distarr) == 1) {
+ $addversion = true;
+ }
+ } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
+ }
+ } else {
+ if (isset($list[strtolower($distrib)]['Name'])) {
+ $this->sys->setDistribution(trim($list[strtolower($distrib)]['Name']));
+ } else {
+ $this->sys->setDistribution($distrib);
+ }
+ if (isset($list[strtolower($distrib)]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
+ }
+ $addversion = true;
+ }
+ if ($addversion) {
+ if (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
+ || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
+ || preg_match('/^DISTRIB_RELEASE=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
+ || preg_match('/^IMAGE_VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) {
$this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
}
+ if (!strstr($this->sys->getDistribution(), "(") && (preg_match('/^VERSION_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)
+ || preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf))) {
+ $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
+ }
}
- if (isset($list[trim($id_buf[1])]['Image'])) {
+ }
+ } elseif (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS")
+ && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
+ && preg_match('/^DISTRO_NAME=["\']([^"\']+)/m', $buf, $id_buf)) {
+ if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
+ $dist = trim($list[strtolower(trim($id_buf[1]))]['Name']);
+ } else {
+ $dist = trim($id_buf[1]);
+ }
+ if (preg_match('/^DISTRO_VERSION=([^$#\n\r]+)/m', $buf, $vers_buf)) {
+ $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1])));
+ } else {
+ $this->sys->setDistribution($dist);
+ }
+ if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
+ $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']);
+ } else {
+ if (isset($list['puppy']['Image'])) {
+ $this->sys->setDistributionIcon($list['puppy']['Image']);
+ if (!preg_match("/puppy/i", $dist = $this->sys->getDistribution())) {
+ $this->sys->setDistribution("Puppy ".$dist);
+ }
+ }
+ }
+ } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release")
+ && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
+ && ($buf !== null) && (trim($buf) != ""))
+ || (CommonFunctions::fileexists($filename="/etc/system-release")
+ && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
+ && ($buf !== null) && (trim($buf) != ""))) {
+ $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($buf)));
+ if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf)
+ && isset($list[trim($id_buf[1])]['Image'])) {
$this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
- }
}
} elseif (CommonFunctions::fileexists($filename="/etc/debian_version")) {
if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
$buf = "";
}
- if (isset($list['Debian']['Image'])) {
- $this->sys->setDistributionIcon($list['Debian']['Image']);
+ if (isset($list['debian']['Image'])) {
+ $this->sys->setDistributionIcon($list['debian']['Image']);
}
- if (isset($list['Debian']['Name'])) {
- if (is_null($buf) || (trim($buf) == "")) {
- $this->sys->setDistribution($list['Debian']['Name']);
+ if (isset($list['debian']['Name'])) {
+ if (($buf === null) || (trim($buf) == "")) {
+ $this->sys->setDistribution($list['debian']['Name']);
} else {
- $this->sys->setDistribution($list['Debian']['Name']." ".trim($buf));
+ $this->sys->setDistribution($list['debian']['Name']." ".trim($buf));
}
} else {
- if (is_null($buf) || (trim($buf) == "")) {
+ if (($buf === null) || (trim($buf) == "")) {
$this->sys->setDistribution('Debian');
} else {
$this->sys->setDistribution(trim($buf));
}
}
+ } elseif (CommonFunctions::fileexists($filename="/etc/slackware-version")) {
+ if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
+ $buf = "";
+ }
+ if (isset($list['slackware']['Image'])) {
+ $this->sys->setDistributionIcon($list['slackware']['Image']);
+ }
+ if (isset($list['slackware']['Name'])) {
+ if (($buf === null) || (trim($buf) == "")) {
+ $this->sys->setDistribution($list['slackware']['Name']);
+ } else {
+ $this->sys->setDistribution($list['slackware']['Name']." ".trim($buf));
+ }
+ } else {
+ if (($buf === null) || (trim($buf) == "")) {
+ $this->sys->setDistribution('Slackware');
+ } else {
+ $this->sys->setDistribution(trim($buf));
+ }
+ }
+ } elseif (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf")
+ && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
+ && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
+ && preg_match("/^Version\s*=\s*([\d\.]+)\r?\nBuild\sNumber\s*=\s*(\S+)/m", $buf, $ver_buf)) {
+ $buf = $ver_buf[1]."-".$ver_buf[2];
+ if (isset($list['qts']['Image'])) {
+ $this->sys->setDistributionIcon($list['qts']['Image']);
+ }
+ if (isset($list['qts']['Name'])) {
+ $this->sys->setDistribution($list['qts']['Name']." ".trim($buf));
+ } else {
+ $this->sys->setDistribution(trim($buf));
+ }
}
}
/* restore error level */
@@ -1041,14 +2334,13 @@ class Linux extends OS
*/
protected function _processes()
{
- $process = glob('/proc/*/status', GLOB_NOSORT);
- if (($total = count($process)) > 0) {
-
+ $process = CommonFunctions::findglob('/proc/*/status', GLOB_NOSORT);
+ if (is_array($process) && (($total = count($process)) > 0)) {
$processes['*'] = 0;
$buf = "";
for ($i = 0; $i < $total; $i++) {
if (CommonFunctions::rfts($process[$i], $buf, 0, 4096, false)) {
- $processes['*']++; //current total
+ $processes['*']++; // current total
if (preg_match('/^State:\s+(\w)/m', $buf, $state)) {
if (isset($processes[$state[1]])) {
$processes[$state[1]]++;
@@ -1059,7 +2351,7 @@ class Linux extends OS
}
}
if (!($processes['*'] > 0)) {
- $processes['*'] = $processes[' '] = $total; //all unknown
+ $processes['*'] = $processes[' '] = $total; // all unknown
}
$this->sys->setProcesses($processes);
}
@@ -1070,27 +2362,38 @@ class Linux extends OS
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_machine();
- $this->_uptime();
- $this->_users();
- $this->_cpuinfo();
- $this->_pci();
- $this->_ide();
- $this->_scsi();
- $this->_usb();
- $this->_i2c();
- $this->_network();
- $this->_memory();
- $this->_filesystems();
- $this->_loadavg();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_machine();
+ $this->_cpuinfo();
+ $this->_virtualizer();
+ $this->_pci();
+ $this->_ide();
+ $this->_scsi();
+ $this->_nvme();
+ $this->_usb();
+ $this->_i2c();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.Minix.inc.php b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php
index 43fd4bf..154d861 100644
--- a/root/opt/phpsysinfo/includes/os/class.Minix.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php
@@ -8,7 +8,7 @@
* @package PSI Minix OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Minix.inc.php 687 2012-09-06 20:54:49Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,26 +20,23 @@
* @package PSI Minix OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class Minix extends OS
{
+ /**
+ * uptime command result.
+ */
+ private $_uptime = null;
+
/**
* content of the syslog
*
* @var array
*/
- private $_dmesg = array();
-
- /**
- * call parent constructor
- */
- public function __construct()
- {
- parent::__construct();
- }
+ private $_dmesg = null;
/**
* read /var/log/messages, but only if we haven't already
@@ -48,11 +45,13 @@ class Minix extends OS
*/
protected function readdmesg()
{
- if (count($this->_dmesg) === 0) {
+ if ($this->_dmesg === null) {
if (CommonFunctions::rfts('/var/log/messages', $buf)) {
- $parts = preg_split("/kernel: APIC/", $buf, -1, PREG_SPLIT_NO_EMPTY);
-// $parts = preg_split("/ syslogd: restart\n/", $buf, -1, PREG_SPLIT_NO_EMPTY);
+ $blocks = preg_replace("/\s(kernel: MINIX \d+\.\d+\.\d+\.)/", '$1', $buf);
+ $parts = preg_split("//", $blocks, -1, PREG_SPLIT_NO_EMPTY);
$this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY);
+ } else {
+ $this->_dmesg = array();
}
}
@@ -62,7 +61,7 @@ class Minix extends OS
/**
* get the cpu information
*
- * @return array
+ * @return void
*/
protected function _cpuinfo()
{
@@ -73,31 +72,32 @@ class Minix extends OS
$dev = new CpuDevice();
$details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
foreach ($details as $detail) {
- $arrBuff = preg_split('/\s+:\s+/', trim($detail));
- if (count($arrBuff) == 2) {
- switch (strtolower($arrBuff[0])) {
+ if (preg_match('/^([^:]+):(.+)$/', trim($detail) , $arrBuff) && (($arrBuff2 = trim($arrBuff[2])) !== '')) {
+ switch (strtolower(trim($arrBuff[1]))) {
case 'model name':
- $_n = $arrBuff[1];
+ $_n = $arrBuff2;
break;
case 'cpu mhz':
- $dev->setCpuSpeed($arrBuff[1]);
+ $dev->setCpuSpeed($arrBuff2);
break;
case 'cpu family':
- $_f = $arrBuff[1];
+ $_f = $arrBuff2;
break;
case 'model':
- $_m = $arrBuff[1];
+ $_m = $arrBuff2;
break;
case 'stepping':
- $_s = $arrBuff[1];
+ $_s = $arrBuff2;
break;
case 'flags':
- if (preg_match("/ vmx/", $arrBuff[1])) {
+ if (preg_match("/ vmx/", $arrBuff2)) {
$dev->setVirt("vmx");
- } elseif (preg_match("/ svm/", $arrBuff[1])) {
+ } elseif (preg_match("/ svm/", $arrBuff2)) {
$dev->setVirt("svm");
}
- break;
+ break;
+ case 'vendor_id':
+ $dev->setVendorId($arrBuff2);
}
}
}
@@ -129,6 +129,7 @@ class Minix extends OS
{
if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
$arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ $arrResults = array();
foreach ($arrLines as $strLine) {
$arrParams = preg_split('/\s+/', trim($strLine), 4);
if (count($arrParams) == 4)
@@ -144,7 +145,7 @@ class Minix extends OS
$this->sys->setPciDevices($dev);
}
}
- if (!(isset($arrResults) && is_array($arrResults)) && is_array($results = Parser::lspci())) {
+ if (!(isset($arrResults) && is_array($arrResults)) && ($results = Parser::lspci())) {
/* if access error: chmod 4755 /usr/bin/lspci */
foreach ($results as $dev) {
$this->sys->setPciDevices($dev);
@@ -159,12 +160,13 @@ class Minix extends OS
*/
private function _kernel()
{
- foreach ($this->readdmesg() as $line) {
- if (preg_match('/kernel: MINIX (.*) \((.*)\)/', $line, $ar_buf)) {
- $branch = $ar_buf[2];
- }
- }
if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) {
+ foreach ($this->readdmesg() as $line) {
+ if (preg_match('/kernel: MINIX (\d+\.\d+\.\d+)\. \((.+)\)/', $line, $ar_buf)) {
+ $branch = $ar_buf[2];
+ break;
+ }
+ }
if (isset($branch))
$this->sys->setKernel($ret.' ('.$branch.')');
else
@@ -195,13 +197,13 @@ class Minix extends OS
*/
private function _uptime()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/up (\d+) day[s]?,\s*(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
$min = $ar_buf[3];
$hours = $ar_buf[2];
$days = $ar_buf[1];
$this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
- } elseif (preg_match("/up (\d+):(\d+),/", $buf, $ar_buf)) {
+ } elseif (preg_match("/up (\d+):(\d+),/", $this->_uptime, $ar_buf)) {
$min = $ar_buf[2];
$hours = $ar_buf[1];
$this->sys->setUptime($hours * 3600 + $min * 60);
@@ -217,27 +219,13 @@ class Minix extends OS
*/
private function _loadavg()
{
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
+ if (($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) {
+ if (preg_match("/load averages: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf)) {
$this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
}
}
}
- /**
- * Number of Users
- *
- * @return void
- */
- private function _users()
- {
- if (CommonFunctions::executeProgram('uptime', '', $buf)) {
- if (preg_match("/, (.*) users, load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
- $this->sys->setUsers($ar_buf[1]);
- }
- }
- }
-
/**
* Virtual Host Name
*
@@ -245,8 +233,8 @@ class Minix extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) {
$ip = gethostbyname($result);
@@ -257,23 +245,6 @@ class Minix extends OS
}
}
- /**
- * IP of the Virtual Host Name
- *
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
/**
* Physical memory information and Swap Space information
@@ -360,23 +331,32 @@ class Minix extends OS
/**
* get the information
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->error->addError("WARN", "The Minix version of phpSysInfo is a work in progress, some things currently don't work");
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_loadavg();
- $this->_pci();
- $this->_cpuinfo();
- $this->_memory();
- $this->_filesystems();
- $this->_network();
- $this->_processes();
+ $this->error->addWarning("The Minix version of phpSysInfo is a work in progress, some things currently don't work");
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_pci();
+ $this->_cpuinfo();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php
index d43e79c..7a802ec 100644
--- a/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php
@@ -8,7 +8,7 @@
* @package PSI NetBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.NetBSD.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI NetBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -29,29 +29,17 @@ class NetBSD extends BSDCommon
/**
* define the regexp for log parser
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- parent::__construct();
- $this->setCPURegExp1("^cpu(.*)\, (.*) MHz");
+ parent::__construct($blockname);
+ //$this->setCPURegExp1("/^cpu(.*)\, (.*) MHz/");
$this->setCPURegExp2("/user = (.*), nice = (.*), sys = (.*), intr = (.*), idle = (.*)/");
- $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*");
- $this->setSCSIRegExp2("^(da[0-9]): (.*)MB ");
- $this->setPCIRegExp1("/(.*) at pci[0-9] dev [0-9]* function [0-9]*: (.*)$/");
+ $this->setSCSIRegExp1("/^(.*) at scsibus.*: <(.*)> .*/");
+ $this->setSCSIRegExp2("/^(sd[0-9]+): (.*)([MG])B,/");
+ $this->setPCIRegExp1("/(.*) at pci[0-9]+ dev [0-9]* function [0-9]*: (.*)$/");
$this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/");
}
- /**
- * UpTime
- * time the system is running
- *
- * @return void
- */
- private function _uptime()
- {
- $a = $this->grabkey('kern.boottime');
- $this->sys->setUptime(time() - $a);
- }
-
/**
* get network information
*
@@ -66,13 +54,39 @@ class NetBSD extends BSDCommon
for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) {
$ar_buf_b = preg_split("/\s+/", $lines_b[$i]);
$ar_buf_n = preg_split("/\s+/", $lines_n[$i]);
- if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) {
+ if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[3]) || ($ar_buf_n[3] === "0"))) {
$dev = new NetDevice();
$dev->setName($ar_buf_b[0]);
$dev->setTxBytes($ar_buf_b[4]);
$dev->setRxBytes($ar_buf_b[3]);
$dev->setDrops($ar_buf_n[8]);
$dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]);
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf_b[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) {
+ $speedinfo = "";
+ $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($bufe2 as $buf2) {
+ if (preg_match('/^\s+address:\s+(\S+)/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2))
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) {
+ if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") {
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (preg_match('/\s(\S+)-duplex/i', $buf2, $ar_buf3))
+ $speedinfo = $ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]);
+ else
+ $speedinfo = $ar_buf2[1].$unit.'b/s';
+ }
+ }
+ if ($speedinfo != "") $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
$this->sys->setNetDevices($dev);
}
}
@@ -86,15 +100,34 @@ class NetBSD extends BSDCommon
protected function ide()
{
foreach ($this->readdmesg() as $line) {
- if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9] (.*): <(.*)>/', $line, $ar_buf)) {
+ if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9]+ (.*): <(.*)>/', $line, $ar_buf)
+ || preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9]+ /', $line, $ar_buf)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[1]);
- // now loop again and find the capacity
- foreach ($this->readdmesg() as $line2) {
- if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) {
- $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049);
- } elseif (preg_match("/^(".$ar_buf[1]."): (.*) MB, (.*), (.*), .*$/", $line2, $ar_buf_n)) {
- $dev->setCapacity($ar_buf_n[2] * 2048);
+ if (isset($ar_buf[4])) {
+ $dev->setName($ar_buf[4]);
+ } else {
+ $dev->setName($ar_buf[1]);
+ // now loop again and find the name
+ foreach ($this->readdmesg() as $line2) {
+ if (preg_match("/^(".$ar_buf[1]."): <(.*)>$/", $line2, $ar_buf_n)) {
+ $dev->setName($ar_buf_n[2]);
+ break;
+ }
+ }
+ }
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ // now loop again and find the capacity
+ foreach ($this->readdmesg() as $line2) {
+ if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) {
+ $dev->setCapacity($ar_buf_n[4] * 1024 * 1024);
+ break;
+ } elseif (preg_match("/^(".$ar_buf[1]."): (.*) MB, (.*), (.*), .*$/", $line2, $ar_buf_n)) {
+ $dev->setCapacity($ar_buf_n[2] * 1024 * 1024);
+ break;
+ } elseif (preg_match("/^(".$ar_buf[1]."): (.*) GB, (.*), (.*), .*$/", $line2, $ar_buf_n)) {
+ $dev->setCapacity($ar_buf_n[2] * 1024 * 1024 * 1024);
+ break;
+ }
}
}
$this->sys->setIdeDevices($dev);
@@ -102,6 +135,77 @@ class NetBSD extends BSDCommon
}
}
+ /**
+ * CPU information
+ *
+ * @return void
+ */
+ protected function cpuinfo()
+ {
+ $was = false;
+ $cpuarray = array();
+ foreach ($this->readdmesg() as $line) {
+ if (preg_match("/^cpu([0-9])+: (.*)/", $line, $ar_buf)) {
+ $was = true;
+ $ar_buf[2] = trim($ar_buf[2]);
+ if (preg_match("/^(.+), ([\d\.]+) MHz/", $ar_buf[2], $ar_buf2)) {
+ if (($model = trim($ar_buf2[1])) !== "") {
+ $cpuarray[$ar_buf[1]]['model'] = $model;
+ }
+ if (($speed = trim($ar_buf2[2])) > 0) {
+ $cpuarray[$ar_buf[1]]['speed'] = $speed;
+ }
+ } elseif (preg_match("/^L2 cache (\d+) ([KM])B /", $ar_buf[2], $ar_buf2)) {
+ if ($ar_buf2[2]=="M") {
+ $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024*1024;
+ } elseif ($ar_buf2[2]=="K") {
+ $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024;
+ }
+ }
+ } elseif (!preg_match("/^cpu[0-9]+ /", $line) && $was) {
+ break;
+ }
+ }
+
+ $ncpu = $this->grabkey('hw.ncpu');
+ if (($ncpu === "") || !($ncpu >= 1)) {
+ $ncpu = 1;
+ }
+ $ncpu = max($ncpu, count($cpuarray));
+
+ $model = $this->grabkey('machdep.cpu_brand');
+ $model2 = $this->grabkey('hw.model');
+ if ($cpuspeed = $this->grabkey('machdep.tsc_freq')) {
+ $speed = round($cpuspeed / 1000000);
+ } else {
+ $speed = "";
+ }
+
+ for ($cpu = 0 ; $cpu < $ncpu ; $cpu++) {
+ $dev = new CpuDevice();
+
+ if (isset($cpuarray[$cpu]['model'])) {
+ $dev->setModel($cpuarray[$cpu]['model']);
+ } elseif ($model !== "") {
+ $dev->setModel($model);
+ } elseif ($model2 !== "") {
+ $dev->setModel($model2);
+ }
+ if (isset($cpuarray[$cpu]['speed'])) {
+ $dev->setCpuSpeed($cpuarray[$cpu]['speed']);
+ } elseif ($speed !== "") {
+ $dev->setCpuSpeed($speed);
+ }
+ if (isset($cpuarray[$cpu]['cache'])) {
+ $dev->setCache($cpuarray[$cpu]['cache']);
+ }
+ if (($ncpu == 1) && PSI_LOAD_BAR) {
+ $dev->setLoad($this->cpuusage());
+ }
+ $this->sys->setCpus($dev);
+ }
+ }
+
/**
* get icon name
*
@@ -146,14 +250,17 @@ class NetBSD extends BSDCommon
*
* @see BSDCommon::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
parent::build();
- $this->_distroicon();
- $this->_network();
- $this->_uptime();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distroicon();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.OS.inc.php b/root/opt/phpsysinfo/includes/os/class.OS.inc.php
index eadf92b..c509e32 100644
--- a/root/opt/phpsysinfo/includes/os/class.OS.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.OS.inc.php
@@ -8,7 +8,7 @@
* @package PSI OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.OS.inc.php 699 2012-09-15 11:57:13Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,10 +28,17 @@ abstract class OS implements PSI_Interface_OS
/**
* object for error handling
*
- * @var Error
+ * @var PSI_Error
*/
protected $error;
+ /**
+ * block name
+ *
+ * @var string
+ */
+ protected $blockname = false;
+
/**
* @var System
*/
@@ -40,10 +47,12 @@ abstract class OS implements PSI_Interface_OS
/**
* build the global Error object
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- $this->error = Error::singleton();
+ $this->error = PSI_Error::singleton();
$this->sys = new System();
+ $this->blockname = $blockname;
+ $this->sys->setOS(get_class($this));
}
/**
@@ -57,6 +66,7 @@ abstract class OS implements PSI_Interface_OS
{
return PSI_SYSTEM_CODEPAGE;
}
+
/**
* get os specific language
*
@@ -69,6 +79,180 @@ abstract class OS implements PSI_Interface_OS
return PSI_SYSTEM_LANG;
}
+ /**
+ * get block name
+ *
+ * @see PSI_Interface_OS::getBlockName()
+ *
+ * @return string
+ */
+ public function getBlockName()
+ {
+ return $this->blockname;
+ }
+
+ /**
+ * Number of Users
+ *
+ * @return void
+ */
+ protected function _users()
+ {
+ if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) {
+ if (strlen($strBuf) > 0) {
+ $lines = preg_split('/\n/', $strBuf);
+ $this->sys->setUsers(count($lines));
+ }
+ } elseif (CommonFunctions::executeProgram('uptime', '', $buf, PSI_DEBUG) && preg_match("/,\s+(\d+)\s+user[s]?,/", $buf, $ar_buf)) {
+ //} elseif (CommonFunctions::executeProgram('uptime', '', $buf) && preg_match("/,\s+(\d+)\s+user[s]?,\s+load average[s]?:\s+(.*),\s+(.*),\s+(.*)$/", $buf, $ar_buf)) {
+ $this->sys->setUsers($ar_buf[1]);
+ } else {
+ $processlist = CommonFunctions::findglob('/proc/*/cmdline', GLOB_NOSORT);
+ if (is_array($processlist) && (($total = count($processlist)) > 0)) {
+ $count = 0;
+ $buf = "";
+ for ($i = 0; $i < $total; $i++) {
+ if (CommonFunctions::rfts($processlist[$i], $buf, 0, 4096, false)) {
+ $name = str_replace(chr(0), ' ', trim($buf));
+ if (preg_match("/^-/", $name)) {
+ $count++;
+ }
+ }
+ }
+ if ($count > 0) {
+ $this->sys->setUsers($count);
+ }
+ }
+ }
+ }
+
+ /**
+ * IP of the Host
+ *
+ * @return void
+ */
+ protected function _ip()
+ {
+ if (PSI_USE_VHOST && !defined('PSI_EMU_HOSTNAME')) {
+ if ((CommonFunctions::readenv('SERVER_ADDR', $result) || CommonFunctions::readenv('LOCAL_ADDR', $result)) //is server address defined
+ && !strstr($result, '.') && strstr($result, ':')) { //is IPv6, quick version of preg_match('/\(([[0-9A-Fa-f\:]+)\)/', $result)
+ $dnsrec = dns_get_record($this->sys->getHostname(), DNS_AAAA);
+ if (isset($dnsrec[0]['ipv6'])) { //is DNS IPv6 record
+ $this->sys->setIp($dnsrec[0]['ipv6']); //from DNS (avoid IPv6 NAT translation)
+ } else {
+ $this->sys->setIp(preg_replace('/^::ffff:/i', '', $result)); //from SERVER_ADDR or LOCAL_ADDR
+ }
+ } else {
+ $this->sys->setIp(gethostbyname($this->sys->getHostname())); //IPv4 only
+ }
+ } elseif (((PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) && (CommonFunctions::readenv('SERVER_ADDR', $result) || CommonFunctions::readenv('LOCAL_ADDR', $result))) {
+ $this->sys->setIp(preg_replace('/^::ffff:/i', '', $result));
+ } else {
+ //$this->sys->setIp(gethostbyname($this->sys->getHostname()));
+ $hn = $this->sys->getHostname();
+ $ghbn = gethostbyname($hn);
+ if (defined('PSI_EMU_HOSTNAME') && ($hn === $ghbn)) {
+ $this->sys->setIp(PSI_EMU_HOSTNAME);
+ } else {
+ $this->sys->setIp($ghbn);
+ }
+ }
+ }
+
+ /**
+ * MEM information from dmidecode
+ *
+ * @return void
+ */
+ protected function _dmimeminfo()
+ {
+ $dmimd = CommonFunctions::readdmimemdata();
+ if (!empty($dmimd)) {
+ foreach ($dmimd as $mem) {
+ if (isset($mem['Size']) && preg_match('/^(\d+)\s(M|G)B$/', $mem['Size'], $size) && ($size[1] > 0)) {
+ $dev = new HWDevice();
+ $name = '';
+ if (isset($mem['Part Number']) && !preg_match("/^PartNum\d+$/", $part = $mem['Part Number']) && ($part != 'None') && ($part != 'N/A') && ($part != 'Not Specified') && ($part != 'NOT AVAILABLE')) {
+ $name = $part;
+ }
+ if (isset($mem['Locator']) && (($dloc = $mem['Locator']) != 'None') && ($dloc != 'N/A') && ($dloc != 'Not Specified')) {
+ if ($name != '') {
+ $name .= ' - '.$dloc;
+ } else {
+ $name = $dloc;
+ }
+ }
+ if (isset($mem['Bank Locator']) && (($bank = $mem['Bank Locator']) != 'None') && ($bank != 'N/A') && ($bank != 'Not Specified')) {
+ if ($name != '') {
+ $name .= ' in '.$bank;
+ } else {
+ $name = 'Physical Memory in '.$bank;
+ }
+ }
+ if ($name != '') {
+ $dev->setName(trim($name));
+ } else {
+ $dev->setName('Physical Memory');
+ }
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($mem['Manufacturer']) && !preg_match("/^([A-F\d]{4}|[A-F\d]{12}|[A-F\d]{16})$/", $manufacturer = $mem['Manufacturer']) && !preg_match("/^Manufacturer\d+$/", $manufacturer) && !preg_match("/^Mfg \d+$/", $manufacturer) && !preg_match("/^JEDEC ID:/", $manufacturer) && ($manufacturer != 'None') && ($manufacturer != 'N/A') && ($manufacturer != 'Not Specified') && ($manufacturer != 'UNKNOWN')) {
+ $dev->setManufacturer($manufacturer);
+ }
+ if ($size[2] == 'G') {
+ $dev->setCapacity($size[1]*1024*1024*1024);
+ } else {
+ $dev->setCapacity($size[1]*1024*1024);
+ }
+ $memtype = '';
+ if (isset($mem['Type']) && (($type = $mem['Type']) != 'None') && ($type != 'N/A') && ($type != 'Not Specified') && ($type != 'Other') && ($type != 'Unknown') && ($type != '')) {
+ if (isset($mem['Speed']) && preg_match('/^(\d+)\s(MHz|MT\/s)/', $mem['Speed'], $speed) && ($speed[1] > 0) && (preg_match('/^(DDR\d*)(.*)/', $type, $dr) || preg_match('/^(SDR)AM(.*)/', $type, $dr))) {
+ if (isset($mem['Minimum Voltage']) && isset($mem['Maximum Voltage']) &&
+ preg_match('/^([\d\.]+)\sV$/', $mem['Minimum Voltage'], $minv) && preg_match('/^([\d\.]+)\sV$/', $mem['Maximum Voltage'], $maxv) &&
+ ($minv[1] > 0) && ($maxv[1] >0) && ($minv[1] < $maxv[1])) {
+ $lv = 'L';
+ } else {
+ $lv = '';
+ }
+ if (isset($dr[2])) {
+ $memtype = $dr[1].$lv.'-'.$speed[1].' '.$dr[2];
+ } else {
+ $memtype = $dr[1].$lv.'-'.$speed[1];
+ }
+ } else {
+ $memtype = $type;
+ }
+ }
+ if (isset($mem['Form Factor']) && (($form = $mem['Form Factor']) != 'None') && ($form != 'N/A') && ($form != 'Not Specified') && ($form != 'Other') && ($form != 'Unknown') && !preg_match('/ '.$form.'$/', $memtype)) {
+ $memtype .= ' '.$form;
+ }
+ if (isset($mem['Data Width']) && isset($mem['Total Width']) &&
+ preg_match('/^(\d+)\sbits$/', $mem['Data Width'], $dataw) && preg_match('/^(\d+)\sbits$/', $mem['Total Width'], $totalw) &&
+ ($dataw[1] > 0) && ($totalw[1] >0) && ($dataw[1] < $totalw[1])) {
+ $memtype .= ' ECC';
+ }
+ if (isset($mem['Type Detail']) && preg_match('/Registered/', $mem['Type Detail'])) {
+ $memtype .= ' REG';
+ }
+ if (($memtype = trim($memtype)) != '') {
+ $dev->setProduct($memtype);
+ }
+ if (isset($mem['Configured Clock Speed']) && preg_match('/^(\d+)\s(MHz|MT\/s)$/', $mem['Configured Clock Speed'], $clock) && ($clock[1] > 0)) {
+ $dev->setSpeed($clock[1]);
+ }
+ if (isset($mem['Configured Voltage']) && preg_match('/^([\d\.]+)\sV$/', $mem['Configured Voltage'], $voltage) && ($voltage[1] > 0)) {
+ $dev->setVoltage($voltage[1]);
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL &&
+ isset($mem['Serial Number']) && !preg_match("/^SerNum\d+$/", $serial = $mem['Serial Number']) && ($serial != 'None') && ($serial != 'Not Specified')) {
+ $dev->setSerial($serial);
+ }
+ }
+ $this->sys->setMemDevices($dev);
+ }
+ }
+ }
+ }
+
/**
* get the filled or unfilled (with default values) System object
*
@@ -79,6 +263,12 @@ abstract class OS implements PSI_Interface_OS
final public function getSys()
{
$this->build();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_ip();
+ }
+ if ((!$this->blockname || $this->blockname==='hardware') && (PSI_OS != 'WINNT') && !defined('PSI_EMU_HOSTNAME')) {
+ $this->_dmimeminfo();
+ }
return $this->sys;
}
diff --git a/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php
index e642d42..9568f09 100644
--- a/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php
@@ -8,7 +8,7 @@
* @package PSI OpenBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.OpenBSD.inc.php 621 2012-07-29 18:49:04Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @package PSI OpenBSD OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -29,29 +29,17 @@ class OpenBSD extends BSDCommon
/**
* define the regexp for log parser
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- parent::__construct();
- $this->setCPURegExp1("^cpu(.*) (.*) MHz");
+ parent::__construct($blockname);
+// $this->setCPURegExp1("/^cpu(.*) (.*) MHz/");
$this->setCPURegExp2("/(.*),(.*),(.*),(.*),(.*)/");
- $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*");
- $this->setSCSIRegExp2("^(da[0-9]): (.*)MB ");
- $this->setPCIRegExp1("/(.*) at pci[0-9] .* \"(.*)\"/");
+ $this->setSCSIRegExp1("/^(.*) at scsibus.*: <(.*)> .*/");
+ $this->setSCSIRegExp2("/^(sd[0-9]+): (.*)MB,/");
+ $this->setPCIRegExp1("/(.*) at pci[0-9]+ .* \"(.*)\"/");
$this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/");
}
- /**
- * UpTime
- * time the system is running
- *
- * @return void
- */
- private function _uptime()
- {
- $a = $this->grabkey('kern.boottime');
- $this->sys->setUptime(time() - $a);
- }
-
/**
* get network information
*
@@ -66,13 +54,43 @@ class OpenBSD extends BSDCommon
for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) {
$ar_buf_b = preg_split("/\s+/", $lines_b[$i]);
$ar_buf_n = preg_split("/\s+/", $lines_n[$i]);
- if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) {
+ if (!empty($ar_buf_b[0]) && (!empty($ar_buf_n[3]) || ($ar_buf_n[3] === "0"))) {
$dev = new NetDevice();
$dev->setName($ar_buf_b[0]);
$dev->setTxBytes($ar_buf_b[4]);
$dev->setRxBytes($ar_buf_b[3]);
- $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]);
- $dev->setDrops($ar_buf_n[8]);
+ if (sizeof($ar_buf_n) == 9) {
+ $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]);
+ $dev->setDrops($ar_buf_n[8]);
+ } elseif (sizeof($ar_buf_n) == 8) {
+ $dev->setDrops($ar_buf_n[4] + $ar_buf_n[6]);
+ }
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf_b[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) {
+ $speedinfo = "";
+ $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($bufe2 as $buf2) {
+ if (preg_match('/^\s+lladdr\s+(\S+)/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ } elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2)
+ || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2))
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
+ } elseif (preg_match('/^\s+media:\s+/i', $buf2) && preg_match('/[\(\s](\d+)(G*)base/i', $buf2, $ar_buf2)) {
+ if (isset($ar_buf2[2]) && strtoupper($ar_buf2[2])=="G") {
+ $unit = "G";
+ } else {
+ $unit = "M";
+ }
+ if (preg_match('/\s(\S+)-duplex/i', $buf2, $ar_buf3))
+ $speedinfo = $ar_buf2[1].$unit.'b/s '.strtolower($ar_buf3[1]);
+ else
+ $speedinfo = $ar_buf2[1].$unit.'b/s';
+ }
+ }
+ if ($speedinfo != "") $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
+ }
$this->sys->setNetDevices($dev);
}
}
@@ -86,13 +104,16 @@ class OpenBSD extends BSDCommon
protected function ide()
{
foreach ($this->readdmesg() as $line) {
- if (preg_match('/^(.*) at pciide[0-9] (.*): <(.*)>/', $line, $ar_buf)) {
+ if (preg_match('/^(.*) at pciide[0-9]+ (.*): <(.*)>/', $line, $ar_buf)) {
$dev = new HWDevice();
- $dev->setName($ar_buf[0]);
- // now loop again and find the capacity
- foreach ($this->readdmesg() as $line2) {
- if (preg_match("/^(".$ar_buf[0]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) {
- $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049);
+ $dev->setName($ar_buf[3]);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ // now loop again and find the capacity
+ foreach ($this->readdmesg() as $line2) {
+ if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) {
+ $dev->setCapacity($ar_buf_n[4] * 1024 * 1024);
+ break;
+ }
}
}
$this->sys->setIdeDevices($dev);
@@ -107,13 +128,81 @@ class OpenBSD extends BSDCommon
*/
protected function cpuinfo()
{
- $dev = new CpuDevice();
- $dev->setModel($this->grabkey('hw.model'));
- $dev->setCpuSpeed($this->grabkey('hw.cpuspeed'));
+ $was = false;
+ $cpuarray = array();
+ foreach ($this->readdmesg() as $line) {
+ if (preg_match("/^cpu([0-9])+: (.*)/", $line, $ar_buf)) {
+ $was = true;
+ $ar_buf[2] = trim($ar_buf[2]);
+ if (preg_match("/^(.+), ([\d\.]+) MHz/", $ar_buf[2], $ar_buf2)) {
+ if (($model = trim($ar_buf2[1])) !== "") {
+ $cpuarray[$ar_buf[1]]['model'] = $model;
+ }
+ if (($speed = trim($ar_buf2[2])) > 0) {
+ $cpuarray[$ar_buf[1]]['speed'] = $speed;
+ }
+ } elseif (preg_match("/(\d+)([KM])B \S+ \S+ L[23] cache$/", $ar_buf[2], $ar_buf2)) {
+ if ($ar_buf2[2]=="M") {
+ $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024*1024;
+ } elseif ($ar_buf2[2]=="K") {
+ $cpuarray[$ar_buf[1]]['cache'] = $ar_buf2[1]*1024;
+ }
+ } else {
+ $feats = preg_split("/,/", strtolower($ar_buf[2]), -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($feats as $feat) {
+ if (($feat=="vmx") || ($feat=="svm")) {
+ $cpuarray[$ar_buf[1]]['virt'] = $feat;
+ } elseif ($feat=="hv") {
+ if (!isset($cpuarray[$ar_buf[1]]['virt'])) {
+ $cpuarray[$ar_buf[1]]['virt'] = 'hypervisor';
+ }
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $this->sys->setVirtualizer("hypervisor", false);
+ }
+ }
+ }
+ }
+ } elseif (!preg_match("/^cpu[0-9]+|^mtrr: |^acpitimer[0-9]+: /", $line) && $was) {
+ break;
+ }
+ }
+
$ncpu = $this->grabkey('hw.ncpu');
- if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1)))
+ if (($ncpu === "") || !($ncpu >= 1)) {
$ncpu = 1;
- for ($ncpu ; $ncpu > 0 ; $ncpu--) {
+ }
+ $ncpu = max($ncpu, count($cpuarray));
+
+ $model = $this->grabkey('hw.model');
+ $speed = $this->grabkey('hw.cpuspeed');
+ $vendor = $this->grabkey('machdep.cpuvendor');
+
+ for ($cpu = 0 ; $cpu < $ncpu ; $cpu++) {
+ $dev = new CpuDevice();
+
+ if (isset($cpuarray[$cpu]['model'])) {
+ $dev->setModel($cpuarray[$cpu]['model']);
+ } elseif ($model !== "") {
+ $dev->setModel($model);
+ }
+ if (isset($cpuarray[$cpu]['speed'])) {
+ $dev->setCpuSpeed($cpuarray[$cpu]['speed']);
+ } elseif ($speed !== "") {
+ $dev->setCpuSpeed($speed);
+ }
+ if (isset($cpuarray[$cpu]['cache'])) {
+ $dev->setCache($cpuarray[$cpu]['cache']);
+ }
+ if (isset($cpuarray[$cpu]['virt'])) {
+ $dev->setVirt($cpuarray[$cpu]['virt']);
+ }
+ if ($vendor !== "") {
+ $dev->setVendorId($vendor);
+ }
+ if (($ncpu == 1) && PSI_LOAD_BAR) {
+ $dev->setLoad($this->cpuusage());
+ }
+
$this->sys->setCpus($dev);
}
}
@@ -161,14 +250,17 @@ class OpenBSD extends BSDCommon
*
* @see BSDCommon::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
parent::build();
- $this->_distroicon();
- $this->_network();
- $this->_uptime();
- $this->_processes();
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distroicon();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.QNX.inc.php b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php
index 203dae3..3b6fd23 100644
--- a/root/opt/phpsysinfo/includes/os/class.QNX.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php
@@ -8,7 +8,7 @@
* @package PSI QNX OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.QNX.inc.php 687 2012-09-06 20:54:49Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,31 +20,16 @@
* @package PSI QNX OS class
* @author Mieczyslaw Nalewaj
* @copyright 2012 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class QNX extends OS
{
- /**
- * content of the syslog
- *
- * @var array
- */
- private $_dmesg = array();
-
- /**
- * call parent constructor
- */
- public function __construct()
- {
- parent::__construct();
- }
-
/**
* get the cpu information
*
- * @return array
+ * @return void
*/
protected function _cpuinfo()
{
@@ -103,23 +88,9 @@ class QNX extends OS
if (CommonFunctions::executeProgram('pidin', 'info', $buf)
&& preg_match('/^.* BootTime:(.*)/', $buf, $bstart)
&& CommonFunctions::executeProgram('date', '', $bstop)) {
- /* default error handler */
- if (function_exists('errorHandlerPsi')) {
- restore_error_handler();
- }
- /* fatal errors only */
- $old_err_rep = error_reporting();
- error_reporting(E_ERROR);
-
+ date_default_timezone_set('UTC');
$uptime = strtotime($bstop)-strtotime($bstart[1]);
if ($uptime > 0) $this->sys->setUptime($uptime);
-
- /* restore error level */
- error_reporting($old_err_rep);
- /* restore error handler */
- if (function_exists('errorHandlerPsi')) {
- set_error_handler('errorHandlerPsi');
- }
}
}
@@ -128,7 +99,7 @@ class QNX extends OS
*
* @return void
*/
- private function _users()
+ protected function _users()
{
$this->sys->setUsers(1);
}
@@ -140,8 +111,8 @@ class QNX extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) {
$ip = gethostbyname($result);
@@ -152,24 +123,6 @@ class QNX extends OS
}
}
- /**
- * IP of the Virtual Host Name
- *
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* Physical memory information and Swap Space information
*
@@ -207,20 +160,21 @@ class QNX extends OS
{
if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) {
$lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
- $notwas = true;
+ $was = false;
+ $dev = null;
foreach ($lines as $line) {
if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
- if (!$notwas) {
+ if ($was) {
$this->sys->setNetDevices($dev);
}
$dev = new NetDevice();
$dev->setName($ar_buf[1]);
- $notwas = false;
+ $was = true;
} else {
- if (!$notwas) {
+ if ($was) {
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
if (preg_match('/^\s+address:\s*(\S+)/i', $line, $ar_buf2)) {
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
} elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2))
$dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
@@ -228,7 +182,7 @@ class QNX extends OS
}
}
}
- if (!$notwas) {
+ if ($was) {
$this->sys->setNetDevices($dev);
}
}
@@ -237,20 +191,29 @@ class QNX extends OS
/**
* get the information
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->error->addError("WARN", "The QNX version of phpSysInfo is a work in progress, some things currently don't work");
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_cpuinfo();
- $this->_memory();
- $this->_filesystems();
- $this->_network();
+ $this->error->addWarning("The QNX version of phpSysInfo is a work in progress, some things currently don't work");
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_cpuinfo();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.SSH.inc.php b/root/opt/phpsysinfo/includes/os/class.SSH.inc.php
new file mode 100644
index 0000000..b8e8ea4
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/os/class.SSH.inc.php
@@ -0,0 +1,857 @@
+
+ * @copyright 2012 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version SVN: $Id: class.SSH.inc.php 687 2012-09-06 20:54:49Z namiltd $
+ * @link http://phpsysinfo.sourceforge.net
+ */
+ /**
+ * SSH sysinfo class
+ * get all the required information from SSH
+ *
+ * @category PHP
+ * @package PSI SSH class
+ * @author Mieczyslaw Nalewaj
+ * @copyright 2022 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class SSH extends GNU
+{
+ /**
+ * content of the system status
+ *
+ * @var string
+ */
+ private $_sysstatus = null;
+
+ /**
+ * content of the system performance status
+ *
+ * @var string
+ */
+ private $_sysperformance = null;
+
+ /**
+ * content of the sys ver systeminfo
+ *
+ * @var string
+ */
+ private $_sysversysteminfo = null;
+
+ /**
+ * content of the show status
+ *
+ * @var string
+ */
+ private $_showstatus = null;
+
+ /**
+ * OS type
+ *
+ * @var string
+ */
+ private $_ostype = null;
+
+ /**
+ * check system type
+ */
+ public function __construct($blockname = false)
+ {
+ parent::__construct($blockname);
+ $this->_ostype = $this->sys->getOS();
+ switch ($this->_ostype) {
+ case '4.2BSD':
+ case 'AIX':
+ case 'Darwin':
+ case 'DragonFly':
+ case 'FreeBSD':
+ case 'HI-UX/MPP':
+ case 'Haiku':
+ case 'Minix':
+ case 'NetBSD':
+ case 'OpenBSD':
+ case 'QNX':
+ case 'SunOS':
+ $this->error->addError("__construct()", "OS ".$this->_ostype. " is not supported via SSH");
+ break;
+ case 'GNU':
+ case 'Linux':
+ break;
+ case 'SSH':
+ $this->error->addError("__construct()", "SSH connection error");
+ break;
+ default:
+ if ($this->getSystemStatus() !== '') {
+ $this->_ostype = 'FortiOS';
+ $this->sys->setOS('Linux');
+ } elseif ($this->getSysVerSysteminfo() !== '') {
+ $this->_ostype = 'DrayOS';
+ $this->sys->setOS('DrayOS');
+ }
+ }
+ }
+
+ /**
+ * get os specific encoding
+ *
+ * @see PSI_Interface_OS::getEncoding()
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+// if (($this->_ostype === 'FortiOS') || ($this->_ostype === 'DrayOS') || ($this->_ostype === 'SSH')) {
+// return 'UTF-8';
+// }
+ //return null;
+ }
+
+ /**
+ * get os specific language
+ *
+ * @see PSI_Interface_OS::getLanguage()
+ *
+ * @return string
+ */
+ public function getLanguage()
+ {
+ //return null;
+ }
+
+ private function getSystemStatus()
+ {
+ if ($this->_sysstatus === null) {
+ if (CommonFunctions::executeProgram('get', 'system status', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $this->_sysstatus = substr($resulte, strlen($resulto[1][0]));
+ } else {
+ $this->_sysstatus = '';
+ }
+ }
+
+ return $this->_sysstatus;
+ }
+
+ private function getSystemPerformance()
+ {
+ if ($this->_sysperformance === null) {
+ if (CommonFunctions::executeProgram('get', 'system performance status', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $this->_sysperformance = substr($resulte, strlen($resulto[1][0]));
+ } else {
+ $this->_sysperformance = '';
+ }
+ }
+
+ return $this->_sysperformance;
+ }
+
+ private function getSysVerSysteminfo()
+ {
+ if ($this->_sysversysteminfo === null) {
+ if (CommonFunctions::executeProgram('sys', 'ver systeminfo', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "")
+ && preg_match('/([\s\S]+> sys ver systeminfo)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $this->_sysversysteminfo = substr($resulte, strlen($resulto[1][0]));
+ } else {
+ $this->_sysversysteminfo = '';
+ }
+ }
+
+ return $this->_sysversysteminfo;
+ }
+
+ private function getShowStatus()
+ {
+ if ($this->_showstatus === null) {
+ if (CommonFunctions::executeProgram('show', 'status', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "")
+ && preg_match('/([\s\S]+> show status)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $this->_showstatus = substr($resulte, strlen($resulto[1][0]));
+ } else {
+ $this->_showstatus = '';
+ }
+ }
+
+ return $this->_showstatus;
+ }
+ /**
+ * Physical memory information and Swap Space information
+ *
+ * @return void
+ */
+ protected function _memory($mbuf = null, $sbuf = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (CommonFunctions::executeProgram('get', 'hardware memory', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ parent::_memory(substr($resulte, strlen($resulto[1][0])));
+ }
+ break;
+ case 'DrayOS':
+ if (($sysstat = $this->getSysVerSysteminfo()) !== '') {
+ $machine= '';
+ if (preg_match("/ Total memory usage : \d+ % \((\d+)K\/(\d+)K\)/", $sysstat, $buf)) {
+ $this->sys->setMemTotal($buf[2]*1024);
+ $this->sys->setMemUsed($buf[1]*1024);
+ $this->sys->setMemFree(($buf[2]-$buf[1])*1024);
+ }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ if (!CommonFunctions::executeProgram('cat', '/proc/meminfo', $mbuf, false) || ($mbuf === "")) {
+ $mbuf = null;
+ }
+ if (!CommonFunctions::executeProgram('cat', '/proc/swaps', $sbuf, false) || ($sbuf === "")) {
+ $sbuf = null;
+ }
+ if (($mbuf !== null) || ($sbuf !== null)) {
+ parent::_memory($mbuf, $sbuf);
+ }
+ }
+
+ }
+
+ /**
+ * USB devices
+ *
+ * @return void
+ */
+ protected function _usb($bufu = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ $bufr = '';
+ if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/bus/usb/devices', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $resulti = substr($resulte, strlen($resulto[1][0]));
+ if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) {
+ $bufr = substr($resulti, 0, $resulto[1][1]);
+ if (count(preg_split('/\n/', $bufr, -1, PREG_SPLIT_NO_EMPTY)) >= 2) {
+ parent::_usb($bufr);
+ }
+ }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_usb();
+ }
+ }
+
+ /**
+ * Network devices
+ * includes also rx/tx bytes
+ *
+ * @return void
+ */
+ protected function _network($bufr = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ $bufr = '';
+ if (CommonFunctions::executeProgram('fnsysctl', 'ifconfig', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $resulti = substr($resulte, strlen($resulto[1][0]));
+ if (preg_match('/(\n.*[\$#])$/', $resulti, $resulto, PREG_OFFSET_CAPTURE)) {
+ $bufr = substr($resulti, 0, $resulto[1][1]);
+ if (count(preg_split('/\n/', $bufr, -1, PREG_SPLIT_NO_EMPTY)) < 2) {
+ $bufr = '';
+ }
+ }
+ }
+
+ if ($bufr !== '') {
+ parent::_network($bufr);
+ } else {
+ $netdevs = array();
+ if (CommonFunctions::executeProgram('diagnose', 'ip address list', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $strBuf = substr($resulte, strlen($resulto[1][0]));
+ $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) if (preg_match('/^IP=(\S+)->.+ devname=(\S+)$/', $line, $buf)) {
+ if (!isset($netdevs[$buf[2]])) {
+ $netdevs[$buf[2]] = $buf[1];
+ } else {
+ $netdevs[$buf[2]] .= ';'.$buf[1];
+ }
+ }
+ }
+ if (CommonFunctions::executeProgram('diagnose', 'ipv6 address list', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $strBuf = substr($resulte, strlen($resulto[1][0]));
+ $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) if (preg_match('/ devname=(\S+) .+ addr=(\S+)/', $line, $buf)) {
+ if (!preg_match('/^fe80::/i', $buf[2])) {
+ if (!isset($netdevs[$buf[1]])) {
+ $netdevs[$buf[1]] = $buf[2];
+ } else {
+ $netdevs[$buf[1]] .= ';'.$buf[2];
+ }
+ }
+ }
+ }
+
+ foreach ($netdevs as $netname=>$netinfo) {
+ if (!preg_match('/^vsys_/i', $netname)) {
+ $dev = new NetDevice();
+// if ($netname === 'root') {
+// $dev->setName('lo');
+// } else {
+ $dev->setName($netname);
+// }
+ $this->sys->setNetDevices($dev);
+ $dev->setInfo($netinfo);
+ }
+ }
+ }
+ break;
+ case 'DrayOS':
+ $macarray = array();
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR)) {
+ if (CommonFunctions::executeProgram('sys', 'iface', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "")
+ && preg_match('/([\s\S]+> sys iface)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $lines = preg_split("/\n/", substr($resulte, strlen($resulto[1][0])), -1, PREG_SPLIT_NO_EMPTY);
+ $ipaddr = 'LAN';
+ foreach ($lines as $line) {
+ if (preg_match("/^IP Address:\s+([\d\.]+)\s/", trim($line), $ar_buf)) {
+ if ($ipaddr === false) {
+ $ipaddr = $ar_buf[1];
+ }
+ } elseif (preg_match("/^MAC:\s+([\d\-A-F]+)/", trim($line), $ar_buf)) {
+ if ($ipaddr !== '0.0.0.0') {
+ $macarray[$ipaddr] = $ar_buf[1];
+ }
+ $ipaddr = false;
+ }
+ }
+ }
+ }
+
+ $lantxrate = false;
+ $lanrxrate = false;
+ if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) {
+ if ((($bufr = $this->getShowStatus()) !== '') && preg_match('/IP Address:[\d\.]+[ ]+Tx Rate:(\d+)[ ]+Rx Rate:(\d+)/m', $bufr, $ar_buf)) {
+ $lantxrate = $ar_buf[1];
+ $lanrxrate = $ar_buf[2];
+ }
+ }
+
+ $notwaslan = true;
+ if (CommonFunctions::executeProgram('show', 'lan', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "")
+ && preg_match('/([\s\S]+> show lan)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $lines = preg_split("/\n/", substr($resulte, strlen($resulto[1][0])), -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) {
+ if (preg_match("/^\[V\](\S+)\s+([\d\.]+)\s/", trim($line), $ar_buf)) {
+ $dev = new NetDevice();
+ $dev->setName($ar_buf[1]);
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ $dev->setInfo($ar_buf[2]);
+ if (isset($macarray['LAN'])) {
+ $dev->setInfo($macarray['LAN'].';'.$ar_buf[2]);
+ } else {
+ $dev->setInfo($ar_buf[2]);
+ }
+ }
+ if ($lantxrate !== false) {
+ $dev->setTxRate($lantxrate);
+ }
+ if ($lanrxrate !== false) {
+ $dev->setRxRate($lanrxrate);
+ }
+ $this->sys->setNetDevices($dev);
+ if (preg_match('/^LAN/', $ar_buf[1])) {
+ $notwaslan = false;
+ }
+ }
+ }
+ }
+ if (($bufr = $this->getShowStatus()) !== '') {
+ $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
+ $last = false;
+ $dev = null;
+ foreach ($lines as $line) {
+ if (preg_match("/^(.+) Status/", trim($line), $ar_buf)) {
+ if (($last !== false) && (($last !== 'LAN') || $notwaslan)) {
+ $this->sys->setNetDevices($dev);
+ }
+ $dev = new NetDevice();
+ $last = preg_replace('/\s+/', '', $ar_buf[1]);
+ $dev->setName($last);
+ } else {
+ if ($last !== false) {
+ if (preg_match('/ IP:([\d\.]+)[ ]+GW/', $line, $ar_buf) || preg_match('/IP Address:([\d\.]+)[ ]+Tx/', $line, $ar_buf)) {
+ if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
+ if ($last === 'LAN') {
+ if (isset($macarray['LAN'])) {
+ $dev->setInfo($macarray['LAN'].';'.$ar_buf[1]);
+ }
+ if ($lantxrate !== false) {
+ $dev->setTxRate($lantxrate);
+ }
+ if ($lanrxrate !== false) {
+ $dev->setRxRate($lanrxrate);
+ }
+ } elseif (isset($macarray[$ar_buf[1]])) {
+ $dev->setInfo($macarray[$ar_buf[1]].';'.$ar_buf[1]);
+ } else {
+ $dev->setInfo($ar_buf[1]);
+ }
+ }
+ } elseif (preg_match('/TX Packets:\d+[ ]+TX Rate\(bps\):(\d+)[ ]+RX Packets:\d+[ ]+RX Rate\(bps\):(\d+)/', $line, $ar_buf)) {
+ if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) {
+ $dev->setTxRate($ar_buf[1]);
+ $dev->setRxRate($ar_buf[2]);
+ }
+ }
+ }
+ }
+ }
+ if (($last !== false) && (($last !== 'LAN') || $notwaslan)) {
+ $this->sys->setNetDevices($dev);
+ }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_network();
+ }
+ }
+
+ /**
+ * CPU information
+ * All of the tags here are highly architecture dependant.
+ *
+ * @return void
+ */
+ protected function _cpuinfo($bufr = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (CommonFunctions::executeProgram('get', 'hardware cpu', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ parent::_cpuinfo(substr($resulte, strlen($resulto[1][0])));
+ }
+ break;
+ case 'DrayOS':
+ if (preg_match_all("/CPU(\d+) speed:[ ]*(\d+) MHz/m", $sysinfo = $this->getSysVerSysteminfo(), $bufarr)) {
+ foreach ($bufarr[1] as $index=>$nr) {
+ $dev = new CpuDevice();
+ $dev->setModel('CPU'.$nr);
+ $dev->setCpuSpeed($bufarr[2][$index]);
+ if (PSI_LOAD_BAR) {
+ $dev->setLoad($this->_parseProcStat('cpu'.$nr));
+ }
+ $this->sys->setCpus($dev);
+ }
+// $this->_cpu_loads['cpu'] = $buf[1];
+// if (preg_match("/CPU1 speed/", $sysinfo)) {
+// $this->_cpu_loads['cpu0'] = $buf[1];
+// }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ if (CommonFunctions::executeProgram('cat', '/proc/cpuinfo', $resulte, false) && ($resulte !== "")) {
+ parent::_cpuinfo($resulte);
+ }
+ }
+ }
+
+ /**
+ * Machine
+ *
+ * @return void
+ */
+ protected function _machine()
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (($sysstat = $this->getSystemStatus()) !== '') {
+ $machine= '';
+ if (preg_match("/^Version: (\S+) v/", $sysstat, $buf)) {
+ $machine = $buf[1];
+ }
+ if (preg_match("/\nSystem Part-Number: (\S+)\n/", $sysstat, $buf)) {
+ $machine .= ' '.$buf[1];
+ }
+ if (preg_match("/\nBIOS version: (\S+)\n/", $sysstat, $buf)) {
+ if (trim($machine) !== '') {
+ $machine .= ', BIOS '.$buf[1];
+ } else {
+ $machine = 'BIOS '.$buf[1];
+ }
+ }
+ $machine = trim($machine);
+
+ if ($machine !== '') {
+ $this->sys->setMachine($machine);
+ }
+ }
+ break;
+ case 'DrayOS':
+ if (($sysstat = $this->getSysVerSysteminfo()) !== '') {
+ $machine= '';
+ if (preg_match("/[\r\n]Router Model: (\S+) /", $sysstat, $buf)) {
+ $machine = $buf[1];
+ }
+ if (preg_match("/[\r\n]Revision: (.+)[\r\n]/", $sysstat, $buf)) {
+ $machine .= ' '.$buf[1];
+ }
+ $machine = trim($machine);
+
+ if ($machine !== '') {
+ $this->sys->setMachine($machine);
+ }
+ }
+ break;
+
+ case 'GNU':
+ case 'Linux':
+ parent::_machine();
+ }
+ }
+
+ /**
+ * Hostname
+ *
+ * @return void
+ */
+ protected function _hostname()
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+// $hostname = PSI_EMU_HOSTNAME;
+ if (preg_match("/\nHostname: ([^\n]+)\n/", $this->getSystemStatus(), $buf)) {
+ $this->sys->setHostname(trim($buf[1]));
+// $hostname = trim($buf[1]);
+ }
+
+// $ip = gethostbyname($hostname);
+// if ($ip != $hostname) {
+// $this->sys->setHostname(gethostbyaddr($ip));
+// } else {
+// $this->sys->setHostname($hostname);
+// }
+ break;
+ case 'DrayOS':
+ if (preg_match("/[\r\n]Router Name: ([^\n\r]+)[\r\n]/", $this->getSysVerSysteminfo(), $buf)) {
+ $this->sys->setHostname(trim($buf[1]));
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_hostname();
+ }
+
+ }
+
+ /**
+ * filesystem information
+ *
+ * @return void
+ */
+ protected function _filesystems()
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (CommonFunctions::executeProgram('fnsysctl', 'df -k', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $resulti = substr($resulte, $resulto[1][1]);
+ $df = preg_split("/\n/", $resulti, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($df as $df_line) {
+ $df_buf1 = preg_split("/(\%\s)/", $df_line, 3);
+ if (count($df_buf1) != 2) {
+ continue;
+ }
+ if (preg_match("/(.*)(\s+)(([0-9]+)(\s+)([0-9]+)(\s+)([\-0-9]+)(\s+)([0-9]+)$)/", $df_buf1[0], $df_buf2)) {
+ $df_buf = array($df_buf2[1], $df_buf2[4], $df_buf2[6], $df_buf2[8], $df_buf2[10], $df_buf1[1]);
+ if (count($df_buf) == 6) {
+ $df_buf[5] = trim($df_buf[5]);
+ $dev = new DiskDevice();
+ $dev->setName(trim($df_buf[0]));
+ if ($df_buf[2] < 0) {
+ $dev->setTotal($df_buf[3] * 1024);
+ $dev->setUsed($df_buf[3] * 1024);
+ } else {
+ $dev->setTotal($df_buf[1] * 1024);
+ $dev->setUsed($df_buf[2] * 1024);
+ if ($df_buf[3]>0) {
+ $dev->setFree($df_buf[3] * 1024);
+ }
+ }
+ if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[5]);
+ $dev->setFsType('unknown');
+ $this->sys->setDiskDevices($dev);
+ }
+ }
+ }
+ }
+ break;
+ case 'DrayOS':
+ if (CommonFunctions::executeProgram('nand', 'usage', $resulte, false, PSI_EXEC_TIMEOUT_INT, '>') && ($resulte !== "")
+ && preg_match('/([\s\S]+> nand usage)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $df = substr($resulte, strlen($resulto[1][0]));
+
+ if (preg_match('/Usecfg/', $df)) { // fix for Vigor2135ac v4.4.2
+ $df = preg_replace("/(cfg|bin)/", "\n$1", substr($resulte, strlen($resulto[1][0])));
+ $percent = '';
+ } else {
+ $percent = '%';
+ }
+
+ $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($df as $df_line) {
+ if (preg_match("/^(\S+)[ ]+(\d+)[ ]+(\d+)[ ]+(\d+)[ ]+(\d+)".$percent."/", trim($df_line), $df_buf)) {
+ $dev = new DiskDevice();
+ $dev->setName($df_buf[1]);
+ $dev->setTotal($df_buf[2]);
+ $dev->setUsed($df_buf[3]);
+ $dev->setFree($df_buf[4]);
+ $dev->setFsType('NAND');
+ $this->sys->setDiskDevices($dev);
+ }
+ }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_filesystems();
+ }
+ }
+
+ /**
+ * Distribution
+ *
+ * @return void
+ */
+ protected function _distro()
+ {
+ switch ($this->_ostype) {
+ case 'SSH':
+ $this->sys->setOS('Unknown');
+ $this->sys->setDistributionIcon('Unknown.png');
+ break;
+ case 'FortiOS':
+ if (preg_match("/^Version: \S+ (v[^\n]+)\n/", $this->getSystemStatus(), $buf)) {
+ $this->sys->setDistribution('FortiOS '.trim($buf[1]));
+ }
+ $this->sys->setDistributionIcon('FortiOS.png');
+ break;
+ case 'DrayOS':
+ if (preg_match("/ Version: ([^\n]+)\n/", $this->getSysVerSysteminfo(), $buf)) {
+ $this->sys->setDistribution('DrayOS '.trim($buf[1]));
+ }
+ $this->sys->setDistributionIcon('DrayOS.png');
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_distro();
+ }
+// if ($this->_ostype !== null) {
+// $this->sys->setDistributionIcon($this->_ostype);
+// }
+ }
+
+ /**
+ * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu
+ *
+ * @param String $cpuline cpu for which load should be meassured
+ *
+ * @return int
+ */
+ protected function _parseProcStat($cpuline)
+ {
+ if ($this->_cpu_loads === null) {
+ $this->_cpu_loads = array();
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (($strBuf = $this->getSystemPerformance()) !== '') {
+ $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) if (preg_match('/^CPU(\d*) states: \d+% user \d+% system \d+% nice (\d+)% idle /', $line, $buf)) {
+ $this->_cpu_loads['cpu'.$buf[1]] = 100-$buf[2];
+ }
+ }
+ break;
+ case 'DrayOS':
+ if (preg_match("/CPU usage :[ ]*(\d+) %/", $sysinfo = $this->getSysVerSysteminfo(), $buf)) {
+ $this->_cpu_loads['cpu'] = $buf[1];
+ if (preg_match("/CPU1 speed/", $sysinfo) && !preg_match("/CPU2 speed/", $sysinfo)) { //only one cpu
+ $this->_cpu_loads['cpu1'] = $buf[1];
+ }
+ }
+ }
+ }
+ if (isset($this->_cpu_loads[$cpuline])) {
+ return $this->_cpu_loads[$cpuline];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Processor Load
+ * optionally create a loadbar
+ *
+ * @return void
+ */
+ protected function _loadavg($bufr = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/loadavg', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ parent::_loadavg(substr($resulte, strlen($resulto[1][0])));
+ }
+ break;
+ case 'DrayOS':
+ if (PSI_LOAD_BAR) {
+ $this->sys->setLoadPercent($this->_parseProcStat('cpu'));
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_loadavg();
+ }
+ }
+
+ /**
+ * UpTime
+ * time the system is running
+ *
+ * @return void
+ */
+ protected function _uptime($bufu = null)
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (preg_match("/\nUptime: ([^\n]+)\n/", $this->getSystemPerformance(), $buf)) {
+ parent::_uptime('up '.trim($buf[1]));
+ }
+ break;
+ case 'DrayOS':
+ if (preg_match("/System Uptime:([\d:]+)/", $this->getShowStatus(), $buf)) {
+ parent::_uptime('up '.trim($buf[1]));
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ if (CommonFunctions::executeProgram('cat', '/proc/uptime', $resulte, false) && ($resulte !== "")) {
+ $ar_buf = preg_split('/ /', $resulte);
+ $this->sys->setUptime(trim($ar_buf[0]));
+ } else {
+ parent::_uptime();
+ }
+ }
+ }
+
+ /**
+ * Kernel Version
+ *
+ * @return void
+ */
+ protected function _kernel()
+ {
+ switch ($this->_ostype) {
+ case 'FortiOS':
+ if (CommonFunctions::executeProgram('fnsysctl', 'cat /proc/version', $resulte, false) && ($resulte !== "")
+ && preg_match('/^(.*[\$#]\s*)/', $resulte, $resulto, PREG_OFFSET_CAPTURE)) {
+ $strBuf = substr($resulte, $resulto[1][1]);
+ if (preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) {
+ $verBuf = $ar_buf[1];
+ if (preg_match('/ SMP /', $strBuf)) {
+ $verBuf .= ' (SMP)';
+ }
+ $this->sys->setKernel($verBuf);
+ }
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::_kernel();
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->error->addWarning("The SSH version of phpSysInfo is a work in progress, some things currently don't work");
+ switch ($this->_ostype) {
+ case 'SSH':
+ $this->_distro();
+ break;
+ case 'FortiOS':
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+// $this->_users();
+ $this->_loadavg();
+// $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_machine();
+ $this->_cpuinfo();
+ //$this->_virtualizer();
+// $this->_pci();
+ $this->_usb();
+// $this->_i2c();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
+ break;
+ case 'DrayOS':
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+// $this->_kernel();
+ $this->_uptime();
+//// $this->_users();
+ $this->_loadavg();
+//// $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_machine();
+ $this->_cpuinfo();
+// //$this->_virtualizer();
+//// $this->_pci();
+// $this->_usb();
+//// $this->_i2c();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
+ break;
+ case 'GNU':
+ case 'Linux':
+ parent::build();
+ }
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php
index e9dee30..89fdad0 100644
--- a/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php
@@ -8,7 +8,7 @@
* @package PSI SunOS OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.SunOS.inc.php 687 2012-09-06 20:54:49Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,12 +20,89 @@
* @package PSI SunOS OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class SunOS extends OS
{
+
+ /**
+ * content of prtconf -v
+ *
+ * @var array
+ */
+ private $_prtconf = null;
+
+ /**
+ * Execute prtconf -v and save ass array
+ *
+ * @return array
+ */
+ protected function prtconf()
+ {
+ if ($this->_prtconf === null) {
+ $this->_prtconf = array();
+ if (CommonFunctions::executeProgram('prtconf', '-v', $buf, PSI_DEBUG) && ($buf!="")) {
+ $blocks = preg_split('/\n(?= \S)/', $buf, -1, PREG_SPLIT_NO_EMPTY);
+ if (!empty($blocks) && (count($blocks)>2)) {
+ array_shift($blocks);
+ foreach ($blocks as $block) {
+ if (preg_match('/^ (\S+) /', $block, $ar_buf)) {
+ $group = trim($ar_buf[1], ',');
+ $grouparr = array();
+ $blocks1 = preg_split('/\n(?= \S)/', $block, -1, PREG_SPLIT_NO_EMPTY);
+ if (!empty($blocks1) && count($blocks1)) {
+ array_shift($blocks1);
+ foreach ($blocks1 as $block1) {
+ if (!preg_match('/^ name=\'([^\']+)\'/', $block1)
+ && preg_match('/^ (\S+) /', $block1, $ar_buf)) {
+ $device = trim($ar_buf[1], ',');
+ $devicearr = array();
+ $blocks2 = preg_split('/\n(?= \S)/', $block1, -1, PREG_SPLIT_NO_EMPTY);
+ if (!empty($blocks2) && count($blocks2)) {
+ array_shift($blocks2);
+ foreach ($blocks2 as $block2) {
+ if (!preg_match('/^ name=\'([^\']+)\'/', $block2)
+ && preg_match('/^ (\S+) /', $block2, $ar_buf)) {
+ $subdev = trim($ar_buf[1], ',');
+ $subdevarr = array();
+ $blocks3 = preg_split('/\n(?= \S)/', $block2, -1, PREG_SPLIT_NO_EMPTY);
+ if (!empty($blocks3) && count($blocks3)) {
+ array_shift($blocks3);
+ foreach ($blocks3 as $block3) {
+ if (preg_match('/^ name=\'([^\']+)\' [\s\S]+ value=\'?([^\']+)\'?/m', $block3, $ar_buf)) {
+ if ($subdev==='Hardware') {
+ $subdevarr[$ar_buf[1]] = $ar_buf[2];
+ $subdevarr['device'] = $device;
+ }
+ }
+ }
+ if (count($subdevarr)) {
+ $devicearr = $subdevarr;
+ }
+ }
+ }
+ }
+ }
+ if (count($devicearr)) {
+ $grouparr[$device][] = $devicearr;
+ }
+ }
+ }
+ }
+ if (count($grouparr)) {
+ $this->_prtconf[$group][] = $grouparr;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return $this->_prtconf;
+ }
+
/**
* Extract kernel values via kstat() interface
*
@@ -35,11 +112,10 @@ class SunOS extends OS
*/
private function _kstat($key)
{
- if (CommonFunctions::executeProgram('kstat', '-p d '.$key, $m, PSI_DEBUG) &&
- !is_null($m) && (trim($m)!=="")) {
- list($key, $value) = preg_split("/\t/", trim($m), 2);
+ if (CommonFunctions::executeProgram('kstat', '-p d '.$key, $m, PSI_DEBUG) && ($m!=="")) {
+ list($key, $value) = preg_split("/\t/", $m, 2);
- return $value;
+ return trim($value);
} else {
return '';
}
@@ -52,8 +128,8 @@ class SunOS extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- $this->sys->setHostname(getenv('SERVER_NAME'));
+ if (PSI_USE_VHOST) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) {
$ip = gethostbyname($result);
@@ -64,24 +140,6 @@ class SunOS extends OS
}
}
- /**
- * IP of the Virtual Host Name
- *
- * @return void
- */
- private function _ip()
- {
- if (PSI_USE_VHOST === true) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- if (!($result = getenv('SERVER_ADDR'))) {
- $this->sys->setIp(gethostbyname($this->sys->getHostname()));
- } else {
- $this->sys->setIp($result);
- }
- }
- }
-
/**
* Kernel Version
*
@@ -89,12 +147,17 @@ class SunOS extends OS
*/
private function _kernel()
{
- if (CommonFunctions::executeProgram('uname', '-s', $os, PSI_DEBUG)) {
- if (CommonFunctions::executeProgram('uname', '-r', $version, PSI_DEBUG)) {
- $this->sys->setKernel($os.' '.$version);
- } else {
- $this->sys->setKernel($os);
+ if (CommonFunctions::executeProgram('uname', '-s', $kernel, PSI_DEBUG) && ($kernel != "")) {
+ if (CommonFunctions::executeProgram('uname', '-r', $version, PSI_DEBUG) && ($version != "")) {
+ $kernel.=' '.$version;
}
+ if (CommonFunctions::executeProgram('uname', '-v', $subversion, PSI_DEBUG) && ($subversion != "")) {
+ $kernel.=' ('.$subversion.')';
+ }
+ if (CommonFunctions::executeProgram('uname', '-i', $platform, PSI_DEBUG) && ($platform != "")) {
+ $kernel.=' '.$platform;
+ }
+ $this->sys->setKernel($kernel);
}
}
@@ -109,19 +172,6 @@ class SunOS extends OS
$this->sys->setUptime(time() - $this->_kstat('unix:0:system_misc:boot_time'));
}
- /**
- * Number of Users
- *
- * @return void
- */
- private function _users()
- {
- if (CommonFunctions::executeProgram('who', '-q', $buf, PSI_DEBUG)) {
- $who = preg_split('/=/', $buf);
- $this->sys->setUsers($who[1]);
- }
- }
-
/**
* Processor Load
* optionally create a loadbar
@@ -143,13 +193,75 @@ class SunOS extends OS
*/
private function _cpuinfo()
{
- $dev = new CpuDevice();
- if (CommonFunctions::executeProgram('uname', '-i', $buf, PSI_DEBUG)) {
- $dev->setModel(trim($buf));
+ if (CommonFunctions::executeProgram('kstat', '-p d cpu_info:*:cpu_info*:core_id', $m, PSI_DEBUG) && ($m!=="")) {
+ $cpuc = count(preg_split('/\n/', $m, -1, PREG_SPLIT_NO_EMPTY));
+ for ($cpu=0; $cpu < $cpuc; $cpu++) {
+ $dev = new CpuDevice();
+ if (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':current_clock_Hz')) !== "") {
+ $dev->setCpuSpeed($buf/1000000);
+ } elseif (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':clock_MHz')) !== "") {
+ $dev->setCpuSpeed($buf);
+ }
+ if (($buf = $this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':supported_frequencies_Hz')) !== "") {
+ $cpuarr = preg_split('/:/', $buf, -1, PREG_SPLIT_NO_EMPTY);
+ if (($cpuarrc=count($cpuarr))>1) {
+ $dev->setCpuSpeedMin($cpuarr[0]/1000000);
+ $dev->setCpuSpeedMax($cpuarr[$cpuarrc-1]/1000000);
+ }
+ }
+ if (($buf =$this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':brand')) !== "") {
+ $dev->setModel($buf);
+ } elseif (($buf =$this->_kstat('cpu_info:'.$cpu.':cpu_info'.$cpu.':cpu_type')) !== "") {
+ $dev->setModel($buf);
+ } elseif (CommonFunctions::executeProgram('uname', '-p', $buf, PSI_DEBUG) && ($buf!="")) {
+ $dev->setModel($buf);
+ } elseif (CommonFunctions::executeProgram('uname', '-i', $buf, PSI_DEBUG) && ($buf!="")) {
+ $dev->setModel($buf);
+ }
+ $this->sys->setCpus($dev);
+ }
+ }
+ }
+
+ /**
+ * PCI devices
+ *
+ * @return void
+ */
+ protected function _pci()
+ {
+ $prtconf = $this->prtconf();
+ if ((count($prtconf)>1) && isset($prtconf['pci'])) {
+ foreach ($prtconf['pci'] as $prt) {
+ foreach ($prt as $pci) {
+ foreach ($pci as $pcidev) {
+ if (isset($pcidev['device'])) {
+ $dev = new HWDevice();
+ if (isset($pcidev['model'])) {
+ $name = $pcidev['model'];
+ } else {
+ $name = $pcidev['device'];
+ }
+ if (isset($pcidev['device-name'])) {
+ $name .= ': '.$pcidev['device-name'];
+ }
+ $dev->setName($name);
+
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($pcidev['subsystem-name']) && ($pcidev['subsystem-name']!=='unknown subsystem')) {
+ $dev->setProduct($pcidev['subsystem-name']);
+ }
+ if (isset($pcidev['vendor-name'])) {
+ $dev->setManufacturer($pcidev['vendor-name']);
+ }
+ }
+
+ $this->sys->setPciDevices($dev);
+ }
+ }
+ }
+ }
}
- $dev->setCpuSpeed($this->_kstat('cpu_info:0:cpu_info0:clock_MHz'));
- $dev->setCache($this->_kstat('cpu_info:0:cpu_info0:cpu_type') * 1024);
- $this->sys->setCpus($dev);
}
/**
@@ -189,23 +301,22 @@ class SunOS extends OS
}
}
if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
- if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0], $bufr2, PSI_DEBUG)
- && !is_null($bufr2) && (trim($bufr2) !== "")) {
+ if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0], $bufr2, PSI_DEBUG) && ($bufr2!=="")) {
$bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe2 as $buf2) {
- if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1]));
- elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2))
+ if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) {
+ if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', strtoupper($ar_buf2[1])));
+ } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) {
$dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ }
}
}
- if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' inet6', $bufr2, PSI_DEBUG)
- && !is_null($bufr2) && (trim($bufr2) !== "")) {
+ if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' inet6', $bufr2, PSI_DEBUG) && ($bufr2!=="")) {
$bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
foreach ($bufe2 as $buf2) {
if (preg_match('/^\s+inet6\s+([^\s\/]+)/i', $buf2, $ar_buf2)
- && !preg_match('/^fe80::/i', $ar_buf2[1]))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
+ && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1]))
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
}
}
}
@@ -227,14 +338,16 @@ class SunOS extends OS
$this->sys->setMemTotal($this->_kstat('unix:0:system_pages:pagestotal') * $pagesize);
$this->sys->setMemUsed($this->_kstat('unix:0:system_pages:pageslocked') * $pagesize);
$this->sys->setMemFree($this->_kstat('unix:0:system_pages:pagesfree') * $pagesize);
- $dev = new DiskDevice();
- $dev->setName('SWAP');
- $dev->setFsType('swap');
- $dev->setMountPoint('SWAP');
- $dev->setTotal($this->_kstat('unix:0:vminfo:swap_avail') / 1024);
- $dev->setUsed($this->_kstat('unix:0:vminfo:swap_alloc') / 1024);
- $dev->setFree($this->_kstat('unix:0:vminfo:swap_free') / 1024);
- $this->sys->setSwapDevices($dev);
+ if (($swap=$this->_kstat('unix:0:vminfo:swap_avail')) > 0) {
+ $dev = new DiskDevice();
+ $dev->setName('SWAP');
+ $dev->setFsType('swap');
+ $dev->setMountPoint('SWAP');
+ $dev->setTotal($swap / 1024);
+ $dev->setUsed($this->_kstat('unix:0:vminfo:swap_alloc') / 1024);
+ $dev->setFree($this->_kstat('unix:0:vminfo:swap_free') / 1024);
+ $this->sys->setSwapDevices($dev);
+ }
}
/**
@@ -289,8 +402,21 @@ class SunOS extends OS
*/
private function _distro()
{
- $this->sys->setDistribution('SunOS');
- $this->sys->setDistributionIcon('SunOS.png');
+ if (CommonFunctions::rfts('/etc/release', $buf, 1, 4096, false) && (trim($buf)!="")) {
+ $this->sys->setDistribution(trim($buf));
+ $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true);
+ if ($list && preg_match('/^(\S+)\s*/', preg_replace('/^open\s+/', 'open', preg_replace('/^oracle\s+/', 'oracle', strtolower(trim($buf)))), $id_buf) && isset($list[$distid=(trim($id_buf[1].' sunos'))]['Image'])) {
+ $this->sys->setDistributionIcon($list[$distid]['Image']);
+ if (isset($list[trim($distid)]['Name'])) {
+ $this->sys->setDistribution(trim($list[$distid]['Name']).' '.$this->sys->getDistribution());
+ }
+ } else {
+ $this->sys->setDistributionIcon('SunOS.png');
+ }
+ } else {
+ $this->sys->setDistribution('SunOS');
+ $this->sys->setDistributionIcon('SunOS.png');
+ }
}
/**
@@ -328,22 +454,32 @@ class SunOS extends OS
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->error->addError("WARN", "The SunOS version of phpSysInfo is a work in progress, some things currently don't work");
- $this->_distro();
- $this->_hostname();
- $this->_ip();
- $this->_kernel();
- $this->_uptime();
- $this->_users();
- $this->_loadavg();
- $this->_cpuinfo();
- $this->_network();
- $this->_memory();
- $this->_filesystems();
- $this->_processes();
+ $this->error->addWarning("The SunOS version of phpSysInfo is a work in progress, some things currently don't work");
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_distro();
+ $this->_hostname();
+ $this->_kernel();
+ $this->_uptime();
+ $this->_users();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_cpuinfo();
+ $this->_pci();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php
index ff5eac5..5cc8758 100644
--- a/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php
+++ b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php
@@ -8,7 +8,7 @@
* @package PSI WINNT OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.WINNT.inc.php 699 2012-09-15 11:57:13Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,25 +21,109 @@
* @package PSI WINNT OS class
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class WINNT extends OS
{
/**
- * holds the COM object that we pull all the WMI data from
+ * holds codepage for chcp
+ *
+ * @var int
+ */
+ private static $_cp = null;
+
+ /**
+ * holds the data from WMI Win32_OperatingSystem
+ *
+ * @var array
+ */
+ private static $_Win32_OperatingSystem = null;
+
+ /**
+ * holds the data from WMI Win32_ComputerSystem
+ *
+ * @var array
+ */
+ private $_Win32_ComputerSystem = null;
+
+ /**
+ * holds the data from WMI Win32_Processor
+ *
+ * @var array
+ */
+ private static $_Win32_Processor = null;
+
+ /**
+ * holds the data from WMI Win32_PhysicalMemory
+ *
+ * @var array
+ */
+ private static $_Win32_PhysicalMemory = null;
+
+ /**
+ * holds the data from WMI Win32_PerfFormattedData_PerfOS_Processor
+ *
+ * @var array
+ */
+ private $_Win32_PerfFormattedData_PerfOS_Processor = null;
+
+ /**
+ * holds the data from systeminfo command
+ *
+ * @var string
+ */
+ private $_systeminfo = null;
+
+ /**
+ * holds the COM object that we pull WMI root\CIMv2 data from
*
* @var Object
*/
- private $_wmi = null;
+ private static $_wmi = null;
+
+ /**
+ * holds the COM object that we pull all the EnumKey and RegRead data from
+ *
+ * @var Object
+ */
+ private $_reg = null;
+
+ /**
+ * holds result of 'cmd /c ver'
+ *
+ * @var string
+ */
+ private $_ver = "";
+
+ /**
+ * holds system manufacturer
+ *
+ * @var string
+ */
+ private $_Manufacturer = "";
+
+ /**
+ * holds system model
+ *
+ * @var string
+ */
+ private $_Model = "";
/**
* holds all devices, which are in the system
*
* @var array
*/
- private $_wmidevices;
+ private $_wmidevices = null;
+
+ /**
+ * holds all disks, which are in the system
+ *
+ * @var array
+ */
+ private $_wmidisks = array();
/**
* store language encoding of the system to convert some output to utf-8
@@ -55,28 +139,493 @@ class WINNT extends OS
*/
private $_syslang = null;
+ /**
+ * value of checking run as administrator
+ *
+ * @var boolean
+ */
+ private static $_asadmin = null;
+
+ /**
+ * returns codepage for chcp
+ *
+ * @return int
+ */
+ public static function getcp()
+ {
+ return self::$_cp;
+ }
+
+ /**
+ * returns the COM object that we pull WMI root\CIMv2 data from
+ *
+ * @return Object
+ */
+ public static function getcimv2wmi()
+ {
+ return self::$_wmi;
+ }
+
+ /**
+ * reads the data from WMI Win32_OperatingSystem
+ *
+ * @return array
+ */
+ public static function _get_Win32_OperatingSystem()
+ {
+ if (self::$_Win32_OperatingSystem === null) self::$_Win32_OperatingSystem = self::getWMI(self::$_wmi, 'Win32_OperatingSystem', array('CodeSet', 'Locale', 'LastBootUpTime', 'LocalDateTime', 'Version', 'ServicePackMajorVersion', 'Caption', 'TotalVisibleMemorySize', 'FreePhysicalMemory'));
+ return self::$_Win32_OperatingSystem;
+ }
+
+ /**
+ * reads the data from WMI Win32_ComputerSystem
+ *
+ * @return array
+ */
+ private function _get_Win32_ComputerSystem()
+ {
+ if ($this->_Win32_ComputerSystem === null) $this->_Win32_ComputerSystem = self::getWMI(self::$_wmi, 'Win32_ComputerSystem', array('Name', 'Manufacturer', 'Model', 'SystemFamily'));
+ return $this->_Win32_ComputerSystem;
+ }
+
+ /**
+ * reads the data from WMI Win32_Processor
+ *
+ * @return array
+ */
+ public static function _get_Win32_Processor()
+ {
+ if (self::$_Win32_Processor === null) self::$_Win32_Processor = self::getWMI(self::$_wmi, 'Win32_Processor', array('DeviceID', 'LoadPercentage', 'AddressWidth', 'Name', 'L2CacheSize', 'L3CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'NumberOfLogicalProcessors', 'MaxClockSpeed', 'Manufacturer', 'Architecture', 'Caption', 'CurrentVoltage'));
+ return self::$_Win32_Processor;
+ }
+
+ /**
+ * reads the data from WMI Win32_PhysicalMemory
+ *
+ * @return array
+ */
+ public static function _get_Win32_PhysicalMemory()
+ {
+ if (self::$_Win32_PhysicalMemory === null) self::$_Win32_PhysicalMemory = self::getWMI(self::$_wmi, 'Win32_PhysicalMemory', array('PartNumber', 'DeviceLocator', 'Capacity', 'Manufacturer', 'SerialNumber', 'Speed', 'ConfiguredClockSpeed', 'ConfiguredVoltage', 'MemoryType', 'SMBIOSMemoryType', 'FormFactor', 'DataWidth', 'TotalWidth', 'BankLabel', 'MinVoltage', 'MaxVoltage'));
+ return self::$_Win32_PhysicalMemory;
+ }
+
+ /**
+ * reads the data from WMI Win32_PerfFormattedData_PerfOS_Processor
+ *
+ * @return array
+ */
+ private function _get_Win32_PerfFormattedData_PerfOS_Processor()
+ {
+ if ($this->_Win32_PerfFormattedData_PerfOS_Processor === null) {
+ $this->_Win32_PerfFormattedData_PerfOS_Processor = array();
+ $buffer = $this->_get_Win32_OperatingSystem();
+ if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "5.1", ">=")) { // minimal windows 2003 or windows XP
+ $cpubuffer = self::getWMI(self::$_wmi, 'Win32_PerfFormattedData_PerfOS_Processor', array('Name', 'PercentProcessorTime'));
+ foreach ($cpubuffer as $cpu) {
+ if (isset($cpu['Name']) && isset($cpu['PercentProcessorTime'])) {
+ $this->_Win32_PerfFormattedData_PerfOS_Processor['cpu'.$cpu['Name']] = $cpu['PercentProcessorTime'];
+ }
+ }
+ }
+ }
+
+ return $this->_Win32_PerfFormattedData_PerfOS_Processor;
+ }
+
+ /**
+ * reads the data from systeminfo
+ *
+ * @return string
+ */
+ private function _get_systeminfo()
+ {
+ if (!defined('PSI_EMU_HOSTNAME')) {
+ if ($this->_systeminfo === null) CommonFunctions::executeProgram('systeminfo', '', $this->_systeminfo, false);
+ return $this->_systeminfo;
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * checks WINNT and 'run as Administrator' mode
+ *
+ * @return boolean
+ */
+ public static function isAdmin()
+ {
+ if (self::$_asadmin == null) {
+ if (PSI_OS == 'WINNT') {
+ $strBuf = '';
+ CommonFunctions::executeProgram('sfc', '2>&1', $strBuf, false); // 'net session' for detection does not work if "Server" (LanmanServer) service is stopped
+ if (preg_match('/^\/SCANNOW\s/m', preg_replace('/(\x00)/', '', $strBuf))) { // SCANNOW checking - also if Unicode
+ self::$_asadmin = true;
+ } else {
+ self::$_asadmin = false;
+ }
+ } else {
+ self::$_asadmin = false;
+ }
+ }
+
+ return self::$_asadmin;
+ }
+
+ /**
+ * function for getting a list of values in the specified context
+ * optionally filter this list, based on the list from third parameter
+ *
+ * @param $wmi object holds the COM object that we pull the WMI data from
+ * @param string $strClass name of the class where the values are stored
+ * @param array $strValue filter out only needed values, if not set all values of the class are returned
+ *
+ * @return array content of the class stored in an array
+ */
+ public static function getWMI($wmi, $strClass, $strValue = array())
+ {
+ $arrData = array();
+ if (gettype($wmi) === "object") {
+ $value = "";
+ try {
+ $objWEBM = $wmi->Get($strClass);
+ $arrProp = $objWEBM->Properties_;
+ $arrWEBMCol = $objWEBM->Instances_();
+ foreach ($arrWEBMCol as $objItem) {
+ if (is_array($arrProp)) {
+ reset($arrProp);
+ }
+ $arrInstance = array();
+ foreach ($arrProp as $propItem) {
+ $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";");
+ if (empty($strValue)) {
+ if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
+ else $arrInstance[$propItem->Name] = $value;
+ } else {
+ if (in_array($propItem->Name, $strValue)) {
+ if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
+ else $arrInstance[$propItem->Name] = $value;
+ }
+ }
+ }
+ $arrData[] = $arrInstance;
+ }
+ } catch (Exception $e) {
+ if (PSI_DEBUG && (($message = trim($e->getMessage())) !== "Source: SWbemServicesExDescription: Not found")) {
+ $error = PSI_Error::singleton();
+ $error->addError("getWMI()", preg_replace('/ /', "\n", preg_replace('/|<\/b>/', '', $message)));
+ }
+ }
+ } elseif ((gettype($wmi) === "string") && (PSI_OS == 'Linux')) {
+ $delimeter = '@@@DELIM@@@';
+ if (CommonFunctions::executeProgram('wmic', '--delimiter="'.$delimeter.'" '.$wmi.' '.$strClass.'" 2>/dev/null', $strBuf, true) && preg_match("/^CLASS:\s/", $strBuf)) {
+ if (self::$_cp) {
+ if (self::$_cp == 932) {
+ $codename = ' (SJIS)';
+ } elseif (self::$_cp == 949) {
+ $codename = ' (EUC-KR)';
+ } elseif (self::$_cp == 950) {
+ $codename = ' (BIG-5)';
+ } else {
+ $codename = '';
+ }
+ self::convertCP($strBuf, 'windows-'.self::$_cp.$codename);
+ }
+ $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY);
+ if (count($lines) >=3) {
+ unset($lines[0]);
+ $names = preg_split('/'.$delimeter.'/', $lines[1], -1, PREG_SPLIT_NO_EMPTY);
+ $namesc = count($names);
+ unset($lines[1]);
+ foreach ($lines as $line) {
+ $arrInstance = array();
+ $values = preg_split('/'.$delimeter.'/', $line, -1);
+ if (count($values) == $namesc) {
+ foreach ($values as $id=>$value) {
+ if (empty($strValue)) {
+ if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value);
+ else $arrInstance[$names[$id]] = null;
+ } else {
+ if (in_array($names[$id], $strValue)) {
+ if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value);
+ else $arrInstance[$names[$id]] = null;
+ }
+ }
+ }
+ $arrData[] = $arrInstance;
+ }
+ }
+ }
+ }
+ }
+
+ return $arrData;
+ }
+
+ /**
+ * readReg function
+ *
+ * @return boolean command successfull or not
+ */
+ public static function readReg($reg, $strName, &$strBuffer, $booErrorRep = true, $dword = false, $bits64 = false)
+ {
+ $strBuffer = '';
+
+ if ($reg === false) {
+ if (defined('PSI_EMU_HOSTNAME')) {
+ return false;
+ }
+ $last = strrpos($strName, "\\");
+ $keyname = substr($strName, $last + 1);
+ if ($bits64) {
+ $param = ' /reg:64';
+ } else {
+ $param = '';
+ }
+ if ($dword) {
+ $valtype = "DWORD";
+ } else {
+ $valtype = "SZ|EXPAND_SZ";
+ }
+ if (self::$_cp) {
+ if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) {
+ if ($dword) {
+ $strBuffer = strval(hexdec($buffer2[2]));
+ } else {
+ $strBuffer = $buffer2[2];
+ }
+ } else {
+ return false;
+ }
+ } else {
+ if (CommonFunctions::executeProgram('reg', 'query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) {
+ if ($dword) {
+ $strBuffer = strval(hexdec($buffer2[2]));
+ } else {
+ $strBuffer = $buffer2[2];
+ }
+ } else {
+ return false;
+ }
+ }
+ } elseif (gettype($reg) === "object") {
+ $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006);
+ $first = strpos($strName, "\\");
+ $last = strrpos($strName, "\\");
+ $hkey = substr($strName, 0, $first);
+ if (isset($_hkey[$hkey])) {
+ $sub_keys = new VARIANT();
+ try {
+ if ($dword) {
+ $reg->Get("StdRegProv")->GetDWORDValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys);
+ } else {
+ $reg->Get("StdRegProv")->GetStringValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys);
+ }
+ } catch (Exception $e) {
+ if ($booErrorRep) {
+ $error = PSI_Error::singleton();
+ $error->addError("GetStringValue()", preg_replace('/ /', "\n", preg_replace('/|<\/b>/', '', $e->getMessage())));
+ }
+
+ return false;
+ }
+ if (variant_get_type($sub_keys) !== VT_NULL) {
+ $strBuffer = strval($sub_keys);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * enumKey function
+ *
+ * @return boolean command successfull or not
+ */
+ public static function enumKey($reg, $strName, &$arrBuffer, $booErrorRep = true)
+ {
+ $arrBuffer = array();
+
+ if ($reg === false) {
+ if (defined('PSI_EMU_HOSTNAME')) {
+ return false;
+ }
+ if (self::$_cp) {
+ if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) {
+ foreach ($buffer2[1] as $sub_key) {
+ $arrBuffer[] = trim($sub_key);
+ }
+ } else {
+ return false;
+ }
+ } else {
+ if (CommonFunctions::executeProgram('reg', 'query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) {
+ foreach ($buffer2[1] as $sub_key) {
+ $arrBuffer[] = trim($sub_key);
+ }
+ } else {
+ return false;
+ }
+ }
+ } elseif (gettype($reg) === "object") {
+ $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006);
+ $first = strpos($strName, "\\");
+ $hkey = substr($strName, 0, $first);
+ if (isset($_hkey[$hkey])) {
+ $sub_keys = new VARIANT();
+ try {
+ $reg->Get("StdRegProv")->EnumKey(strval($_hkey[$hkey]), substr($strName, $first+1), $sub_keys);
+ } catch (Exception $e) {
+ if ($booErrorRep) {
+ $error = PSI_Error::singleton();
+ $error->addError("enumKey()", preg_replace('/ /', "\n", preg_replace('/|<\/b>/', '', $e->getMessage())));;
+ }
+
+ return false;
+ }
+ if (variant_get_type($sub_keys) !== VT_NULL) {
+ foreach ($sub_keys as $sub_key) {
+ $arrBuffer[] = $sub_key;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * initWMI function
+ *
+ * @return string, object or false
+ */
+ public static function initWMI($namespace, $booErrorRep = false)
+ {
+ $wmi = false;
+ if (self::$_wmi !== false) { // WMI not disabled
+ try {
+ if (PSI_OS == 'Linux') {
+ if (defined('PSI_EMU_HOSTNAME'))
+ $wmi = '--namespace="'.$namespace.'" -U '.PSI_EMU_USER.'%'.PSI_EMU_PASSWORD.' //'.PSI_EMU_HOSTNAME.' "select * from';
+ } elseif (PSI_OS == 'WINNT') {
+ $objLocator = new COM('WbemScripting.SWbemLocator');
+ if (defined('PSI_EMU_HOSTNAME'))
+ $wmi = $objLocator->ConnectServer(PSI_EMU_HOSTNAME, $namespace, PSI_EMU_USER, PSI_EMU_PASSWORD);
+ else
+ $wmi = $objLocator->ConnectServer('', $namespace);
+ }
+ } catch (Exception $e) {
+ if ($booErrorRep) {
+ $error = PSI_Error::singleton();
+ $error->addError("WMI connect ".$namespace." error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed or credentials.");
+ }
+ }
+ }
+
+ return $wmi;
+ }
+
+ /**
+ * convertCP function
+ *
+ * @return void
+ */
+ public static function convertCP(&$strBuf, $encoding)
+ {
+ if (defined('PSI_SYSTEM_CODEPAGE') && (PSI_SYSTEM_CODEPAGE != null) && ($encoding != null) && ($encoding != PSI_SYSTEM_CODEPAGE)) {
+ $systemcp = PSI_SYSTEM_CODEPAGE;
+ if (preg_match("/^windows-\d+ \((.+)\)$/", $systemcp, $buf)) {
+ $systemcp = $buf[1];
+ }
+ if (preg_match("/^windows-\d+ \((.+)\)$/", $encoding, $buf)) {
+ $encoding = $buf[1];
+ }
+ $enclist = mb_list_encodings();
+ if (in_array($encoding, $enclist) && in_array($systemcp, $enclist)) {
+ $strBuf = mb_convert_encoding($strBuf, $encoding, $systemcp);
+ } elseif (function_exists("iconv")) {
+ if (($iconvout=iconv($systemcp, $encoding.'//IGNORE', $strBuf))!==false) {
+ $strBuf = $iconvout;
+ }
+ } elseif (function_exists("libiconv") && (($iconvout=libiconv($systemcp, $encoding, $strBuf))!==false)) {
+ $strBuf = $iconvout;
+ }
+ }
+ }
+
/**
* build the global Error object and create the WMI connection
*/
- public function __construct()
+ public function __construct($blockname = false)
{
- parent::__construct();
- // don't set this params for local connection, it will not work
- $strHostname = '';
- $strUser = '';
- $strPassword = '';
- try {
- // initialize the wmi object
- $objLocator = new COM('WbemScripting.SWbemLocator');
- if ($strHostname == "") {
- $this->_wmi = $objLocator->ConnectServer();
-
- } else {
- $this->_wmi = $objLocator->ConnectServer($strHostname, 'root\CIMv2', $strHostname.'\\'.$strUser, $strPassword);
- }
- } catch (Exception $e) {
- $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed.");
+ parent::__construct($blockname);
+ if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('cmd', '/c ver 2>nul', $ver_value, false) && (($ver_value = trim($ver_value)) !== "")) {
+ $this->_ver = $ver_value;
}
+ if (($this->_ver !== "") && preg_match("/ReactOS\r?\n\S+\s+.+/", $this->_ver)) {
+ self::$_wmi = false; // No WMI info on ReactOS yet
+ $this->_reg = false; // No EnumKey and ReadReg on ReactOS yet
+ } else {
+ if ((PSI_OS == 'WINNT') && !defined('PSI_SYSTEM_CODEPAGE')) {
+ if (defined('PSI_EMU_HOSTNAME')) {
+ try {
+ $objLocator = new COM('WbemScripting.SWbemLocator');
+ $wmi = $objLocator->ConnectServer('', 'root\CIMv2');
+ $buffer = self::getWMI($wmi, 'Win32_OperatingSystem', array('CodeSet'));
+ if (!$buffer) {
+ $reg = $objLocator->ConnectServer('', 'root\default');
+ if (self::readReg($reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) {
+ $buffer[0]['CodeSet'] = $strBuf;
+ }
+ }
+ if ($buffer && isset($buffer[0]) && isset($buffer[0]['CodeSet'])) {
+ $codeset = $buffer[0]['CodeSet'];
+ if ($codeset == 932) {
+ $codename = ' (SJIS)';
+ } elseif ($codeset == 949) {
+ $codename = ' (EUC-KR)';
+ } elseif ($codeset == 950) {
+ $codename = ' (BIG-5)';
+ } else {
+ $codename = '';
+ }
+ define('PSI_SYSTEM_CODEPAGE', 'windows-'.$codeset.$codename);
+ } else {
+ define('PSI_SYSTEM_CODEPAGE', null);
+ if (PSI_DEBUG) {
+ $this->error->addError("__construct()", "PhpSysInfo can not detect PSI_SYSTEM_CODEPAGE");
+ }
+ }
+ } catch (Exception $e) {
+ define('PSI_SYSTEM_CODEPAGE', null);
+ if (PSI_DEBUG) {
+ $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed");
+ }
+ }
+ } else {
+ define('PSI_SYSTEM_CODEPAGE', null);
+ }
+ }
+ self::$_wmi = self::initWMI('root\CIMv2', true);
+ if (PSI_OS == 'WINNT') {
+ $this->_reg = self::initWMI('root\default', PSI_DEBUG);
+ if (gettype($this->_reg) === "object") {
+ $this->_reg->Security_->ImpersonationLevel = 3;
+ }
+ } else {
+ $this->_reg = false; // No EnumKey and ReadReg on Linux
+ }
+ }
+
$this->_getCodeSet();
}
@@ -87,19 +636,42 @@ class WINNT extends OS
*/
private function _getCodeSet()
{
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('CodeSet', 'OSLanguage'));
- if ($buffer) {
- $this->_codepage = 'windows-'.$buffer[0]['CodeSet'];
- $lang = "";
- if (is_readable(APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(APP_ROOT.'/data/languages.ini', true))) {
- if (isset($langdata['WINNT'][$buffer[0]['OSLanguage']])) {
- $lang = $langdata['WINNT'][$buffer[0]['OSLanguage']];
+ $buffer = $this->_get_Win32_OperatingSystem();
+ if (!$buffer) {
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) {
+ $buffer[0]['CodeSet'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Language\\Default", $strBuf, false)) {
+ $buffer[0]['Locale'] = $strBuf;
+ }
+ }
+ if ($buffer && isset($buffer[0])) {
+ if (isset($buffer[0]['CodeSet'])) {
+ $codeset = $buffer[0]['CodeSet'];
+ if ($codeset == 932) {
+ $codename = ' (SJIS)';
+ } elseif ($codeset == 949) {
+ $codename = ' (EUC-KR)';
+ } elseif ($codeset == 950) {
+ $codename = ' (BIG-5)';
+ } else {
+ $codename = '';
}
+ self::$_cp = $codeset;
+ $this->_codepage = 'windows-'.$codeset.$codename;
}
- if ($lang == "") {
- $lang = 'Unknown';
+ if (isset($buffer[0]['Locale']) && (($locale = hexdec($buffer[0]['Locale']))>0)) {
+ $lang = "";
+ if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) {
+ if (isset($langdata['WINNT'][$locale])) {
+ $lang = $langdata['WINNT'][$locale];
+ }
+ }
+ if ($lang == "") {
+ $lang = 'Unknown';
+ }
+ $this->_syslang = $lang.' ('.$locale.')';
}
- $this->_syslang = $lang.' ('.$buffer[0]['OSLanguage'].')';
}
}
@@ -112,13 +684,132 @@ class WINNT extends OS
*/
private function _devicelist($strType)
{
- if (empty($this->_wmidevices)) {
- $this->_wmidevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID'));
+ if ($this->_wmidevices === null) {
+ $this->_wmidevices = array();
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID', 'Manufacturer', 'PNPClass'));
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size', 'SerialNumber'));
+ } else {
+ $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size'));
+ }
+ } else {
+ $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID'));
+ }
+
+ if (empty($this->_wmidevices)) {
+ $lstdevs = array();
+ $services = array();
+ foreach (array('PCI', 'USB') as $type) {
+ $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$type;
+ if (self::enumKey($this->_reg, $hkey, $vendevs, false)) {
+ foreach ($vendevs as $vendev) if (self::enumKey($this->_reg, $hkey."\\".$vendev, $ids, false)) {
+ foreach ($ids as $id) {
+ if ($type === 'PCI') { // enumerate all PCI devices
+ $lstdevs[$type."\\".$vendev."\\".$id] = true;
+ } elseif (self::readReg($this->_reg, $hkey."\\".$vendev."\\".$id."\\Service", $service, false)) {
+ $services[$service] = true; // ever used USB services
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services";
+ foreach ($services as $service=>$tmp) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\Count", $count, false, true) && ($count > 0)) {
+ for ($i = 0; $i < $count; $i++) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\".$i, $id, false) && preg_match("/^USB/", $id)) {
+ $lstdevs[$id] = true; // used USB devices
+ }
+ }
+
+ $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\";
+ foreach ($lstdevs as $lstdev=>$tmp) {
+ if (self::readReg($this->_reg, $hkey.$lstdev."\\DeviceDesc", $nameBuf, false)) {
+ $namesplit = preg_split('/;/', $nameBuf, -1, PREG_SPLIT_NO_EMPTY);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && self::readReg($this->_reg, $hkey.$lstdev."\\Mfg", $mfgBuf, false)) {
+ $mfgsplit = preg_split('/;/', $mfgBuf, -1, PREG_SPLIT_NO_EMPTY);
+ $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev, 'Manufacturer'=>$mfgsplit[count($mfgsplit)-1]);
+ } else {
+ $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev);
+ }
+ }
+ }
+
+ $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi";
+ $id = 0;
+ if (self::enumKey($this->_reg, $hkey, $portBuf, false)) {
+ foreach ($portBuf as $scsiport) {
+ if (self::enumKey($this->_reg, $hkey."\\".$scsiport, $busBuf, false)) {
+ foreach ($busBuf as $scsibus) {
+ if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus, $tarBuf, false)) {
+ foreach ($tarBuf as $scsitar) if (!strncasecmp($scsitar, "Target Id ", strlen("Target Id "))) {
+ if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar, $logBuf, false)) {
+ foreach ($logBuf as $scsilog) if (!strncasecmp($scsilog, "Logical Unit Id ", strlen("Logical Unit Id "))) {
+ $hkey2 = $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar."\\".$scsilog."\\";
+ if ((self::readReg($this->_reg, $hkey2."DeviceType", $typeBuf, false) || self::readReg($this->_reg, $hkey2."Type", $typeBuf, false))
+ && (($typeBuf=strtolower(trim($typeBuf))) !== "")) {
+ if ((($typeBuf == 'diskperipheral') || ($typeBuf == 'cdromperipheral'))
+ && self::readReg($this->_reg, $hkey2."Identifier", $ideBuf, false)) {
+ $this->_wmidevices[] = array('Name'=>$ideBuf, 'PNPDeviceID'=>'SCSI\\'.$id);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
+ && self::readReg($this->_reg, $hkey2."SerialNumber", $serBuf, false)
+ && (($serBuf=trim($serBuf)) !== "")) {
+ $this->_wmidisks[] = array('PNPDeviceID'=>'SCSI\\'.$id, 'SerialNumber'=>$serBuf);
+ }
+ $id++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
+
$list = array();
foreach ($this->_wmidevices as $device) {
if (substr($device['PNPDeviceID'], 0, strpos($device['PNPDeviceID'], "\\") + 1) == ($strType."\\")) {
- $list[] = $device['Name'];
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (!isset($device['PNPClass']) || ($device['PNPClass']===$strType) || ($device['PNPClass']==='System')) {
+ $device['PNPClass'] = null;
+ }
+ if (!isset($device['Manufacturer']) || preg_match('/^\(.*\)$/', $device['Manufacturer']) || (($device['PNPClass']==='USB') && preg_match('/\sUSB\s/', $device['Manufacturer']))) {
+ $device['Manufacturer'] = null;
+ }
+ $device['Capacity'] = null;
+ if (($strType==='IDE')||($strType==='SCSI')) {
+ foreach ($this->_wmidisks as $disk) {
+ if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['Size'])) {
+ $device['Capacity'] = $disk['Size'];
+ break;
+ }
+ }
+ }
+ $device['Serial'] = null;
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ if ($strType==='USB') {
+// if (preg_match('/\\\\([^\\\\][^&\\\\][^\\\\]+)$/', $device['PNPDeviceID'], $buf)) { // second character !== &
+ if (preg_match('/\\\\(\w+)$/', $device['PNPDeviceID'], $buf)) {
+ $device['Serial'] = $buf[1];
+ }
+ } elseif (($strType==='IDE')||($strType==='SCSI')) {
+ foreach ($this->_wmidisks as $disk) {
+ if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['SerialNumber'])) {
+ $device['Serial'] = $disk['SerialNumber'];
+ break;
+ }
+ }
+ }
+ }
+ $list[] = array('Name'=>$device['Name'], 'Manufacturer'=>$device['Manufacturer'], 'Product'=>$device['PNPClass'], 'Capacity'=>$device['Capacity'], 'Serial'=>$device['Serial']);
+ } else {
+ $list[] = array('Name'=>$device['Name']);
+ }
}
}
@@ -132,48 +823,76 @@ class WINNT extends OS
*/
private function _hostname()
{
- if (PSI_USE_VHOST === true) {
- if ($hnm = getenv('SERVER_NAME')) $this->sys->setHostname($hnm);
+ if (PSI_USE_VHOST && !defined('PSI_EMU_HOSTNAME')) {
+ if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
} else {
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name'));
+ $buffer = $this->_get_Win32_ComputerSystem();
+ if (!$buffer && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName\\ComputerName", $strBuf, false) && (strlen($strBuf) > 0)) {
+ $buffer[0]['Name'] = $strBuf;
+ }
if ($buffer) {
$result = $buffer[0]['Name'];
$ip = gethostbyname($result);
if ($ip != $result) {
- $long = ip2long($ip);
- if (($long >= 167772160 && $long <= 184549375) ||
- ($long >= -1408237568 && $long <= -1407188993) ||
- ($long >= -1062731776 && $long <= -1062666241) ||
- ($long >= 2130706432 && $long <= 2147483647) || $long == -1) {
- $this->sys->setHostname($result); //internal ip
+ if ((version_compare("10.0.0.0", $ip, "<=") && version_compare($ip, "10.255.255.255", "<=")) ||
+ (version_compare("172.16.0.0", $ip, "<=") && version_compare($ip, "172.31.255.255", "<=")) ||
+ (version_compare("192.168.0.0", $ip, "<=") && version_compare($ip, "192.168.255.255", "<=")) ||
+ (version_compare("127.0.0.0", $ip, "<=") && version_compare($ip, "127.255.255.255", "<=")) ||
+ (version_compare("169.254.1.0", $ip, "<=") && version_compare($ip, "169.254.254.255", "<=")) ||
+ (version_compare("255.255.255.255", $ip, "=="))) {
+ $this->sys->setHostname($result); // internal ip
} else {
- $this->sys->setHostname(gethostbyaddr($ip));
+ $hostname = gethostbyaddr($ip);
+ if ($hostname !== false)
+ $this->sys->setHostname($hostname);
+ else
+ $this->sys->setHostname($result);
}
+ } else {
+ $this->sys->setHostname($result);
}
- } else {
- if ($hnm = getenv('COMPUTERNAME')) $this->sys->setHostname($hnm);
+ } elseif (defined('PSI_EMU_HOSTNAME')) {
+ $this->sys->setHostname(PSI_EMU_HOSTNAME);
+ } elseif (CommonFunctions::readenv('COMPUTERNAME', $hnm)) {
+ $this->sys->setHostname($hnm);
}
}
}
/**
- * IP of the Canonical Host Name
+ * Virtualizer info
*
* @return void
*/
- private function _ip()
+ protected function _virtualizer()
{
- if (PSI_USE_VHOST === true) {
- if ((($hnm=$this->sys->getHostname()) != 'localhost') &&
- (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip);
- } else {
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name'));
- if ($buffer) {
- $result = $buffer[0]['Name'];
- $this->sys->setIp(gethostbyname($result));
- } else {
- if ((($hnm=$this->sys->getHostname()) != 'localhost') &&
- (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip);
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo()
+
+ $vendor_array = array();
+ if ($this->_Model != "") {
+ $vendor_array[] = $this->_Model;
+ }
+ if ($this->_Manufacturer != "") {
+ if ($this->_Model != "") {
+ $vendor_array[] = $this->_Manufacturer." ".$this->_Model;
+ } else {
+ $vendor_array[] = $this->_Manufacturer;
+ }
+ }
+ $novm = true;
+ if (count($vendor_array)>0) {
+ $virt = CommonFunctions::decodevirtualizer($vendor_array);
+ if ($virt !== null) {
+ $this->sys->setVirtualizer($virt);
+ $novm = false;
+ }
+ }
+ if ($novm) {
+ // Detect QEMU cpu
+ if (isset($cpuvirt["cpuid:QEMU"])) {
+ $this->sys->setVirtualizer('qemu'); // QEMU
+ }
}
}
}
@@ -188,24 +907,43 @@ class WINNT extends OS
{
$result = 0;
date_default_timezone_set('UTC');
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('LastBootUpTime', 'LocalDateTime'));
- if ($buffer) {
- $byear = intval(substr($buffer[0]['LastBootUpTime'], 0, 4));
- $bmonth = intval(substr($buffer[0]['LastBootUpTime'], 4, 2));
- $bday = intval(substr($buffer[0]['LastBootUpTime'], 6, 2));
- $bhour = intval(substr($buffer[0]['LastBootUpTime'], 8, 2));
- $bminute = intval(substr($buffer[0]['LastBootUpTime'], 10, 2));
- $bseconds = intval(substr($buffer[0]['LastBootUpTime'], 12, 2));
- $lyear = intval(substr($buffer[0]['LocalDateTime'], 0, 4));
- $lmonth = intval(substr($buffer[0]['LocalDateTime'], 4, 2));
- $lday = intval(substr($buffer[0]['LocalDateTime'], 6, 2));
- $lhour = intval(substr($buffer[0]['LocalDateTime'], 8, 2));
- $lminute = intval(substr($buffer[0]['LocalDateTime'], 10, 2));
- $lseconds = intval(substr($buffer[0]['LocalDateTime'], 12, 2));
- $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear);
- $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear);
+ $buffer = $this->_get_Win32_OperatingSystem();
+ if ($buffer && ($buffer[0]['LastBootUpTime'] !== null)) {
+ $local = $buffer[0]['LocalDateTime'];
+ $boot = $buffer[0]['LastBootUpTime'];
+
+ $lyear = intval(substr($local, 0, 4));
+ $lmonth = intval(substr($local, 4, 2));
+ $lday = intval(substr($local, 6, 2));
+ $lhour = intval(substr($local, 8, 2));
+ $lminute = intval(substr($local, 10, 2));
+ $lseconds = intval(substr($local, 12, 2));
+ $loffset = intval(substr($boot, 21, 4));
+
+ $byear = intval(substr($boot, 0, 4));
+ $bmonth = intval(substr($boot, 4, 2));
+ $bday = intval(substr($boot, 6, 2));
+ $bhour = intval(substr($boot, 8, 2));
+ $bminute = intval(substr($boot, 10, 2));
+ $bseconds = intval(substr($boot, 12, 2));
+ $boffset = intval(substr($boot, 21, 4));
+
+ if (version_compare($buffer[0]['Version'], "5.1", "<")) { // fix LastBootUpTime on Windows 2000 and older
+ $boffset += $boffset;
+ }
+
+ $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear) - $loffset*60;
+ $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear) - $boffset*60;
+
$result = $localtime - $boottime;
+
$this->sys->setUptime($result);
+ } elseif (!defined('PSI_EMU_HOSTNAME') && (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('uptime', '', $strBuf, false) && (strlen($strBuf) > 0) && preg_match("/^System Up Time:\s+(\d+) days, (\d+) Hours, (\d+) Minutes, (\d+) Seconds/", $strBuf, $ar_buf)) {
+ $sec = $ar_buf[4];
+ $min = $ar_buf[3];
+ $hours = $ar_buf[2];
+ $days = $ar_buf[1];
+ $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60 + $sec);
}
}
@@ -214,14 +952,14 @@ class WINNT extends OS
*
* @return void
*/
- private function _users()
+ protected function _users()
{
- if (CommonFunctions::executeProgram("quser", "", $strBuf, false) && (strlen(trim($strBuf)) > 0)) {
+ if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('quser', '', $strBuf, false) && (strlen($strBuf) > 0)) {
$lines = preg_split('/\n/', $strBuf);
$users = count($lines)-1;
} else {
$users = 0;
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption'));
+ $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption'));
foreach ($buffer as $process) {
if (strtoupper($process['Caption']) == strtoupper('explorer.exe')) {
$users++;
@@ -238,46 +976,124 @@ class WINNT extends OS
*/
private function _distro()
{
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('Version', 'ServicePackMajorVersion', 'Caption', 'OSArchitecture'));
+ $buffer = $this->_get_Win32_OperatingSystem();
if ($buffer) {
- $kernel = $buffer[0]['Version'];
+ $ver = $buffer[0]['Version'];
+ if (($this->_ver !== "") && preg_match("/^Microsoft [^\[]*\s*\[\D*\s*(".$ver."\.\d+).*\]/", $this->_ver, $ar_temp)) {
+ $kernel = $ar_temp[1];
+ } else {
+ $kernel = $ver;
+ }
if ($buffer[0]['ServicePackMajorVersion'] > 0) {
$kernel .= ' SP'.$buffer[0]['ServicePackMajorVersion'];
}
- if (isset($buffer[0]['OSArchitecture']) && preg_match("/^(\d+)/", $buffer[0]['OSArchitecture'], $bits)) {
- $this->sys->setKernel($kernel.' ('.$bits[1].'-bit)');
- } elseif (($allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('AddressWidth'))) && isset($allCpus[0]['AddressWidth'])) {
- $this->sys->setKernel($kernel.' ('.$allCpus[0]['AddressWidth'].'-bit)');
- } else {
- $this->sys->setKernel($kernel);
+ if ($allCpus = $this->_get_Win32_Processor()) {
+ $addresswidth = 0;
+ if (isset($allCpus[0]['AddressWidth']) && (($addresswidth = $allCpus[0]['AddressWidth']) > 0)) {
+ $kernel .= ' ('.$addresswidth.'-bit)';
+ }
+ if (isset($allCpus[0]['Architecture'])) {
+ switch ($allCpus[0]['Architecture']) {
+ case 0: $kernel .= ' x86'; break;
+ case 1: $kernel .= ' MIPS'; break;
+ case 2: $kernel .= ' Alpha'; break;
+ case 3: $kernel .= ' PowerPC'; break;
+ case 5: $kernel .= ' ARM'; break;
+ case 6: $kernel .= ' ia64'; break;
+ case 9: if ($addresswidth == 32) {
+ $kernel .= ' x86';
+ } else {
+ $kernel .= ' x64';
+ }
+ break;
+ case 12: if ($addresswidth == 32) {
+ $kernel .= ' ARM';
+ } else {
+ $kernel .= ' ARM64';
+ }
+ }
+ }
}
- $this->sys->setDistribution($buffer[0]['Caption']);
-
- if ((($kernel[1] == ".") && ($kernel[0] <5)) || (substr($kernel, 0, 4) == "5.0."))
+ $this->sys->setKernel($kernel);
+ $distribution = $buffer[0]['Caption'];
+ if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $buffer[0]['Caption']) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) {
+ $karray = preg_split('/\./', $ver);
+ if (isset($karray[2]) && isset($list['win10'][$karray[2]])) {
+ $distribution .= ' ('.$list['win10'][$karray[2]].')';
+ }
+ }
+ $this->sys->setDistribution($distribution);
+ if (version_compare($ver, "5.1", "<"))
$icon = 'Win2000.png';
- elseif ((substr($kernel, 0, 4) == "6.0.") || (substr($kernel, 0, 4) == "6.1."))
+ elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<"))
+ $icon = 'WinXP.png';
+ elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<"))
$icon = 'WinVista.png';
- elseif ((substr($kernel, 0, 4) == "6.2.") || (substr($kernel, 0, 4) == "6.3.") || (substr($kernel, 0, 4) == "6.4.") || (substr($kernel, 0, 5) == "10.0."))
+ elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<"))
$icon = 'Win8.png';
else
- $icon = 'WinXP.png';
+ $icon = 'Win11.png';
$this->sys->setDistributionIcon($icon);
- } elseif (CommonFunctions::executeProgram("cmd", "/c ver 2>nul", $ver_value, false)) {
- if (preg_match("/ReactOS\r?\nVersion\s+(.+)/", $ver_value, $ar_temp)) {
- $this->sys->setDistribution("ReactOS");
- $this->sys->setKernel($ar_temp[1]);
+ } elseif ($this->_ver !== "") {
+ if (preg_match("/ReactOS\r?\n\S+\s+(.+)/", $this->_ver, $ar_temp)) {
+ if (preg_match("/^(\d+\.\d+\.\d+[\S]*)(.+)$/", trim($ar_temp[1]), $ver_temp)) {
+ $this->sys->setDistribution("ReactOS ".trim($ver_temp[1]));
+ $this->sys->setKernel(trim($ver_temp[2]));
+ } else {
+ $this->sys->setDistribution("ReactOS");
+ $this->sys->setKernel($ar_temp[1]);
+ }
$this->sys->setDistributionIcon('ReactOS.png');
- } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*(.+)\]/", $ver_value, $ar_temp)) {
- $this->sys->setDistribution($ar_temp[1]);
- $this->sys->setKernel($ar_temp[2]);
- $this->sys->setDistributionIcon('Win2000.png');
+ } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*([\.\d]+)\]/", $this->_ver, $ar_temp)) {
+ $ver = $ar_temp[2];
+ $kernel = $ver;
+ if (($this->_reg === false) && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false, false, true) && (strlen($strBuf) > 0)) { // only if reg query via cmd
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $tmpBuf, false)) {
+ $kernel .= ' (64-bit)';
+ }
+ if (preg_match("/^Microsoft /", $strBuf)) {
+ $distribution = $strBuf;
+ } else {
+ $distribution = "Microsoft ".$strBuf;
+ }
+ } elseif (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false) && (strlen($strBuf) > 0)) {
+ if (preg_match("/^Microsoft /", $strBuf)) {
+ $distribution = $strBuf;
+ } else {
+ $distribution = "Microsoft ".$strBuf;
+ }
+ } else {
+ $distribution = $ar_temp[1];
+ }
+ $this->sys->setKernel($kernel);
+ if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $this->sys->getDistribution()) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) {
+ if (version_compare($ver, "10.0.21996", ">=") && version_compare($ver, "11.0", "<")) {
+ $distribution = preg_replace("/Windows 10/", "Windows 11", $distribution); // fix Windows 11 detection
+ }
+ $karray = preg_split('/\./', $ver);
+ if (isset($karray[2]) && isset($list['win10'][$karray[2]])) {
+ $distribution .= ' ('.$list['win10'][$karray[2]].')';
+ }
+ }
+ $this->sys->setDistribution($distribution);
+ if (version_compare($ver, "5.1", "<"))
+ $icon = 'Win2000.png';
+ elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<"))
+ $icon = 'WinXP.png';
+ elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<"))
+ $icon = 'WinVista.png';
+ elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<"))
+ $icon = 'Win8.png';
+ else
+ $icon = 'Win11.png';
+ $this->sys->setDistributionIcon($icon);
} else {
- $this->sys->setDistribution("WinNT");
- $this->sys->setDistributionIcon('Win2000.png');
+ $this->sys->setDistribution("WINNT");
+ $this->sys->setDistributionIcon('WINNT.png');
}
} else {
- $this->sys->setDistribution("WinNT");
- $this->sys->setDistributionIcon('Win2000.png');
+ $this->sys->setDistribution("WINNT");
+ $this->sys->setDistributionIcon('WINNT.png');
}
}
@@ -289,18 +1105,29 @@ class WINNT extends OS
*/
private function _loadavg()
{
- $loadavg = "";
- $sum = 0;
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('LoadPercentage'));
- if ($buffer) {
+ if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && isset($cpubuffer['cpu_Total'])) {
+ $this->sys->setLoad($cpubuffer['cpu_Total']);
+ if (PSI_LOAD_BAR) {
+ $this->sys->setLoadPercent($cpubuffer['cpu_Total']);
+ }
+ } elseif ($buffer = $this->_get_Win32_Processor()) {
+ $loadok = true;
+ $sum = 0;
foreach ($buffer as $load) {
$value = $load['LoadPercentage'];
- $loadavg .= $value.' ';
- $sum += $value;
+ if ($value !== null) {
+ $sum += $value;
+ } else {
+ $loadok = false;
+ break;
+ }
}
- $this->sys->setLoad(trim($loadavg));
- if (PSI_LOAD_BAR) {
- $this->sys->setLoadPercent($sum / count($buffer));
+ if ($loadok) {
+ $percent = $sum / count($buffer);
+ $this->sys->setLoad($percent);
+ if (PSI_LOAD_BAR) {
+ $this->sys->setLoadPercent($percent);
+ }
}
}
}
@@ -312,19 +1139,116 @@ class WINNT extends OS
*/
private function _cpuinfo()
{
- $allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('Name', 'L2CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'MaxClockSpeed'));
- foreach ($allCpus as $oneCpu) {
- $coreCount = 1;
- if (isset($oneCpu['NumberOfCores'])) {
- $coreCount = $oneCpu['NumberOfCores'];
+ $allCpus = $this->_get_Win32_Processor();
+ if (empty($allCpus)) {
+ $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
+ if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
+ foreach ($arrBuf as $coreCount) {
+ if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\ProcessorNameString", $strBuf, false)) {
+ $allCpus[$coreCount]['Name'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\~MHz", $strBuf, false)) {
+ if (preg_match("/^0x([0-9a-f]+)$/i", $strBuf, $hexvalue)) {
+ $allCpus[$coreCount]['CurrentClockSpeed'] = hexdec($hexvalue[1]);
+ }
+ }
+ if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\VendorIdentifier", $strBuf, false)) {
+ $allCpus[$coreCount]['Manufacturer'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\Identifier", $strBuf, false)) {
+ $allCpus[$coreCount]['Caption'] = $strBuf;
+ }
+ }
}
- for ($i = 0; $i < $coreCount; $i++) {
+ }
+
+ $globalcpus = 0;
+ foreach ($allCpus as $oneCpu) {
+ $cpuCount = 1;
+ if (isset($oneCpu['NumberOfLogicalProcessors'])) {
+ $cpuCount = $oneCpu['NumberOfLogicalProcessors'];
+ } elseif (isset($oneCpu['NumberOfCores'])) {
+ $cpuCount = $oneCpu['NumberOfCores'];
+ }
+ $globalcpus+=$cpuCount;
+ }
+
+ $cpulist = null;
+ foreach ($allCpus as $oneCpu) {
+ $cpuCount = 1;
+ if (isset($oneCpu['NumberOfLogicalProcessors'])) {
+ $cpuCount = $oneCpu['NumberOfLogicalProcessors'];
+ } elseif (isset($oneCpu['NumberOfCores'])) {
+ $cpuCount = $oneCpu['NumberOfCores'];
+ }
+ for ($i = 0; $i < $cpuCount; $i++) {
$cpu = new CpuDevice();
- $cpu->setModel($oneCpu['Name']);
- $cpu->setCache($oneCpu['L2CacheSize'] * 1024);
- $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']);
- $cpu->setBusSpeed($oneCpu['ExtClock']);
- if ($oneCpu['CurrentClockSpeed'] < $oneCpu['MaxClockSpeed']) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']);
+ if (isset($oneCpu['Name'])) $cpu->setModel($oneCpu['Name']);
+ if (isset($oneCpu['L3CacheSize']) && ($oneCpu['L3CacheSize'] > 0)) {
+ $cpu->setCache($oneCpu['L3CacheSize'] * 1024);
+ } elseif (isset($oneCpu['L2CacheSize']) && ($oneCpu['L2CacheSize'] > 0)) {
+ $cpu->setCache($oneCpu['L2CacheSize'] * 1024);
+ }
+ if (isset($oneCpu['CurrentVoltage']) && ($oneCpu['CurrentVoltage'] > 0)) {
+ $cpu->setVoltage($oneCpu['CurrentVoltage']/10);
+ }
+ if (isset($oneCpu['CurrentClockSpeed']) && ($oneCpu['CurrentClockSpeed'] > 0)) {
+ $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']);
+ if (isset($oneCpu['MaxClockSpeed']) && ($oneCpu['CurrentClockSpeed'] <= $oneCpu['MaxClockSpeed'])) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']);
+ }
+ if (isset($oneCpu['ExtClock']) && ($oneCpu['ExtClock'] > 0)) {
+ $cpu->setBusSpeed($oneCpu['ExtClock']);
+ }
+ if (isset($oneCpu['Manufacturer'])) {
+ $cpumanufacturer = $oneCpu['Manufacturer'];
+ $cpu->setVendorId($cpumanufacturer);
+ if ($cpumanufacturer === "QEMU") {
+ if (isset($oneCpu['Caption'])) {
+ $impl = '';
+ if (preg_match('/^ARMv8 \(64-bit\) Family 8 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) {
+ switch (strtolower($partvar[1])) {
+ case '51':
+ $impl = '0x0'; break; // Qemu
+ case 'd03':
+ case 'd07':
+ case 'd08':
+ $impl = '0x41'; break; // ARM Limited
+ case '1':
+ $impl = '0x46'; // Fujitsu Ltd.
+ }
+ } elseif (preg_match('/^ARM Family 7 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) {
+ switch (strtolower($partvar[1])) {
+ case 'c07':
+ case 'c0f':
+ $impl = '0x41'; // ARM Limited
+ }
+ }
+ if ($impl !== '') {
+ if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
+ if ($cpulist) {
+ if ((isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1].',0x'.$partvar[2])]))
+ || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1])])) {
+ if (($cpumodel = $cpu->getModel()) !== '') {
+ $cpu->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]);
+ } else {
+ $cpu->setModel($cpulist['cpu'][$cpufromlist]);
+ }
+ }
+ }
+ }
+ }
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $this->sys->setVirtualizer("cpuid:QEMU", false);
+ }
+ }
+ }
+ if (PSI_LOAD_BAR) {
+ if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && (count($cpubuffer) == ($globalcpus+1)) && isset($cpubuffer['cpu'.$i])) {
+ $cpu->setLoad($cpubuffer['cpu'.$i]);
+ } elseif ((count($allCpus) == $globalcpus) && isset($oneCpu['LoadPercentage'])) {
+ $cpu->setLoad($oneCpu['LoadPercentage']);
+ }
+ }
$this->sys->setCpus($cpu);
}
}
@@ -337,18 +1261,85 @@ class WINNT extends OS
*/
private function _machine()
{
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Manufacturer', 'Model'));
- if ($buffer) {
- $buf = "";
+ $buffer = $this->_get_Win32_ComputerSystem();
+ $bufferp = self::getWMI(self::$_wmi, 'Win32_BaseBoard', array('Product'));
+ $bufferb = self::getWMI(self::$_wmi, 'Win32_BIOS', array('SMBIOSBIOSVersion', 'ReleaseDate'));
+
+ if (!$buffer) {
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\systemManufacturer", $strBuf, false)) {
+ $buffer[0]['Manufacturer'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemProductName", $strBuf, false)) {
+ $buffer[0]['Model'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemFamily", $strBuf, false)) {
+ $buffer[0]['SystemFamily'] = $strBuf;
+ }
+ }
+ if (!$bufferp) {
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BaseBoardProduct", $strBuf, false)) {
+ $bufferp[0]['Product'] = $strBuf;
+ }
+ }
+ if (!$bufferb) {
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSVersion", $strBuf, false)) {
+ $bufferb[0]['SMBIOSBIOSVersion'] = $strBuf;
+ }
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSReleaseDate", $strBuf, false)) {
+ $bufferb[0]['ReleaseDate'] = $strBuf;
+ }
+ }
+
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
if (isset($buffer[0]['Manufacturer'])) {
- $buf .= ' '.$buffer[0]['Manufacturer'];
+ $this->_Manufacturer = $buffer[0]['Manufacturer'];
}
if (isset($buffer[0]['Model'])) {
- $buf .= ' '.$buffer[0]['Model'];
+ $this->_Model = $buffer[0]['Model'];
}
- if (trim($buf) != "") {
- $this->sys->setMachine(trim($buf));
+ }
+
+ $buf = "";
+ $model = "";
+ if ($buffer && isset($buffer[0])) {
+ if (isset($buffer[0]['Manufacturer']) && !preg_match("/^To be filled by O\.E\.M\.$|^System manufacturer$|^Not Specified$/i", $buf2=trim($buffer[0]['Manufacturer'])) && ($buf2 !== "")) {
+ $buf .= ' '.$buf2;
}
+
+ if (isset($buffer[0]['Model']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Product Name$|^Not Specified$/i", $buf2=trim($buffer[0]['Model'])) && ($buf2 !== "")) {
+ $model = $buf2;
+ $buf .= ' '.$buf2;
+ }
+ }
+ if ($bufferp && isset($bufferp[0])) {
+ if (isset($bufferp[0]['Product']) && !preg_match("/^To be filled by O\.E\.M\.$|^BaseBoard Product Name$|^Not Specified$|^Default string$/i", $buf2=trim($bufferp[0]['Product'])) && ($buf2 !== "")) {
+ if ($buf2 !== $model) {
+ $buf .= '/'.$buf2;
+ } elseif (isset($buffer[0]['SystemFamily']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Family$|^Not Specified$/i", $buf2=trim($buffer[0]['SystemFamily'])) && ($buf2 !== "")) {
+ $buf .= '/'.$buf2;
+ }
+ }
+ }
+ if ($bufferb && isset($bufferb[0])) {
+ $bver = "";
+ $brel = "";
+ if (isset($bufferb[0]['SMBIOSBIOSVersion']) && (($buf2=trim($bufferb[0]['SMBIOSBIOSVersion'])) !== "")) {
+ $bver .= ' '.$buf2;
+ }
+ if (isset($bufferb[0]['ReleaseDate'])) {
+ if (preg_match("/^(\d{4})(\d{2})(\d{2})\d{6}\.\d{6}\+\d{3}$/", $bufferb[0]['ReleaseDate'], $dateout)) {
+ $brel .= ' '.$dateout[2].'/'.$dateout[3].'/'.$dateout[1];
+ } elseif (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $bufferb[0]['ReleaseDate'])) {
+ $brel .= ' '.$bufferb[0]['ReleaseDate'];
+ }
+ }
+ if ((trim($bver) !== "") || (trim($brel) !== "")) {
+ $buf .= ', BIOS'.$bver.$brel;
+ }
+ }
+
+ if (trim($buf) != "") {
+ $this->sys->setMachine(trim($buf));
}
}
@@ -361,25 +1352,52 @@ class WINNT extends OS
{
foreach ($this->_devicelist('PCI') as $pciDev) {
$dev = new HWDevice();
- $dev->setName($pciDev);
+ $dev->setName($pciDev['Name']);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (($pciDev['Manufacturer'] !== null) && preg_match("/^@[^\.]+\.inf,%([^%]+)%$/i", trim($pciDev['Manufacturer']), $mbuff)) {
+ $dev->setManufacturer($mbuff[1]);
+ } else {
+ $dev->setManufacturer($pciDev['Manufacturer']);
+ }
+ $dev->setProduct($pciDev['Product']);
+ }
$this->sys->setPciDevices($dev);
}
foreach ($this->_devicelist('IDE') as $ideDev) {
$dev = new HWDevice();
- $dev->setName($ideDev);
+ $dev->setName($ideDev['Name']);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setCapacity($ideDev['Capacity']);
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $dev->setSerial($ideDev['Serial']);
+ }
+ }
$this->sys->setIdeDevices($dev);
}
foreach ($this->_devicelist('SCSI') as $scsiDev) {
$dev = new HWDevice();
- $dev->setName($scsiDev);
+ $dev->setName($scsiDev['Name']);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setCapacity($scsiDev['Capacity']);
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $dev->setSerial($scsiDev['Serial']);
+ }
+ }
$this->sys->setScsiDevices($dev);
}
foreach ($this->_devicelist('USB') as $usbDev) {
$dev = new HWDevice();
- $dev->setName($usbDev);
+ $dev->setName($usbDev['Name']);
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $dev->setManufacturer($usbDev['Manufacturer']);
+ $dev->setProduct($usbDev['Product']);
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
+ $dev->setSerial($usbDev['Serial']);
+ }
+ }
$this->sys->setUsbDevices($dev);
}
}
@@ -391,75 +1409,167 @@ class WINNT extends OS
*/
private function _network()
{
- $allDevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded'));
- $allNetworkAdapterConfigurations = CommonFunctions::getWMI($this->_wmi, 'Win32_NetworkAdapterConfiguration', array('Description', 'MACAddress', 'IPAddress', 'SettingID'));
-
- foreach ($allDevices as $device) {
- $dev = new NetDevice();
- $name=$device['Name'];
-
- if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name, $ar_name)) { //isatap device
- foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) {
- if ($ar_name[1]==$NetworkAdapterConfiguration['SettingID']) {
- $dev->setName($NetworkAdapterConfiguration['Description']);
- if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) {
- $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress']));
- if (isset($NetworkAdapterConfiguration['IPAddress']))
- foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres)
- if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres);
- }
-
- break;
- }
- }
+ if (self::$_wmi) {
+ $buffer = $this->_get_Win32_OperatingSystem();
+ if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "6.2", ">=")) { // minimal windows 2012 or windows 8
+ $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkAdapter', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth'));
+ } else {
+ $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth'));
}
- if ($dev->getName() == "") { //no isatap or no isatap description
- $cname=preg_replace('/[^A-Za-z0-9]/', '_', $name); //convert to canonical
- if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name))
- $name=substr($name, 0, strlen($name)-strlen($ar_name[0]));
- $dev->setName($name);
-
- if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) {
- if (preg_replace('/[^A-Za-z0-9]/', '_', $NetworkAdapterConfiguration['Description']) == $cname) {
- if (!is_null($dev->getInfo())) {
- $dev->setInfo(''); //multiple with the same name
- } else {
- $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress']));
- if (isset($NetworkAdapterConfiguration['IPAddress']))
- foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres)
- if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres))
- $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres);
+ if ($allDevices) {
+ $aliases = array();
+ $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
+ if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
+ foreach ($arrBuf as $netID) {
+ if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\PnPInstanceId", $strInstanceID, false)) {
+ if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$strInstanceID."\\FriendlyName", $strName, false)) {
+ $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical
+ if (!isset($aliases[$cname])) { // duplicate checking
+ $aliases[$cname]['id'] = $netID;
+ $aliases[$cname]['name'] = $strName;
+ if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\Name", $strCName, false)
+ && (str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strCName) !== $cname)) {
+ $aliases[$cname]['netname'] = $strCName;
+ }
+ } else {
+ $aliases[$cname]['id'] = '';
+ }
+ }
}
}
}
- }
- // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp
- // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that
- // magative numbers would occour, try to calculate the nagative value from total - positive number
- $txbytes = $device['BytesSentPersec'];
- $rxbytes = $device['BytesReceivedPersec'];
- if (($txbytes < 0) && ($rxbytes < 0)) {
- $txbytes += 4294967296;
- $rxbytes += 4294967296;
- } elseif ($txbytes < 0) {
- if ($device['BytesTotalPersec'] > $rxbytes)
- $txbytes = $device['BytesTotalPersec'] - $rxbytes;
- else
- $txbytes += 4294967296;
- } elseif ($rxbytes < 0) {
- if ($device['BytesTotalPersec'] > $txbytes)
- $rxbytes = $device['BytesTotalPersec'] - $txbytes;
- else
- $rxbytes += 4294967296;
- }
- $dev->setTxBytes($txbytes);
- $dev->setRxBytes($rxbytes);
- $dev->setErrors($device['PacketsReceivedErrors']);
- $dev->setDrops($device['PacketsReceivedDiscarded']);
+ $aliases2 = array();
+ $hkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
+ if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
+ foreach ($arrBuf as $netCount) {
+ if (self::readReg($this->_reg, $hkey."\\".$netCount."\\Description", $strName, false)
+ && self::readReg($this->_reg, $hkey."\\".$netCount."\\ServiceName", $strGUID, false)) {
+ $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical
+ if (!isset($aliases2[$cname])) { // duplicate checking
+ $aliases2[$cname]['id'] = $strGUID;
+ $aliases2[$cname]['name'] = $strName;
+ } else {
+ $aliases2[$cname]['id'] = '';
+ }
+ }
+ }
+ }
- $this->sys->setNetDevices($dev);
+ $allNetworkAdapterConfigurations = self::getWMI(self::$_wmi, 'Win32_NetworkAdapterConfiguration', array('SettingID', /*'Description',*/ 'MACAddress', 'IPAddress'));
+ foreach ($allDevices as $device) if (!preg_match('/^WAN Miniport \[/', $device['Name'])) {
+ $dev = new NetDevice();
+ $name = $device['Name'];
+
+ if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name)) {
+ $dev->setName("Microsoft ISATAP Adapter");
+ } else {
+ if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name)) {
+ $name=substr($name, 0, strlen($name)-strlen($ar_name[0]));
+ }
+ $dev->setName($name);
+ }
+
+ $macexist = false;
+ if (((($ali=$aliases) && isset($ali[$name])) || (($ali=$aliases2) && isset($ali[$name]))) && isset($ali[$name]['id']) && ($ali[$name]['id'] !== "")) {
+ foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) {
+ if ($ali[$name]['id']==$NetworkAdapterConfiguration['SettingID']) {
+ $mininame = $ali[$name]['name'];
+ if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $mininame))
+ $mininame="Microsoft ISATAP Adapter";
+ elseif (preg_match('/\s-\s([^-]*)$/', $mininame, $ar_name))
+ $name=substr($mininame, 0, strlen($mininame)-strlen($ar_name[0]));
+ $dev->setName($mininame);
+ if (isset($NetworkAdapterConfiguration['MACAddress']) && trim($NetworkAdapterConfiguration['MACAddress']) !== "") $macexist = true;
+ if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) {
+ if (isset($ali[$name]['netname'])) $dev->setInfo(str_replace(';', ':', $ali[$name]['netname']));
+ if ((!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR)
+ && $macexist) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').str_replace(':', '-', strtoupper(trim($NetworkAdapterConfiguration['MACAddress']))));
+ if (isset($NetworkAdapterConfiguration['IPAddress']))
+ foreach ($NetworkAdapterConfiguration['IPAddress'] as $ipaddres)
+ if (($ipaddres != "0.0.0.0") && ($ipaddres != "::") && !preg_match('/^fe80::/i', $ipaddres))
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres));
+ }
+
+ break;
+ }
+ }
+ }
+
+ if ($macexist
+// || ($device['CurrentBandwidth'] >= 1000000)
+ || ($device['BytesTotalPersec'] != 0)
+ || ($device['BytesSentPersec'] != 0)
+ || ($device['BytesReceivedPersec'] != 0)
+ || ($device['PacketsReceivedErrors'] != 0)
+ || ($device['PacketsReceivedDiscarded'] != 0)) { // hide unused
+ if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) {
+ if (($speedinfo = $device['CurrentBandwidth']) >= 1000000) {
+ if ($speedinfo > 1000000000) {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000000, 2)."Gb/s");
+ } else {
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000, 2)."Mb/s");
+ }
+ }
+ }
+
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp
+ // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that
+ // magative numbers would occour, try to calculate the nagative value from total - positive number
+ $txbytes = $device['BytesSentPersec'];
+ $rxbytes = $device['BytesReceivedPersec'];
+ if (($txbytes < 0) && ($rxbytes < 0)) {
+ $txbytes += 4294967296;
+ $rxbytes += 4294967296;
+ } elseif ($txbytes < 0) {
+ if ($device['BytesTotalPersec'] > $rxbytes)
+ $txbytes = $device['BytesTotalPersec'] - $rxbytes;
+ else
+ $txbytes += 4294967296;
+ } elseif ($rxbytes < 0) {
+ if ($device['BytesTotalPersec'] > $txbytes)
+ $rxbytes = $device['BytesTotalPersec'] - $txbytes;
+ else
+ $rxbytes += 4294967296;
+ }
+ $dev->setTxBytes($txbytes);
+ $dev->setRxBytes($rxbytes);
+ $dev->setErrors($device['PacketsReceivedErrors']);
+ $dev->setDrops($device['PacketsReceivedDiscarded']);
+
+ $this->sys->setNetDevices($dev);
+ }
+ }
+ }
+ } elseif (($buffer = $this->_get_systeminfo()) && preg_match('/^(\s+)\[\d+\]:[^\r\n]+\r\n\s+[^\s\[]/m', $buffer, $matches, PREG_OFFSET_CAPTURE)) {
+ $netbuf = substr($buffer, $matches[0][1]);
+ if (preg_match('/^[^\s]/m', $netbuf, $matches2, PREG_OFFSET_CAPTURE)) {
+ $netbuf = substr($netbuf, 0, $matches2[0][1]);
+ }
+ $netstrs = preg_split('/^'.$matches[1][0].'\[\d+\]:/m', $netbuf, -1, PREG_SPLIT_NO_EMPTY);
+ $devnr = 0;
+ foreach ($netstrs as $netstr) {
+ $netstrls = preg_split('/\r\n/', $netstr, -1, PREG_SPLIT_NO_EMPTY);
+ if (sizeof($netstrls)>1) {
+ $dev = new NetDevice();
+ foreach ($netstrls as $nr=>$netstrl) {
+ if ($nr === 0) {
+ $name = trim($netstrl);
+ if ($name !== "") {
+ $dev->setName($name);
+ } else {
+ $dev->setName('dev'.$devnr);
+ $devnr++;
+ }
+ } elseif (preg_match('/\[\d+\]:\s+(.+)/', $netstrl, $netinfo)) {
+ $ipaddres = trim($netinfo[1]);
+ if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres))
+ $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres));
+ }
+ }
+ $this->sys->setNetDevices($dev);
+ }
+ }
}
}
@@ -472,23 +1582,30 @@ class WINNT extends OS
*/
private function _memory()
{
- $buffer = CommonFunctions::getWMI($this->_wmi, "Win32_OperatingSystem", array('TotalVisibleMemorySize', 'FreePhysicalMemory'));
- if ($buffer) {
- $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024);
- $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024);
+ if (self::$_wmi) {
+ $buffer = $this->_get_Win32_OperatingSystem();
+ if ($buffer) {
+ $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024);
+ $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024);
+ $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
+ }
+ $buffer = self::getWMI(self::$_wmi, 'Win32_PageFileUsage');
+ foreach ($buffer as $swapdevice) {
+ $dev = new DiskDevice();
+ $dev->setName("SWAP");
+ $dev->setMountPoint($swapdevice['Name']);
+ $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024);
+ $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024);
+ $dev->setFree($dev->getTotal() - $dev->getUsed());
+ $dev->setFsType('swap');
+ $this->sys->setSwapDevices($dev);
+ }
+ } elseif (($buffer = $this->_get_systeminfo()) && preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n/m", $buffer, $buffer2)) {
+// && (preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n.*:\s+(\S+)\r\n/m", $buffer, $buffer2)) {
+ $this->sys->setMemTotal(preg_replace('/(\s)|(\xFF)/', '', $buffer2[1]) * 1024 * 1024);
+ $this->sys->setMemFree(preg_replace('/(\s)|(\xFF)/', '', $buffer2[2]) * 1024 * 1024);
$this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
}
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_PageFileUsage');
- foreach ($buffer as $swapdevice) {
- $dev = new DiskDevice();
- $dev->setName("SWAP");
- $dev->setMountPoint($swapdevice['Name']);
- $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024);
- $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024);
- $dev->setFree($dev->getTotal() - $dev->getUsed());
- $dev->setFsType('swap');
- $this->sys->setSwapDevices($dev);
- }
}
/**
@@ -500,11 +1617,13 @@ class WINNT extends OS
{
$typearray = array('Unknown', 'No Root Directory', 'Removable Disk', 'Local Disk', 'Network Drive', 'Compact Disc', 'RAM Disk');
$floppyarray = array('Unknown', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', 'Other', 'HD', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '8 in.');
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType'));
+ $buffer = self::getWMI(self::$_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType'));
foreach ($buffer as $filesystem) {
$dev = new DiskDevice();
$dev->setMountPoint($filesystem['Name']);
- $dev->setFsType($filesystem['FileSystem']);
+ if (isset($filesystem['FileSystem'])) {
+ $dev->setFsType($filesystem['FileSystem']);
+ }
if ($filesystem['Size'] > 0) {
$dev->setTotal($filesystem['Size']);
$dev->setFree($filesystem['FreeSpace']);
@@ -517,25 +1636,64 @@ class WINNT extends OS
}
$this->sys->setDiskDevices($dev);
}
- if (!$buffer && ($this->sys->getDistribution()=="ReactOS")) {
- // test for command 'free' on current disk
- if (CommonFunctions::executeProgram("cmd", "/c free 2>nul", $out_value, true)) {
- for ($letter='A'; $letter!='AA'; $letter++) if (CommonFunctions::executeProgram("cmd", "/c free ".$letter.": 2>nul", $out_value, false)) {
- if (preg_match('/\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*$/', $out_value, $out_dig)) {
- $size = preg_replace('/(\.)|(\,)/', '', $out_dig[1]);
- $used = preg_replace('/(\.)|(\,)/', '', $out_dig[2]);
- $free = preg_replace('/(\.)|(\,)/', '', $out_dig[3]);
+ if (!$buffer && !defined('PSI_EMU_HOSTNAME')) {
+ $letters = array();
+ if (CommonFunctions::executeProgram('fsutil', 'fsinfo drives 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/^Drives:\s*(.+)$/i', $out_value, $disks)) {
+ $diskarr = preg_split('/ /', $disks[1], -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($diskarr as $disk) if (preg_match('/^(\w):\\\\$/', $disk, $diskletter)) {
+ $letters[] = $diskletter[1];
+ }
+ }
+ if (count($letters) == 0) for ($letter='A'; $letter!='AA'; $letter++) {
+ $letters[] = $letter;
+ }
+ if ((substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('cmd', '/c free 2>nul', $out_value, false)) {
+ foreach ($letters as $letter) if (CommonFunctions::executeProgram('cmd', '/c free '.$letter.': 2>nul', $out_value, false)) {
+ $values = preg_replace('/[^\d\n]/', '', $out_value);
+ if (preg_match('/\n(\d+)\n(\d+)\n(\d+)$/', $values, $out_dig)) {
+ $size = $out_dig[1];
+ $used = $out_dig[2];
+ $free = $out_dig[3];
if ($used + $free == $size) {
$dev = new DiskDevice();
$dev->setMountPoint($letter.":");
- $dev->setFsType('Unknown');
+ if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.':\ 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) {
+ $dev->setFsType($fsname[1]);
+ } else {
+ $dev->setFsType('Unknown');
+ }
+ $dev->setName('Unknown');
$dev->setTotal($size);
- $dev->setFree($free);
$dev->setUsed($used);
+ $dev->setFree($free);
$this->sys->setDiskDevices($dev);
}
}
}
+ } else {
+ if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") {
+ $disksep = ':\\';
+ } else {
+ $disksep = ':';
+ }
+ foreach ($letters as $letter) {
+ $size = disk_total_space($letter.':\\');
+ $free = disk_free_space($letter.':\\');
+ if (($size !== false) && ($free !== false) && ($size >= 0) && ($free >= 0) && ($size >= $free)) {
+ $dev = new DiskDevice();
+ $dev->setMountPoint($letter.":");
+ if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.$disksep.' 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) {
+ $dev->setFsType($fsname[1]);
+ } else {
+ $dev->setFsType('Unknown');
+ }
+ $dev->setName('Unknown');
+ $dev->setTotal($size);
+ $dev->setUsed($size - $free);
+ $dev->setFree($free);
+ $this->sys->setDiskDevices($dev);
+ }
+ }
}
}
}
@@ -567,43 +1725,231 @@ class WINNT extends OS
public function _processes()
{
$processes['*'] = 0;
- if (CommonFunctions::executeProgram("qprocess", "*", $strBuf, false) && (strlen(trim($strBuf)) > 0)) {
+ if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('qprocess', '*', $strBuf, false) && (strlen($strBuf) > 0)) {
$lines = preg_split('/\n/', $strBuf);
- $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *"
+ $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *"
}
if ($processes['*'] <= 0) {
- $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption'));
+ $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption'));
$processes['*'] = count($buffer);
}
$processes[' '] = $processes['*'];
$this->sys->setProcesses($processes);
}
+ /**
+ * MEM information
+ *
+ * @return void
+ */
+ private function _meminfo()
+ {
+ $allMems = self::_get_Win32_PhysicalMemory();
+ if ($allMems) {
+ $reg = false;
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ $arrMems = self::getWMI(self::$_wmi, 'Win32_PhysicalMemoryArray', array('MemoryErrorCorrection'));
+ $reg = (count($arrMems) == 1) && isset($arrMems[0]['MemoryErrorCorrection']) && ($arrMems[0]['MemoryErrorCorrection'] == 6);
+ }
+ foreach ($allMems as $mem) {
+ $dev = new HWDevice();
+ $name = '';
+ if (isset($mem['PartNumber']) && !preg_match("/^PartNum\d+$/", $part = $mem['PartNumber']) && ($part != '') && ($part != 'None') && ($part != 'N/A') && ($part != 'NOT AVAILABLE')) {
+ $name = $part;
+ }
+ if (isset($mem['DeviceLocator']) && (($dloc = $mem['DeviceLocator']) != '') && ($dloc != 'None') && ($dloc != 'N/A')) {
+ if ($name != '') {
+ $name .= ' - '.$dloc;
+ } else {
+ $name = $dloc;
+ }
+ }
+ if (isset($mem['BankLabel']) && (($bank = $mem['BankLabel']) != '') && ($bank != 'None') && ($bank != 'N/A')) {
+ if ($name != '') {
+ $name .= ' in '.$bank;
+ } else {
+ $name = 'Physical Memory in '.$bank;
+ }
+ }
+ if ($name != '') {
+ $dev->setName(trim($name));
+ } else {
+ $dev->setName('Physical Memory');
+ }
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if (isset($mem['Manufacturer']) && !preg_match("/^([A-F\d]{4}|[A-F\d]{12}|[A-F\d]{16})$/", $manufacturer = $mem['Manufacturer']) && !preg_match("/^Manufacturer\d+$/", $manufacturer) && !preg_match("/^Mfg \d+$/", $manufacturer) && ($manufacturer != '') && ($manufacturer != 'None') && ($manufacturer != 'N/A') && ($manufacturer != 'UNKNOWN')) {
+ $dev->setManufacturer($manufacturer);
+ }
+ if (isset($mem['Capacity'])) {
+ $dev->setCapacity($mem['Capacity']);
+ }
+ $memtype = '';
+ if (isset($mem['MemoryType']) && (($memval = $mem['MemoryType']) != 0)) {
+ switch ($memval) {
+// case 0: $memtype = 'Unknown'; break;
+// case 1: $memtype = 'Other'; break;
+ case 2: $memtype = 'DRAM'; break;
+ case 3: $memtype = 'Synchronous DRAM'; break;
+ case 4: $memtype = 'Cache DRAM'; break;
+ case 5: $memtype = 'EDO'; break;
+ case 6: $memtype = 'EDRAM'; break;
+ case 7: $memtype = 'VRAM'; break;
+ case 8: $memtype = 'SRAM'; break;
+ case 9: $memtype = 'RAM'; break;
+ case 10: $memtype = 'ROM'; break;
+ case 11: $memtype = 'Flash'; break;
+ case 12: $memtype = 'EEPROM'; break;
+ case 13: $memtype = 'FEPROM'; break;
+ case 14: $memtype = 'EPROM'; break;
+ case 15: $memtype = 'CDRAM'; break;
+ case 16: $memtype = '3DRAM'; break;
+ case 17: $memtype = 'SDRAM'; break;
+ case 18: $memtype = 'SGRAM'; break;
+ case 19: $memtype = 'RDRAM'; break;
+ case 20: $memtype = 'DDR'; break;
+ case 21: $memtype = 'DDR2'; break;
+ case 22: $memtype = 'DDR2 FB-DIMM'; break;
+ case 24: $memtype = 'DDR3'; break;
+ case 25: $memtype = 'FBD2'; break;
+ case 26: $memtype = 'DDR4';
+ }
+ } elseif (isset($mem['SMBIOSMemoryType'])) {
+ switch ($mem['SMBIOSMemoryType']) {
+// case 0: $memtype = 'Invalid'; break;
+// case 1: $memtype = 'Other'; break;
+// case 2: $memtype = 'Unknown'; break;
+ case 3: $memtype = 'DRAM'; break;
+ case 4: $memtype = 'EDRAM'; break;
+ case 5: $memtype = 'VRAM'; break;
+ case 6: $memtype = 'SRAM'; break;
+ case 7: $memtype = 'RAM'; break;
+ case 8: $memtype = 'ROM'; break;
+ case 9: $memtype = 'FLASH'; break;
+ case 10: $memtype = 'EEPROM'; break;
+ case 11: $memtype = 'FEPROM'; break;
+ case 12: $memtype = 'EPROM'; break;
+ case 13: $memtype = 'CDRAM'; break;
+ case 14: $memtype = '3DRAM'; break;
+ case 15: $memtype = 'SDRAM'; break;
+ case 16: $memtype = 'SGRAM'; break;
+ case 17: $memtype = 'RDRAM'; break;
+ case 18: $memtype = 'DDR'; break;
+ case 19: $memtype = 'DDR2'; break;
+ case 20: $memtype = 'DDR2 FB-DIMM'; break;
+ case 24: $memtype = 'DDR3'; break;
+ case 25: $memtype = 'FBD2'; break;
+ case 26: $memtype = 'DDR4'; break;
+ case 27: $memtype = 'LPDDR'; break;
+ case 28: $memtype = 'LPDDR2'; break;
+ case 29: $memtype = 'LPDDR3'; break;
+ case 30: $memtype = 'DDR3'; break;
+ case 31: $memtype = 'FBD2'; break;
+ case 32: $memtype = 'Logical non-volatile device'; break;
+ case 33: $memtype = 'HBM2'; break;
+ case 34: $memtype = 'DDR5'; break;
+ case 35: $memtype = 'LPDDR5';
+ }
+ }
+ if (isset($mem['Speed']) && (($speed = $mem['Speed']) > 0) && (preg_match('/^(DDR\d*)(.*)/', $memtype, $dr) || preg_match('/^(SDR)AM(.*)/', $memtype, $dr))) {
+ if (isset($mem['MinVoltage']) && isset($mem['MaxVoltage']) && (($minv = $mem['MinVoltage']) > 0) && (($maxv = $mem['MaxVoltage']) > 0) && ($minv < $maxv)) {
+ $lv = 'L';
+ } else {
+ $lv = '';
+ }
+ if (isset($dr[2])) {
+ $memtype = $dr[1].$lv.'-'.$speed.' '.$dr[2];
+ } else {
+ $memtype = $dr[1].$lv.'-'.$speed;
+ }
+ }
+ if (isset($mem['FormFactor'])) {
+ switch ($mem['FormFactor']) {
+// case 0: $memtype .= ' Unknown'; break;
+// case 1: $memtype .= ' Other'; break;
+ case 2: $memtype .= ' SIP'; break;
+ case 3: $memtype .= ' DIP'; break;
+ case 4: $memtype .= ' ZIP'; break;
+ case 5: $memtype .= ' SOJ'; break;
+ case 6: $memtype .= ' Proprietary'; break;
+ case 7: $memtype .= ' SIMM'; break;
+ case 8: $memtype .= ' DIMM'; break;
+ case 9: $memtype .= ' TSOPO'; break;
+ case 10: $memtype .= ' PGA'; break;
+ case 11: $memtype .= ' RIM'; break;
+ case 12: $memtype .= ' SODIMM'; break;
+ case 13: $memtype .= ' SRIMM'; break;
+ case 14: $memtype .= ' SMD'; break;
+ case 15: $memtype .= ' SSMP'; break;
+ case 16: $memtype .= ' QFP'; break;
+ case 17: $memtype .= ' TQFP'; break;
+ case 18: $memtype .= ' SOIC'; break;
+ case 19: $memtype .= ' LCC'; break;
+ case 20: $memtype .= ' PLCC'; break;
+ case 21: $memtype .= ' BGA'; break;
+ case 22: $memtype .= ' FPBGA'; break;
+ case 23: $memtype .= ' LGA';
+ }
+ }
+ if (isset($mem['DataWidth']) && isset($mem['TotalWidth']) && (($dataw = $mem['DataWidth']) > 0) && (($totalw = $mem['TotalWidth']) > 0) && ($dataw < $totalw)) {
+ $memtype .= ' ECC';
+ }
+ if ($reg) {
+ $memtype .= ' REG';
+ }
+ if (($memtype = trim($memtype)) != '') {
+ $dev->setProduct($memtype);
+ }
+ if (isset($mem['ConfiguredClockSpeed']) && (($clock = $mem['ConfiguredClockSpeed']) > 0)) {
+ $dev->setSpeed($clock);
+ }
+ if (isset($mem['ConfiguredVoltage']) && (($voltage = $mem['ConfiguredVoltage']) > 0)) {
+ $dev->setVoltage($voltage/1000);
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL &&
+ isset($mem['SerialNumber']) && !preg_match("/^SerNum\d+$/", $serial = $mem['SerialNumber']) && ($serial != '') && ($serial != 'None')) {
+ $dev->setSerial($serial);
+ }
+ }
+ $this->sys->setMemDevices($dev);
+ }
+ }
+ }
/**
* get the information
*
* @see PSI_Interface_OS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
- $this->_distro();
- if ($this->sys->getDistribution()=="ReactOS") {
- $this->error->addError("WARN", "The ReactOS version of phpSysInfo is a work in progress, some things currently don't work");
+ $this->_distro(); // share getDistribution()
+ if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") {
+ $this->error->addWarning("The ReactOS version of phpSysInfo is a work in progress, some things currently don't work");
+ }
+ if (!$this->blockname || $this->blockname==='vitals') {
+ $this->_hostname();
+ $this->_users();
+ $this->_uptime();
+ $this->_loadavg();
+ $this->_processes();
+ }
+ if (!$this->blockname || $this->blockname==='hardware') {
+ $this->_machine();
+ $this->_cpuinfo();
+ $this->_virtualizer();
+ $this->_meminfo();
+ $this->_hardware();
+ }
+ if (!$this->blockname || $this->blockname==='memory') {
+ $this->_memory();
+ }
+ if (!$this->blockname || $this->blockname==='filesystem') {
+ $this->_filesystems();
+ }
+ if (!$this->blockname || $this->blockname==='network') {
+ $this->_network();
}
- $this->_hostname();
- $this->_ip();
- $this->_users();
- $this->_machine();
- $this->_uptime();
- $this->_cpuinfo();
- $this->_network();
- $this->_hardware();
- $this->_filesystems();
- $this->_memory();
- $this->_loadavg();
- $this->_processes();
}
}
diff --git a/root/opt/phpsysinfo/includes/output/class.Output.inc.php b/root/opt/phpsysinfo/includes/output/class.Output.inc.php
index 4d561e3..7872b53 100644
--- a/root/opt/phpsysinfo/includes/output/class.Output.inc.php
+++ b/root/opt/phpsysinfo/includes/output/class.Output.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Output
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Output.inc.php 569 2012-04-16 06:08:18Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_Output
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,7 +28,7 @@ abstract class Output
/**
* error object for logging errors
*
- * @var Error
+ * @var PSI_Error
*/
protected $error;
@@ -37,11 +37,9 @@ abstract class Output
*/
public function __construct()
{
- $this->error = Error::singleton();
+ $this->error = PSI_Error::singleton();
$this->_checkConfig();
CommonFunctions::checkForExtensions();
-// $this->error = Error::singleton();
-// $this->_checkConfig();
}
/**
@@ -51,7 +49,7 @@ abstract class Output
*/
private function _checkConfig()
{
- include_once APP_ROOT.'/read_config.php';
+ include_once PSI_APP_ROOT.'/read_config.php';
if ($this->error->errorsExist()) {
$this->error->errorsAsXML();
diff --git a/root/opt/phpsysinfo/includes/output/class.Template.inc.php b/root/opt/phpsysinfo/includes/output/class.Template.inc.php
index 3fa71ce..830448a 100644
--- a/root/opt/phpsysinfo/includes/output/class.Template.inc.php
+++ b/root/opt/phpsysinfo/includes/output/class.Template.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Output
* @author Damien Roth
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Output.inc.php 315 2009-09-02 15:48:31Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_Output
* @author Damien Roth
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,14 +28,14 @@ class Template
/**
* Vars used in the template
*
- * @Array
+ * @var array
*/
private $_vars;
/**
* Template file
*
- * @String
+ * @var string
*/
private $_file;
@@ -53,8 +53,8 @@ class Template
/**
* Set a template variable.
*
- * @param string variable name
- * @param string variable value
+ * @param string $name variable name
+ * @param string|array|Template $value variable value
*/
public function set($name, $value)
{
@@ -80,7 +80,7 @@ class Template
// Start output buffering
ob_start();
- include(APP_ROOT.$file);
+ include(PSI_APP_ROOT.$file);
// Get the contents of the buffer
$contents = ob_get_contents();
diff --git a/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php
index 2d27fea..6a2b6c7 100644
--- a/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php
+++ b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Web
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.Webpage.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,45 +19,82 @@
* @package PSI_Web
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
class Webpage extends Output implements PSI_Interface_Output
{
+ /**
+ * configured indexname
+ *
+ * @var string
+ */
+ private $_indexname;
+
/**
* configured language
*
- * @var String
+ * @var string
*/
private $_language;
/**
* configured template
*
- * @var String
+ * @var string
*/
private $_template;
/**
* all available templates
*
- * @var Array
+ * @var array
*/
private $_templates = array();
+ /**
+ * configured bootstrap template
+ *
+ * @var string
+ */
+ private $_bootstrap_template;
+
+ /**
+ * all available bootstrap templates
+ *
+ * @var array
+ */
+ private $_bootstrap_templates = array();
+
/**
* all available languages
*
- * @var Array
+ * @var array
*/
private $_languages = array();
/**
- * check for all extensions that are needed, initialize needed vars and read phpsysinfo.ini
+ * configured show picklist language
+ *
+ * @var boolean
*/
- public function __construct()
+ private $_pick_language;
+
+ /**
+ * configured show picklist template
+ *
+ * @var boolean
+ */
+ private $_pick_template;
+
+ /**
+ * check for all extensions that are needed, initialize needed vars and read phpsysinfo.ini
+ * @param string $indexname
+ */
+ public function __construct($indexname="dynamic")
{
+ $this->_indexname = $indexname;
parent::__construct();
$this->_getTemplateList();
$this->_getLanguageList();
@@ -71,15 +108,18 @@ class Webpage extends Output implements PSI_Interface_Output
*/
private function _checkTemplateLanguage()
{
- $this->_template = trim(strtolower(PSI_DEFAULT_TEMPLATE));
- if (!file_exists(APP_ROOT.'/templates/'.$this->_template.".css")) {
+ if (!defined("PSI_DEFAULT_TEMPLATE") || (($this->_template = strtolower(trim(PSI_DEFAULT_TEMPLATE))) == "") || !file_exists(PSI_APP_ROOT.'/templates/'.$this->_template.".css")) {
$this->_template = 'phpsysinfo';
}
+ if (!defined("PSI_DEFAULT_BOOTSTRAP_TEMPLATE") || (($this->_bootstrap_template = strtolower(trim(PSI_DEFAULT_BOOTSTRAP_TEMPLATE))) == "") || !file_exists(PSI_APP_ROOT.'/templates/'.$this->_bootstrap_template."_bootstrap.css")) {
+ $this->_bootstrap_template = 'phpsysinfo';
+ }
+ $this->_pick_template = !defined("PSI_SHOW_PICKLIST_TEMPLATE") || (PSI_SHOW_PICKLIST_TEMPLATE !== false);
- $this->_language = trim(strtolower(PSI_DEFAULT_LANG));
- if (!file_exists(APP_ROOT.'/language/'.$this->_language.".xml")) {
+ if (!defined("PSI_DEFAULT_LANG") || (($this->_language = strtolower(trim(PSI_DEFAULT_LANG))) == "") || !file_exists(PSI_APP_ROOT.'/language/'.$this->_language.".xml")) {
$this->_language = 'en';
}
+ $this->_pick_language = !defined("PSI_SHOW_PICKLIST_LANG") || (PSI_SHOW_PICKLIST_LANG !== false);
}
/**
@@ -89,13 +129,17 @@ class Webpage extends Output implements PSI_Interface_Output
*/
private function _getTemplateList()
{
- $dirlist = CommonFunctions::gdc(APP_ROOT.'/templates/');
+ $dirlist = CommonFunctions::gdc(PSI_APP_ROOT.'/templates/');
sort($dirlist);
foreach ($dirlist as $file) {
$tpl_ext = substr($file, strlen($file) - 4);
$tpl_name = substr($file, 0, strlen($file) - 4);
- if (($tpl_ext === ".css") && ($tpl_name !== "phpsysinfo_bootstrap")) {
- array_push($this->_templates, $tpl_name);
+ if ($tpl_ext === ".css") {
+ if (preg_match("/(\S+)_bootstrap$/", $tpl_name, $ar_buf)) {
+ array_push($this->_bootstrap_templates, $ar_buf[1]);
+ } else {
+ array_push($this->_templates, $tpl_name);
+ }
}
}
}
@@ -107,11 +151,11 @@ class Webpage extends Output implements PSI_Interface_Output
*/
private function _getLanguageList()
{
- $dirlist = CommonFunctions::gdc(APP_ROOT.'/language/');
+ $dirlist = CommonFunctions::gdc(PSI_APP_ROOT.'/language/');
sort($dirlist);
foreach ($dirlist as $file) {
- $lang_ext = substr($file, strlen($file) - 4);
- $lang_name = substr($file, 0, strlen($file) - 4);
+ $lang_ext = strtolower(substr($file, strlen($file) - 4));
+ $lang_name = strtolower(substr($file, 0, strlen($file) - 4));
if ($lang_ext == ".xml") {
array_push($this->_languages, $lang_name);
}
@@ -127,12 +171,52 @@ class Webpage extends Output implements PSI_Interface_Output
{
$this->_checkTemplateLanguage();
- $tpl = new Template("/templates/html/index_dynamic.html");
+ $tpl = new Template("/templates/html/index_".$this->_indexname.".html");
$tpl->set("template", $this->_template);
$tpl->set("templates", $this->_templates);
+ $tpl->set("bootstraptemplate", $this->_bootstrap_template);
+ $tpl->set("bootstraptemplates", $this->_bootstrap_templates);
+ $tpl->set("picktemplate", $this->_pick_template);
$tpl->set("language", $this->_language);
$tpl->set("languages", $this->_languages);
+ $tpl->set("picklanguage", $this->_pick_language);
+ $tpl->set("showCPUListExpanded", defined('PSI_SHOW_CPULIST_EXPANDED') ? (PSI_SHOW_CPULIST_EXPANDED ? 'true' : 'false') : 'true');
+ $tpl->set("showCPUInfoExpanded", defined('PSI_SHOW_CPUINFO_EXPANDED') ? (PSI_SHOW_CPUINFO_EXPANDED ? 'true' : 'false') : 'false');
+ $tpl->set("showNetworkInfosExpanded", defined('PSI_SHOW_NETWORK_INFOS_EXPANDED') ? (PSI_SHOW_NETWORK_INFOS_EXPANDED ? 'true' : 'false') : 'false');
+ $tpl->set("showMemoryInfosExpanded", defined('PSI_SHOW_MEMORY_INFOS_EXPANDED') ? (PSI_SHOW_MEMORY_INFOS_EXPANDED ? 'true' : 'false') : 'false');
+ $tpl->set("showNetworkActiveSpeed", defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') ? (PSI_SHOW_NETWORK_ACTIVE_SPEED ? ((strtolower(PSI_SHOW_NETWORK_ACTIVE_SPEED) === 'bps') ? 'bps' :'true') : 'false') : 'false');
+ $tpl->set("showCPULoadCompact", defined('PSI_LOAD_BAR') ? ((strtolower(PSI_LOAD_BAR) === 'compact') ? 'true' :'false') : 'false');
+ $tpl->set("hideBootstrapLoader", defined('PSI_HIDE_BOOTSTRAP_LOADER') ? (PSI_HIDE_BOOTSTRAP_LOADER ? 'true' : 'false') : 'false');
+ $tpl->set("increaseWidth", defined('PSI_INCREASE_WIDTH') ? ((intval(PSI_INCREASE_WIDTH)>0) ? intval(PSI_INCREASE_WIDTH) : 0) : 0);
+ $tpl->set("hideTotals", defined('PSI_HIDE_TOTALS') ? (PSI_HIDE_TOTALS ? 'true' : 'false') : 'false');
+ if (defined('PSI_BLOCKS')) {
+ if (is_string(PSI_BLOCKS)) {
+ if (preg_match(ARRAY_EXP, PSI_BLOCKS)) {
+ $blocks = eval(strtolower(PSI_BLOCKS));
+ } else {
+ $blocks = array(strtolower(PSI_BLOCKS));
+ }
+ $blocklist = '';
+ $validblocks = array('vitals','hardware','memory','filesystem','network','voltage','current','temperature','fans','power','other','ups');
+ foreach ($blocks as $block) {
+ if (in_array($block, $validblocks)) {
+ if (empty($blocklist)) {
+ $blocklist = $block;
+ } else {
+ $blocklist .= ','.$block;
+ }
+ }
+ }
+ if (!empty($blocklist)) {
+ $tpl->set("blocks", $blocklist);
+ }
+ } elseif (PSI_BLOCKS) {
+ $tpl->set("blocks", 'true');
+ }
+ } else {
+ $tpl->set("blocks", 'true');
+ }
echo $tpl->fetch();
}
diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php
index 43c226d..0c59a67 100644
--- a/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php
+++ b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php
@@ -8,7 +8,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.WebpageXML.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -32,13 +32,6 @@ class WebpageXML extends Output implements PSI_Interface_Output
*/
private $_xml;
- /**
- * only plugin xml
- *
- * @var boolean
- */
- private $_pluginRequest = false;
-
/**
* complete xml
*
@@ -53,6 +46,13 @@ class WebpageXML extends Output implements PSI_Interface_Output
*/
private $_pluginName = null;
+ /**
+ * name of the block
+ *
+ * @var string
+ */
+ private $_blockName = null;
+
/**
* generate the output
*
@@ -60,82 +60,161 @@ class WebpageXML extends Output implements PSI_Interface_Output
*/
private function _prepare()
{
- if (!$this->_pluginRequest) {
- // Figure out which OS we are running on, and detect support
- if (!file_exists(APP_ROOT.'/includes/os/class.'.PSI_OS.'.inc.php')) {
- $this->error->addError("file_exists(class.".PSI_OS.".inc.php)", PSI_OS." is not currently supported");
+ if ($this->_pluginName === null) {
+ if ((PSI_OS == 'Linux') && defined('PSI_SSH_HOSTNAME') && defined('PSI_SSH_USER') && defined('PSI_SSH_PASSWORD')) {
+ $fgthost = preg_split("/:/", PSI_SSH_HOSTNAME, -1, PREG_SPLIT_NO_EMPTY);
+ define('PSI_EMU_HOSTNAME', trim($fgthost[0]));
+ if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) {
+ define('PSI_EMU_PORT', trim($fgthost[1]));
+ } else {
+ define('PSI_EMU_PORT', 22);
+ }
+ define('PSI_EMU_USER', PSI_SSH_USER);
+ define('PSI_EMU_PASSWORD', PSI_SSH_PASSWORD);
+ if (defined('PSI_SSH_ADD_PATHS')) {
+ define('PSI_EMU_ADD_PATHS', PSI_SSH_ADD_PATHS);
+ }
+ if (defined('PSI_SSH_ADD_OPTIONS')) {
+ define('PSI_EMU_ADD_OPTIONS', PSI_SSH_ADD_OPTIONS);
+ }
+ if (!file_exists(PSI_APP_ROOT.'/includes/os/class.Linux.inc.php')) {
+ $this->error->addError("file_exists(class.Linux.inc.php)", "Linux is not currently supported");
+ }
+ } elseif (((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) && defined('PSI_WMI_HOSTNAME')) {
+ define('PSI_EMU_HOSTNAME', PSI_WMI_HOSTNAME);
+ if (defined('PSI_WMI_USER') && defined('PSI_WMI_PASSWORD')) {
+ define('PSI_EMU_USER', PSI_WMI_USER);
+ define('PSI_EMU_PASSWORD', PSI_WMI_PASSWORD);
+ } else {
+ define('PSI_EMU_USER', null);
+ define('PSI_EMU_PASSWORD', null);
+ }
+ if (!file_exists(PSI_APP_ROOT.'/includes/os/class.WINNT.inc.php')) {
+ $this->error->addError("file_exists(class.WINNT.inc.php)", "WINNT is not currently supported");
+ }
+ } else {
+ // Figure out which OS we are running on, and detect support
+ if (!file_exists(PSI_APP_ROOT.'/includes/os/class.'.PSI_OS.'.inc.php')) {
+ $this->error->addError("file_exists(class.".PSI_OS.".inc.php)", PSI_OS." is not currently supported");
+ }
}
- // check if there is a valid sensor configuration in phpsysinfo.ini
- $foundsp = array();
- if (defined('PSI_SENSOR_PROGRAM') && is_string(PSI_SENSOR_PROGRAM)) {
- if (preg_match(ARRAY_EXP, PSI_SENSOR_PROGRAM)) {
- $sensorprograms = eval(strtolower(PSI_SENSOR_PROGRAM));
- } else {
- $sensorprograms = array(strtolower(PSI_SENSOR_PROGRAM));
- }
- foreach ($sensorprograms as $sensorprogram) {
- if (!file_exists(APP_ROOT.'/includes/mb/class.'.$sensorprogram.'.inc.php')) {
- $this->error->addError("file_exists(class.".htmlspecialchars($sensorprogram).".inc.php)", "specified sensor program is not supported");
+ if (!defined('PSI_MBINFO') && (!$this->_blockName || in_array($this->_blockName, array('mbinfo','voltage','current','temperature','fans','power','other')))) {
+ // check if there is a valid sensor configuration in phpsysinfo.ini
+ $foundsp = array();
+ if (defined('PSI_SENSOR_PROGRAM') && is_string(PSI_SENSOR_PROGRAM)) {
+ if (preg_match(ARRAY_EXP, PSI_SENSOR_PROGRAM)) {
+ $sensorprograms = eval(strtolower(PSI_SENSOR_PROGRAM));
} else {
- $foundsp[] = $sensorprogram;
+ $sensorprograms = array(strtolower(PSI_SENSOR_PROGRAM));
+ }
+ foreach ($sensorprograms as $sensorprogram) {
+ if (!file_exists(PSI_APP_ROOT.'/includes/mb/class.'.$sensorprogram.'.inc.php')) {
+ $this->error->addError("file_exists(class.".htmlspecialchars($sensorprogram).".inc.php)", "specified sensor program is not supported");
+ } else {
+ $foundsp[] = $sensorprogram;
+ }
}
}
+
+ /**
+ * motherboard information
+ *
+ * @var string serialized array
+ */
+ define('PSI_MBINFO', serialize($foundsp));
}
- /**
- * motherboard information
- *
- * @var serialized array
- */
- define('PSI_MBINFO', serialize($foundsp));
-
- // check if there is a valid hddtemp configuration in phpsysinfo.ini
- $found = false;
- if (PSI_HDD_TEMP !== false) {
- $found = true;
- }
- /**
- * hddtemp information available or not
- *
- * @var boolean
- */
- define('PSI_HDDTEMP', $found);
-
- // check if there is a valid ups configuration in phpsysinfo.ini
- $foundup = array();
- if (defined('PSI_UPS_PROGRAM') && is_string(PSI_UPS_PROGRAM)) {
- if (preg_match(ARRAY_EXP, PSI_UPS_PROGRAM)) {
- $upsprograms = eval(strtolower(PSI_UPS_PROGRAM));
- } else {
- $upsprograms = array(strtolower(PSI_UPS_PROGRAM));
- }
- foreach ($upsprograms as $upsprogram) {
- if (!file_exists(APP_ROOT.'/includes/ups/class.'.$upsprogram.'.inc.php')) {
- $this->error->addError("file_exists(class.".htmlspecialchars($upsprogram).".inc.php)", "specified UPS program is not supported");
+ if (!defined('PSI_UPSINFO') && (!$this->_blockName || ($this->_blockName==='ups'))) {
+ // check if there is a valid ups configuration in phpsysinfo.ini
+ $foundup = array();
+ if (defined('PSI_UPS_PROGRAM') && is_string(PSI_UPS_PROGRAM)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_PROGRAM)) {
+ $upsprograms = eval(strtolower(PSI_UPS_PROGRAM));
} else {
- $foundup[] = $upsprogram;
+ $upsprograms = array(strtolower(PSI_UPS_PROGRAM));
+ }
+ foreach ($upsprograms as $upsprogram) {
+ if (!file_exists(PSI_APP_ROOT.'/includes/ups/class.'.$upsprogram.'.inc.php')) {
+ $this->error->addError("file_exists(class.".htmlspecialchars($upsprogram).".inc.php)", "specified UPS program is not supported");
+ } else {
+ $foundup[] = $upsprogram;
+ }
}
}
+ /**
+ * ups information
+ *
+ * @var string serialized array
+ */
+ define('PSI_UPSINFO', serialize($foundup));
}
- /**
- * ups information
- *
- * @var serialized array
- */
- define('PSI_UPSINFO', serialize($foundup));
// if there are errors stop executing the script until they are fixed
if ($this->error->errorsExist()) {
$this->error->errorsAsXML();
}
- }
- // Create the XML
- if ($this->_pluginRequest) {
- $this->_xml = new XML(false, $this->_pluginName);
+ // Create the XML
+ $this->_xml = new XML($this->_completeXML, '', $this->_blockName);
} else {
- $this->_xml = new XML($this->_completeXML);
+ if ((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) {
+ $plugname = strtoupper(trim($this->_pluginName));
+ if ((PSI_OS == 'Linux') && defined('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME') && defined('PSI_PLUGIN_'.$plugname.'_SSH_USER') && defined('PSI_PLUGIN_'.$plugname.'_SSH_PASSWORD')) {
+ $fgthost = preg_split("/:/", constant('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME'), -1, PREG_SPLIT_NO_EMPTY);
+ define('PSI_EMU_HOSTNAME', trim($fgthost[0]));
+ if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) {
+ define('PSI_EMU_PORT', trim($fgthost[1]));
+ } else {
+ define('PSI_EMU_PORT', 22);
+ }
+ define('PSI_EMU_USER', constant('PSI_PLUGIN_'.$plugname.'_SSH_USER'));
+ define('PSI_EMU_PASSWORD', constant('PSI_PLUGIN_'.$plugname.'_SSH_PASSWORD'));
+ if (defined('PSI_PLUGIN_'.$plugname.'_SSH_ADD_PATHS')) {
+ define('PSI_EMU_ADD_PATHS', constant('PSI_PLUGIN_'.$plugname.'_SSH_ADD_PATHS'));
+ }
+ if (defined('PSI_PLUGIN_'.$plugname.'_SSH_ADD_OPTIONS')) {
+ define('PSI_EMU_ADD_OPTIONS', constant('PSI_PLUGIN_'.$plugname.'_SSH_ADD_OPTIONS'));
+ }
+ } elseif (defined('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME')) {
+ define('PSI_EMU_HOSTNAME', constant('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME'));
+ if (defined('PSI_PLUGIN_'.$plugname.'_WMI_USER') && defined('PSI_PLUGIN_'.$plugname.'_WMI_PASSWORD')) {
+ define('PSI_EMU_USER', constant('PSI_PLUGIN_'.$plugname.'_WMI_USER'));
+ define('PSI_EMU_PASSWORD', constant('PSI_PLUGIN_'.$plugname.'_WMI_PASSWORD'));
+ } else {
+ define('PSI_EMU_USER', null);
+ define('PSI_EMU_PASSWORD', null);
+ }
+ } elseif ((PSI_OS == 'Linux') && defined('PSI_SSH_HOSTNAME') && defined('PSI_SSH_USER') && defined('PSI_SSH_PASSWORD')) {
+ $fgthost = preg_split("/:/", PSI_SSH_HOSTNAME, -1, PREG_SPLIT_NO_EMPTY);
+ define('PSI_EMU_HOSTNAME', trim($fgthost[0]));
+ if (isset($fgthost[1]) && (trim($fgthost[1] !== ''))) {
+ define('PSI_EMU_PORT', trim($fgthost[1]));
+ } else {
+ define('PSI_EMU_PORT', 22);
+ }
+ define('PSI_EMU_USER', PSI_SSH_USER);
+ define('PSI_EMU_PASSWORD', PSI_SSH_PASSWORD);
+ if (defined('PSI_SSH_ADD_PATHS')) {
+ define('PSI_EMU_ADD_PATHS', PSI_SSH_ADD_PATHS);
+ }
+ if (defined('PSI_SSH_ADD_OPTIONS')) {
+ define('PSI_EMU_ADD_OPTIONS', PSI_SSH_ADD_OPTIONS);
+ }
+ } elseif (defined('PSI_WMI_HOSTNAME')) {
+ define('PSI_EMU_HOSTNAME', PSI_WMI_HOSTNAME);
+ if (defined('PSI_WMI_USER') && defined('PSI_WMI_PASSWORD')) {
+ define('PSI_EMU_USER', PSI_WMI_USER);
+ define('PSI_EMU_PASSWORD', PSI_WMI_PASSWORD);
+ } else {
+ define('PSI_EMU_USER', null);
+ define('PSI_EMU_PASSWORD', null);
+ }
+ }
+ }
+
+ // Create the XML
+ $this->_xml = new XML(false, $this->_pluginName);
}
}
@@ -146,8 +225,8 @@ class WebpageXML extends Output implements PSI_Interface_Output
*/
public function run()
{
- header("Cache-Control: no-cache, must-revalidate\n");
- header("Content-Type: text/xml\n\n");
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Content-Type: text/xml');
$xml = $this->_xml->getXml();
echo $xml->asXML();
}
@@ -164,24 +243,52 @@ class WebpageXML extends Output implements PSI_Interface_Output
return $xml->asXML();
}
+ /**
+ * get json string
+ *
+ * @return string
+ */
+ public function getJsonString()
+ {
+ if (defined('PSI_JSON_ISSUE') && (PSI_JSON_ISSUE)) {
+ return json_encode(simplexml_load_string(str_replace(">", ">\n", $this->getXMLString()))); // solving json_encode issue
+ } else {
+ return json_encode(simplexml_load_string($this->getXMLString()));
+ }
+ }
+
+ /**
+ * get array
+ *
+ * @return array
+ */
+ public function getArray()
+ {
+ return json_decode($this->getJsonString());
+ }
+
/**
* set parameters for the XML generation process
*
- * @param boolean $completeXML switch for complete xml with all plugins
- * @param string $plugin name of the plugin
+ * @param string $plugin name of the plugin, block or 'complete' for all plugins
*
* @return void
*/
- public function __construct($completeXML, $plugin = null)
+ public function __construct($plugin = "")
{
parent::__construct();
- if ($completeXML) {
- $this->_completeXML = true;
- }
- if ($plugin) {
- if (in_array(strtolower($plugin), CommonFunctions::getPlugins())) {
+
+ if (is_string($plugin) && ($plugin !== "")) {
+ if (preg_match('/[^A-Za-z]/', $plugin)) {
+ $this->_blockName = ' '; // mask wrong plugin name
+ } elseif (($plugin = strtolower($plugin)) === "complete") {
+ $this->_completeXML = true;
+ } elseif (in_array($plugin, array('vitals','hardware','memory','filesystem','network','mbinfo','voltage','current','temperature','fans','power','other','ups'))) {
+ $this->_blockName = $plugin;
+ } elseif (in_array($plugin, CommonFunctions::getPlugins())) {
$this->_pluginName = $plugin;
- $this->_pluginRequest = true;
+ } else {
+ $this->_blockName = ' '; // disable all blocks
}
}
$this->_prepare();
diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php
index 284498c..9c3597e 100644
--- a/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php
+++ b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Web
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.WebpageXSLT.inc.php 569 2012-04-16 06:08:18Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_Web
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,7 +30,7 @@ class WebpageXSLT extends WebpageXML implements PSI_Interface_Output
*/
public function __construct()
{
- parent::__construct(false, null);
+ parent::__construct();
}
/**
@@ -49,6 +49,7 @@ class WebpageXSLT extends WebpageXML implements PSI_Interface_Output
$domxsl->load($xslfile);
$xsltproc = new XSLTProcessor;
$xsltproc->importStyleSheet($domxsl);
+ header('Cache-Control: no-cache, must-revalidate');
echo $xsltproc->transformToXML($domxml);
}
}
diff --git a/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php
index 583ef8c..fc670fc 100644
--- a/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php
+++ b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php
@@ -8,7 +8,7 @@
* @package PSI_Plugin
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.PSI_Plugin.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -23,7 +23,7 @@
* @package PSI_Plugin
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -61,17 +61,16 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin
* build the global Error object, read the configuration and check if all files are available
* for a minimalistic function of the plugin
*
- * @param String $plugin_name name of the plugin
- * @param String $enc target encoding
- *
+ * @param string $plugin_name name of the plugin
+ * @param string $enc target encoding
* @return void
*/
public function __construct($plugin_name, $enc)
{
- $this->global_error = Error::Singleton();
+ $this->global_error = PSI_Error::Singleton();
if (trim($plugin_name) != "") {
$this->_plugin_name = $plugin_name;
- $this->_plugin_base = APP_ROOT."/plugins/".strtolower($this->_plugin_name)."/";
+ $this->_plugin_base = PSI_APP_ROOT."/plugins/".strtolower($this->_plugin_name)."/";
$this->_checkfiles();
$this->_getconfig();
} else {
@@ -87,9 +86,11 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin
*/
private function _getconfig()
{
- if ((!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_ACCESS')) &&
- (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_FILE'))) {
- $this->global_error->addError("config.ini", "Config for plugin ".$this->_plugin_name." not exist!");
+ if ((strtoupper($this->_plugin_name) !== 'DISKLOAD') &&
+ (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_ACCESS')) &&
+ (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_FILE')) &&
+ (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SHOW_SERIAL'))) {
+ $this->global_error->addError("phpsysinfo.ini", "Config for plugin ".$this->_plugin_name." not exist!");
}
}
@@ -120,9 +121,9 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin
/**
* create the xml template where plugin information are added to
*
- * @param String $enc target encoding
+ * @param string $enc target encoding
*
- * @return Void
+ * @return void
*/
private function _createXml($enc)
{
@@ -130,5 +131,13 @@ abstract class PSI_Plugin implements PSI_Interface_Plugin
$root = $dom->createElement("Plugin_".$this->_plugin_name);
$dom->appendChild($root);
$this->xml = new SimpleXMLExtended(simplexml_import_dom($dom), $enc);
+ $plugname = strtoupper($this->_plugin_name);
+ if ((PSI_OS == 'Linux') && defined('PSI_PLUGIN_'.$plugname.'_SSH_HOSTNAME') &&
+ (!defined('PSI_SSH_HOSTNAME') || (PSI_SSH_HOSTNAME != constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SSH_HOSTNAME')))) {
+ $this->xml->addAttribute('Hostname', constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_SSH_HOSTNAME'));
+ } elseif (((PSI_OS == 'WINNT') || (PSI_OS == 'Linux')) && defined('PSI_PLUGIN_'.$plugname.'_WMI_HOSTNAME') &&
+ (!defined('PSI_WMI_HOSTNAME') || (PSI_WMI_HOSTNAME != constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_WMI_HOSTNAME')))) {
+ $this->xml->addAttribute('Hostname', constant('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_WMI_HOSTNAME'));
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php
index 07c254c..aa07cab 100644
--- a/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php
+++ b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.MBInfo.inc.php 253 2009-06-17 13:07:50Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,7 +30,7 @@ class MBInfo
*
* @see SensorDevice
*
- * @var Array
+ * @var array
*/
private $_mbTemp = array();
@@ -39,7 +39,7 @@ class MBInfo
*
* @see SensorDevice
*
- * @var Array
+ * @var array
*/
private $_mbFan = array();
@@ -48,7 +48,7 @@ class MBInfo
*
* @see SensorDevice
*
- * @var Array
+ * @var array
*/
private $_mbVolt = array();
@@ -57,7 +57,7 @@ class MBInfo
*
* @see SensorDevice
*
- * @var Array
+ * @var array
*/
private $_mbPower = array();
@@ -66,19 +66,32 @@ class MBInfo
*
* @see SensorDevice
*
- * @var Array
+ * @var array
*/
private $_mbCurrent = array();
+ /**
+ * array with SensorDevices for other
+ *
+ * @see SensorDevice
+ *
+ * @var array
+ */
+ private $_mbOther = array();
+
/**
* Returns $_mbFan.
*
* @see System::$_mbFan
*
- * @return Array
+ * @return array
*/
public function getMbFan()
{
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbFan, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_mbFan;
}
@@ -89,7 +102,7 @@ class MBInfo
*
* @see System::$_mbFan
*
- * @return Void
+ * @return void
*/
public function setMbFan($mbFan)
{
@@ -101,21 +114,25 @@ class MBInfo
*
* @see System::$_mbTemp
*
- * @return Array
+ * @return array
*/
public function getMbTemp()
{
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbTemp, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_mbTemp;
}
/**
* Sets $_mbTemp.
*
- * @param Sensor $mbTemp temp device
+ * @param SensorDevice $mbTemp temp device
*
* @see System::$_mbTemp
*
- * @return Void
+ * @return void
*/
public function setMbTemp($mbTemp)
{
@@ -127,21 +144,25 @@ class MBInfo
*
* @see System::$_mbVolt
*
- * @return Array
+ * @return array
*/
public function getMbVolt()
{
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbVolt, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_mbVolt;
}
/**
* Sets $_mbVolt.
*
- * @param Sensor $mbVolt voltage device
+ * @param SensorDevice $mbVolt voltage device
*
* @see System::$_mbVolt
*
- * @return Void
+ * @return void
*/
public function setMbVolt($mbVolt)
{
@@ -153,49 +174,88 @@ class MBInfo
*
* @see System::$_mbPower
*
- * @return Array
+ * @return array
*/
public function getMbPower()
{
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbPower, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_mbPower;
}
/**
* Sets $_mbPower.
*
- * @param Sensor $mbPower power device
+ * @param SensorDevice $mbPower power device
*
* @see System::$_mbPower
*
- * @return Void
+ * @return void
*/
public function setMbPower($mbPower)
{
array_push($this->_mbPower, $mbPower);
}
+
/**
* Returns $_mbCurrent.
*
* @see System::$_mbCurrent
*
- * @return Array
+ * @return array
*/
public function getMbCurrent()
{
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbCurrent, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_mbCurrent;
}
/**
* Sets $_mbCurrent.
*
- * @param Sensor $mbCurrent current device
+ * @param SensorDevice $mbCurrent current device
*
* @see System::$_mbCurrent
*
- * @return Void
+ * @return void
*/
public function setMbCurrent($mbCurrent)
{
array_push($this->_mbCurrent, $mbCurrent);
}
+
+ /**
+ * Returns $_mbOther.
+ *
+ * @see System::$_mbOther
+ *
+ * @return array
+ */
+ public function getMbOther()
+ {
+ if (defined('PSI_SORT_SENSORS_LIST') && PSI_SORT_SENSORS_LIST) {
+ usort($this->_mbOther, array('CommonFunctions', 'name_natural_compare'));
+ }
+
+ return $this->_mbOther;
+ }
+
+ /**
+ * Sets $_mbOther.
+ *
+ * @param SensorDevice $mbOther other device
+ *
+ * @see System::$_mbOther
+ *
+ * @return void
+ */
+ public function setMbOther($mbOther)
+ {
+ array_push($this->_mbOther, $mbOther);
+ }
}
diff --git a/root/opt/phpsysinfo/includes/to/class.System.inc.php b/root/opt/phpsysinfo/includes/to/class.System.inc.php
index 938139e..8ace1dd 100644
--- a/root/opt/phpsysinfo/includes/to/class.System.inc.php
+++ b/root/opt/phpsysinfo/includes/to/class.System.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.System.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,70 +28,70 @@ class System
/**
* name of the host where phpSysInfo runs
*
- * @var String
+ * @var string
*/
private $_hostname = "localhost";
/**
* ip of the host where phpSysInfo runs
*
- * @var String
+ * @var string
*/
private $_ip = "127.0.0.1";
/**
- * detailed Information about the kernel
+ * detailed information about the kernel
*
- * @var String
+ * @var string
*/
private $_kernel = "Unknown";
/**
* name of the distribution
*
- * @var String
+ * @var string
*/
private $_distribution = "Unknown";
/**
* icon of the distribution (must be available in phpSysInfo)
*
- * @var String
+ * @var string
*/
private $_distributionIcon = "unknown.png";
/**
* detailed Information about the machine name
*
- * @var String
+ * @var string
*/
private $_machine = "";
/**
* time in sec how long the system is running
*
- * @var Integer
+ * @var int
*/
private $_uptime = 0;
/**
* count of users that are currently logged in
*
- * @var Integer
+ * @var int
*/
private $_users = 0;
/**
* load of the system
*
- * @var String
+ * @var string
*/
private $_load = "";
/**
* load of the system in percent (all cpus, if more than one)
*
- * @var Integer
+ * @var int
*/
private $_loadPercent = null;
@@ -100,7 +100,7 @@ class System
*
* @see CpuDevice
*
- * @var Array
+ * @var array
*/
private $_cpus = array();
@@ -109,7 +109,7 @@ class System
*
* @see NetDevice
*
- * @var Array
+ * @var array
*/
private $_netDevices = array();
@@ -118,7 +118,7 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_pciDevices = array();
@@ -127,7 +127,7 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_ideDevices = array();
@@ -136,7 +136,7 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_scsiDevices = array();
@@ -145,7 +145,7 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_usbDevices = array();
@@ -154,7 +154,7 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_tbDevices = array();
@@ -163,58 +163,76 @@ class System
*
* @see HWDevice
*
- * @var Array
+ * @var array
*/
private $_i2cDevices = array();
+ /**
+ * array with NVMe devices
+ *
+ * @see HWDevice
+ *
+ * @var array
+ */
+ private $_nvmeDevices = array();
+
+ /**
+ * array with Mem devices
+ *
+ * @see HWDevice
+ *
+ * @var array
+ */
+ private $_memDevices = array();
+
/**
* array with disk devices
*
* @see DiskDevice
*
- * @var Array
+ * @var array
*/
private $_diskDevices = array();
/**
* free memory in bytes
*
- * @var Integer
+ * @var int
*/
private $_memFree = 0;
/**
* total memory in bytes
*
- * @var Integer
+ * @var int
*/
private $_memTotal = 0;
/**
* used memory in bytes
*
- * @var Integer
+ * @var int
*/
private $_memUsed = 0;
/**
* used memory by applications in bytes
*
- * @var Integer
+ * @var int
*/
private $_memApplication = null;
/**
* used memory for buffers in bytes
*
- * @var Integer
+ * @var int
*/
private $_memBuffer = null;
/**
* used memory for cache in bytes
*
- * @var Integer
+ * @var int
*/
private $_memCache = null;
@@ -223,25 +241,39 @@ class System
*
* @see DiskDevice
*
- * @var Array
+ * @var array
*/
private $_swapDevices = array();
/**
* array of types of processes
*
- * @var Array
+ * @var array
*/
private $_processes = array();
+ /**
+ * array with Virtualizer information
+ *
+ * @var array
+ */
+ private $_virtualizer = array();
+
+ /**
+ * operating system type
+ *
+ * @var string
+ */
+ private $_OS = "";
+
/**
* remove duplicate Entries and Count
*
- * @param Array $arrDev list of HWDevices
+ * @param array $arrDev list of HWDevices
*
* @see HWDevice
*
- * @return Array
+ * @return array
*/
public static function removeDupsAndCount($arrDev)
{
@@ -273,7 +305,7 @@ class System
* @see System::_memUsed
* @see System::_memTotal
*
- * @return Integer
+ * @return int
*/
public function getMemPercentUsed()
{
@@ -290,7 +322,7 @@ class System
* @see System::_memApplication
* @see System::_memTotal
*
- * @return Integer
+ * @return int
*/
public function getMemPercentApplication()
{
@@ -311,7 +343,7 @@ class System
* @see System::_memCache
* @see System::_memTotal
*
- * @return Integer
+ * @return int
*/
public function getMemPercentCache()
{
@@ -336,7 +368,7 @@ class System
* @see System::_memBuffer
* @see System::_memTotal
*
- * @return Integer
+ * @return int
*/
public function getMemPercentBuffer()
{
@@ -367,7 +399,7 @@ class System
* @see System::_swapDevices
* @see DiskDevice::getFree()
*
- * @return Integer
+ * @return int
*/
public function getSwapFree()
{
@@ -389,7 +421,7 @@ class System
* @see System::_swapDevices
* @see DiskDevice::getTotal()
*
- * @return Integer
+ * @return int
*/
public function getSwapTotal()
{
@@ -411,7 +443,7 @@ class System
* @see System::_swapDevices
* @see DiskDevice::getUsed()
*
- * @return Integer
+ * @return int
*/
public function getSwapUsed()
{
@@ -433,7 +465,7 @@ class System
* @see System::getSwapUsed()
* @see System::getSwapTotal()
*
- * @return Integer
+ * @return int
*/
public function getSwapPercentUsed()
{
@@ -467,7 +499,7 @@ class System
*
* @see System::$_distribution
*
- * @return Void
+ * @return void
*/
public function setDistribution($distribution)
{
@@ -493,7 +525,7 @@ class System
*
* @see System::$_distributionIcon
*
- * @return Void
+ * @return void
*/
public function setDistributionIcon($distributionIcon)
{
@@ -519,7 +551,7 @@ class System
*
* @see System::$_hostname
*
- * @return Void
+ * @return void
*/
public function setHostname($hostname)
{
@@ -545,7 +577,7 @@ class System
*
* @see System::$_ip
*
- * @return Void
+ * @return void
*/
public function setIp($ip)
{
@@ -571,7 +603,7 @@ class System
*
* @see System::$_kernel
*
- * @return Void
+ * @return void
*/
public function setKernel($kernel)
{
@@ -597,7 +629,7 @@ class System
*
* @see System::$_load
*
- * @return Void
+ * @return void
*/
public function setLoad($load)
{
@@ -609,7 +641,7 @@ class System
*
* @see System::$_loadPercent
*
- * @return Integer
+ * @return int
*/
public function getLoadPercent()
{
@@ -619,11 +651,11 @@ class System
/**
* Sets $_loadPercent.
*
- * @param Integer $loadPercent load percent
+ * @param int $loadPercent load percent
*
* @see System::$_loadPercent
*
- * @return Void
+ * @return void
*/
public function setLoadPercent($loadPercent)
{
@@ -645,11 +677,11 @@ class System
/**
* Sets $_machine.
*
- * @param Interger $machine machine
+ * @param string $machine machine
*
* @see System::$_machine
*
- * @return Void
+ * @return void
*/
public function setMachine($machine)
{
@@ -661,7 +693,7 @@ class System
*
* @see System::$_uptime
*
- * @return Integer
+ * @return int
*/
public function getUptime()
{
@@ -671,11 +703,11 @@ class System
/**
* Sets $_uptime.
*
- * @param Interger $uptime uptime
+ * @param integer $uptime uptime
*
* @see System::$_uptime
*
- * @return Void
+ * @return void
*/
public function setUptime($uptime)
{
@@ -687,7 +719,7 @@ class System
*
* @see System::$_users
*
- * @return Integer
+ * @return int
*/
public function getUsers()
{
@@ -697,11 +729,11 @@ class System
/**
* Sets $_users.
*
- * @param Integer $users user count
+ * @param int $users user count
*
* @see System::$_users
*
- * @return Void
+ * @return void
*/
public function setUsers($users)
{
@@ -713,7 +745,7 @@ class System
*
* @see System::$_cpus
*
- * @return Array
+ * @return array
*/
public function getCpus()
{
@@ -723,12 +755,12 @@ class System
/**
* Sets $_cpus.
*
- * @param Cpu $cpus cpu device
+ * @param CpuDevice $cpus cpu device
*
* @see System::$_cpus
* @see CpuDevice
*
- * @return Void
+ * @return void
*/
public function setCpus($cpus)
{
@@ -740,10 +772,14 @@ class System
*
* @see System::$_netDevices
*
- * @return Array
+ * @return array
*/
public function getNetDevices()
{
+ if (defined('PSI_SORT_NETWORK_INTERFACES_LIST') && PSI_SORT_NETWORK_INTERFACES_LIST) {
+ usort($this->_netDevices, array('CommonFunctions', 'name_natural_compare'));
+ }
+
return $this->_netDevices;
}
@@ -755,7 +791,7 @@ class System
* @see System::$_netDevices
* @see NetDevice
*
- * @return Void
+ * @return void
*/
public function setNetDevices($netDevices)
{
@@ -767,7 +803,7 @@ class System
*
* @see System::$_pciDevices
*
- * @return Array
+ * @return array
*/
public function getPciDevices()
{
@@ -782,7 +818,7 @@ class System
* @see System::$_pciDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setPciDevices($pciDevices)
{
@@ -794,7 +830,7 @@ class System
*
* @see System::$_ideDevices
*
- * @return Array
+ * @return array
*/
public function getIdeDevices()
{
@@ -809,7 +845,7 @@ class System
* @see System::$_ideDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setIdeDevices($ideDevices)
{
@@ -821,7 +857,7 @@ class System
*
* @see System::$_scsiDevices
*
- * @return Array
+ * @return array
*/
public function getScsiDevices()
{
@@ -836,7 +872,7 @@ class System
* @see System::$_scsiDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setScsiDevices($scsiDevices)
{
@@ -848,7 +884,7 @@ class System
*
* @see System::$_usbDevices
*
- * @return Array
+ * @return array
*/
public function getUsbDevices()
{
@@ -863,7 +899,7 @@ class System
* @see System::$_usbDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setUsbDevices($usbDevices)
{
@@ -875,7 +911,7 @@ class System
*
* @see System::$_tbDevices
*
- * @return Array
+ * @return array
*/
public function getTbDevices()
{
@@ -890,7 +926,7 @@ class System
* @see System::$_tbDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setTbDevices($tbDevices)
{
@@ -902,7 +938,7 @@ class System
*
* @see System::$_i2cDevices
*
- * @return Array
+ * @return array
*/
public function getI2cDevices()
{
@@ -917,19 +953,73 @@ class System
* @see System::$_i2cDevices
* @see HWDevice
*
- * @return Void
+ * @return void
*/
public function setI2cDevices($i2cDevices)
{
array_push($this->_i2cDevices, $i2cDevices);
}
+ /**
+ * Returns $_nvmeDevices.
+ *
+ * @see System::$_nvmeDevices
+ *
+ * @return array
+ */
+ public function getNvmeDevices()
+ {
+ return $this->_nvmeDevices;
+ }
+
+ /**
+ * Sets $_nvmeDevices.
+ *
+ * @param HWDevice $nvmeDevices NVMe device
+ *
+ * @see System::$_nvmeDevices
+ * @see HWDevice
+ *
+ * @return void
+ */
+ public function setNvmeDevices($nvmeDevices)
+ {
+ array_push($this->_nvmeDevices, $nvmeDevices);
+ }
+
+ /**
+ * Returns $_memDevices.
+ *
+ * @see System::$_memDevices
+ *
+ * @return array
+ */
+ public function getMemDevices()
+ {
+ return $this->_memDevices;
+ }
+
+ /**
+ * Sets $_memDevices.
+ *
+ * @param HWDevice $memDevices mem device
+ *
+ * @see System::$_memDevices
+ * @see HWDevice
+ *
+ * @return void
+ */
+ public function setMemDevices($memDevices)
+ {
+ array_push($this->_memDevices, $memDevices);
+ }
+
/**
* Returns $_diskDevices.
*
* @see System::$_diskDevices
*
- * @return Array
+ * @return array
*/
public function getDiskDevices()
{
@@ -956,7 +1046,7 @@ class System
*
* @see System::$_memApplication
*
- * @return Integer
+ * @return int
*/
public function getMemApplication()
{
@@ -966,11 +1056,11 @@ class System
/**
* Sets $_memApplication.
*
- * @param Integer $memApplication application memory
+ * @param int $memApplication application memory
*
* @see System::$_memApplication
*
- * @return Void
+ * @return void
*/
public function setMemApplication($memApplication)
{
@@ -982,7 +1072,7 @@ class System
*
* @see System::$_memBuffer
*
- * @return Integer
+ * @return int
*/
public function getMemBuffer()
{
@@ -992,11 +1082,11 @@ class System
/**
* Sets $_memBuffer.
*
- * @param Integer $memBuffer buffer memory
+ * @param int $memBuffer buffer memory
*
* @see System::$_memBuffer
*
- * @return Void
+ * @return void
*/
public function setMemBuffer($memBuffer)
{
@@ -1008,7 +1098,7 @@ class System
*
* @see System::$_memCache
*
- * @return Integer
+ * @return int
*/
public function getMemCache()
{
@@ -1018,11 +1108,11 @@ class System
/**
* Sets $_memCache.
*
- * @param Integer $memCache cache memory
+ * @param int $memCache cache memory
*
* @see System::$_memCache
*
- * @return Void
+ * @return void
*/
public function setMemCache($memCache)
{
@@ -1034,7 +1124,7 @@ class System
*
* @see System::$_memFree
*
- * @return Integer
+ * @return int
*/
public function getMemFree()
{
@@ -1044,11 +1134,11 @@ class System
/**
* Sets $_memFree.
*
- * @param Integer $memFree free memory
+ * @param int $memFree free memory
*
* @see System::$_memFree
*
- * @return Void
+ * @return void
*/
public function setMemFree($memFree)
{
@@ -1060,7 +1150,7 @@ class System
*
* @see System::$_memTotal
*
- * @return Integer
+ * @return int
*/
public function getMemTotal()
{
@@ -1070,11 +1160,11 @@ class System
/**
* Sets $_memTotal.
*
- * @param Integer $memTotal total memory
+ * @param int $memTotal total memory
*
* @see System::$_memTotal
*
- * @return Void
+ * @return void
*/
public function setMemTotal($memTotal)
{
@@ -1086,7 +1176,7 @@ class System
*
* @see System::$_memUsed
*
- * @return Integer
+ * @return int
*/
public function getMemUsed()
{
@@ -1096,11 +1186,11 @@ class System
/**
* Sets $_memUsed.
*
- * @param Integer $memUsed used memory
+ * @param int $memUsed used memory
*
* @see System::$_memUsed
*
- * @return Void
+ * @return void
*/
public function setMemUsed($memUsed)
{
@@ -1112,7 +1202,7 @@ class System
*
* @see System::$_swapDevices
*
- * @return Array
+ * @return array
*/
public function getSwapDevices()
{
@@ -1127,7 +1217,7 @@ class System
* @see System::$_swapDevices
* @see DiskDevice
*
- * @return Void
+ * @return void
*/
public function setSwapDevices($swapDevices)
{
@@ -1139,7 +1229,7 @@ class System
*
* @see System::$_processes
*
- * @return Array
+ * @return array
*/
public function getProcesses()
{
@@ -1153,7 +1243,7 @@ class System
*
* @see System::$_processes
*
- * @return Void
+ * @return void
*/
public function setProcesses($processes)
{
@@ -1164,4 +1254,64 @@ class System
}
*/
}
+
+ /**
+ * Returns $_virtualizer.
+ *
+ * @see System::$_virtualizer
+ *
+ * @return array
+ */
+ public function getVirtualizer()
+ {
+ return $this->_virtualizer;
+ }
+
+ /**
+ * Sets $_virtualizer.
+ *
+ * @param String $virtualizer virtualizername
+ * @param Bool|String $value true, false or virtualizername to replace
+ *
+ * @see System::$_virtualizer
+ *
+ * @return void
+ */
+ public function setVirtualizer($virtualizer, $value = true)
+ {
+ if (!isset($this->_virtualizer[$virtualizer])) {
+ if (is_bool($value)) {
+ $this->_virtualizer[$virtualizer] = $value;
+ } else { // replace the virtualizer with another
+ $this->_virtualizer[$virtualizer] = true;
+ $this->_virtualizer[$value] = false;
+ }
+ }
+ }
+
+ /**
+ * Returns $_OS.
+ *
+ * @see System::$_OS
+ *
+ * @return string
+ */
+ public function getOS()
+ {
+ return $this->_OS;
+ }
+
+ /**
+ * Sets $_OS.
+ *
+ * @param $os operating system type
+ *
+ * @see System::$_OS
+ *
+ * @return void
+ */
+ public function setOS($OS)
+ {
+ $this->_OS = $OS;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php
index 26b81cf..3b120f4 100644
--- a/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php
+++ b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.UPSInfo.inc.php 329 2009-09-07 11:21:44Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -30,7 +30,7 @@ class UPSInfo
*
* @see UPSDevice
*
- * @var Array
+ * @var array
*/
private $_upsDevices = array();
@@ -39,7 +39,7 @@ class UPSInfo
*
* @see UPSInfo::$_upsDevices
*
- * @return Array
+ * @return array
*/
public function getUpsDevices()
{
@@ -53,7 +53,7 @@ class UPSInfo
*
* @see UPSInfo::$_upsDevices
*
- * @return Void
+ * @return void
*/
public function setUpsDevices($upsDevices)
{
diff --git a/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php
index e690ef2..a229801 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.CpuDevice.inc.php 411 2010-12-28 22:32:52Z Jacky672 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,123 +28,215 @@ class CpuDevice
/**
* model of the cpu
*
- * @var String
+ * @var string
*/
private $_model = "";
+ /**
+ * cpu voltage
+ *
+ * @var Float
+ */
+ private $_voltage = 0;
+
/**
* speed of the cpu in hertz
*
- * @var Integer
+ * @var int
*/
private $_cpuSpeed = 0;
/**
* max speed of the cpu in hertz
*
- * @var Integer
+ * @var int
*/
private $_cpuSpeedMax = 0;
/**
* min speed of the cpu in hertz
*
- * @var Integer
+ * @var int
*/
private $_cpuSpeedMin = 0;
/**
* cache size in bytes, if available
*
- * @var Integer
+ * @var int
*/
private $_cache = null;
/**
* virtualization, if available
*
- * @var String
+ * @var string
*/
private $_virt = null;
/**
* busspeed in hertz, if available
*
- * @var Integer
+ * @var int
*/
private $_busSpeed = null;
- /**
- * temperature of the cpu, if available
- *
- * @var Integer
- */
- private $_temp = null;
-
/**
* bogomips of the cpu, if available
*
- * @var Integer
+ * @var int
*/
private $_bogomips = null;
+ /**
+ * temperature of the cpu, if available
+ *
+ * @var int
+ */
+ private $_temp = null;
+
+ /**
+ * vendorid, if available
+ *
+ * @var string
+ */
+ private $_vendorid = null;
+
/**
* current load in percent of the cpu, if available
*
- * @var Integer
+ * @var int
*/
private $_load = null;
/**
- * Returns $_bogomips.
+ * Returns $_model.
*
- * @see Cpu::$_bogomips
+ * @see Cpu::$_model
*
- * @return Integer
+ * @return String
*/
- public function getBogomips()
+ public function getModel()
{
- return $this->_bogomips;
+ return $this->_model;
}
/**
- * Sets $_bogomips.
+ * Sets $_model.
*
- * @param Integer $bogomips bogompis
+ * @param String $model cpumodel
*
- * @see Cpu::$_bogomips
+ * @see Cpu::$_model
*
- * @return Void
+ * @return void
*/
- public function setBogomips($bogomips)
+ public function setModel($model)
{
- $this->_bogomips = $bogomips;
+ $this->_model = $model;
}
/**
- * Returns $_busSpeed.
+ * Returns $_voltage.
*
- * @see Cpu::$_busSpeed
+ * @see Cpu::$_voltage
*
- * @return Integer
+ * @return Float
*/
- public function getBusSpeed()
+ public function getVoltage()
{
- return $this->_busSpeed;
+ return $this->_voltage;
}
/**
- * Sets $_busSpeed.
+ * Sets $_voltage.
*
- * @param Integer $busSpeed busspeed
+ * @param int $voltage voltage
*
- * @see Cpu::$_busSpeed
+ * @see Cpu::$_voltage
*
- * @return Void
+ * @return void
*/
- public function setBusSpeed($busSpeed)
+ public function setVoltage($voltage)
{
- $this->_busSpeed = $busSpeed;
+ $this->_voltage = $voltage;
+ }
+
+ /**
+ * Returns $_cpuSpeed.
+ *
+ * @see Cpu::$_cpuSpeed
+ *
+ * @return int
+ */
+ public function getCpuSpeed()
+ {
+ return $this->_cpuSpeed;
+ }
+
+ /**
+ * Sets $_cpuSpeed.
+ *
+ * @param int $cpuSpeed cpuspeed
+ *
+ * @see Cpu::$_cpuSpeed
+ *
+ * @return void
+ */
+ public function setCpuSpeed($cpuSpeed)
+ {
+ $this->_cpuSpeed = $cpuSpeed;
+ }
+
+ /**
+ * Returns $_cpuSpeedMax.
+ *
+ * @see Cpu::$_cpuSpeedMAx
+ *
+ * @return int
+ */
+ public function getCpuSpeedMax()
+ {
+ return $this->_cpuSpeedMax;
+ }
+
+ /**
+ * Sets $_cpuSpeedMax.
+ *
+ * @param int $cpuSpeedMax cpuspeedmax
+ *
+ * @see Cpu::$_cpuSpeedMax
+ *
+ * @return void
+ */
+ public function setCpuSpeedMax($cpuSpeedMax)
+ {
+ $this->_cpuSpeedMax = $cpuSpeedMax;
+ }
+
+ /**
+ * Returns $_cpuSpeedMin.
+ *
+ * @see Cpu::$_cpuSpeedMin
+ *
+ * @return int
+ */
+ public function getCpuSpeedMin()
+ {
+ return $this->_cpuSpeedMin;
+ }
+
+ /**
+ * Sets $_cpuSpeedMin.
+ *
+ * @param int $cpuSpeedMin cpuspeedmin
+ *
+ * @see Cpu::$_cpuSpeedMin
+ *
+ * @return void
+ */
+ public function setCpuSpeedMin($cpuSpeedMin)
+ {
+ $this->_cpuSpeedMin = $cpuSpeedMin;
}
/**
@@ -152,7 +244,7 @@ class CpuDevice
*
* @see Cpu::$_cache
*
- * @return Integer
+ * @return int
*/
public function getCache()
{
@@ -162,11 +254,11 @@ class CpuDevice
/**
* Sets $_cache.
*
- * @param Integer $cache cache size
+ * @param int $cache cache size
*
* @see Cpu::$_cache
*
- * @return Void
+ * @return void
*/
public function setCache($cache)
{
@@ -188,11 +280,11 @@ class CpuDevice
/**
* Sets $_virt.
*
- * @param String $_virt
+ * @param string $virt
*
* @see Cpu::$_virt
*
- * @return Void
+ * @return void
*/
public function setVirt($virt)
{
@@ -200,107 +292,55 @@ class CpuDevice
}
/**
- * Returns $_cpuSpeed.
+ * Returns $_busSpeed.
*
- * @see Cpu::$_cpuSpeed
+ * @see Cpu::$_busSpeed
*
- * @return Integer
+ * @return int
*/
- public function getCpuSpeed()
+ public function getBusSpeed()
{
- return $this->_cpuSpeed;
+ return $this->_busSpeed;
}
/**
- * Returns $_cpuSpeedMax.
+ * Sets $_busSpeed.
*
- * @see Cpu::$_cpuSpeedMAx
+ * @param int $busSpeed busspeed
*
- * @return Integer
+ * @see Cpu::$_busSpeed
+ *
+ * @return void
*/
- public function getCpuSpeedMax()
+ public function setBusSpeed($busSpeed)
{
- return $this->_cpuSpeedMax;
+ $this->_busSpeed = $busSpeed;
}
/**
- * Returns $_cpuSpeedMin.
+ * Returns $_bogomips.
*
- * @see Cpu::$_cpuSpeedMin
+ * @see Cpu::$_bogomips
*
- * @return Integer
+ * @return int
*/
- public function getCpuSpeedMin()
+ public function getBogomips()
{
- return $this->_cpuSpeedMin;
+ return $this->_bogomips;
}
/**
- * Sets $_cpuSpeed.
+ * Sets $_bogomips.
*
- * @param Integer $cpuSpeed cpuspeed
+ * @param int $bogomips bogompis
*
- * @see Cpu::$_cpuSpeed
+ * @see Cpu::$_bogomips
*
- * @return Void
+ * @return void
*/
- public function setCpuSpeed($cpuSpeed)
+ public function setBogomips($bogomips)
{
- $this->_cpuSpeed = $cpuSpeed;
- }
-
- /**
- * Sets $_cpuSpeedMax.
- *
- * @param Integer $cpuSpeedMax cpuspeedmax
- *
- * @see Cpu::$_cpuSpeedMax
- *
- * @return Void
- */
- public function setCpuSpeedMax($cpuSpeedMax)
- {
- $this->_cpuSpeedMax = $cpuSpeedMax;
- }
-
- /**
- * Sets $_cpuSpeedMin.
- *
- * @param Integer $cpuSpeedMin cpuspeedmin
- *
- * @see Cpu::$_cpuSpeedMin
- *
- * @return Void
- */
- public function setCpuSpeedMin($cpuSpeedMin)
- {
- $this->_cpuSpeedMin = $cpuSpeedMin;
- }
-
- /**
- * Returns $_model.
- *
- * @see Cpu::$_model
- *
- * @return String
- */
- public function getModel()
- {
- return $this->_model;
- }
-
- /**
- * Sets $_model.
- *
- * @param String $model cpumodel
- *
- * @see Cpu::$_model
- *
- * @return Void
- */
- public function setModel($model)
- {
- $this->_model = $model;
+ $this->_bogomips = $bogomips;
}
/**
@@ -308,33 +348,63 @@ class CpuDevice
*
* @see Cpu::$_temp
*
- * @return Integer
+ * @return int
*/
+/*
public function getTemp()
{
return $this->_temp;
}
+*/
/**
* Sets $_temp.
*
- * @param Integer $temp temperature
+ * @param int $temp temperature
*
* @see Cpu::$_temp
*
- * @return Void
+ * @return void
*/
+/*
public function setTemp($temp)
{
$this->_temp = $temp;
}
+*/
+
+ /**
+ * Returns $_vendorid.
+ *
+ * @see Cpu::$_vendorid
+ *
+ * @return String
+ */
+ public function getVendorId()
+ {
+ return $this->_vendorid;
+ }
+
+ /**
+ * Sets $_vendorid.
+ *
+ * @param string $vendorid
+ *
+ * @see Cpu::$_vendorid
+ *
+ * @return void
+ */
+ public function setVendorId($vendorid)
+ {
+ $this->_vendorid = trim(preg_replace('/[\s!]/', '', $vendorid));
+ }
/**
* Returns $_load.
*
* @see CpuDevice::$_load
*
- * @return Integer
+ * @return int
*/
public function getLoad()
{
@@ -344,11 +414,11 @@ class CpuDevice
/**
* Sets $_load.
*
- * @param Integer $load load percent
+ * @param int $load load percent
*
* @see CpuDevice::$_load
*
- * @return Void
+ * @return void
*/
public function setLoad($load)
{
diff --git a/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php
index 32e5b73..aa7a9c5 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.DiskDevice.inc.php 252 2009-06-17 13:06:44Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,71 +28,78 @@ class DiskDevice
/**
* name of the disk device
*
- * @var String
+ * @var string
*/
private $_name = "";
/**
* type of the filesystem on the disk device
*
- * @var String
+ * @var string
*/
private $_fsType = "";
/**
* diskspace that is free in bytes
*
- * @var Integer
+ * @var int
*/
private $_free = 0;
/**
* diskspace that is used in bytes
*
- * @var Integer
+ * @var int
*/
private $_used = 0;
/**
* total diskspace
*
- * @var Integer
+ * @var int
*/
private $_total = 0;
/**
* mount point of the disk device if available
*
- * @var String
+ * @var string
*/
private $_mountPoint = null;
/**
* additional options of the device, like mount options
*
- * @var String
+ * @var string
*/
private $_options = null;
/**
* inodes usage in percent if available
*
- * @var
+ * @var int
*/
private $_percentInodesUsed = null;
+ /**
+ * ignore mode
+ *
+ * @var int
+ */
+ private $_ignore = 0;
+
/**
* Returns PercentUsed calculated when function is called from internal values
*
* @see DiskDevice::$_total
* @see DiskDevice::$_used
*
- * @return Integer
+ * @return int
*/
public function getPercentUsed()
{
if ($this->_total > 0) {
- return round($this->_used / $this->_total * 100);
+ return 100 - min(floor($this->_free / $this->_total * 100), 100);
} else {
return 0;
}
@@ -103,7 +110,7 @@ class DiskDevice
*
* @see DiskDevice::$_PercentInodesUsed
*
- * @return Integer
+ * @return int
*/
public function getPercentInodesUsed()
{
@@ -113,11 +120,11 @@ class DiskDevice
/**
* Sets $_PercentInodesUsed.
*
- * @param Integer $percentInodesUsed inodes percent
+ * @param int $percentInodesUsed inodes percent
*
* @see DiskDevice::$_PercentInodesUsed
*
- * @return Void
+ * @return void
*/
public function setPercentInodesUsed($percentInodesUsed)
{
@@ -129,7 +136,7 @@ class DiskDevice
*
* @see DiskDevice::$_free
*
- * @return Integer
+ * @return int
*/
public function getFree()
{
@@ -139,11 +146,11 @@ class DiskDevice
/**
* Sets $_free.
*
- * @param Integer $free free bytes
+ * @param int $free free bytes
*
* @see DiskDevice::$_free
*
- * @return Void
+ * @return void
*/
public function setFree($free)
{
@@ -155,7 +162,7 @@ class DiskDevice
*
* @see DiskDevice::$_fsType
*
- * @return String
+ * @return string
*/
public function getFsType()
{
@@ -169,7 +176,7 @@ class DiskDevice
*
* @see DiskDevice::$_fsType
*
- * @return Void
+ * @return void
*/
public function setFsType($fsType)
{
@@ -181,7 +188,7 @@ class DiskDevice
*
* @see DiskDevice::$_mountPoint
*
- * @return String
+ * @return string
*/
public function getMountPoint()
{
@@ -191,11 +198,11 @@ class DiskDevice
/**
* Sets $_mountPoint.
*
- * @param String $mountPoint mountpoint
+ * @param string $mountPoint mountpoint
*
* @see DiskDevice::$_mountPoint
*
- * @return Void
+ * @return void
*/
public function setMountPoint($mountPoint)
{
@@ -207,7 +214,7 @@ class DiskDevice
*
* @see DiskDevice::$_name
*
- * @return String
+ * @return string
*/
public function getName()
{
@@ -217,11 +224,11 @@ class DiskDevice
/**
* Sets $_name.
*
- * @param String $name device name
+ * @param string $name device name
*
* @see DiskDevice::$_name
*
- * @return Void
+ * @return void
*/
public function setName($name)
{
@@ -233,7 +240,7 @@ class DiskDevice
*
* @see DiskDevice::$_options
*
- * @return String
+ * @return string
*/
public function getOptions()
{
@@ -243,11 +250,11 @@ class DiskDevice
/**
* Sets $_options.
*
- * @param String $options additional options
+ * @param string $options additional options
*
* @see DiskDevice::$_options
*
- * @return Void
+ * @return void
*/
public function setOptions($options)
{
@@ -259,7 +266,7 @@ class DiskDevice
*
* @see DiskDevice::$_total
*
- * @return Integer
+ * @return int
*/
public function getTotal()
{
@@ -269,11 +276,11 @@ class DiskDevice
/**
* Sets $_total.
*
- * @param Integer $total total bytes
+ * @param int $total total bytes
*
* @see DiskDevice::$_total
*
- * @return Void
+ * @return void
*/
public function setTotal($total)
{
@@ -285,7 +292,7 @@ class DiskDevice
*
* @see DiskDevice::$_used
*
- * @return Integer
+ * @return int
*/
public function getUsed()
{
@@ -295,14 +302,38 @@ class DiskDevice
/**
* Sets $_used.
*
- * @param Integer $used used bytes
+ * @param int $used used bytes
*
* @see DiskDevice::$_used
*
- * @return Void
+ * @return void
*/
public function setUsed($used)
{
$this->_used = $used;
}
+
+ /**
+ * Returns $_ignore.
+ *
+ * @see DiskDevice::$_ignore
+ *
+ * @return int
+ */
+ public function getIgnore()
+ {
+ return $this->_ignore;
+ }
+
+ /**
+ * Sets $_ignore.
+ *
+ * @see DiskDevice::$_ignore
+ *
+ * @return void
+ */
+ public function setIgnore($ignore)
+ {
+ $this->_ignore = $ignore;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php
index 3a2b0f1..c4db009 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.HWDevice.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,21 +28,56 @@ class HWDevice
/**
* name of the device
*
- * @var String
+ * @var string
*/
private $_name = "";
/**
* capacity of the device, if not available it will be null
*
- * @var Integer
+ * @var int
*/
private $_capacity = null;
+ /**
+ * manufacturer of the device, if not available it will be null
+ *
+ * @var int
+ */
+ private $_manufacturer = null;
+
+ /**
+ * product of the device, if not available it will be null
+ *
+ * @var int
+ */
+ private $_product = null;
+
+ /**
+ * serial number of the device, if not available it will be null
+ *
+ * @var string
+ */
+ private $_serial = null;
+
+ /**
+ * speed of the device, if not available it will be null
+ *
+ * @var Float
+ */
+ private $_speed = null;
+
+ /**
+ * voltage of the device, if not available it will be null
+ *
+ * @var Float
+ */
+ private $_voltage = null;
+
/**
* count of the device
*
- * @var Integer
+ * @var int
*/
private $_count = 1;
@@ -55,39 +90,18 @@ class HWDevice
*/
public function equals(HWDevice $dev)
{
- if ($dev->getName() === $this->_name && $dev->getCapacity() === $this->_capacity) {
+ if ($dev->getName() === $this->_name
+ && $dev->getCapacity() === $this->_capacity
+ && $dev->getManufacturer() === $this->_manufacturer
+ && $dev->getProduct() === $this->_product
+ && $dev->getSerial() === $this->_serial
+ && $dev->getSpeed() === $this->_speed) {
return true;
} else {
return false;
}
}
- /**
- * Returns $_capacity.
- *
- * @see HWDevice::$_capacity
- *
- * @return Integer
- */
- public function getCapacity()
- {
- return $this->_capacity;
- }
-
- /**
- * Sets $_capacity.
- *
- * @param Integer $capacity device capacity
- *
- * @see HWDevice::$_capacity
- *
- * @return Void
- */
- public function setCapacity($capacity)
- {
- $this->_capacity = $capacity;
- }
-
/**
* Returns $_name.
*
@@ -107,19 +121,175 @@ class HWDevice
*
* @see HWDevice::$_name
*
- * @return Void
+ * @return void
*/
public function setName($name)
{
$this->_name = $name;
}
+ /**
+ * Returns $_manufacturer.
+ *
+ * @see HWDevice::$_manufacturer
+ *
+ * @return String
+ */
+ public function getManufacturer()
+ {
+ return $this->_manufacturer;
+ }
+
+ /**
+ * Sets $_manufacturer.
+ *
+ * @param String $manufacturer manufacturer name
+ *
+ * @see HWDevice::$_manufacturer
+ *
+ * @return void
+ */
+ public function setManufacturer($manufacturer)
+ {
+ $this->_manufacturer = $manufacturer;
+ }
+
+ /**
+ * Returns $_product.
+ *
+ * @see HWDevice::$_product
+ *
+ * @return String
+ */
+ public function getProduct()
+ {
+ return $this->_product;
+ }
+
+ /**
+ * Sets $_product.
+ *
+ * @param String $product product name
+ *
+ * @see HWDevice::$_product
+ *
+ * @return void
+ */
+ public function setProduct($product)
+ {
+ $this->_product = $product;
+ }
+
+ /**
+ * Returns $_serial.
+ *
+ * @see HWDevice::$_serial
+ *
+ * @return String
+ */
+ public function getSerial()
+ {
+ return $this->_serial;
+ }
+
+ /**
+ * Sets $_serial.
+ *
+ * @param String $serial serial number
+ *
+ * @see HWDevice::$_serial
+ *
+ * @return void
+ */
+ public function setSerial($serial)
+ {
+ $this->_serial = $serial;
+ }
+
+ /**
+ * Returns $_speed.
+ *
+ * @see HWDevice::$_speed
+ *
+ * @return Float
+ */
+ public function getSpeed()
+ {
+ return $this->_speed;
+ }
+
+ /**
+ * Sets $_speed.
+ *
+ * @param Float $speed speed
+ *
+ * @see HWDevice::$_speed
+ *
+ * @return void
+ */
+ public function setSpeed($speed)
+ {
+ $this->_speed = $speed;
+ }
+
+ /**
+ * Returns $_voltage.
+ *
+ * @see HWDevice::$_voltage
+ *
+ * @return Float
+ */
+ public function getVoltage()
+ {
+ return $this->_voltage;
+ }
+
+ /**
+ * Sets $_voltage.
+ *
+ * @param Float $voltage voltage
+ *
+ * @see HWDevice::$_voltage
+ *
+ * @return void
+ */
+ public function setVoltage($voltage)
+ {
+ $this->_voltage = $voltage;
+ }
+
+ /**
+ * Returns $_capacity.
+ *
+ * @see HWDevice::$_capacity
+ *
+ * @return int
+ */
+ public function getCapacity()
+ {
+ return $this->_capacity;
+ }
+
+ /**
+ * Sets $_capacity.
+ *
+ * @param int $capacity device capacity
+ *
+ * @see HWDevice::$_capacity
+ *
+ * @return void
+ */
+ public function setCapacity($capacity)
+ {
+ $this->_capacity = $capacity;
+ }
+
/**
* Returns $_count.
*
* @see HWDevice::$_count
*
- * @return Integer
+ * @return int
*/
public function getCount()
{
@@ -129,11 +299,11 @@ class HWDevice
/**
* Sets $_count.
*
- * @param Integer $count device count
+ * @param int $count device count
*
* @see HWDevice::$_count
*
- * @return Void
+ * @return void
*/
public function setCount($count)
{
diff --git a/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php
index 6f8d3b9..20e7dc5 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.NetDevice.inc.php 547 2012-03-22 09:44:38Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,51 +28,72 @@ class NetDevice
/**
* name of the device
*
- * @var String
+ * @var string
*/
private $_name = "";
/**
* transmitted bytes
*
- * @var Integer
+ * @var int
*/
private $_txBytes = 0;
/**
* received bytes
*
- * @var Integer
+ * @var int
*/
private $_rxBytes = 0;
/**
* counted error packages
*
- * @var Integer
+ * @var int
*/
private $_errors = 0;
/**
* counted droped packages
*
- * @var Integer
+ * @var int
*/
private $_drops = 0;
/**
* string with info
*
- * @var String
+ * @var string
*/
private $_info = null;
+ /**
+ * string with bridge
+ *
+ * @var string
+ */
+ private $_bridge = null;
+
+ /**
+ * transmitted bytes rate
+ *
+ * @var int
+ */
+ private $_txRate = null;
+
+ /**
+ * received bytes rate
+ *
+ * @var int
+ */
+ private $_rxRate = null;
+
/**
* Returns $_drops.
*
* @see NetDevice::$_drops
*
- * @return Integer
+ * @return int
*/
public function getDrops()
{
@@ -82,11 +103,11 @@ class NetDevice
/**
* Sets $_drops.
*
- * @param Integer $drops dropped packages
+ * @param int $drops dropped packages
*
* @see NetDevice::$_drops
*
- * @return Void
+ * @return void
*/
public function setDrops($drops)
{
@@ -98,7 +119,7 @@ class NetDevice
*
* @see NetDevice::$_errors
*
- * @return Integer
+ * @return int
*/
public function getErrors()
{
@@ -108,11 +129,11 @@ class NetDevice
/**
* Sets $_errors.
*
- * @param Integer $errors error packages
+ * @param int $errors error packages
*
* @see NetDevice::$_errors
*
- * @return Void
+ * @return void
*/
public function setErrors($errors)
{
@@ -138,7 +159,7 @@ class NetDevice
*
* @see NetDevice::$_name
*
- * @return Void
+ * @return void
*/
public function setName($name)
{
@@ -150,7 +171,7 @@ class NetDevice
*
* @see NetDevice::$_rxBytes
*
- * @return Integer
+ * @return int
*/
public function getRxBytes()
{
@@ -160,11 +181,11 @@ class NetDevice
/**
* Sets $_rxBytes.
*
- * @param Integer $rxBytes received bytes
+ * @param int $rxBytes received bytes
*
* @see NetDevice::$_rxBytes
*
- * @return Void
+ * @return void
*/
public function setRxBytes($rxBytes)
{
@@ -176,7 +197,7 @@ class NetDevice
*
* @see NetDevice::$_txBytes
*
- * @return Integer
+ * @return int
*/
public function getTxBytes()
{
@@ -186,11 +207,11 @@ class NetDevice
/**
* Sets $_txBytes.
*
- * @param Integer $txBytes transmitted bytes
+ * @param int $txBytes transmitted bytes
*
* @see NetDevice::$_txBytes
*
- * @return Void
+ * @return void
*/
public function setTxBytes($txBytes)
{
@@ -216,10 +237,88 @@ class NetDevice
*
* @see NetDevice::$_info
*
- * @return Void
+ * @return void
*/
public function setInfo($info)
{
$this->_info = $info;
}
+
+ /**
+ * Returns $_bridge.
+ *
+ * @see NetDevice::$_bridge
+ *
+ * @return String
+ */
+ public function getBridge()
+ {
+ return $this->_bridge;
+ }
+
+ /**
+ * Sets $_bridge.
+ *
+ * @param String $bridge bridge string
+ *
+ * @see NetDevice::$_bridge
+ *
+ * @return void
+ */
+ public function setBridge($bridge)
+ {
+ $this->_bridge = $bridge;
+ }
+
+ /**
+ * Returns $_rxRate.
+ *
+ * @see NetDevice::$_rxRate
+ *
+ * @return int
+ */
+ public function getRxRate()
+ {
+ return $this->_rxRate;
+ }
+
+ /**
+ * Sets $_rxRate.
+ *
+ * @param int $rxRate received bytes rate
+ *
+ * @see NetDevice::$_rxRate
+ *
+ * @return void
+ */
+ public function setRxRate($rxRate)
+ {
+ $this->_rxRate = $rxRate;
+ }
+
+ /**
+ * Returns $_txRate.
+ *
+ * @see NetDevice::$_txRate
+ *
+ * @return int
+ */
+ public function getTxRate()
+ {
+ return $this->_txRate;
+ }
+
+ /**
+ * Sets $_txRate.
+ *
+ * @param int $txRate transmitted bytes rate
+ *
+ * @see NetDevice::$_txRate
+ *
+ * @return void
+ */
+ public function setTxRate($txRate)
+ {
+ $this->_txRate = $txRate;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php
index 65c2f6c..80ccf37 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.SensorDevice.inc.php 592 2012-07-03 10:55:51Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,44 +28,51 @@ class SensorDevice
/**
* name of the sensor
*
- * @var String
+ * @var string
*/
private $_name = "";
/**
* current value of the sensor
*
- * @var Integer
+ * @var int
*/
private $_value = 0;
/**
* maximum value of the sensor
*
- * @var Integer
+ * @var int
*/
private $_max = null;
/**
* minimum value of the sensor
*
- * @var Integer
+ * @var int
*/
private $_min = null;
/**
* event of the sensor
*
- * @var String
+ * @var string
*/
private $_event = "";
+ /**
+ * unit of values of the sensor
+ *
+ * @var string
+ */
+ private $_unit = "";
+
/**
* Returns $_max.
*
* @see Sensor::$_max
*
- * @return Integer
+ * @return int
*/
public function getMax()
{
@@ -75,11 +82,11 @@ class SensorDevice
/**
* Sets $_max.
*
- * @param Integer $max maximum value
+ * @param int $max maximum value
*
* @see Sensor::$_max
*
- * @return Void
+ * @return void
*/
public function setMax($max)
{
@@ -91,7 +98,7 @@ class SensorDevice
*
* @see Sensor::$_min
*
- * @return Integer
+ * @return int
*/
public function getMin()
{
@@ -101,11 +108,11 @@ class SensorDevice
/**
* Sets $_min.
*
- * @param Integer $min minimum value
+ * @param int $min minimum value
*
* @see Sensor::$_min
*
- * @return Void
+ * @return void
*/
public function setMin($min)
{
@@ -131,7 +138,7 @@ class SensorDevice
*
* @see Sensor::$_name
*
- * @return Void
+ * @return void
*/
public function setName($name)
{
@@ -143,7 +150,7 @@ class SensorDevice
*
* @see Sensor::$_value
*
- * @return Integer
+ * @return int
*/
public function getValue()
{
@@ -153,11 +160,11 @@ class SensorDevice
/**
* Sets $_value.
*
- * @param Integer $value current value
+ * @param int $value current value
*
* @see Sensor::$_value
*
- * @return Void
+ * @return void
*/
public function setValue($value)
{
@@ -183,10 +190,36 @@ class SensorDevice
*
* @see Sensor::$_event
*
- * @return Void
+ * @return void
*/
public function setEvent($event)
{
$this->_event = $event;
}
+
+ /**
+ * Returns $_unit.
+ *
+ * @see Sensor::$_unit
+ *
+ * @return String
+ */
+ public function getUnit()
+ {
+ return $this->_unit;
+ }
+
+ /**
+ * Sets $_unit.
+ *
+ * @param String $unit sensor unit
+ *
+ * @see Sensor::$_unit
+ *
+ * @return void
+ */
+ public function setUnit($unit)
+ {
+ $this->_unit = $unit;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php
index f72e30a..052785d 100644
--- a/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php
+++ b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php
@@ -8,7 +8,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.UPSDevice.inc.php 262 2009-06-22 10:48:33Z bigmichi1 $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_TO
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,121 +28,128 @@ class UPSDevice
/**
* name of the ups
*
- * @var String
+ * @var string
*/
private $_name = "";
/**
* model of the ups
*
- * @var String
+ * @var string
*/
private $_model = "";
/**
* mode of the ups
*
- * @var String
+ * @var string
*/
private $_mode = "";
/**
* last start time
*
- * @var String
+ * @var string
*/
private $_startTime = "";
/**
* status of the ups
*
- * @var String
+ * @var string
*/
private $_status = "";
/**
* temperature of the ups
*
- * @var Integer
+ * @var string
*/
private $_temperatur = null;
/**
* outages count
*
- * @var Integer
+ * @var int
*/
private $_outages = null;
/**
* date of last outtage
*
- * @var String
+ * @var string
*/
private $_lastOutage = null;
/**
* date of last outage finish
*
- * @var String
+ * @var string
*/
private $_lastOutageFinish = null;
/**
* line volt
*
- * @var Integer
+ * @var float
*/
private $_lineVoltage = null;
/**
* line freq
*
- * @var Integer
+ * @var int
*/
private $_lineFrequency = null;
/**
* current load of the ups in percent
*
- * @var Integer
+ * @var float
*/
private $_load = null;
/**
* battery installation date
*
- * @var String
+ * @var string
*/
private $_batteryDate = null;
/**
* current battery volt
*
- * @var Integer
+ * @var float
*/
private $_batteryVoltage = null;
/**
* current charge in percent of the battery
*
- * @var Integer
+ * @var float
*/
private $_batterCharge = null;
/**
* time left
*
- * @var String
+ * @var string
*/
private $_timeLeft = null;
+ /**
+ * beeper enabled or disabled
+ *
+ * @var string
+ */
+ private $_beeperStatus = null;
+
/**
* Returns $_batterCharge.
*
* @see UPSDevice::$_batterCharge
*
- * @return integer
+ * @return float
*/
public function getBatterCharge()
{
@@ -152,7 +159,7 @@ class UPSDevice
/**
* Sets $_batterCharge.
*
- * @param Integer $batterCharge battery charge
+ * @param float $batterCharge battery charge
*
* @see UPSDevice::$_batterCharge
*
@@ -182,7 +189,7 @@ class UPSDevice
*
* @see UPSDevice::$_batteryDate
*
- * @return Void
+ * @return void
*/
public function setBatteryDate($batteryDate)
{
@@ -194,7 +201,7 @@ class UPSDevice
*
* @see UPSDevice::$_batteryVoltage
*
- * @return Integer
+ * @return float
*/
public function getBatteryVoltage()
{
@@ -204,11 +211,11 @@ class UPSDevice
/**
* Sets $_batteryVoltage.
*
- * @param object $batteryVoltage battery volt
+ * @param float $batteryVoltage battery volt
*
* @see UPSDevice::$_batteryVoltage
*
- * @return Void
+ * @return void
*/
public function setBatteryVoltage($batteryVoltage)
{
@@ -234,7 +241,7 @@ class UPSDevice
*
* @see UPSDevice::$lastOutage
*
- * @return Void
+ * @return void
*/
public function setLastOutage($lastOutage)
{
@@ -260,7 +267,7 @@ class UPSDevice
*
* @see UPSDevice::$_lastOutageFinish
*
- * @return Void
+ * @return void
*/
public function setLastOutageFinish($lastOutageFinish)
{
@@ -272,7 +279,7 @@ class UPSDevice
*
* @see UPSDevice::$_lineVoltage
*
- * @return Integer
+ * @return float
*/
public function getLineVoltage()
{
@@ -282,11 +289,11 @@ class UPSDevice
/**
* Sets $_lineVoltage.
*
- * @param Integer $lineVoltage line voltage
+ * @param float $lineVoltage line voltage
*
* @see UPSDevice::$_lineVoltage
*
- * @return Void
+ * @return void
*/
public function setLineVoltage($lineVoltage)
{
@@ -298,7 +305,7 @@ class UPSDevice
*
* @see UPSDevice::$_lineFrequency
*
- * @return Integer
+ * @return int
*/
public function getLineFrequency()
{
@@ -308,11 +315,11 @@ class UPSDevice
/**
* Sets $_lineFrequency.
*
- * @param Integer $lineFrequency line frequency
+ * @param int $lineFrequency line frequency
*
* @see UPSDevice::$_lineFrequency
*
- * @return Void
+ * @return void
*/
public function setLineFrequency($lineFrequency)
{
@@ -324,7 +331,7 @@ class UPSDevice
*
* @see UPSDevice::$_load
*
- * @return Integer
+ * @return float
*/
public function getLoad()
{
@@ -334,11 +341,11 @@ class UPSDevice
/**
* Sets $_load.
*
- * @param Integer $load current load
+ * @param float $load current load
*
* @see UPSDevice::$_load
*
- * @return Void
+ * @return void
*/
public function setLoad($load)
{
@@ -364,7 +371,7 @@ class UPSDevice
*
* @see UPSDevice::$_mode
*
- * @return Void
+ * @return void
*/
public function setMode($mode)
{
@@ -390,7 +397,7 @@ class UPSDevice
*
* @see UPSDevice::$_model
*
- * @return Void
+ * @return void
*/
public function setModel($model)
{
@@ -416,7 +423,7 @@ class UPSDevice
*
* @see UPSDevice::$_name
*
- * @return Void
+ * @return void
*/
public function setName($name)
{
@@ -428,7 +435,7 @@ class UPSDevice
*
* @see UPSDevice::$_outages
*
- * @return Integer
+ * @return int
*/
public function getOutages()
{
@@ -438,11 +445,11 @@ class UPSDevice
/**
* Sets $_outages.
*
- * @param Integer $outages outages count
+ * @param int $outages outages count
*
* @see UPSDevice::$_outages
*
- * @return Void
+ * @return void
*/
public function setOutages($outages)
{
@@ -468,7 +475,7 @@ class UPSDevice
*
* @see UPSDevice::$_startTime
*
- * @return Void
+ * @return void
*/
public function setStartTime($startTime)
{
@@ -494,7 +501,7 @@ class UPSDevice
*
* @see UPSDevice::$_status
*
- * @return Void
+ * @return void
*/
public function setStatus($status)
{
@@ -506,7 +513,7 @@ class UPSDevice
*
* @see UPSDevice::$_temperatur
*
- * @return Integer
+ * @return string
*/
public function getTemperatur()
{
@@ -516,11 +523,11 @@ class UPSDevice
/**
* Sets $_temperatur.
*
- * @param Integer $temperatur temperature
+ * @param string $temperatur temperature
*
* @see UPSDevice::$_temperatur
*
- * @return Void
+ * @return void
*/
public function setTemperatur($temperatur)
{
@@ -546,10 +553,36 @@ class UPSDevice
*
* @see UPSDevice::$_timeLeft
*
- * @return Void
+ * @return void
*/
public function setTimeLeft($timeLeft)
{
$this->_timeLeft = $timeLeft;
}
+
+ /**
+ * Returns $_beeperStatus.
+ *
+ * @see UPSDevice::$_beeperStatus
+ *
+ * @return String
+ */
+ public function getBeeperStatus()
+ {
+ return $this->_beeperStatus;
+ }
+
+ /**
+ * Sets $_beeperStatus.
+ *
+ * @param String $beeperStatus beeper status
+ *
+ * @see UPSDevice::$_beeperStatus
+ *
+ * @return void
+ */
+ public function setBeeperStatus($beeperStatus)
+ {
+ $this->_beeperStatus = $beeperStatus;
+ }
}
diff --git a/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php
index 0a0744a..9152191 100644
--- a/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php
+++ b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php
@@ -8,7 +8,7 @@
* @package PSI_UPS
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.apcupsd.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -20,7 +20,7 @@
* @author Michael Cramer
* @author Artem Volk
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -29,7 +29,7 @@ class Apcupsd extends UPS
/**
* internal storage for all gathered data
*
- * @var Array
+ * @var array
*/
private $_output = array();
@@ -39,22 +39,53 @@ class Apcupsd extends UPS
public function __construct()
{
parent::__construct();
- if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) {
- if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) {
- $upses = eval(PSI_UPS_APCUPSD_LIST);
+ if (!defined('PSI_UPS_APCUPSD_ACCESS')) {
+ define('PSI_UPS_APCUPSD_ACCESS', false);
+ }
+ switch (strtolower(PSI_UPS_APCUPSD_ACCESS)) {
+ case 'data':
+ if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) {
+ $upss = eval(PSI_UPS_APCUPSD_LIST);
+ } else {
+ $upss = array(PSI_UPS_APCUPSD_LIST);
+ }
} else {
- $upses = array(PSI_UPS_APCUPSD_LIST);
+ $upss = array('UPS');
}
- foreach ($upses as $ups) {
- CommonFunctions::executeProgram('apcaccess', 'status '.trim($ups), $temp);
+ $un = 0;
+ foreach ($upss as $ups) {
+ $temp = "";
+ CommonFunctions::rftsdata("upsapcupsd{$un}.tmp", $temp);
if (! empty($temp)) {
$this->_output[] = $temp;
}
+ $un++;
}
- } else { //use default if address and port not defined
- CommonFunctions::executeProgram('apcaccess', 'status', $temp);
- if (! empty($temp)) {
- $this->_output[] = $temp;
+ break;
+ default:
+ if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) {
+ $upses = eval(PSI_UPS_APCUPSD_LIST);
+ } else {
+ $upses = array(PSI_UPS_APCUPSD_LIST);
+ }
+ foreach ($upses as $ups) {
+ $temp = "";
+ CommonFunctions::executeProgram('apcaccess', 'status '.trim($ups), $temp);
+ if (! empty($temp)) {
+ $this->_output[] = $temp;
+ }
+ }
+ } else { //use default if address and port not defined
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) {
+ CommonFunctions::executeProgram('apcaccess', 'status', $temp);
+ } else {
+ CommonFunctions::executeProgram('apcaccess', 'status '.PSI_EMU_HOSTNAME, $temp);
+ }
+ if (! empty($temp)) {
+ $this->_output[] = $temp;
+ }
}
}
}
@@ -62,7 +93,7 @@ class Apcupsd extends UPS
/**
* parse the input and store data in resultset for xml generation
*
- * @return Void
+ * @return void
*/
private function _info()
{
@@ -75,7 +106,7 @@ class Apcupsd extends UPS
$dev->setName(trim($data[1]));
}
if (preg_match('/^MODEL\s*:\s*(.*)$/m', $ups, $data)) {
- $model=trim($data[1]);
+ $model = trim($data[1]);
if (preg_match('/^APCMODEL\s*:\s*(.*)$/m', $ups, $data)) {
$dev->setModel($model.' ('.trim($data[1]).')');
} else {
@@ -92,7 +123,10 @@ class Apcupsd extends UPS
$dev->setStatus(trim($data[1]));
}
if (preg_match('/^ITEMP\s*:\s*(.*)$/m', $ups, $data)) {
- $dev->setTemperatur(trim($data[1]));
+ $temperatur = trim($data[1]);
+ if (($temperatur !== "-273.1 C") && ($temperatur !== "-273.1 C Internal")) {
+ $dev->setTemperatur($temperatur);
+ }
}
// Outages
if (preg_match('/^NUMXFERS\s*:\s*(.*)$/m', $ups, $data)) {
@@ -136,7 +170,7 @@ class Apcupsd extends UPS
*
* @see PSI_Interface_UPS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/ups/class.nut.inc.php b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php
index b9b86a9..4f4b5b4 100644
--- a/root/opt/phpsysinfo/includes/ups/class.nut.inc.php
+++ b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php
@@ -9,7 +9,7 @@
* @author Artem Volk
* @author Anders Häggström
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -21,7 +21,7 @@
* @author Artem Volk
* @author Anders Häggström
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -40,29 +40,62 @@ class Nut extends UPS
public function __construct()
{
parent::__construct();
- if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) {
- if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) {
- $upses = eval(PSI_UPS_NUT_LIST);
+ if (!defined('PSI_UPS_NUT_ACCESS')) {
+ define('PSI_UPS_NUT_ACCESS', false);
+ }
+ switch (strtolower(PSI_UPS_NUT_ACCESS)) {
+ case 'data':
+ if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) {
+ $upss = eval(PSI_UPS_NUT_LIST);
+ } else {
+ $upss = array(PSI_UPS_NUT_LIST);
+ }
} else {
- $upses = array(PSI_UPS_NUT_LIST);
+ $upss = array('UPS');
}
- foreach ($upses as $ups) {
- CommonFunctions::executeProgram('upsc', '-l '.trim($ups), $output);
- $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($ups_names as $ups_name) {
- CommonFunctions::executeProgram('upsc', trim($ups_name).'@'.trim($ups), $temp);
- if (! empty($temp)) {
- $this->_output[trim($ups_name).'@'.trim($ups)] = $temp;
+ $un = 0;
+ foreach ($upss as $ups) {
+ $temp = "";
+ CommonFunctions::rftsdata("upsnut{$un}.tmp", $temp);
+ if (! empty($temp)) {
+ $this->_output[$ups] = $temp;
+ }
+ $un++;
+ }
+ break;
+ default:
+ if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) {
+ $upses = eval(PSI_UPS_NUT_LIST);
+ } else {
+ $upses = array(PSI_UPS_NUT_LIST);
+ }
+ foreach ($upses as $ups) {
+ CommonFunctions::executeProgram('upsc', '-l '.trim($ups), $output, PSI_DEBUG);
+ $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($ups_names as $ups_name) {
+ $upsname = trim($ups_name).'@'.trim($ups);
+ $temp = "";
+ CommonFunctions::executeProgram('upsc', $upsname, $temp, PSI_DEBUG);
+ if (! empty($temp)) {
+ $this->_output[$upsname] = $temp;
+ }
}
}
- }
- } else { //use default if address and port not defined
- CommonFunctions::executeProgram('upsc', '-l', $output);
- $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($ups_names as $ups_name) {
- CommonFunctions::executeProgram('upsc', trim($ups_name), $temp);
- if (! empty($temp)) {
- $this->_output[trim($ups_name)] = $temp;
+ } else { //use default if address and port not defined
+ if (!defined('PSI_EMU_HOSTNAME') || defined('PSI_EMU_PORT')) {
+ CommonFunctions::executeProgram('upsc', '-l', $output, PSI_DEBUG);
+ } else {
+ CommonFunctions::executeProgram('upsc', '-l '.PSI_EMU_HOSTNAME, $output, PSI_DEBUG);
+ }
+ $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($ups_names as $ups_name) {
+ $temp = "";
+ CommonFunctions::executeProgram('upsc', trim($ups_name), $temp, PSI_DEBUG);
+ if (! empty($temp)) {
+ $this->_output[trim($ups_name)] = $temp;
+ }
}
}
}
@@ -71,16 +104,16 @@ class Nut extends UPS
/**
* parse the input and store data in resultset for xml generation
*
- * @return array
+ * @return void
*/
private function _info()
{
if (! empty($this->_output)) {
- foreach ($this->_output as $name=>$value) {
+ foreach ($this->_output as $name => $value) {
$temp = preg_split("/\n/", $value, -1, PREG_SPLIT_NO_EMPTY);
$ups_data = array();
- foreach ($temp as $value) {
- $line = preg_split('/: /', $value, 2);
+ foreach ($temp as $valueTemp) {
+ $line = preg_split('/: /', $valueTemp, 2);
$ups_data[$line[0]] = isset($line[1]) ? trim($line[1]) : '';
}
$dev = new UPSDevice();
@@ -95,6 +128,9 @@ class Nut extends UPS
if (isset($ups_data['ups.status'])) {
$dev->setStatus($ups_data['ups.status']);
}
+ if (isset($ups_data['ups.beeper.status'])) {
+ $dev->setBeeperStatus($ups_data['ups.beeper.status']);
+ }
//Line
if (isset($ups_data['input.voltage'])) {
@@ -133,7 +169,7 @@ class Nut extends UPS
*
* @see PSI_Interface_UPS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php
index b334eb9..438b9f7 100644
--- a/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php
+++ b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php
@@ -8,7 +8,7 @@
* @package PSI_UPS
* @author Robert Pelletier
* @copyright 2014 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_UPS
* @author Robert Pelletier
* @copyright 2014 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -38,41 +38,60 @@ class Pmset extends UPS
public function __construct()
{
parent::__construct();
- CommonFunctions::executeProgram('pmset', '-g batt', $temp);
- if (! empty($temp)) {
- $this->_output[] = $temp;
+ if (defined('PSI_UPS_PMSET_ACCESS') && (strtolower(trim(PSI_UPS_PMSET_ACCESS))==='data')) {
+ if (CommonFunctions::rftsdata('upspmset.tmp', $temp)) {
+ $this->_output[] = $temp;
+ }
+ } elseif (PSI_OS == 'Darwin') {
+ if (CommonFunctions::executeProgram('pmset', '-g batt', $temp) && !empty($temp)) {
+ $this->_output[] = $temp;
+ }
}
}
/**
* parse the input and store data in resultset for xml generation
*
- * @return array
+ * @return void
*/
private function _info()
{
+ if (empty($this->_output)) {
+ return;
+ }
$model = array();
$percCharge = array();
$lines = explode(PHP_EOL, implode($this->_output));
- $dev = new UPSDevice();
- $model = explode('FW:', $lines[1]);
- if (strpos($model[0], 'InternalBattery') === false) {
- $percCharge = explode(';', $lines[1]);
- $dev->setName('UPS');
- if ($model !== false) {
- $dev->setModel(substr(trim($model[0]), 1));
- }
- if ($percCharge !== false) {
- $dev->setBatterCharge(trim(substr($percCharge[0], -4, 3)));
- $dev->setStatus(trim($percCharge[1]));
- if (isset($percCharge[2])) {
- $time = explode(':', $percCharge[2]);
- $hours = $time[0];
- $minutes = $hours*60+substr($time[1], 0, 2);
- $dev->setTimeLeft($minutes);
+ if (count($lines)>1) {
+ if (strpos($lines[1], 'InternalBattery') === false) {
+ $dev = new UPSDevice();
+ $dev->setName('UPS');
+ $percCharge = explode(';', $lines[1]);
+ $model = explode('FW:', $lines[1]);
+ if ($model !== false) {
+ $dev->setModel(substr(trim($model[0]), 1));
}
+ if ($percCharge !== false) {
+ if (preg_match("/\s(\d+)\%$/", trim($percCharge[0]), $tmpbuf)) {
+ if ($tmpbuf[1]>100) {
+ $dev->setBatterCharge(100);
+ } else {
+ $dev->setBatterCharge($tmpbuf[1]);
+ }
+ }
+ $percCharge[1]=trim($percCharge[1]);
+ if (preg_match("/^(.+) present:/", $percCharge[1], $tmpbuf)) {
+ $dev->setStatus(trim($tmpbuf[1]));
+ } else {
+ $dev->setStatus($percCharge[1]);
+ }
+ if (isset($percCharge[2]) && preg_match("/\s(\d+):(\d+)\s/", $percCharge[2], $tmpbuf)) {
+ $dev->setTimeLeft($tmpbuf[1]*60+$tmpbuf[2]);
+ }
+ }
+ $dev->setMode("pmset");
+ $this->upsinfo->setUpsDevices($dev);
}
- $this->upsinfo->setUpsDevices($dev);
}
}
@@ -81,7 +100,7 @@ class Pmset extends UPS
*
* @see PSI_Interface_UPS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php
index b43ac34..9023b3d 100644
--- a/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php
+++ b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php
@@ -8,7 +8,7 @@
* @package PSI_UPS
* @author Mieczyslaw Nalewaj
* @copyright 2014 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.powersoftplus.inc.php 661 2014-06-13 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_UPS
* @author Mieczyslaw Nalewaj
* @copyright 2014 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,7 +28,7 @@ class PowerSoftPlus extends UPS
/**
* internal storage for all gathered data
*
- * @var Array
+ * @var array
*/
private $_output = array();
@@ -38,16 +38,23 @@ class PowerSoftPlus extends UPS
public function __construct()
{
parent::__construct();
- CommonFunctions::executeProgram('powersoftplus', '-p', $temp);
- if (! empty($temp)) {
- $this->_output[] = $temp;
+ if (defined('PSI_UPS_POWERSOFTPLUS_ACCESS') && (strtolower(trim(PSI_UPS_POWERSOFTPLUS_ACCESS))==='data')) {
+ CommonFunctions::rftsdata('upspowersoftplus.tmp', $temp);
+ if (! empty($temp)) {
+ $this->_output[] = $temp;
+ }
+ } elseif (PSI_OS == 'Linux') {
+ CommonFunctions::executeProgram('powersoftplus', '-p', $temp);
+ if (! empty($temp)) {
+ $this->_output[] = $temp;
+ }
}
}
/**
* parse the input and store data in resultset for xml generation
*
- * @return Void
+ * @return void
*/
private function _info()
{
@@ -69,18 +76,18 @@ class PowerSoftPlus extends UPS
if (preg_match('/^Current UPS state\s*:\s*(.*)$/m', $ups, $data)) {
$dev->setStatus(trim($data[1]));
}
- if (preg_match('/^Output load\s*:\s*(.*)\s\[\%\]$/m', $ups, $data)) {
+ if (preg_match('/^Output load\s*:\s*(.*)\s\[\%\]\r?$/m', $ups, $data)) {
$load = trim($data[1]);
}
//wrong Output load issue
- if (($load == 0) && ($maxpwr != 0) && preg_match('/^Effective power\s*:\s*(.*)\s\[W\]$/m', $ups, $data)) {
+ if (($load == 0) && ($maxpwr != 0) && preg_match('/^Effective power\s*:\s*(.*)\s\[W\]\r?$/m', $ups, $data)) {
$load = 100.0*trim($data[1])/$maxpwr;
}
if ($load != null) {
$dev->setLoad($load);
}
// Battery
- if (preg_match('/^Battery voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) {
+ if (preg_match('/^Battery voltage\s*:\s*(.*)\s\[Volt\]\r?$/m', $ups, $data)) {
$dev->setBatteryVoltage(trim($data[1]));
}
if (preg_match('/^Battery state\s*:\s*(.*)$/m', $ups, $data)) {
@@ -91,10 +98,10 @@ class PowerSoftPlus extends UPS
}
}
// Line
- if (preg_match('/^Input voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) {
+ if (preg_match('/^Input voltage\s*:\s*(.*)\s\[Volt\]\r?$/m', $ups, $data)) {
$dev->setLineVoltage(trim($data[1]));
}
- if (preg_match('/^Input frequency\s*:\s*(.*)\s\[Hz\]$/m', $ups, $data)) {
+ if (preg_match('/^Input frequency\s*:\s*(.*)\s\[Hz\]\r?$/m', $ups, $data)) {
$dev->setLineFrequency(trim($data[1]));
}
$this->upsinfo->setUpsDevices($dev);
@@ -106,7 +113,7 @@ class PowerSoftPlus extends UPS
*
* @see PSI_Interface_UPS::build()
*
- * @return Void
+ * @return void
*/
public function build()
{
diff --git a/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php b/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php
new file mode 100644
index 0000000..1ffe0df
--- /dev/null
+++ b/root/opt/phpsysinfo/includes/ups/class.snmpups.inc.php
@@ -0,0 +1,292 @@
+
+ * @copyright 2009 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version SVN: $Id: class.apcupsd.inc.php 661 2012-08-27 11:26:39Z namiltd $
+ * @link http://phpsysinfo.sourceforge.net
+ */
+ /**
+ * getting ups information from SNMPups program
+ *
+ * @category PHP
+ * @package PSI_UPS
+ * @author Michael Cramer
+ * @author Artem Volk
+ * @copyright 2009 phpSysInfo
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
+ * @version Release: 3.0
+ * @link http://phpsysinfo.sourceforge.net
+ */
+class SNMPups extends UPS
+{
+ /**
+ * internal storage for all gathered data
+ *
+ * @var array
+ */
+ private $_output = array();
+
+ /**
+ * get all information from all configured ups in phpsysinfo.ini and store output in internal array
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ if (!defined('PSI_UPS_SNMPUPS_ACCESS')) {
+ define('PSI_UPS_SNMPUPS_ACCESS', 'php-snmp');
+ }
+ switch (strtolower(PSI_UPS_SNMPUPS_ACCESS)) {
+ case 'data':
+ if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) {
+ $upss = eval(PSI_UPS_SNMPUPS_LIST);
+ } else {
+ $upss = array(PSI_UPS_SNMPUPS_LIST);
+ }
+ } else {
+ $upss = array('UPS');
+ }
+ $un = 0;
+ foreach ($upss as $ups) {
+ $temp = "";
+ CommonFunctions::rftsdata("upssnmpups{$un}.tmp", $temp);
+ if (! empty($temp)) {
+ $this->_output[] = $temp;
+ }
+ $un++;
+ }
+ break;
+ case 'command':
+ if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) {
+ $upss = eval(PSI_UPS_SNMPUPS_LIST);
+ } else {
+ $upss = array(PSI_UPS_SNMPUPS_LIST);
+ }
+ foreach ($upss as $ups) {
+ $buffer = "";
+ CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.1", $buffer, PSI_DEBUG);
+ if (strlen($buffer) > 0) {
+ $this->_output[$ups] = $buffer;
+ $buffer = "";
+ CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.2", $buffer, PSI_DEBUG);
+ if (strlen($buffer) > 0) {
+ $this->_output[$ups] .= "\n".$buffer;
+ }
+ $buffer = "";
+ CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.3", $buffer, PSI_DEBUG);
+ if (strlen($buffer) > 0) {
+ $this->_output[$ups] .= "\n".$buffer;
+ }
+ $buffer = "";
+ CommonFunctions::executeProgram("snmpwalk", "-Ona -c public -v 1 -t ".PSI_SNMP_TIMEOUT_INT." -r ".PSI_SNMP_RETRY_INT." ".$ups." .1.3.6.1.4.1.318.1.1.1.4", $buffer, PSI_DEBUG);
+ if (strlen($buffer) > 0) {
+ $this->_output[$ups] .= "\n".$buffer;
+ }
+ }
+ }
+ }
+ break;
+ case 'php-snmp':
+ if (!extension_loaded("snmp")) {
+ $this->error->addError("Requirements error", "SNMPups plugin requires the snmp extension to php in order to work properly");
+ break;
+ }
+ snmp_set_valueretrieval(SNMP_VALUE_LIBRARY);
+ snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
+ if (defined('PSI_UPS_SNMPUPS_LIST') && is_string(PSI_UPS_SNMPUPS_LIST)) {
+ if (preg_match(ARRAY_EXP, PSI_UPS_SNMPUPS_LIST)) {
+ $upss = eval(PSI_UPS_SNMPUPS_LIST);
+ } else {
+ $upss = array(PSI_UPS_SNMPUPS_LIST);
+ }
+ foreach ($upss as $ups) {
+ if (! PSI_DEBUG) {
+ restore_error_handler(); /* default error handler */
+ $old_err_rep = error_reporting();
+ error_reporting(E_ERROR); /* fatal errors only */
+ }
+ $bufferarr=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.1", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT);
+ if (! PSI_DEBUG) {
+ error_reporting($old_err_rep); /* restore error level */
+ set_error_handler('errorHandlerPsi'); /* restore error handler */
+ }
+ if (! empty($bufferarr)) {
+ $buffer="";
+ foreach ($bufferarr as $id=>$string) {
+ $buffer .= $id." = ".$string."\n";
+ }
+
+ if (! PSI_DEBUG) {
+ restore_error_handler(); /* default error handler */
+ $old_err_rep = error_reporting();
+ error_reporting(E_ERROR); /* fatal errors only */
+ }
+ $bufferarr2=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.2", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT);
+ $bufferarr3=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.3", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT);
+ $bufferarr4=snmprealwalk($ups, "public", ".1.3.6.1.4.1.318.1.1.1.4", 1000000 * PSI_SNMP_TIMEOUT_INT, PSI_SNMP_RETRY_INT);
+ if (! PSI_DEBUG) {
+ error_reporting($old_err_rep); /* restore error level */
+ set_error_handler('errorHandlerPsi'); /* restore error handler */
+ }
+ if (! empty($bufferarr2)) {
+ foreach ($bufferarr2 as $id=>$string) {
+ $buffer .= $id." = ".$string."\n";
+ }
+ }
+ if (! empty($bufferarr3)) {
+ foreach ($bufferarr3 as $id=>$string) {
+ $buffer .= $id." = ".$string."\n";
+ }
+ }
+ if (! empty($bufferarr4)) {
+ foreach ($bufferarr4 as $id=>$string) {
+ $buffer .= $id." = ".$string."\n";
+ }
+ }
+ if (strlen(trim($buffer)) > 0) {
+ $this->_output[$ups] = $buffer;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ $this->error->addError("switch(PSI_UPS_SNMPUPS_ACCESS)", "Bad SNMPups configuration in phpsysinfo.ini");
+ }
+ }
+
+ /**
+ * parse the input and store data in resultset for xml generation
+ *
+ * @return void
+ */
+ private function _info()
+ {
+ if (empty($this->_output)) {
+ return;
+ }
+ foreach ($this->_output as $result) {
+ $dev = new UPSDevice();
+ $status = "";
+ $status2 = "";
+ $status3 = "";
+ $dev->setMode("SNMP");
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.1\.1\.2\.0 = STRING:\s(.*)/m', $result, $data)) {
+ $dev->setName(trim($data[1], "\" \r\t"));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.1\.1\.1\.0 = STRING:\s(.*)/m', $result, $data)) {
+ $dev->setModel(trim($data[1], "\" \r\t"));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.1\.1\.0 = INTEGER:\s(.*)/m', $result, $data)) {
+ switch (trim($data[1])) {
+ case 1: $status = "Unknown"; break;
+ case 2: $status = "On Line"; break;
+ case 3: $status = "On Battery"; break;
+ case 4: $status = "On Smart Boost"; break;
+ case 5: $status = "Timed Sleeping"; break;
+ case 6: $status = "Software Bypass"; break;
+ case 7: $status = "Off"; break;
+ case 8: $status = "Rebooting"; break;
+ case 9: $status = "Switched Bypass"; break;
+ case 10:$status = "Hardware Failure Bypass"; break;
+ case 11:$status = "Sleeping Until Power Returns"; break;
+ case 12:$status = "On Smart Trim"; break;
+ default: $status = "Unknown state (".trim($data[1]).")";
+ }
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.1\.1\.0 = INTEGER:\s(.*)/m', $result, $data)) {
+ $batstat = "";
+ switch (trim($data[1])) {
+ case 1: $batstat = "Battery Unknown"; break;
+ case 2: break;
+ case 3: $batstat = "Battery Low"; break;
+ default: $batstat = "Battery Unknown (".trim($data[1]).")";
+ }
+ if ($batstat !== "") {
+ if ($status !== "") {
+ $status .= ", ".$batstat;
+ } else {
+ $status = $batstat;
+ }
+ }
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.4\.0 = INTEGER:\s(.*)/m', $result, $data)) {
+ $batstat = "";
+ switch (trim($data[1])) {
+ case 1: break;
+ case 2: $batstat = "Replace Battery"; break;
+ default: $batstat = "Replace Battery (".trim($data[1]).")";
+ }
+ if ($batstat !== "") {
+ if ($status !== "") {
+ $status .= ", ".$batstat;
+ } else {
+ $status = $batstat;
+ }
+ }
+ }
+ if ($status !== "") {
+ $dev->setStatus(trim($status));
+ }
+
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.3\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLineVoltage(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.2\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLineVoltage(trim($data[1]));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.3\.3\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLoad(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.4\.2\.3\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLoad(trim($data[1]));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.4\.0 = INTEGER:\s(.*)/m', $result, $data)) {
+ $dev->setBatteryVoltage(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.8\.0 = INTEGER:\s(.*)/m', $result, $data)) {
+ $dev->setBatteryVoltage(trim($data[1]));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setBatterCharge(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.1\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setBatterCharge(trim($data[1]));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.3\.0 = Timeticks:\s\((\d*)\)/m', $result, $data)) {
+ $dev->setTimeLeft(trim($data[1])/6000);
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.3\.2\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setTemperatur(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.2\.2\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setTemperatur(trim($data[1]));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.2\.1\.3\.0 = STRING:\s(.*)/m', $result, $data)) {
+ $dev->setBatteryDate(trim($data[1], "\" \r\t"));
+ }
+ if (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.3\.4\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLineFrequency(trim($data[1])/10);
+ } elseif (preg_match('/^\.1\.3\.6\.1\.4\.1\.318\.1\.1\.1\.3\.2\.4\.0 = Gauge32:\s(.*)/m', $result, $data)) {
+ $dev->setLineFrequency(trim($data[1]));
+ }
+
+ $this->upsinfo->setUpsDevices($dev);
+ }
+ }
+
+ /**
+ * get the information
+ *
+ * @see PSI_Interface_UPS::build()
+ *
+ * @return void
+ */
+ public function build()
+ {
+ $this->_info();
+ }
+}
diff --git a/root/opt/phpsysinfo/includes/ups/class.ups.inc.php b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php
index c0970b4..2eae83a 100644
--- a/root/opt/phpsysinfo/includes/ups/class.ups.inc.php
+++ b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php
@@ -8,7 +8,7 @@
* @package PSI_UPS
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.ups.inc.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_UPS
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,9 +28,9 @@ abstract class UPS implements PSI_Interface_UPS
/**
* object for error handling
*
- * @var Error
+ * @var PSI_Error
*/
- protected $error;
+ public $error;
/**
* main object for ups information
@@ -44,7 +44,7 @@ abstract class UPS implements PSI_Interface_UPS
*/
public function __construct()
{
- $this->error = Error::singleton();
+ $this->error = PSI_Error::singleton();
$this->upsinfo = new UPSInfo();
}
diff --git a/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php
index a05ff2c..7713322 100644
--- a/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php
+++ b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php
@@ -8,7 +8,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.SimpleXMLExtended.inc.php 610 2012-07-11 19:12:12Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -28,7 +28,7 @@ class SimpleXMLExtended
/**
* store the encoding that is used for conversation to utf8
*
- * @var String base encoding
+ * @var string base encoding
*/
private $_encoding = null;
@@ -42,7 +42,7 @@ class SimpleXMLExtended
/**
* _CP437toUTF8Table for code page conversion for CP437
*
- * @var _CP437toUTF8Table array
+ * @var array _CP437toUTF8Table array
*/
private static $_CP437toUTF8Table = array(
"\xC3\x87","\xC3\xBC","\xC3\xA9","\xC3\xA2",
@@ -108,7 +108,7 @@ class SimpleXMLExtended
if ($value == null) {
return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8), $this->_encoding);
} else {
- $valueUtf8 = htmlspecialchars($this->_toUTF8($value));
+ $valueUtf8 = htmlspecialchars($this->_toUTF8($value), ENT_COMPAT, "UTF-8");
return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8, $valueUtf8), $this->_encoding);
}
@@ -139,13 +139,17 @@ class SimpleXMLExtended
* @param String $name name of the attribute
* @param String $value value of the attribute
*
- * @return Void
+ * @return void
*/
public function addAttribute($name, $value)
{
$nameUtf8 = $this->_toUTF8($name);
- $valueUtf8 = htmlspecialchars($this->_toUTF8($value));
- $this->_SimpleXmlElement->addAttribute($nameUtf8, $valueUtf8);
+ $valueUtf8 = htmlspecialchars($this->_toUTF8($value), ENT_COMPAT, "UTF-8");
+ if (($valueUtf8 === "") && (version_compare("5.2.2", PHP_VERSION, ">"))) {
+ $this->_SimpleXmlElement->addAttribute($nameUtf8, "\0"); // Fixing bug #41175 (addAttribute() fails to add an attribute with an empty value)
+ } else {
+ $this->_SimpleXmlElement->addAttribute($nameUtf8, $valueUtf8);
+ }
}
/**
@@ -153,7 +157,7 @@ class SimpleXMLExtended
*
* @param SimpleXMLElement $new_child child that should be appended
*
- * @return Void
+ * @return void
*/
public function combinexml(SimpleXMLElement $new_child)
{
@@ -172,31 +176,46 @@ class SimpleXMLExtended
*/
private function _toUTF8($str)
{
+ $str = trim(preg_replace('/[\x00-\x09\x0b-\x1F]/', ' ', strval($str))); //remove nonprintable characters
if ($this->_encoding != null) {
if (strcasecmp($this->_encoding, "UTF-8") == 0) {
- return trim($str);
+ return $str;
} elseif (strcasecmp($this->_encoding, "CP437") == 0) {
- $str = trim($str);
$strr = "";
if (($strl = strlen($str)) > 0) for ($i = 0; $i < $strl; $i++) {
$strc = substr($str, $i, 1);
if ($strc < 128) $strr.=$strc;
- else $strr.=$_CP437toUTF8Table[$strc-128];
+ else $strr.=self::$_CP437toUTF8Table[$strc-128];
}
return $strr;
} else {
- $enclist = mb_list_encodings();
- if (in_array($this->_encoding, $enclist)) {
- return mb_convert_encoding(trim($str), 'UTF-8', $this->_encoding);
- } elseif (function_exists("iconv")) {
- return iconv($this->_encoding, 'UTF-8', trim($str));
+ if (preg_match("/^windows-\d+ \((.+)\)$/", $this->_encoding, $buf)) {
+ $encoding = $buf[1];
} else {
- return mb_convert_encoding(trim($str), 'UTF-8');
+ $encoding = $this->_encoding;
}
- }
+ $enclist = mb_list_encodings();
+ if (in_array($encoding, $enclist)) {
+ return mb_convert_encoding($str, 'UTF-8', $encoding);
+ } elseif (function_exists("iconv")) {
+ if (($iconvout=iconv($encoding, 'UTF-8', $str))!==false) {
+ return $iconvout;
+ } else {
+ return mb_convert_encoding($str, 'UTF-8');
+ }
+ } elseif (function_exists("libiconv") && (($iconvout=libiconv($encoding, 'UTF-8', $str))!==false)) {
+ return $iconvout;
+ } else {
+ return mb_convert_encoding($str, 'UTF-8');
+ }
+ }
} else {
- return mb_convert_encoding(trim($str), 'UTF-8');
+ if (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($str, 'UTF-8');
+ } else {
+ return $str;
+ }
}
}
diff --git a/root/opt/phpsysinfo/includes/xml/class.XML.inc.php b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php
index b46330a..8f2c187 100644
--- a/root/opt/phpsysinfo/includes/xml/class.XML.inc.php
+++ b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php
@@ -8,7 +8,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: class.XML.inc.php 699 2012-09-15 11:57:13Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -19,7 +19,7 @@
* @package PSI_XML
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version Release: 3.0
* @link http://phpsysinfo.sourceforge.net
*/
@@ -47,7 +47,7 @@ class XML
/**
* object for error handling
*
- * @var Error
+ * @var PSI_Error
*/
private $_errors;
@@ -65,13 +65,6 @@ class XML
*/
private $_plugin = '';
- /**
- * generate a xml for a plugin or for the main app
- *
- * @var boolean
- */
- private $_plugin_request = false;
-
/**
* generate the entire xml with all plugins or only a part of the xml (main or plugin)
*
@@ -90,23 +83,23 @@ class XML
*
* @return void
*/
- public function __construct($complete = false, $pluginname = "")
+ public function __construct($complete = false, $pluginname = "", $blockname = false)
{
- $this->_errors = Error::singleton();
- if ($pluginname == "") {
- $this->_plugin_request = false;
- $this->_plugin = '';
- } else {
- $this->_plugin_request = true;
- $this->_plugin = $pluginname;
- }
+ $this->_errors = PSI_Error::singleton();
+ $this->_plugin = $pluginname;
if ($complete) {
$this->_complete_request = true;
} else {
$this->_complete_request = false;
}
- $os = PSI_OS;
- $this->_sysinfo = new $os();
+ if (defined('PSI_EMU_PORT')) {
+ $os = 'SSH';
+ } elseif (defined('PSI_EMU_HOSTNAME')) {
+ $os = 'WINNT';
+ } else {
+ $os = PSI_OS;
+ }
+ $this->_sysinfo = new $os($blockname);
$this->_plugins = CommonFunctions::getPlugins();
$this->_xmlbody();
}
@@ -169,7 +162,14 @@ class XML
}
}
}
- $vitals->addAttribute('OS', PSI_OS);
+
+ if (($os = $this->_sys->getOS()) == 'Android') {
+ $vitals->addAttribute('OS', 'Linux');
+ } elseif ($os == 'GNU') {
+ $vitals->addAttribute('OS', 'Hurd');
+ } else {
+ $vitals->addAttribute('OS', $os);
+ }
}
/**
@@ -193,15 +193,50 @@ class XML
}
}
foreach ($this->_sys->getNetDevices() as $dev) {
- if (!in_array(trim($dev->getName()), $hideDevices)) {
+ if (defined('PSI_HIDE_NETWORK_INTERFACE_REGEX') && PSI_HIDE_NETWORK_INTERFACE_REGEX) {
+ $hide = false;
+ foreach ($hideDevices as $hidedev) {
+ if (preg_match('/^'.$hidedev.'$/', trim($dev->getName()))) {
+ $hide = true;
+ break;
+ }
+ }
+ } else {
+ $hide =in_array(trim($dev->getName()), $hideDevices);
+ }
+ if (!$hide) {
$device = $network->addChild('NetDevice');
$device->addAttribute('Name', $dev->getName());
- $device->addAttribute('RxBytes', $dev->getRxBytes());
- $device->addAttribute('TxBytes', $dev->getTxBytes());
+ $rxbytes = $dev->getRxBytes();
+ $txbytes = $dev->getTxBytes();
+ $device->addAttribute('RxBytes', $rxbytes);
+ $device->addAttribute('TxBytes', $txbytes);
+ if (defined('PSI_SHOW_NETWORK_ACTIVE_SPEED') && PSI_SHOW_NETWORK_ACTIVE_SPEED) {
+ if (($rxbytes == 0) && ($txbytes == 0)) {
+ $rxrate = $dev->getRxRate();
+ $txrate = $dev->getTxRate();
+ if (($rxrate !== null) || ($txrate !== null)) {
+ if ($rxrate !== null) {
+ $device->addAttribute('RxRate', $rxrate);
+ } else {
+ $device->addAttribute('RxRate', 0);
+ }
+ if ($txrate !== null) {
+ $device->addAttribute('TxRate', $txrate);
+ } else {
+ $device->addAttribute('TxRate', 0);
+ }
+ }
+ }
+ }
$device->addAttribute('Err', $dev->getErrors());
$device->addAttribute('Drops', $dev->getDrops());
- if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS && $dev->getInfo())
+ if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE && $dev->getBridge()) {
+ $device->addAttribute('Bridge', $dev->getBridge());
+ }
+ if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS && $dev->getInfo()) {
$device->addAttribute('Info', $dev->getInfo());
+ }
}
}
}
@@ -213,77 +248,90 @@ class XML
*/
private function _buildHardware()
{
- $dev = new HWDevice();
$hardware = $this->_xml->addChild('Hardware');
- if ($this->_sys->getMachine() != "") {
- $hardware->addAttribute('Name', $this->_sys->getMachine());
- }
- $pci = null;
- foreach (System::removeDupsAndCount($this->_sys->getPciDevices()) as $dev) {
- if ($pci === null) $pci = $hardware->addChild('PCI');
- $tmp = $pci->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
- }
- $usb = null;
- foreach (System::removeDupsAndCount($this->_sys->getUsbDevices()) as $dev) {
- if ($usb === null) $usb = $hardware->addChild('USB');
- $tmp = $usb->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
- }
- $ide = null;
- foreach (System::removeDupsAndCount($this->_sys->getIdeDevices()) as $dev) {
- if ($ide === null) $ide = $hardware->addChild('IDE');
- $tmp = $ide->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
- if ($dev->getCapacity() !== null) {
- $tmp->addAttribute('Capacity', $dev->getCapacity());
+ if (($machine = $this->_sys->getMachine()) != "") {
+ $machine = trim(preg_replace("/\s+/", " ", preg_replace("/^\s*[\/,]*/", "", preg_replace("/\/\s+,/", "/,", $machine)))); // remove leading slash or comma and unnecessary spaces
+ if (preg_match('/, BIOS .*$/', $machine, $mbuf, PREG_OFFSET_CAPTURE)) {
+ $comapos = $mbuf[0][1];
+ $endstr = $mbuf[0][0];
+ $offset = 0;
+ while (($offset < $comapos)
+ && (($slashpos = strpos($machine, "/", $offset)) !== false)
+ && ($slashpos < $comapos)) {
+ $len1 = $comapos - $slashpos - 1;
+ $str1 = substr($machine, $slashpos + 1, $len1);
+ $begstr = substr($machine, 0, $slashpos);
+ if ($len1 > 0) { // no empty
+ $str2 = substr($begstr, -$len1 - 1);
+ } else {
+ $str2 = " ";
+ }
+ if ((" ".$str1 === $str2) || ($str1 === $begstr)) { // duplicates
+ $machine = $begstr.$endstr;
+ break;
+ }
+ $offset = $slashpos + 1;
+ }
+ }
+
+ if ($machine != "") {
+ $hardware->addAttribute('Name', $machine);
}
}
- $scsi = null;
- foreach (System::removeDupsAndCount($this->_sys->getScsiDevices()) as $dev) {
- if ($scsi === null) $scsi = $hardware->addChild('SCSI');
- $tmp = $scsi->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
- if ($dev->getCapacity() !== null) {
- $tmp->addAttribute('Capacity', $dev->getCapacity());
+
+ if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
+ $virt = $this->_sys->getVirtualizer();
+ $virtstring = "";
+ foreach ($virt as $virtkey=>$virtvalue) if ($virtvalue) {
+ if ($virtstring !== "") {
+ $virtstring .= ", ";
+ }
+ if ($virtkey === 'microsoft') {
+ if (!isset($virt["wsl"]) || !$virt["wsl"]) {
+ $virtstring .= 'hyper-v';
+ }
+ } elseif ($virtkey === 'kvm') {
+ $virtstring .= 'qemu-kvm';
+ } elseif ($virtkey === 'oracle') {
+ $virtstring .= 'virtualbox';
+ } elseif ($virtkey === 'zvm') {
+ $virtstring .= 'z/vm';
+ } elseif ($virtkey === 'sre') {
+ $virtstring .= 'lmhs sre';
+ } else {
+ $virtstring .= $virtkey;
+ }
+ }
+ if ($virtstring !== "") {
+ $hardware->addAttribute('Virtualizer', $virtstring);
}
- }
- $tb = null;
- foreach (System::removeDupsAndCount($this->_sys->getTbDevices()) as $dev) {
- if ($tb === null) $tb = $hardware->addChild('TB');
- $tmp = $tb->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
- }
- $i2c = null;
- foreach (System::removeDupsAndCount($this->_sys->getI2cDevices()) as $dev) {
- if ($i2c === null) $i2c = $hardware->addChild('I2C');
- $tmp = $i2c->addChild('Device');
- $tmp->addAttribute('Name', $dev->getName());
- $tmp->addAttribute('Count', $dev->getCount());
}
$cpu = null;
+ $vendortab = null;
foreach ($this->_sys->getCpus() as $oneCpu) {
if ($cpu === null) $cpu = $hardware->addChild('CPU');
$tmp = $cpu->addChild('CpuCore');
$tmp->addAttribute('Model', $oneCpu->getModel());
- if ($oneCpu->getCpuSpeed() !== 0) {
- $tmp->addAttribute('CpuSpeed', $oneCpu->getCpuSpeed());
+ if ($oneCpu->getVoltage() > 0) {
+ $tmp->addAttribute('Voltage', $oneCpu->getVoltage());
}
- if ($oneCpu->getCpuSpeedMax() !== 0) {
+ if ($oneCpu->getCpuSpeed() > 0) {
+ $tmp->addAttribute('CpuSpeed', $oneCpu->getCpuSpeed());
+ } elseif ($oneCpu->getCpuSpeed() == -1) {
+ $tmp->addAttribute('CpuSpeed', 0); // core stopped
+ }
+ if ($oneCpu->getCpuSpeedMax() > 0) {
$tmp->addAttribute('CpuSpeedMax', $oneCpu->getCpuSpeedMax());
}
- if ($oneCpu->getCpuSpeedMin() !== 0) {
+ if ($oneCpu->getCpuSpeedMin() > 0) {
$tmp->addAttribute('CpuSpeedMin', $oneCpu->getCpuSpeedMin());
}
+/*
if ($oneCpu->getTemp() !== null) {
$tmp->addAttribute('CpuTemp', $oneCpu->getTemp());
}
+*/
if ($oneCpu->getBusSpeed() !== null) {
$tmp->addAttribute('BusSpeed', $oneCpu->getBusSpeed());
}
@@ -293,6 +341,13 @@ class XML
if ($oneCpu->getVirt() !== null) {
$tmp->addAttribute('Virt', $oneCpu->getVirt());
}
+ if ($oneCpu->getVendorId() !== null) {
+ if ($vendortab === null) $vendortab = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
+ $shortvendorid = $oneCpu->getVendorId();
+ if ($vendortab && ($shortvendorid != "") && isset($vendortab['manufacturer'][$shortvendorid])) {
+ $tmp->addAttribute('Manufacturer', $vendortab['manufacturer'][$shortvendorid]);
+ }
+ }
if ($oneCpu->getBogomips() !== null) {
$tmp->addAttribute('Bogomips', $oneCpu->getBogomips());
}
@@ -300,6 +355,144 @@ class XML
$tmp->addAttribute('Load', $oneCpu->getLoad());
}
}
+ $mem = null;
+ foreach (System::removeDupsAndCount($this->_sys->getMemDevices()) as $dev) {
+ if ($mem === null) $mem = $hardware->addChild('MEM');
+ $tmp = $mem->addChild('Chip');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getCapacity() !== null) {
+ $tmp->addAttribute('Capacity', $dev->getCapacity());
+ }
+ if ($dev->getManufacturer() !== null) {
+ $tmp->addAttribute('Manufacturer', $dev->getManufacturer());
+ }
+ if ($dev->getProduct() !== null) {
+ $tmp->addAttribute('Product', $dev->getProduct());
+ }
+ if ($dev->getSpeed() !== null) {
+ $tmp->addAttribute('Speed', $dev->getSpeed());
+ }
+ if ($dev->getVoltage() !== null) {
+ $tmp->addAttribute('Voltage', $dev->getVoltage());
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) {
+ $tmp->addAttribute('Serial', $dev->getSerial());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $pci = null;
+ foreach (System::removeDupsAndCount($this->_sys->getPciDevices()) as $dev) {
+ if ($pci === null) $pci = $hardware->addChild('PCI');
+ $tmp = $pci->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getManufacturer() !== null) {
+ $tmp->addAttribute('Manufacturer', $dev->getManufacturer());
+ }
+ if ($dev->getProduct() !== null) {
+ $tmp->addAttribute('Product', $dev->getProduct());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $ide = null;
+ foreach (System::removeDupsAndCount($this->_sys->getIdeDevices()) as $dev) {
+ if ($ide === null) $ide = $hardware->addChild('IDE');
+ $tmp = $ide->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getCapacity() !== null) {
+ $tmp->addAttribute('Capacity', $dev->getCapacity());
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) {
+ $tmp->addAttribute('Serial', $dev->getSerial());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $scsi = null;
+ foreach (System::removeDupsAndCount($this->_sys->getScsiDevices()) as $dev) {
+ if ($scsi === null) $scsi = $hardware->addChild('SCSI');
+ $tmp = $scsi->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getCapacity() !== null) {
+ $tmp->addAttribute('Capacity', $dev->getCapacity());
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) {
+ $tmp->addAttribute('Serial', $dev->getSerial());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $nvme = null;
+ foreach (System::removeDupsAndCount($this->_sys->getNvmeDevices()) as $dev) {
+ if ($nvme === null) $nvme = $hardware->addChild('NVMe');
+ $tmp = $nvme->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getCapacity() !== null) {
+ $tmp->addAttribute('Capacity', $dev->getCapacity());
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) {
+ $tmp->addAttribute('Serial', $dev->getSerial());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $usb = null;
+ foreach (System::removeDupsAndCount($this->_sys->getUsbDevices()) as $dev) {
+ if ($usb === null) $usb = $hardware->addChild('USB');
+ $tmp = $usb->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
+ if ($dev->getManufacturer() !== null) {
+ $tmp->addAttribute('Manufacturer', $dev->getManufacturer());
+ }
+ if ($dev->getProduct() !== null) {
+ $tmp->addAttribute('Product', $dev->getProduct());
+ }
+ if ($dev->getSpeed() !== null) {
+ $tmp->addAttribute('Speed', $dev->getSpeed());
+ }
+ if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL && ($dev->getSerial() !== null)) {
+ $tmp->addAttribute('Serial', $dev->getSerial());
+ }
+ }
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $tb = null;
+ foreach (System::removeDupsAndCount($this->_sys->getTbDevices()) as $dev) {
+ if ($tb === null) $tb = $hardware->addChild('TB');
+ $tmp = $tb->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
+ $i2c = null;
+ foreach (System::removeDupsAndCount($this->_sys->getI2cDevices()) as $dev) {
+ if ($i2c === null) $i2c = $hardware->addChild('I2C');
+ $tmp = $i2c->addChild('Device');
+ $tmp->addAttribute('Name', $dev->getName());
+ if ($dev->getCount() > 1) {
+ $tmp->addAttribute('Count', $dev->getCount());
+ }
+ }
}
/**
@@ -348,28 +541,32 @@ class XML
*
* @param SimpleXmlExtended $mount Xml-Element
* @param DiskDevice $dev DiskDevice
- * @param Integer $i counter
+ * @param int $i counter
*
- * @return Void
+ * @return void
*/
private function _fillDevice(SimpleXMLExtended $mount, DiskDevice $dev, $i)
{
$mount->addAttribute('MountPointID', $i);
- $mount->addAttribute('FSType', $dev->getFsType());
+ if ($dev->getFsType()!=="") {
+ $mount->addAttribute('FSType', $dev->getFsType());
+ }
$mount->addAttribute('Name', $dev->getName());
$mount->addAttribute('Free', sprintf("%.0f", $dev->getFree()));
$mount->addAttribute('Used', sprintf("%.0f", $dev->getUsed()));
$mount->addAttribute('Total', sprintf("%.0f", $dev->getTotal()));
- $mount->addAttribute('Percent', $dev->getPercentUsed());
- if (PSI_SHOW_MOUNT_OPTION === true) {
+ $percentUsed = $dev->getPercentUsed();
+ $mount->addAttribute('Percent', $percentUsed);
+ if ($dev->getPercentInodesUsed() !== null) {
+ $mount->addAttribute('Inodes', $dev->getPercentInodesUsed());
+ }
+ if ($dev->getIgnore() > 0) $mount->addAttribute('Ignore', $dev->getIgnore());
+ if (PSI_SHOW_MOUNT_OPTION) {
if ($dev->getOptions() !== null) {
$mount->addAttribute('MountOptions', preg_replace("/,/", ", ", $dev->getOptions()));
}
}
- if ($dev->getPercentInodesUsed() !== null) {
- $mount->addAttribute('Inodes', $dev->getPercentInodesUsed());
- }
- if (PSI_SHOW_MOUNT_POINT === true) {
+ if (PSI_SHOW_MOUNT_POINT && ($dev->getMountPoint() !== null)) {
$mount->addAttribute('MountPoint', $dev->getMountPoint());
}
}
@@ -381,8 +578,7 @@ class XML
*/
private function _buildFilesystems()
{
- $hideMounts = $hideFstypes = $hideDisks = array();
- $i = 1;
+ $hideMounts = $hideFstypes = $hideDisks = $ignoreFree = $ignoreTotal = $ignoreUsage = $ignoreThreshold = array();
if (defined('PSI_HIDE_MOUNTS') && is_string(PSI_HIDE_MOUNTS)) {
if (preg_match(ARRAY_EXP, PSI_HIDE_MOUNTS)) {
$hideMounts = eval(PSI_HIDE_MOUNTS);
@@ -408,10 +604,48 @@ class XML
return;
}
}
+ if (defined('PSI_IGNORE_FREE') && is_string(PSI_IGNORE_FREE)) {
+ if (preg_match(ARRAY_EXP, PSI_IGNORE_FREE)) {
+ $ignoreFree = eval(PSI_IGNORE_FREE);
+ } else {
+ $ignoreFree = array(PSI_IGNORE_FREE);
+ }
+ }
+ if (defined('PSI_IGNORE_TOTAL') && is_string(PSI_IGNORE_TOTAL)) {
+ if (preg_match(ARRAY_EXP, PSI_IGNORE_TOTAL)) {
+ $ignoreTotal = eval(PSI_IGNORE_TOTAL);
+ } else {
+ $ignoreTotal = array(PSI_IGNORE_TOTAL);
+ }
+ }
+ if (defined('PSI_IGNORE_USAGE') && is_string(PSI_IGNORE_USAGE)) {
+ if (preg_match(ARRAY_EXP, PSI_IGNORE_USAGE)) {
+ $ignoreUsage = eval(PSI_IGNORE_USAGE);
+ } else {
+ $ignoreUsage = array(PSI_IGNORE_USAGE);
+ }
+ }
+ if (defined('PSI_IGNORE_THRESHOLD_FS_TYPES') && is_string(PSI_IGNORE_THRESHOLD_FS_TYPES)) {
+ if (preg_match(ARRAY_EXP, PSI_IGNORE_THRESHOLD_FS_TYPES)) {
+ $ignoreThreshold = eval(PSI_IGNORE_THRESHOLD_FS_TYPES);
+ } else {
+ $ignoreThreshold = array(PSI_IGNORE_THRESHOLD_FS_TYPES);
+ }
+ }
$fs = $this->_xml->addChild('FileSystem');
+ $i = 1;
foreach ($this->_sys->getDiskDevices() as $disk) {
if (!in_array($disk->getMountPoint(), $hideMounts, true) && !in_array($disk->getFsType(), $hideFstypes, true) && !in_array($disk->getName(), $hideDisks, true)) {
$mount = $fs->addChild('Mount');
+ if (in_array($disk->getFsType(), $ignoreThreshold, true)) {
+ $disk->setIgnore(4);
+ } elseif (in_array($disk->getMountPoint(), $ignoreUsage, true)) {
+ $disk->setIgnore(3);
+ } elseif (in_array($disk->getMountPoint(), $ignoreTotal, true)) {
+ $disk->setIgnore(2);
+ } elseif (in_array($disk->getMountPoint(), $ignoreFree, true)) {
+ $disk->setIgnore(1);
+ }
$this->_fillDevice($mount, $disk, $i++);
}
}
@@ -425,105 +659,151 @@ class XML
private function _buildMbinfo()
{
$mbinfo = $this->_xml->addChild('MBInfo');
- $temp = $fan = $volt = $power = $current = null;
+ $temp = $fan = $volt = $power = $current = $other = null;
+ $hideSensors = array();
if (sizeof(unserialize(PSI_MBINFO))>0) {
+ if (defined('PSI_HIDE_SENSORS') && is_string(PSI_HIDE_SENSORS)) {
+ if (preg_match(ARRAY_EXP, PSI_HIDE_SENSORS)) {
+ $hideSensors = eval(PSI_HIDE_SENSORS);
+ } else {
+ $hideSensors = array(PSI_HIDE_SENSORS);
+ }
+ }
foreach (unserialize(PSI_MBINFO) as $mbinfoclass) {
$mbinfo_data = new $mbinfoclass();
$mbinfo_detail = $mbinfo_data->getMBInfo();
-
- foreach ($mbinfo_detail->getMbTemp() as $dev) {
- if ($temp == null) {
- $temp = $mbinfo->addChild('Temperature');
- }
- $item = $temp->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMax() !== null) {
- $item->addAttribute('Max', $dev->getMax());
- }
- if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
- $item->addAttribute('Event', $dev->getEvent());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='temperature' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbTemp() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($temp == null) {
+ $temp = $mbinfo->addChild('Temperature');
+ }
+ $item = $temp->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ $alarm = false;
+ if ($dev->getMax() !== null) {
+ $item->addAttribute('Max', $dev->getMax());
+ $alarm = true;
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
}
}
- foreach ($mbinfo_detail->getMbFan() as $dev) {
- if ($fan == null) {
- $fan = $mbinfo->addChild('Fans');
- }
- $item = $fan->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMin() !== null) {
- $item->addAttribute('Min', $dev->getMin());
- }
- if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
- $item->addAttribute('Event', $dev->getEvent());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='fans' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbFan() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($fan == null) {
+ $fan = $mbinfo->addChild('Fans');
+ }
+ $item = $fan->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ $alarm = false;
+ if ($dev->getMin() !== null) {
+ $item->addAttribute('Min', $dev->getMin());
+ $alarm = true;
+ }
+ if ($dev->getUnit() !== "") {
+ $item->addAttribute('Unit', $dev->getUnit());
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
}
}
- foreach ($mbinfo_detail->getMbVolt() as $dev) {
- if ($volt == null) {
- $volt = $mbinfo->addChild('Voltage');
- }
- $item = $volt->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMin() !== null) {
- $item->addAttribute('Min', $dev->getMin());
- }
- if ($dev->getMax() !== null) {
- $item->addAttribute('Max', $dev->getMax());
- }
- if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
- $item->addAttribute('Event', $dev->getEvent());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='voltage' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbVolt() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($volt == null) {
+ $volt = $mbinfo->addChild('Voltage');
+ }
+ $item = $volt->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ $alarm = false;
+ if (($dev->getMin() === null) || ($dev->getMin() != 0) || ($dev->getMax() === null) || ($dev->getMax() != 0)) {
+ if ($dev->getMin() !== null) {
+ $item->addAttribute('Min', $dev->getMin());
+ $alarm = true;
+ }
+ if ($dev->getMax() !== null) {
+ $item->addAttribute('Max', $dev->getMax());
+ $alarm = true;
+ }
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
}
}
- foreach ($mbinfo_detail->getMbPower() as $dev) {
- if ($power == null) {
- $power = $mbinfo->addChild('Power');
- }
- $item = $power->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMax() !== null) {
- $item->addAttribute('Max', $dev->getMax());
- }
- if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
- $item->addAttribute('Event', $dev->getEvent());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='power' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbPower() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($power == null) {
+ $power = $mbinfo->addChild('Power');
+ }
+ $item = $power->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ $alarm = false;
+ if ($dev->getMax() !== null) {
+ $item->addAttribute('Max', $dev->getMax());
+ $alarm = true;
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
}
}
- foreach ($mbinfo_detail->getMbCurrent() as $dev) {
- if ($current == null) {
- $current = $mbinfo->addChild('Current');
- }
- $item = $current->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMax() !== null) {
- $item->addAttribute('Max', $dev->getMax());
- }
- if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
- $item->addAttribute('Event', $dev->getEvent());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='current' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbCurrent() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($current == null) {
+ $current = $mbinfo->addChild('Current');
+ }
+ $item = $current->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ $alarm = false;
+ if (($dev->getMin() === null) || ($dev->getMin() != 0) || ($dev->getMax() === null) || ($dev->getMax() != 0)) {
+ if ($dev->getMin() !== null) {
+ $item->addAttribute('Min', $dev->getMin());
+ $alarm = true;
+ }
+ if ($dev->getMax() !== null) {
+ $item->addAttribute('Max', $dev->getMax());
+ $alarm = true;
+ }
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && ($dev->getEvent() !== "") && (((strtolower($dev->getEvent())) !== "alarm") || $alarm || ($dev->getValue() == 0))) {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
}
}
- }
- }
- if (PSI_HDDTEMP) {
- $hddtemp = new HDDTemp();
- $hddtemp_data = $hddtemp->getMBInfo();
- foreach ($hddtemp_data->getMbTemp() as $dev) {
- if ($temp == null) {
- $temp = $mbinfo->addChild('Temperature');
- }
- $item = $temp->addChild('Item');
- $item->addAttribute('Label', $dev->getName());
- $item->addAttribute('Value', $dev->getValue());
- if ($dev->getMax() !== null) {
- $item->addAttribute('Max', $dev->getMax());
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='other' || $this->_sysinfo->getBlockName()==='mbinfo') foreach ($mbinfo_detail->getMbOther() as $dev) {
+ $mbinfo_name = $dev->getName();
+ if (!in_array($mbinfo_name, $hideSensors, true)) {
+ if ($other == null) {
+ $other = $mbinfo->addChild('Other');
+ }
+ $item = $other->addChild('Item');
+ $item->addAttribute('Label', $mbinfo_name);
+ $item->addAttribute('Value', $dev->getValue());
+ if ($dev->getUnit() !== "") {
+ $item->addAttribute('Unit', $dev->getUnit());
+ }
+ if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") {
+ $item->addAttribute('Event', ucfirst(strtolower($dev->getEvent())));
+ }
+ }
}
}
}
@@ -537,7 +817,7 @@ class XML
private function _buildUpsinfo()
{
$upsinfo = $this->_xml->addChild('UPSInfo');
- if (defined('PSI_UPS_APCUPSD_CGI_ENABLE') && PSI_UPS_APCUPSD_CGI_ENABLE) {
+ if (!defined('PSI_EMU_HOSTNAME') && defined('PSI_UPS_APCUPSD_CGI_ENABLE') && PSI_UPS_APCUPSD_CGI_ENABLE) {
$upsinfo->addAttribute('ApcupsdCgiLinks', true);
}
if (sizeof(unserialize(PSI_UPSINFO))>0) {
@@ -550,11 +830,16 @@ class XML
if ($ups->getModel() !== "") {
$item->addAttribute('Model', $ups->getModel());
}
- $item->addAttribute('Mode', $ups->getMode());
+ if ($ups->getMode() !== "") {
+ $item->addAttribute('Mode', $ups->getMode());
+ }
if ($ups->getStartTime() !== "") {
$item->addAttribute('StartTime', $ups->getStartTime());
}
$item->addAttribute('Status', $ups->getStatus());
+ if ($ups->getBeeperStatus() !== null) {
+ $item->addAttribute('BeeperStatus', $ups->getBeeperStatus());
+ }
if ($ups->getTemperatur() !== null) {
$item->addAttribute('Temperature', $ups->getTemperatur());
}
@@ -600,9 +885,14 @@ class XML
*/
private function _buildXml()
{
- if (!$this->_plugin_request || $this->_complete_request) {
+ if (($this->_plugin == '') || $this->_complete_request) {
if ($this->_sys === null) {
- if (PSI_DEBUG === true) {
+ if (PSI_DEBUG) {
+ // unstable version check
+ if (!is_numeric(substr(PSI_VERSION, -1))) {
+ $this->_errors->addWarning("This is an unstable version of phpSysInfo, some things may not work correctly");
+ }
+
// Safe mode check
$safe_mode = @ini_get("safe_mode") ? true : false;
if ($safe_mode) {
@@ -620,28 +910,28 @@ class XML
$this->_errors->addError("WARN", "PhpSysInfo requires '.' inside the 'include_path' in php.ini");
}
// popen mode check
- if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) {
+ if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN) {
$this->_errors->addError("WARN", "Installed version of PHP does not support proc_open() function, popen() is used");
}
}
$this->_sys = $this->_sysinfo->getSys();
}
- $this->_buildVitals();
- $this->_buildNetwork();
- $this->_buildHardware();
- $this->_buildMemory();
- $this->_buildFilesystems();
- $this->_buildMbinfo();
- $this->_buildUpsinfo();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='vitals') $this->_buildVitals();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='network') $this->_buildNetwork();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='hardware') $this->_buildHardware();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='memory') $this->_buildMemory();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='filesystem') $this->_buildFilesystems();
+ if (!$this->_sysinfo->getBlockName() || in_array($this->_sysinfo->getBlockName(), array('mbinfo','voltage','current','temperature','fans','power','other'))) $this->_buildMbinfo();
+ if (!$this->_sysinfo->getBlockName() || $this->_sysinfo->getBlockName()==='ups') $this->_buildUpsinfo();
}
- $this->_buildPlugins();
+ if (!$this->_sysinfo->getBlockName()) $this->_buildPlugins();
$this->_xml->combinexml($this->_errors->errorsAddToXML($this->_sysinfo->getEncoding()));
}
/**
* get the xml object
*
- * @return string
+ * @return SimpleXmlElement
*/
public function getXml()
{
@@ -658,20 +948,25 @@ class XML
private function _buildPlugins()
{
$pluginroot = $this->_xml->addChild("Plugins");
- if (($this->_plugin_request || $this->_complete_request) && count($this->_plugins) > 0) {
+ if ((($this->_plugin != '') || $this->_complete_request) && count($this->_plugins) > 0) {
$plugins = array();
if ($this->_complete_request) {
$plugins = $this->_plugins;
}
- if ($this->_plugin_request) {
+ if (($this->_plugin != '')) {
$plugins = array($this->_plugin);
}
foreach ($plugins as $plugin) {
- $object = new $plugin($this->_sysinfo->getEncoding());
- $object->execute();
- $oxml = $object->xml();
- if (sizeof($oxml) > 0) {
- $pluginroot->combinexml($oxml);
+ if (!$this->_complete_request ||
+ (!defined('PSI_PLUGIN_'.strtoupper($plugin).'_SSH_HOSTNAME') && !defined('PSI_PLUGIN_'.strtoupper($plugin).'_WMI_HOSTNAME')) ||
+ (defined('PSI_SSH_HOSTNAME') && (PSI_SSH_HOSTNAME == constant('PSI_PLUGIN_'.strtoupper($plugin).'_SSH_HOSTNAME'))) ||
+ (defined('PSI_WMI_HOSTNAME') && (PSI_WMI_HOSTNAME == constant('PSI_PLUGIN_'.strtoupper($plugin).'_WMI_HOSTNAME')))) {
+ $object = new $plugin($this->_sysinfo->getEncoding());
+ $object->execute();
+ $oxml = $object->xml();
+ if (sizeof($oxml) > 0) {
+ $pluginroot->combinexml($oxml);
+ }
}
}
}
@@ -698,32 +993,21 @@ class XML
$options = $this->_xml->addChild('Options');
$options->addAttribute('tempFormat', defined('PSI_TEMP_FORMAT') ? strtolower(PSI_TEMP_FORMAT) : 'c');
$options->addAttribute('byteFormat', defined('PSI_BYTE_FORMAT') ? strtolower(PSI_BYTE_FORMAT) : 'auto_binary');
+ $options->addAttribute('datetimeFormat', defined('PSI_DATETIME_FORMAT') ? strtolower(PSI_DATETIME_FORMAT) : 'utc');
if (defined('PSI_REFRESH')) {
- if (PSI_REFRESH === false) {
- $options->addAttribute('refresh', 0);
- } elseif (PSI_REFRESH === true) {
- $options->addAttribute('refresh', 1);
- } else {
- $options->addAttribute('refresh', PSI_REFRESH);
- }
+ $options->addAttribute('refresh', max(intval(PSI_REFRESH), 0));
} else {
$options->addAttribute('refresh', 60000);
}
if (defined('PSI_FS_USAGE_THRESHOLD')) {
- if (PSI_FS_USAGE_THRESHOLD === true) {
- $options->addAttribute('threshold', 1);
- } elseif ((PSI_FS_USAGE_THRESHOLD !== false) && (PSI_FS_USAGE_THRESHOLD >= 1) && (PSI_FS_USAGE_THRESHOLD <= 99)) {
- $options->addAttribute('threshold', PSI_FS_USAGE_THRESHOLD);
+ if ((($fsut = intval(PSI_FS_USAGE_THRESHOLD)) >= 1) && ($fsut <= 99)) {
+ $options->addAttribute('threshold', $fsut);
}
} else {
$options->addAttribute('threshold', 90);
}
- $options->addAttribute('showPickListTemplate', defined('PSI_SHOW_PICKLIST_TEMPLATE') ? (PSI_SHOW_PICKLIST_TEMPLATE ? 'true' : 'false') : 'false');
- $options->addAttribute('showPickListLang', defined('PSI_SHOW_PICKLIST_LANG') ? (PSI_SHOW_PICKLIST_LANG ? 'true' : 'false') : 'false');
- $options->addAttribute('showCPUListExpanded', defined('PSI_SHOW_CPULIST_EXPANDED') ? (PSI_SHOW_CPULIST_EXPANDED ? 'true' : 'false') : 'true');
- $options->addAttribute('showCPUInfoExpanded', defined('PSI_SHOW_CPUINFO_EXPANDED') ? (PSI_SHOW_CPUINFO_EXPANDED ? 'true' : 'false') : 'false');
if (count($this->_plugins) > 0) {
- if ($this->_plugin_request) {
+ if (($this->_plugin != '')) {
$plug = $this->_xml->addChild('UsedPlugins');
$plug->addChild('Plugin')->addAttribute('name', $this->_plugin);
} elseif ($this->_complete_request) {
@@ -731,11 +1015,13 @@ class XML
foreach ($this->_plugins as $plugin) {
$plug->addChild('Plugin')->addAttribute('name', $plugin);
}
+/*
} else {
$plug = $this->_xml->addChild('UnusedPlugins');
foreach ($this->_plugins as $plugin) {
$plug->addChild('Plugin')->addAttribute('name', $plugin);
}
+*/
}
}
}
diff --git a/root/opt/phpsysinfo/index.php b/root/opt/phpsysinfo/index.php
index 2314548..fbd88e7 100644
--- a/root/opt/phpsysinfo/index.php
+++ b/root/opt/phpsysinfo/index.php
@@ -9,7 +9,7 @@
* @package PSI
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: index.php 687 2012-09-06 20:54:49Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -17,27 +17,19 @@
* define the application root path on the webserver
* @var string
*/
-define('APP_ROOT', dirname(__FILE__));
+define('PSI_APP_ROOT', dirname(__FILE__));
-/**
- * internal xml or external
- * external is needed when running in static mode
- *
- * @var boolean
- */
-define('PSI_INTERNAL_XML', false);
-
-if (version_compare("5.2", PHP_VERSION, ">")) {
- die("PHP 5.2 or greater is required!!!");
+if (version_compare("5.1.3", PHP_VERSION, ">")) {
+ die("PHP 5.1.3 or greater is required!!!");
}
if (!extension_loaded("pcre")) {
die("phpSysInfo requires the pcre extension to php in order to work properly.");
}
-require_once APP_ROOT.'/includes/autoloader.inc.php';
+require_once PSI_APP_ROOT.'/includes/autoloader.inc.php';
// Load configuration
-require_once APP_ROOT.'/read_config.php';
+require_once PSI_APP_ROOT.'/read_config.php';
if (!defined('PSI_CONFIG_FILE') || !defined('PSI_DEBUG')) {
$tpl = new Template("/templates/html/error_config.html");
@@ -46,7 +38,7 @@ if (!defined('PSI_CONFIG_FILE') || !defined('PSI_DEBUG')) {
}
// redirect to page with and without javascript
-$display = isset($_GET['disp']) ? $_GET['disp'] : strtolower(PSI_DEFAULT_DISPLAY_MODE);
+$display = strtolower(isset($_GET['disp']) ? $_GET['disp'] : PSI_DEFAULT_DISPLAY_MODE);
switch ($display) {
case "static":
$webpage = new WebpageXSLT();
@@ -57,15 +49,45 @@ case "dynamic":
$webpage->run();
break;
case "xml":
- $webpage = new WebpageXML(true, null);
+ $webpage = new WebpageXML("complete");
$webpage->run();
break;
+case "json":
+ $webpage = new WebpageXML("complete");
+ $json = $webpage->getJsonString();
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Content-Type: application/json');
+ echo $json;
+ break;
case "bootstrap":
+/*
$tpl = new Template("/templates/html/index_bootstrap.html");
echo $tpl->fetch();
+*/
+ $webpage = new Webpage("bootstrap");
+ $webpage->run();
break;
-default:
+case "auto":
$tpl = new Template("/templates/html/index_all.html");
echo $tpl->fetch();
break;
+default:
+ $defaultdisplay = strtolower(PSI_DEFAULT_DISPLAY_MODE);
+ switch ($defaultdisplay) {
+ case "static":
+ $webpage = new WebpageXSLT();
+ $webpage->run();
+ break;
+ case "dynamic":
+ $webpage = new Webpage();
+ $webpage->run();
+ break;
+ case "bootstrap":
+ $webpage = new Webpage("bootstrap");
+ $webpage->run();
+ break;
+ default:
+ $tpl = new Template("/templates/html/index_all.html");
+ echo $tpl->fetch();
+ }
}
diff --git a/root/opt/phpsysinfo/js.php b/root/opt/phpsysinfo/js.php
index 375cb99..39f30a5 100644
--- a/root/opt/phpsysinfo/js.php
+++ b/root/opt/phpsysinfo/js.php
@@ -8,7 +8,7 @@
* @package PSI_JS
* @author Michael Cramer
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: js.php 661 2012-08-27 11:26:39Z namiltd $
* @link http://phpsysinfo.sourceforge.net
*/
@@ -17,11 +17,11 @@
*
* @var string
*/
-define('APP_ROOT', dirname(__FILE__));
+define('PSI_APP_ROOT', dirname(__FILE__));
-require_once APP_ROOT.'/includes/autoloader.inc.php';
+require_once PSI_APP_ROOT.'/includes/autoloader.inc.php';
-require_once APP_ROOT.'/read_config.php';
+require_once PSI_APP_ROOT.'/read_config.php';
$file = isset($_GET['name']) ? basename(htmlspecialchars($_GET['name'])) : null;
$plugin = isset($_GET['plugin']) ? basename(htmlspecialchars($_GET['plugin'])) : null;
@@ -29,16 +29,16 @@ $script = null;
if ($file != null && $plugin == null) {
if (strtolower(substr($file, 0, 6)) == 'jquery') {
- $script = APP_ROOT.'/js/jQuery/'.$file;
+ $script = PSI_APP_ROOT.'/js/jQuery/'.$file;
} elseif (strtolower(substr($file, 0, 10)) == 'phpsysinfo') {
- $script = APP_ROOT.'/js/phpSysInfo/'.$file;
+ $script = PSI_APP_ROOT.'/js/phpSysInfo/'.$file;
} else {
- $script = APP_ROOT.'/js/vendor/'.$file;
+ $script = PSI_APP_ROOT.'/js/vendor/'.$file;
}
} elseif ($file == null && $plugin != null) {
- $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($plugin);
+ $script = PSI_APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($plugin);
} elseif ($file != null && $plugin != null) {
- $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($file);
+ $script = PSI_APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($file);
}
if ($script != null) {
@@ -46,40 +46,33 @@ if ($script != null) {
$scriptmin = $script.'.min.js';
$compression = false;
- header("content-type: application/x-javascript");
+ header('content-type: application/x-javascript');
if ((!defined("PSI_DEBUG") || (PSI_DEBUG !== true)) && defined("PSI_JS_COMPRESSION")) {
$compression = strtolower(PSI_JS_COMPRESSION);
}
switch ($compression) {
- case "normal":
- if (file_exists($scriptmin) && is_readable($scriptmin)) {
- $filecontent = file_get_contents($scriptmin);
- echo $filecontent;
- } elseif (file_exists($scriptjs) && is_readable($scriptjs)) {
- $filecontent = file_get_contents($scriptjs);
- $packer = new JavaScriptPacker($filecontent);
- echo $packer->pack();
- }
- break;
- case "none":
- if (file_exists($scriptjs) && is_readable($scriptjs)) {
- $filecontent = file_get_contents($scriptjs);
- $packer = new JavaScriptPacker($filecontent, 0);
- echo $packer->pack();
- } elseif (file_exists($scriptmin) && is_readable($scriptmin)) {
- $filecontent = file_get_contents($scriptmin);
- echo $filecontent;
- }
- break;
- default:
- if (file_exists($scriptjs) && is_readable($scriptjs)) {
- $filecontent = file_get_contents($scriptjs);
- } elseif (file_exists($scriptmin) && is_readable($scriptmin)) {
- $filecontent = file_get_contents($scriptmin);
- } else break;
-
- echo $filecontent;
- break;
+ case "normal":
+ if (file_exists($scriptmin) && is_readable($scriptmin)) {
+ echo file_get_contents($scriptmin);
+ } elseif (file_exists($scriptjs) && is_readable($scriptjs)) {
+ $packer = new JavaScriptPacker(file_get_contents($scriptjs));
+ echo $packer->pack();
+ }
+ break;
+ case "none":
+ if (file_exists($scriptjs) && is_readable($scriptjs)) {
+ $packer = new JavaScriptPacker(file_get_contents($scriptjs), 0);
+ echo $packer->pack();
+ } elseif (file_exists($scriptmin) && is_readable($scriptmin)) {
+ echo file_get_contents($scriptmin);
+ }
+ break;
+ default:
+ if (file_exists($scriptjs) && is_readable($scriptjs)) {
+ echo file_get_contents($scriptjs);
+ } elseif (file_exists($scriptmin) && is_readable($scriptmin)) {
+ echo file_get_contents($scriptmin);
+ }
}
}
diff --git a/root/opt/phpsysinfo/js/jQuery/README b/root/opt/phpsysinfo/js/jQuery/README
index 5e80578..8f5300c 100644
--- a/root/opt/phpsysinfo/js/jQuery/README
+++ b/root/opt/phpsysinfo/js/jQuery/README
@@ -1,17 +1,10 @@
versions, links and simple description of used jquery files
===========================================================
+
jquery.js
---------
-VERSION : 2.1.4
-URL : http://jquery.com/
-DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle
- events, perform animations, and add Ajax interactions to your web pages.
-USED : used for the entire userinterface
-
-jquery-1.js
----------
-VERSION : 1.11.3
+VERSION : v1.12.4-ff3fix-ff2fix-CVE_2015_9251fix-CVE_2019_11358fix-CVE_2020_11022fix-CVE_2020_11023fix
URL : http://jquery.com/
DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle
events, perform animations, and add Ajax interactions to your web pages.
@@ -20,7 +13,7 @@ USED : used for the entire userinterface
jquery.dataTables.js
--------------------
-VERSION : 1.8.2
+VERSION : 1.8.2+jquery1.9fix+parseJSONfix2+bindfix+samesitefix+noeval
URL : http://plugins.jquery.com/project/DataTables
DESC : dataTables is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable
table without page refreshes.
@@ -28,31 +21,38 @@ USED : provide tablesorting for the filesystem table
jquery.nyroModal.js
-------------------
-VERSION : 1.6.2+jquery1.8fix
+VERSION : 1.6.2+jquery1.8fix+bindfix+ff2fix
URL : http://plugins.jquery.com/project/nyroModal
DESC : nyroModal is a high customizable modal window plugin.
USED : provide a modal dialog, that is shown when errors are found during execution of the php parsers, or lets say
in this way: if there are error elements in the xml file
-jquery.timers.js
+jquery.timer.js
----------------
VERSION : 0.1
-URL : http://plugins.jquery.com/project/Timer
+URL : http://plugins.jquery.com/project/Timer; https://github.com/sloat/timer
DESC : provides a cleaner way to handle intervals
USED : automatic reloading of the entire page
jquery.jgrowl.js
----------------
-VERSION : 1.2.6
+VERSION : 1.2.6+jquery1.9fix+jquery3fix+bindfix
URL : http://plugins.jquery.com/project/jGrowl
DESC : jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works
USED : show alert and error message
jquery.treeTable.js
-------------------
-VERSION : 2009-06-22+statefix
+VERSION : 2009-06-22+statefix+spanfix+altfix+undefinedfix+ie6cachefix+multilinefix+divfix
URL : http://plugins.jquery.com/project/jQTreeTable; http://www.hanpau.com/index.php?page=jqtreetable
DESC : Take a plain html table, wrap the rows you want collapsing/expanding in a tbody tag with an id of treetable, map each row to it's parent row, set some options, and let jQTreeTable take it from there.
USED : Hardware, Memory, UPS blocks
+jquery.ifixpng.js
+-------------------
+VERSION : 2.1 (23/04/2008)+jquery1.9fix
+URL : http://jquery.khurshid.com
+DESC : Designed to fix that problem by applying appropriate filters to user specified elements, while keeping all element tags intact.
+USED : used for the entire userinterface
+
$Id: README 702 2012-09-21 16:52:32Z namiltd $
diff --git a/root/opt/phpsysinfo/js/jQuery/README_bootstrap b/root/opt/phpsysinfo/js/jQuery/README_bootstrap
index 18e9b93..2cda39e 100644
--- a/root/opt/phpsysinfo/js/jQuery/README_bootstrap
+++ b/root/opt/phpsysinfo/js/jQuery/README_bootstrap
@@ -3,15 +3,7 @@ versions, links and simple description of used jquery files
jquery.js
---------
-VERSION : 2.1.4
-URL : http://jquery.com/
-DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle
- events, perform animations, and add Ajax interactions to your web pages.
-USED : used for the entire userinterface
-
-jquery-1.js
----------
-VERSION : 1.11.3
+VERSION : v1.12.4-ff3fix-ff2fix-CVE_2015_9251fix-CVE_2019_11358fix-CVE_2020_11022fix-CVE_2020_11023fix
URL : http://jquery.com/
DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle
events, perform animations, and add Ajax interactions to your web pages.
diff --git a/root/opt/phpsysinfo/js/jQuery/jquery-1.js b/root/opt/phpsysinfo/js/jQuery/jquery-1.js
deleted file mode 100644
index 6feb110..0000000
--- a/root/opt/phpsysinfo/js/jQuery/jquery-1.js
+++ /dev/null
@@ -1,10351 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.11.3
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-28T16:19Z
- */
-
-(function( global, factory ) {
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
- // For CommonJS and CommonJS-like environments where a proper window is present,
- // execute the factory and get jQuery
- // For environments that do not inherently posses a window with a document
- // (such as Node.js), expose a jQuery-making factory as module.exports
- // This accentuates the need for the creation of a real window
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Can't do this because several apps including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-// Support: Firefox 18+
-//
-
-var deletedIds = [];
-
-var slice = deletedIds.slice;
-
-var concat = deletedIds.concat;
-
-var push = deletedIds.push;
-
-var indexOf = deletedIds.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var support = {};
-
-
-
-var
- version = "1.11.3",
-
- // Define a local copy of jQuery
- jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- // Need init if jQuery is called (just allow error to be thrown if not included)
- return new jQuery.fn.init( selector, context );
- },
-
- // Support: Android<4.1, IE<9
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([\da-z])/gi,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
-jQuery.fn = jQuery.prototype = {
- // The current version of jQuery being used
- jquery: version,
-
- constructor: jQuery,
-
- // Start with an empty selector
- selector: "",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- toArray: function() {
- return slice.call( this );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num != null ?
-
- // Return just the one element from the set
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
- // Return all the elements in a clean array
- slice.call( this );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
-
- // Build a new jQuery matched element set
- var ret = jQuery.merge( this.constructor(), elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ) );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- eq: function( i ) {
- var len = this.length,
- j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
- },
-
- end: function() {
- return this.prevObject || this.constructor(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: deletedIds.sort,
- splice: deletedIds.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
- var src, copyIsArray, copy, name, options, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
-
- // skip the boolean and the target
- target = arguments[ i ] || {};
- i++;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( i === length ) {
- target = this;
- i--;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
- // Assume jQuery is ready without the ready module
- isReady: true,
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- noop: function() {},
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray || function( obj ) {
- return jQuery.type(obj) === "array";
- },
-
- isWindow: function( obj ) {
- /* jshint eqeqeq: false */
- return obj != null && obj == obj.window;
- },
-
- isNumeric: function( obj ) {
- // parseFloat NaNs numeric-cast false positives (null|true|false|"")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- // adding 1 corrects loss of precision from parseFloat (#15100)
- return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
- },
-
- isEmptyObject: function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
-
- isPlainObject: function( obj ) {
- var key;
-
- // Must be an Object.
- // Because of IE, we also have to check the presence of the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- try {
- // Not own constructor property must be Object
- if ( obj.constructor &&
- !hasOwn.call(obj, "constructor") &&
- !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
- return false;
- }
- } catch ( e ) {
- // IE8,9 Will throw exceptions on certain host objects #9897
- return false;
- }
-
- // Support: IE<9
- // Handle iteration over inherited properties before own properties.
- if ( support.ownLast ) {
- for ( key in obj ) {
- return hasOwn.call( obj, key );
- }
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
- for ( key in obj ) {}
-
- return key === undefined || hasOwn.call( obj, key );
- },
-
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call(obj) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- // Workarounds based on findings by Jim Driscoll
- // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
- globalEval: function( data ) {
- if ( data && jQuery.trim( data ) ) {
- // We use execScript on Internet Explorer
- // We use an anonymous function so that context is window
- // rather than jQuery in Firefox
- ( window.execScript || function( data ) {
- window[ "eval" ].call( window, data );
- } )( data );
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
- },
-
- // args is for internal usage only
- each: function( obj, callback, args ) {
- var value,
- i = 0,
- length = obj.length,
- isArray = isArraylike( obj );
-
- if ( args ) {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- }
- }
-
- return obj;
- },
-
- // Support: Android<4.1, IE<9
- trim: function( text ) {
- return text == null ?
- "" :
- ( text + "" ).replace( rtrim, "" );
- },
-
- // results is for internal usage only
- makeArray: function( arr, results ) {
- var ret = results || [];
-
- if ( arr != null ) {
- if ( isArraylike( Object(arr) ) ) {
- jQuery.merge( ret,
- typeof arr === "string" ?
- [ arr ] : arr
- );
- } else {
- push.call( ret, arr );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, arr, i ) {
- var len;
-
- if ( arr ) {
- if ( indexOf ) {
- return indexOf.call( arr, elem, i );
- }
-
- len = arr.length;
- i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
-
- for ( ; i < len; i++ ) {
- // Skip accessing in sparse arrays
- if ( i in arr && arr[ i ] === elem ) {
- return i;
- }
- }
- }
-
- return -1;
- },
-
- merge: function( first, second ) {
- var len = +second.length,
- j = 0,
- i = first.length;
-
- while ( j < len ) {
- first[ i++ ] = second[ j++ ];
- }
-
- // Support: IE<9
- // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
- if ( len !== len ) {
- while ( second[j] !== undefined ) {
- first[ i++ ] = second[ j++ ];
- }
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, invert ) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- callbackInverse = !callback( elems[ i ], i );
- if ( callbackInverse !== callbackExpect ) {
- matches.push( elems[ i ] );
- }
- }
-
- return matches;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var value,
- i = 0,
- length = elems.length,
- isArray = isArraylike( elems ),
- ret = [];
-
- // Go through the array, translating each of the items to their new values
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( i in elems ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
- }
-
- // Flatten any nested arrays
- return concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var args, proxy, tmp;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: function() {
- return +( new Date() );
- },
-
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-function isArraylike( obj ) {
-
- // Support: iOS 8.2 (not reproducible in simulator)
- // `in` check used to prevent JIT error (gh-2145)
- // hasOwn isn't used here due to false negatives
- // regarding Nodelist length in IE
- var length = "length" in obj && obj.length,
- type = jQuery.type( obj );
-
- if ( type === "function" || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.nodeType === 1 && length ) {
- return true;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.2.0-pre
- * http://sizzlejs.com/
- *
- * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-12-16
- */
-(function( window ) {
-
-var i,
- support,
- Expr,
- getText,
- isXML,
- tokenize,
- compile,
- select,
- outermostContext,
- sortInput,
- hasDuplicate,
-
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
-
- // Instance-specific data
- expando = "sizzle" + 1 * new Date(),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- // General-purpose constants
- MAX_NEGATIVE = 1 << 31,
-
- // Instance methods
- hasOwn = ({}).hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf as it's faster than native
- // http://jsperf.com/thor-indexof-vs-for/5
- indexOf = function( list, elem ) {
- var i = 0,
- len = list.length;
- for ( ; i < len; i++ ) {
- if ( list[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
- // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace +
- // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
- "*\\]",
-
- pseudos = ":(" + characterEncoding + ")(?:\\((" +
- // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
- // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
- // 3. anything else (capture 2)
- ".*" +
- ")\\)|)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rwhitespace = new RegExp( whitespace + "+", "g" ),
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
- },
-
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
-
- rnative = /^[^{]+\{\s*\[native \w/,
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
- rsibling = /[+~]/,
- rescape = /'|\\/g,
-
- // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
- high < 0 ?
- // BMP codepoint
- String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
- },
-
- // Used for iframes
- // See setDocument()
- // Removing the function wrapper causes a "Permission Denied"
- // error in IE
- unloadHandler = function() {
- setDocument();
- };
-
-// Optimize for push.apply( _, NodeList )
-try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
- }
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- var match, elem, m, nodeType,
- // QSA vars
- i, groups, old, nid, newContext, newSelector;
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
-
- context = context || document;
- results = results || [];
- nodeType = context.nodeType;
-
- if ( typeof selector !== "string" || !selector ||
- nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
- return results;
- }
-
- if ( !seed && documentIsHTML ) {
-
- // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document (jQuery #6963)
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && support.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // QSA path
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- nid = old = expando;
- newContext = context;
- newSelector = nodeType !== 1 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + toSelector( groups[i] );
- }
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
-function createCache() {
- var keys = [];
-
- function cache( key, value ) {
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
- }
- return (cache[ key + " " ] = value);
- }
- return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
- var div = document.createElement("div");
-
- try {
- return !!fn( div );
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if ( div.parentNode ) {
- div.parentNode.removeChild( div );
- }
- // release memory in IE
- div = null;
- }
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
- i = attrs.length;
-
- while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
- }
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
- ( ~a.sourceIndex || MAX_NEGATIVE );
-
- // Use IE sourceIndex if available on both nodes
- if ( diff ) {
- return diff;
- }
-
- // Check if b follows a
- if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
- if ( cur === b ) {
- return -1;
- }
- }
- }
-
- return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
- return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare, parent,
- doc = node ? node.ownerDocument || node : preferredDoc;
-
- // If no document and documentElement is available, return
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Set our document
- document = doc;
- docElem = doc.documentElement;
- parent = doc.defaultView;
-
- // Support: IE>8
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
- // IE6-8 do not support the defaultView property so parent will be undefined
- if ( parent && parent !== parent.top ) {
- // IE11 does not have attachEvent, so all must suffer
- if ( parent.addEventListener ) {
- parent.addEventListener( "unload", unloadHandler, false );
- } else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", unloadHandler );
- }
- }
-
- /* Support tests
- ---------------------------------------------------------------------- */
- documentIsHTML = !isXML( doc );
-
- /* Attributes
- ---------------------------------------------------------------------- */
-
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not properties
- // (excepting IE8 booleans)
- support.attributes = assert(function( div ) {
- div.className = "i";
- return !div.getAttribute("className");
- });
-
- /* getElement(s)By*
- ---------------------------------------------------------------------- */
-
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( div ) {
- div.appendChild( doc.createComment("") );
- return !div.getElementsByTagName("*").length;
- });
-
- // Support: IE<9
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
-
- // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function( div ) {
- docElem.appendChild( div ).id = expando;
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
- });
-
- // ID find and filter
- if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [ m ] : [];
- }
- };
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute("id") === attrId;
- };
- };
- } else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- };
- }
-
- // Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- return context.getElementsByTagName( tag );
-
- // DocumentFragment nodes don't have gEBTN
- } else if ( support.qsa ) {
- return context.querySelectorAll( tag );
- }
- } :
-
- function( tag, context ) {
- var elem,
- tmp = [],
- i = 0,
- // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
- results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- };
-
- // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( documentIsHTML ) {
- return context.getElementsByClassName( className );
- }
- };
-
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
-
- // QSA and matchesSelector support
-
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = [];
-
- // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
- // See http://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
-
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- docElem.appendChild( div ).innerHTML = " " +
- "" +
- " ";
-
- // Support: IE8, Opera 11-12.16
- // Nothing should be selected when empty strings follow ^= or $= or *=
- // The test attribute must be unknown in Opera but "safe" for WinRT
- // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( div.querySelectorAll("[msallowcapture^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
- }
-
- // Support: IE8
- // Boolean attributes and "value" are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
- }
-
- // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
- if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
- rbuggyQSA.push("~=");
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
-
- // Support: Safari 8+, iOS 8+
- // https://bugs.webkit.org/show_bug.cgi?id=136851
- // In-page `selector#id sibing-combinator selector` fails
- if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
- rbuggyQSA.push(".#.+[+~]");
- }
- });
-
- assert(function( div ) {
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- var input = doc.createElement("input");
- input.setAttribute( "type", "hidden" );
- div.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE8
- // Enforce case-sensitivity of name attribute
- if ( div.querySelectorAll("[name=d]").length ) {
- rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Opera 10-11 does not throw on post-comma invalid pseudos
- div.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
-
- if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
- docElem.webkitMatchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
-
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( div, "[s!='']:x" );
- rbuggyMatches.push( "!=", pseudos );
- });
- }
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
- /* Contains
- ---------------------------------------------------------------------- */
- hasCompare = rnative.test( docElem.compareDocumentPosition );
-
- // Element contains another
- // Purposefully does not implement inclusive descendent
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test( docElem.contains ) ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && (
- adown.contains ?
- adown.contains( bup ) :
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ));
- } :
- function( a, b ) {
- if ( b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- }
- return false;
- };
-
- /* Sorting
- ---------------------------------------------------------------------- */
-
- // Document order sorting
- sortOrder = hasCompare ?
- function( a, b ) {
-
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if ( compare ) {
- return compare;
- }
-
- // Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
- // Choose the first element that is related to our preferred document
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
- return -1;
- }
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
- return 1;
- }
-
- // Maintain original order
- return sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
- }
-
- return compare & 4 ? -1 : 1;
- } :
- function( a, b ) {
- // Exit early if the nodes are identical
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [ a ],
- bp = [ b ];
-
- // Parentless nodes are either documents or disconnected
- if ( !aup || !bup ) {
- return a === doc ? -1 :
- b === doc ? 1 :
- aup ? -1 :
- bup ? 1 :
- sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
-
- // If the nodes are siblings, we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
- }
-
- // Otherwise we need full lists of their ancestors for comparison
- cur = a;
- while ( (cur = cur.parentNode) ) {
- ap.unshift( cur );
- }
- cur = b;
- while ( (cur = cur.parentNode) ) {
- bp.unshift( cur );
- }
-
- // Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
- i++;
- }
-
- return i ?
- // Do a sibling check if the nodes have a common ancestor
- siblingCheck( ap[i], bp[i] ) :
-
- // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
- 0;
- };
-
- return doc;
-};
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- if ( support.matchesSelector && documentIsHTML &&
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
-
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch (e) {}
- }
-
- return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
- // Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
- setDocument( context );
- }
- return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- var fn = Expr.attrHandle[ name.toLowerCase() ],
- // Don't get fooled by Object.prototype properties (jQuery #13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
-
- return val !== undefined ?
- val :
- support.attributes || !documentIsHTML ?
- elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
- val.value :
- null;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0;
-
- // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice( 0 );
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
- j = duplicates.push( i );
- }
- }
- while ( j-- ) {
- results.splice( duplicates[ j ], 1 );
- }
- }
-
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
- return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( !nodeType ) {
- // If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
-
- return ret;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- attrHandle: {},
-
- find: {},
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1].slice( 0, 3 ) === "nth" ) {
- // nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var excess,
- unquoted = !match[6] && match[2];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[3] ) {
- match[2] = match[4] || match[5] || "";
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- "TAG": function( nodeNameSelector ) {
- var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() { return true; } :
- function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
- });
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, what, argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, context, xml ) {
- var cache, outerCache, node, diff, nodeIndex, start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType;
-
- if ( parent ) {
-
- // :(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( (node = node[ dir ]) ) {
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
- return false;
- }
- }
- // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ? parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...) stores cache data on `parent`
- if ( forward && useCache ) {
- // Seek `elem` from a previously-cached index
- outerCache = parent[ expando ] || (parent[ expando ] = {});
- cache = outerCache[ type ] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = cache[0] === dirruns && cache[2];
- node = nodeIndex && parent.childNodes[ nodeIndex ];
-
- while ( (node = ++nodeIndex && node && node[ dir ] ||
-
- // Fallback to seeking `elem` from the start
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- // When found, cache indexes on `parent` and break
- if ( node.nodeType === 1 && ++diff && node === elem ) {
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- // Use previously-cached element index if available
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
- diff = cache[1];
-
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
- } else {
- // Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
- // Cache the index of each encountered element
- if ( useCache ) {
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
- }
-
- if ( node === elem ) {
- break;
- }
- }
- }
- }
-
- // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- // Don't keep the element (issue #299)
- input[0] = null;
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- text = text.replace( runescape, funescape );
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction( function( lang ) {
- // lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
- Sizzle.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape ).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( (elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
- return false;
- };
- }),
-
- // Miscellaneous
- "target": function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- "root": function( elem ) {
- return elem === docElem;
- },
-
- "focus": function( elem ) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
- },
-
- // Boolean properties
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- // Element/input types
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "text": function( elem ) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" &&
- elem.type === "text" &&
-
- // Support: IE<8
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- "first": createPositionalPseudo(function() {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
- }
- groups.push( (tokens = []) );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[i].value;
- }
- return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
- if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- if ( matcher( elem, context, xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || (elem[ expando ] = {});
- if ( (oldCache = outerCache[ dir ]) &&
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache so results back-propagate to previous elements
- return (newCache[ 2 ] = oldCache[ 2 ]);
- } else {
- // Reuse newcache so results back-propagate to previous elements
- outerCache[ dir ] = newCache;
-
- // A match means we're done; a fail means we have to keep checking
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
- return true;
- }
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
- }
- return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- var temp, i, elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- // Restore matcherIn since elem is not yet a final match
- temp.push( (matcherIn[i] = elem) );
- }
- }
- postFinder( null, (matcherOut = []), temp, xml );
- }
-
- // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
- seed[temp] = !(results[temp] = elem);
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- // Avoid hanging onto element (issue #299)
- checkContext = null;
- return ret;
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
- } else {
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
- ).replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost ) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
- len = elems.length;
-
- if ( outermost ) {
- outermostContext = context !== document && context;
- }
-
- // Add elements passing elementMatchers directly to results
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
- while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context, xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( (matcher = setMatchers[j++]) ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !match ) {
- match = tokenize( selector );
- }
- i = match.length;
- while ( i-- ) {
- cached = matcherFromTokens( match[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
- // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( (selector = compiled.selector || selector) );
-
- results = results || [];
-
- // Try to minimize operations if there is no seed and only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 && documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
- if ( !context ) {
- return results;
-
- // Precompiled matchers will still verify ancestry, so step up a level
- } else if ( compiled ) {
- context = context.parentNode;
- }
-
- selector = selector.slice( tokens.shift().value.length );
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
- while ( i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape, funescape ),
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector( tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
-
- // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector above
- ( compiled || compile( selector, match ) )(
- seed,
- context,
- !documentIsHTML,
- results,
- rsibling.test( selector ) && testContext( context.parentNode ) || context
- );
- return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( document.createElement("div") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
- div.innerHTML = " ";
- return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
- }
- });
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
- div.innerHTML = " ";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
- addHandle( "value", function( elem, name, isXML ) {
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
- }
- });
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
- return div.getAttribute("disabled") == null;
-}) ) {
- addHandle( booleans, function( elem, name, isXML ) {
- var val;
- if ( !isXML ) {
- return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name )) && val.specified ?
- val.value :
- null;
- }
- });
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
- return !!qualifier.call( elem, i, elem ) !== not;
- });
-
- }
-
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- });
-
- }
-
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- qualifier = jQuery.filter( qualifier, elements );
- }
-
- return jQuery.grep( elements, function( elem ) {
- return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
- });
-}
-
-jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- }));
-};
-
-jQuery.fn.extend({
- find: function( selector ) {
- var i,
- ret = [],
- self = this,
- len = self.length;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- }) );
- }
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- // Needed because $( selector, context ) becomes $( context ).find( selector )
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
- ret.selector = this.selector ? this.selector + " " + selector : selector;
- return ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector || [], false) );
- },
- not: function( selector ) {
- return this.pushStack( winnow(this, selector || [], true) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test( selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
-});
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- // A simple way to check for HTML strings
- // Prioritize #id over to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
- init = jQuery.fn.init = function( selector, context ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ? context[0] : context;
-
- // scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[1],
- context && context.nodeType ? context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
- // Properties of context are called as methods if possible
- if ( jQuery.isFunction( this[ match ] ) ) {
- this[ match ]( context[ match ] );
-
- // ...and otherwise set as attributes
- } else {
- this.attr( match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById( match[2] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id !== match[2] ) {
- return rootjQuery.find( selector );
- }
-
- // Otherwise, we inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return typeof rootjQuery.ready !== "undefined" ?
- rootjQuery.ready( selector ) :
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- };
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.extend({
- dir: function( elem, dir, until ) {
- var matched = [],
- cur = elem[ dir ];
-
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
- if ( cur.nodeType === 1 ) {
- matched.push( cur );
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- sibling: function( n, elem ) {
- var r = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- r.push( n );
- }
- }
-
- return r;
- }
-});
-
-jQuery.fn.extend({
- has: function( target ) {
- var i,
- targets = jQuery( target, this ),
- len = targets.length;
-
- return this.filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
- // Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector(cur, selectors)) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
- }
-
- // index in selector
- if ( typeof elem === "string" ) {
- return jQuery.inArray( this[0], jQuery( elem ) );
- }
-
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.unique(
- jQuery.merge( this.get(), jQuery( selector, context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter(selector)
- );
- }
-});
-
-function sibling( cur, dir ) {
- do {
- cur = cur[ dir ];
- } while ( cur && cur.nodeType !== 1 );
-
- return cur;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return jQuery.nodeName( elem, "iframe" ) ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.merge( [], elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var ret = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- ret = jQuery.filter( selector, ret );
- }
-
- if ( this.length > 1 ) {
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- ret = jQuery.unique( ret );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- ret = ret.reverse();
- }
- }
-
- return this.pushStack( ret );
- };
-});
-var rnotwhite = (/\S+/g);
-
-
-
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in cache
-function createOptions( options ) {
- var object = optionsCache[ options ] = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- });
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- ( optionsCache[ options ] || createOptions( options ) ) :
- jQuery.extend( {}, options );
-
- var // Flag to know if list is currently firing
- firing,
- // Last fire value (for non-forgettable lists)
- memory,
- // Flag to know if list was already fired
- fired,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if needed)
- firingIndex,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // Actual callback list
- list = [],
- // Stack of fire calls for repeatable lists
- stack = !options.once && [],
- // Fire callbacks
- fire = function( data ) {
- memory = options.memory && data;
- fired = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- firing = true;
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
- if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
- memory = false; // To prevent further calls using add
- break;
- }
- }
- firing = false;
- if ( list ) {
- if ( stack ) {
- if ( stack.length ) {
- fire( stack.shift() );
- }
- } else if ( memory ) {
- list = [];
- } else {
- self.disable();
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
- // First, we save the current length
- var start = list.length;
- (function add( args ) {
- jQuery.each( args, function( _, arg ) {
- var type = jQuery.type( arg );
- if ( type === "function" ) {
- if ( !options.unique || !self.has( arg ) ) {
- list.push( arg );
- }
- } else if ( arg && arg.length && type !== "string" ) {
- // Inspect recursively
- add( arg );
- }
- });
- })( arguments );
- // Do we need to add the callbacks to the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away
- } else if ( memory ) {
- firingStart = start;
- fire( memory );
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function() {
- if ( list ) {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
- // Handle firing indexes
- if ( firing ) {
- if ( index <= firingLength ) {
- firingLength--;
- }
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
- }
- });
- }
- return this;
- },
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function( fn ) {
- return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
- },
- // Remove all callbacks from the list
- empty: function() {
- list = [];
- firingLength = 0;
- return this;
- },
- // Have the list do nothing anymore
- disable: function() {
- list = stack = memory = undefined;
- return this;
- },
- // Is it disabled?
- disabled: function() {
- return !list;
- },
- // Lock the list in its current state
- lock: function() {
- stack = undefined;
- if ( !memory ) {
- self.disable();
- }
- return this;
- },
- // Is it locked?
- locked: function() {
- return !stack;
- },
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( list && ( !fired || stack ) ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
- if ( firing ) {
- stack.push( args );
- } else {
- fire( args );
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-jQuery.extend({
-
- Deferred: function( func ) {
- var tuples = [
- // action, add listener, listener list, final state
- [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
- [ "notify", "progress", jQuery.Callbacks("memory") ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail( arguments );
- return this;
- },
- then: function( /* fnDone, fnFail, fnProgress */ ) {
- var fns = arguments;
- return jQuery.Deferred(function( newDefer ) {
- jQuery.each( tuples, function( i, tuple ) {
- var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
- // deferred[ done | fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[1] ](function() {
- var returned = fn && fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
- returned.promise()
- .done( newDefer.resolve )
- .fail( newDefer.reject )
- .progress( newDefer.notify );
- } else {
- newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
- }
- });
- });
- fns = null;
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend( obj, promise ) : promise;
- }
- },
- deferred = {};
-
- // Keep pipe for back-compat
- promise.pipe = promise.then;
-
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 3 ];
-
- // promise[ done | fail | progress ] = list.add
- promise[ tuple[1] ] = list.add;
-
- // Handle state
- if ( stateString ) {
- list.add(function() {
- // state = [ resolved | rejected ]
- state = stateString;
-
- // [ reject_list | resolve_list ].disable; progress_list.lock
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
- }
-
- // deferred[ resolve | reject | notify ]
- deferred[ tuple[0] ] = function() {
- deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
- return this;
- };
- deferred[ tuple[0] + "With" ] = list.fireWith;
- });
-
- // Make the deferred a promise
- promise.promise( deferred );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( subordinate /* , ..., subordinateN */ ) {
- var i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
-
- // the count of uncompleted subordinates
- remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
- // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
- deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
- // Update function for both resolve and progress values
- updateFunc = function( i, contexts, values ) {
- return function( value ) {
- contexts[ i ] = this;
- values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
- if ( values === progressValues ) {
- deferred.notifyWith( contexts, values );
-
- } else if ( !(--remaining) ) {
- deferred.resolveWith( contexts, values );
- }
- };
- },
-
- progressValues, progressContexts, resolveContexts;
-
- // add listeners to Deferred subordinates; treat others as resolved
- if ( length > 1 ) {
- progressValues = new Array( length );
- progressContexts = new Array( length );
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
- if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
- resolveValues[ i ].promise()
- .done( updateFunc( i, resolveContexts, resolveValues ) )
- .fail( deferred.reject )
- .progress( updateFunc( i, progressContexts, progressValues ) );
- } else {
- --remaining;
- }
- }
- }
-
- // if we're not waiting on anything, resolve the master
- if ( !remaining ) {
- deferred.resolveWith( resolveContexts, resolveValues );
- }
-
- return deferred.promise();
- }
-});
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
- // Add the callback
- jQuery.ready.promise().done( fn );
-
- return this;
-};
-
-jQuery.extend({
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
-
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
-
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( !document.body ) {
- return setTimeout( jQuery.ready );
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
- jQuery( document ).off( "ready" );
- }
- }
-});
-
-/**
- * Clean-up method for dom ready events
- */
-function detach() {
- if ( document.addEventListener ) {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
-
- } else {
- document.detachEvent( "onreadystatechange", completed );
- window.detachEvent( "onload", completed );
- }
-}
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
- // readyState === "complete" is good enough for us to call the dom ready in oldIE
- if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
- detach();
- jQuery.ready();
- }
-}
-
-jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
-
- readyList = jQuery.Deferred();
-
- // Catch cases where $(document).ready() is called after the browser event has already occurred.
- // we once tried to use readyState "interactive" here, but it caused issues like the one
- // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- setTimeout( jQuery.ready );
-
- // Standards-based browsers support DOMContentLoaded
- } else if ( document.addEventListener ) {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed, false );
-
- // If IE event model is used
- } else {
- // Ensure firing before onload, maybe late but safe also for iframes
- document.attachEvent( "onreadystatechange", completed );
-
- // A fallback to window.onload, that will always work
- window.attachEvent( "onload", completed );
-
- // If IE and not a frame
- // continually check to see if the document is ready
- var top = false;
-
- try {
- top = window.frameElement == null && document.documentElement;
- } catch(e) {}
-
- if ( top && top.doScroll ) {
- (function doScrollCheck() {
- if ( !jQuery.isReady ) {
-
- try {
- // Use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- top.doScroll("left");
- } catch(e) {
- return setTimeout( doScrollCheck, 50 );
- }
-
- // detach all dom ready events
- detach();
-
- // and execute any waiting functions
- jQuery.ready();
- }
- })();
- }
- }
- }
- return readyList.promise( obj );
-};
-
-
-var strundefined = typeof undefined;
-
-
-
-// Support: IE<9
-// Iteration over object's inherited properties before its own
-var i;
-for ( i in jQuery( support ) ) {
- break;
-}
-support.ownLast = i !== "0";
-
-// Note: most support tests are defined in their respective modules.
-// false until the test is run
-support.inlineBlockNeedsLayout = false;
-
-// Execute ASAP in case we need to set body.style.zoom
-jQuery(function() {
- // Minified: var a,b,c,d
- var val, div, body, container;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Return for frameset docs that don't have a body
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- if ( typeof div.style.zoom !== strundefined ) {
- // Support: IE<8
- // Check if natively block-level elements act like inline-block
- // elements when setting their display to 'inline' and giving
- // them layout
- div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
-
- support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
- if ( val ) {
- // Prevent IE 6 from affecting layout for positioned elements #11048
- // Prevent IE from shrinking the body in IE 7 mode #12869
- // Support: IE<8
- body.style.zoom = 1;
- }
- }
-
- body.removeChild( container );
-});
-
-
-
-
-(function() {
- var div = document.createElement( "div" );
-
- // Execute the test only if not already executed in another module.
- if (support.deleteExpando == null) {
- // Support: IE<9
- support.deleteExpando = true;
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
- }
- }
-
- // Null elements to avoid leaks in IE.
- div = null;
-})();
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( elem ) {
- var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
- nodeType = +elem.nodeType || 1;
-
- // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
- return nodeType !== 1 && nodeType !== 9 ?
- false :
-
- // Nodes accept data unless otherwise specified; rejection can be conditional
- !noData || noData !== true && elem.getAttribute("classid") === noData;
-};
-
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /([A-Z])/g;
-
-function dataAttr( elem, key, data ) {
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
-
- var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
-
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- jQuery.data( elem, key, data );
-
- } else {
- data = undefined;
- }
- }
-
- return data;
-}
-
-// checks a cache object for emptiness
-function isEmptyDataObject( obj ) {
- var name;
- for ( name in obj ) {
-
- // if the public data object is empty, the private is still empty
- if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
- continue;
- }
- if ( name !== "toJSON" ) {
- return false;
- }
- }
-
- return true;
-}
-
-function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var ret, thisCache,
- internalKey = jQuery.expando,
-
- // We have to handle DOM nodes and JS objects differently because IE6-7
- // can't GC object references properly across the DOM-JS boundary
- isNode = elem.nodeType,
-
- // Only DOM nodes need the global jQuery cache; JS object data is
- // attached directly to the object so GC can occur automatically
- cache = isNode ? jQuery.cache : elem,
-
- // Only defining an ID for JS objects if its cache already exists allows
- // the code to shortcut on the same path as a DOM node with no cache
- id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
-
- // Avoid doing any more work than we need to when trying to get data on an
- // object that has no data at all
- if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
- return;
- }
-
- if ( !id ) {
- // Only DOM nodes need a new unique ID for each element since their data
- // ends up in the global cache
- if ( isNode ) {
- id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
- } else {
- id = internalKey;
- }
- }
-
- if ( !cache[ id ] ) {
- // Avoid exposing jQuery metadata on plain JS objects when the object
- // is serialized using JSON.stringify
- cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
- }
-
- // An object can be passed to jQuery.data instead of a key/value pair; this gets
- // shallow copied over onto the existing cache
- if ( typeof name === "object" || typeof name === "function" ) {
- if ( pvt ) {
- cache[ id ] = jQuery.extend( cache[ id ], name );
- } else {
- cache[ id ].data = jQuery.extend( cache[ id ].data, name );
- }
- }
-
- thisCache = cache[ id ];
-
- // jQuery data() is stored in a separate object inside the object's internal data
- // cache in order to avoid key collisions between internal data and user-defined
- // data.
- if ( !pvt ) {
- if ( !thisCache.data ) {
- thisCache.data = {};
- }
-
- thisCache = thisCache.data;
- }
-
- if ( data !== undefined ) {
- thisCache[ jQuery.camelCase( name ) ] = data;
- }
-
- // Check for both converted-to-camel and non-converted data property names
- // If a data property was specified
- if ( typeof name === "string" ) {
-
- // First Try to find as-is property data
- ret = thisCache[ name ];
-
- // Test for null|undefined property data
- if ( ret == null ) {
-
- // Try to find the camelCased property
- ret = thisCache[ jQuery.camelCase( name ) ];
- }
- } else {
- ret = thisCache;
- }
-
- return ret;
-}
-
-function internalRemoveData( elem, name, pvt ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var thisCache, i,
- isNode = elem.nodeType,
-
- // See jQuery.data for more information
- cache = isNode ? jQuery.cache : elem,
- id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
-
- // If there is already no cache entry for this object, there is no
- // purpose in continuing
- if ( !cache[ id ] ) {
- return;
- }
-
- if ( name ) {
-
- thisCache = pvt ? cache[ id ] : cache[ id ].data;
-
- if ( thisCache ) {
-
- // Support array or space separated string names for data keys
- if ( !jQuery.isArray( name ) ) {
-
- // try the string as a key before any manipulation
- if ( name in thisCache ) {
- name = [ name ];
- } else {
-
- // split the camel cased version by spaces unless a key with the spaces exists
- name = jQuery.camelCase( name );
- if ( name in thisCache ) {
- name = [ name ];
- } else {
- name = name.split(" ");
- }
- }
- } else {
- // If "name" is an array of keys...
- // When data is initially created, via ("key", "val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument path.
- name = name.concat( jQuery.map( name, jQuery.camelCase ) );
- }
-
- i = name.length;
- while ( i-- ) {
- delete thisCache[ name[i] ];
- }
-
- // If there is no data left in the cache, we want to continue
- // and let the cache object itself get destroyed
- if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
- return;
- }
- }
- }
-
- // See jQuery.data for more information
- if ( !pvt ) {
- delete cache[ id ].data;
-
- // Don't destroy the parent cache unless the internal data object
- // had been the only thing left in it
- if ( !isEmptyDataObject( cache[ id ] ) ) {
- return;
- }
- }
-
- // Destroy the cache
- if ( isNode ) {
- jQuery.cleanData( [ elem ], true );
-
- // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
- /* jshint eqeqeq: false */
- } else if ( support.deleteExpando || cache != cache.window ) {
- /* jshint eqeqeq: true */
- delete cache[ id ];
-
- // When all else fails, null
- } else {
- cache[ id ] = null;
- }
-}
-
-jQuery.extend({
- cache: {},
-
- // The following elements (space-suffixed to avoid Object.prototype collisions)
- // throw uncatchable exceptions if you attempt to set expando properties
- noData: {
- "applet ": true,
- "embed ": true,
- // ...but Flash objects (which have this classid) *can* handle expandos
- "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
- },
-
- hasData: function( elem ) {
- elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
- return !!elem && !isEmptyDataObject( elem );
- },
-
- data: function( elem, name, data ) {
- return internalData( elem, name, data );
- },
-
- removeData: function( elem, name ) {
- return internalRemoveData( elem, name );
- },
-
- // For internal use only.
- _data: function( elem, name, data ) {
- return internalData( elem, name, data, true );
- },
-
- _removeData: function( elem, name ) {
- return internalRemoveData( elem, name, true );
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var i, name, data,
- elem = this[0],
- attrs = elem && elem.attributes;
-
- // Special expections of .data basically thwart jQuery.access,
- // so implement the relevant behavior ourselves
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = jQuery.data( elem );
-
- if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
-
- // Support: IE11+
- // The attrs elements can be null (#14894)
- if ( attrs[ i ] ) {
- name = attrs[ i ].name;
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice(5) );
- dataAttr( elem, name, data[ name ] );
- }
- }
- }
- jQuery._data( elem, "parsedAttrs", true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each(function() {
- jQuery.data( this, key );
- });
- }
-
- return arguments.length > 1 ?
-
- // Sets one value
- this.each(function() {
- jQuery.data( this, key, value );
- }) :
-
- // Gets one value
- // Try to fetch any internally stored data first
- elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
- },
-
- removeData: function( key ) {
- return this.each(function() {
- jQuery.removeData( this, key );
- });
- }
-});
-
-
-jQuery.extend({
- queue: function( elem, type, data ) {
- var queue;
-
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = jQuery._data( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !queue || jQuery.isArray(data) ) {
- queue = jQuery._data( elem, type, jQuery.makeArray(data) );
- } else {
- queue.push( data );
- }
- }
- return queue || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
-
- if ( fn ) {
-
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- // clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
- }
- },
-
- // not intended for public consumption - generates a queueHooks object, or returns the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return jQuery._data( elem, key ) || jQuery._data( elem, key, {
- empty: jQuery.Callbacks("once memory").add(function() {
- jQuery._removeData( elem, type + "queue" );
- jQuery._removeData( elem, key );
- })
- });
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
- }
-
- return data === undefined ?
- this :
- this.each(function() {
- var queue = jQuery.queue( this, type, data );
-
- // ensure a hooks for this queue
- jQuery._queueHooks( this, type );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
- }
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
-
- while ( i-- ) {
- tmp = jQuery._data( elements[ i ], type + "queueHooks" );
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
- }
- }
- resolve();
- return defer.promise( obj );
- }
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
- // isHidden might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
- };
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- length = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < length; i++ ) {
- fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- length ? fn( elems[0], key ) : emptyGet;
-};
-var rcheckableType = (/^(?:checkbox|radio)$/i);
-
-
-
-(function() {
- // Minified: var a,b,c
- var input = document.createElement( "input" ),
- div = document.createElement( "div" ),
- fragment = document.createDocumentFragment();
-
- // Setup
- div.innerHTML = " a ";
-
- // IE strips leading whitespace when .innerHTML is used
- support.leadingWhitespace = div.firstChild.nodeType === 3;
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- support.tbody = !div.getElementsByTagName( "tbody" ).length;
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
-
- // Makes sure cloning an html5 element does not cause problems
- // Where outerHTML is undefined, this still works
- support.html5Clone =
- document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>";
-
- // Check if a disconnected checkbox will retain its checked
- // value of true after appended to the DOM (IE6/7)
- input.type = "checkbox";
- input.checked = true;
- fragment.appendChild( input );
- support.appendChecked = input.checked;
-
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- // Support: IE6-IE11+
- div.innerHTML = "";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-
- // #11217 - WebKit loses check when the name is after the checked attribute
- fragment.appendChild( div );
- div.innerHTML = " ";
-
- // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
- // old WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Support: IE<9
- // Opera does not clone events (and typeof div.attachEvent === undefined).
- // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
- support.noCloneEvent = true;
- if ( div.attachEvent ) {
- div.attachEvent( "onclick", function() {
- support.noCloneEvent = false;
- });
-
- div.cloneNode( true ).click();
- }
-
- // Execute the test only if not already executed in another module.
- if (support.deleteExpando == null) {
- // Support: IE<9
- support.deleteExpando = true;
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
- }
- }
-})();
-
-
-(function() {
- var i, eventName,
- div = document.createElement( "div" );
-
- // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
- for ( i in { submit: true, change: true, focusin: true }) {
- eventName = "on" + i;
-
- if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
- // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
- div.setAttribute( eventName, "t" );
- support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
- }
- }
-
- // Null elements to avoid leaks in IE.
- div = null;
-})();
-
-
-var rformElems = /^(?:input|select|textarea)$/i,
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
-
-function returnTrue() {
- return true;
-}
-
-function returnFalse() {
- return false;
-}
-
-function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
- global: {},
-
- add: function( elem, types, handler, data, selector ) {
- var tmp, events, t, handleObjIn,
- special, eventHandle, handleObj,
- handlers, type, namespaces, origType,
- elemData = jQuery._data( elem );
-
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if ( !elemData ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this is the first
- if ( !(events = elemData.events) ) {
- events = elemData.events = {};
- }
- if ( !(eventHandle = elemData.handle) ) {
- eventHandle = elemData.handle = function( e ) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
- jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
- undefined;
- };
- // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
- eventHandle.elem = elem;
- }
-
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
- }
-
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener/attachEvent if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
- var j, handleObj, tmp,
- origCount, t, events,
- special, handlers, type,
- namespaces, origType,
- elemData = jQuery.hasData( elem ) && jQuery._data( elem );
-
- if ( !elemData || !(events = elemData.events) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType : special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
-
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
-
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
-
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- delete elemData.handle;
-
- // removeData also checks for emptiness and clears the expando if empty
- // so use it instead of delete
- jQuery._removeData( elem, "events" );
- }
- },
-
- trigger: function( event, data, elem, onlyHandlers ) {
- var handle, ontype, cur,
- bubbleType, special, tmp, i,
- eventPath = [ elem || document ],
- type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
-
- cur = tmp = elem = elem || document;
-
- // Don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf(".") >= 0 ) {
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf(":") < 0 && "on" + type;
-
- // Caller can pass in a jQuery.Event object, Object, or just an event type string
- event = event[ jQuery.expando ] ?
- event :
- new jQuery.Event( type, typeof event === "object" && event );
-
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
- null;
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the handler arg list
- data = data == null ?
- [ event ] :
- jQuery.makeArray( data, [ event ] );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
- bubbleType = special.delegateType || type;
- if ( !rfocusMorph.test( bubbleType + type ) ) {
- cur = cur.parentNode;
- }
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push( cur );
- tmp = cur;
- }
-
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
- eventPath.push( tmp.defaultView || tmp.parentWindow || window );
- }
- }
-
- // Fire handlers on the event path
- i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
-
- event.type = i > 1 ?
- bubbleType :
- special.bindType || type;
-
- // jQuery handler
- handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
-
- // Native handler
- handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
- event.result = handle.apply( cur, data );
- if ( event.result === false ) {
- event.preventDefault();
- }
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
-
- // Call a native DOM method on the target with the same name name as the event.
- // Can't use an .isFunction() check here because IE6/7 fails that test.
- // Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when we call its FOO() method
- tmp = elem[ ontype ];
-
- if ( tmp ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- try {
- elem[ type ]();
- } catch ( e ) {
- // IE<9 dies on focus/blur to hidden element (#1486,#12518)
- // only reproducible on winXP IE8 native, not IE9 in IE8 mode
- }
- jQuery.event.triggered = undefined;
-
- if ( tmp ) {
- elem[ ontype ] = tmp;
- }
- }
- }
- }
-
- return event.result;
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
-
- var i, ret, handleObj, matched, j,
- handlerQueue = [],
- args = slice.call( arguments ),
- handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
-
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
-
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
- // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
-
- j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
-
- // Triggered event must either 1) have no namespace, or
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
-
- event.handleObj = handleObj;
- event.data = handleObj.data;
-
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
-
- if ( ret !== undefined ) {
- if ( (event.result = ret) === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- handlers: function( event, handlers ) {
- var sel, handleObj, matches, i,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
-
- // Find delegate handlers
- // Black-hole SVG instance trees (#13180)
- // Avoid non-left-click bubbling in Firefox (#3861)
- if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
-
- /* jshint eqeqeq: false */
- for ( ; cur != this; cur = cur.parentNode || this ) {
- /* jshint eqeqeq: true */
-
- // Don't check non-elements (#13208)
- // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
- matches = [];
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
-
- // Don't conflict with Object.prototype properties (#13203)
- sel = handleObj.selector + " ";
-
- if ( matches[ sel ] === undefined ) {
- matches[ sel ] = handleObj.needsContext ?
- jQuery( sel, this ).index( cur ) >= 0 :
- jQuery.find( sel, this, null, [ cur ] ).length;
- }
- if ( matches[ sel ] ) {
- matches.push( handleObj );
- }
- }
- if ( matches.length ) {
- handlerQueue.push({ elem: cur, handlers: matches });
- }
- }
- }
- }
-
- // Add the remaining (directly-bound) handlers
- if ( delegateCount < handlers.length ) {
- handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
- }
-
- return handlerQueue;
- },
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: IE<9
- // Fix target property (#1925)
- if ( !event.target ) {
- event.target = originalEvent.srcElement || document;
- }
-
- // Support: Chrome 23+, Safari?
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- // Support: IE<9
- // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
- event.metaKey = !!event.metaKey;
-
- return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
- },
-
- // Includes some event props shared by KeyEvent and MouseEvent
- props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split(" "),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
- filter: function( event, original ) {
- var body, eventDoc, doc,
- button = original.button,
- fromElement = original.fromElement;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && fromElement ) {
- event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
- special: {
- load: {
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
- focus: {
- // Fire native event if possible so blur/focus sequence is correct
- trigger: function() {
- if ( this !== safeActiveElement() && this.focus ) {
- try {
- this.focus();
- return false;
- } catch ( e ) {
- // Support: IE<9
- // If we error on focus to hidden element (#1486, #12518),
- // let .trigger() run the handlers
- }
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function() {
- if ( this === safeActiveElement() && this.blur ) {
- this.blur();
- return false;
- }
- },
- delegateType: "focusout"
- },
- click: {
- // For checkbox, fire native event so checked state will be right
- trigger: function() {
- if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
- this.click();
- return false;
- }
- },
-
- // For cross-browser consistency, don't fire native .click() on links
- _default: function( event ) {
- return jQuery.nodeName( event.target, "a" );
- }
- },
-
- beforeunload: {
- postDispatch: function( event ) {
-
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue field is not set.
- if ( event.result !== undefined && event.originalEvent ) {
- event.originalEvent.returnValue = event.result;
- }
- }
- }
- },
-
- simulate: function( type, elem, event, bubble ) {
- // Piggyback on a donor event to simulate a different one.
- // Fake originalEvent to avoid donor's stopPropagation, but if the
- // simulated event prevents default then we do the same on the donor.
- var e = jQuery.extend(
- new jQuery.Event(),
- event,
- {
- type: type,
- isSimulated: true,
- originalEvent: {}
- }
- );
- if ( bubble ) {
- jQuery.event.trigger( e, null, elem );
- } else {
- jQuery.event.dispatch.call( elem, e );
- }
- if ( e.isDefaultPrevented() ) {
- event.preventDefault();
- }
- }
-};
-
-jQuery.removeEvent = document.removeEventListener ?
- function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
- } :
- function( elem, type, handle ) {
- var name = "on" + type;
-
- if ( elem.detachEvent ) {
-
- // #8545, #7054, preventing memory leaks for custom events in IE6-8
- // detachEvent needed property on element, by name of that event, to properly expose it to GC
- if ( typeof elem[ name ] === strundefined ) {
- elem[ name ] = null;
- }
-
- elem.detachEvent( name, handle );
- }
- };
-
-jQuery.Event = function( src, props ) {
- // Allow instantiation without the 'new' keyword
- if ( !(this instanceof jQuery.Event) ) {
- return new jQuery.Event( src, props );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented ||
- src.defaultPrevented === undefined &&
- // Support: IE < 9, Android < 4.0
- src.returnValue === false ?
- returnTrue :
- returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
- }
-
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
-
- preventDefault: function() {
- var e = this.originalEvent;
-
- this.isDefaultPrevented = returnTrue;
- if ( !e ) {
- return;
- }
-
- // If preventDefault exists, run it on the original event
- if ( e.preventDefault ) {
- e.preventDefault();
-
- // Support: IE
- // Otherwise set the returnValue property of the original event to false
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function() {
- var e = this.originalEvent;
-
- this.isPropagationStopped = returnTrue;
- if ( !e ) {
- return;
- }
- // If stopPropagation exists, run it on the original event
- if ( e.stopPropagation ) {
- e.stopPropagation();
- }
-
- // Support: IE
- // Set the cancelBubble property of the original event to true
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- var e = this.originalEvent;
-
- this.isImmediatePropagationStopped = returnTrue;
-
- if ( e && e.stopImmediatePropagation ) {
- e.stopImmediatePropagation();
- }
-
- this.stopPropagation();
- }
-};
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
-
- handle: function( event ) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj;
-
- // For mousenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments );
- event.type = fix;
- }
- return ret;
- }
- };
-});
-
-// IE submit delegation
-if ( !support.submitBubbles ) {
-
- jQuery.event.special.submit = {
- setup: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Lazy-add a submit handler when a descendant form may potentially be submitted
- jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
- // Node name check avoids a VML-related crash in IE (#9807)
- var elem = e.target,
- form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
- if ( form && !jQuery._data( form, "submitBubbles" ) ) {
- jQuery.event.add( form, "submit._submit", function( event ) {
- event._submit_bubble = true;
- });
- jQuery._data( form, "submitBubbles", true );
- }
- });
- // return undefined since we don't need an event listener
- },
-
- postDispatch: function( event ) {
- // If form was submitted by the user, bubble the event up the tree
- if ( event._submit_bubble ) {
- delete event._submit_bubble;
- if ( this.parentNode && !event.isTrigger ) {
- jQuery.event.simulate( "submit", this.parentNode, event, true );
- }
- }
- },
-
- teardown: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
- jQuery.event.remove( this, "._submit" );
- }
- };
-}
-
-// IE change delegation and checkbox/radio fix
-if ( !support.changeBubbles ) {
-
- jQuery.event.special.change = {
-
- setup: function() {
-
- if ( rformElems.test( this.nodeName ) ) {
- // IE doesn't fire change on a check/radio until blur; trigger it on click
- // after a propertychange. Eat the blur-change in special.change.handle.
- // This still fires onchange a second time for check/radio after blur.
- if ( this.type === "checkbox" || this.type === "radio" ) {
- jQuery.event.add( this, "propertychange._change", function( event ) {
- if ( event.originalEvent.propertyName === "checked" ) {
- this._just_changed = true;
- }
- });
- jQuery.event.add( this, "click._change", function( event ) {
- if ( this._just_changed && !event.isTrigger ) {
- this._just_changed = false;
- }
- // Allow triggered, simulated change events (#11500)
- jQuery.event.simulate( "change", this, event, true );
- });
- }
- return false;
- }
- // Delegated event; lazy-add a change handler on descendant inputs
- jQuery.event.add( this, "beforeactivate._change", function( e ) {
- var elem = e.target;
-
- if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
- jQuery.event.add( elem, "change._change", function( event ) {
- if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
- jQuery.event.simulate( "change", this.parentNode, event, true );
- }
- });
- jQuery._data( elem, "changeBubbles", true );
- }
- });
- },
-
- handle: function( event ) {
- var elem = event.target;
-
- // Swallow native change events from checkbox/radio, we already triggered them above
- if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
- return event.handleObj.handler.apply( this, arguments );
- }
- },
-
- teardown: function() {
- jQuery.event.remove( this, "._change" );
-
- return !rformElems.test( this.nodeName );
- }
- };
-}
-
-// Create "bubbling" focus and blur events
-if ( !support.focusinBubbles ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
- // Attach a single capturing handler on the document while someone wants focusin/focusout
- var handler = function( event ) {
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
- };
-
- jQuery.event.special[ fix ] = {
- setup: function() {
- var doc = this.ownerDocument || this,
- attaches = jQuery._data( doc, fix );
-
- if ( !attaches ) {
- doc.addEventListener( orig, handler, true );
- }
- jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
- },
- teardown: function() {
- var doc = this.ownerDocument || this,
- attaches = jQuery._data( doc, fix ) - 1;
-
- if ( !attaches ) {
- doc.removeEventListener( orig, handler, true );
- jQuery._removeData( doc, fix );
- } else {
- jQuery._data( doc, fix, attaches );
- }
- }
- };
- });
-}
-
-jQuery.fn.extend({
-
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var type, origFn;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- this.on( type, selector, data, types[ type ], one );
- }
- return this;
- }
-
- if ( data == null && fn == null ) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return this;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return this.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- });
- },
- one: function( types, selector, data, fn ) {
- return this.on( types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- var handleObj, type;
- if ( types && types.preventDefault && types.handleObj ) {
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
- }
- if ( typeof types === "object" ) {
- // ( types-object [, selector] )
- for ( type in types ) {
- this.off( type, selector, types[ type ] );
- }
- return this;
- }
- if ( selector === false || typeof selector === "function" ) {
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if ( fn === false ) {
- fn = returnFalse;
- }
- return this.each(function() {
- jQuery.event.remove( this, types, fn, selector );
- });
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
- triggerHandler: function( type, data ) {
- var elem = this[0];
- if ( elem ) {
- return jQuery.event.trigger( type, data, elem, true );
- }
- }
-});
-
-
-function createSafeFragment( document ) {
- var list = nodeNames.split( "|" ),
- safeFrag = document.createDocumentFragment();
-
- if ( safeFrag.createElement ) {
- while ( list.length ) {
- safeFrag.createElement(
- list.pop()
- );
- }
- }
- return safeFrag;
-}
-
-var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
- "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
- rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
- rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
- rtagName = /<([\w:]+)/,
- rtbody = /\s*$/g,
-
- // We have to close these tags to support XHTML (#13200)
- wrapMap = {
- option: [ 1, "", " " ],
- legend: [ 1, "", " " ],
- area: [ 1, "", " " ],
- param: [ 1, "", " " ],
- thead: [ 1, "" ],
- tr: [ 2, "" ],
- col: [ 2, "" ],
- td: [ 3, "" ],
-
- // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
- // unless wrapped in a div with non-breaking characters in front of it.
- _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X", "
" ]
- },
- safeFragment = createSafeFragment( document ),
- fragmentDiv = safeFragment.appendChild( document.createElement("div") );
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-function getAll( context, tag ) {
- var elems, elem,
- i = 0,
- found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
- typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
- undefined;
-
- if ( !found ) {
- for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
- if ( !tag || jQuery.nodeName( elem, tag ) ) {
- found.push( elem );
- } else {
- jQuery.merge( found, getAll( elem, tag ) );
- }
- }
- }
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], found ) :
- found;
-}
-
-// Used in buildFragment, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
- if ( rcheckableType.test( elem.type ) ) {
- elem.defaultChecked = elem.checked;
- }
-}
-
-// Support: IE<8
-// Manipulating tables requires a tbody
-function manipulationTarget( elem, content ) {
- return jQuery.nodeName( elem, "table" ) &&
- jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
-
- elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
- elem;
-}
-
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
- elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
- return elem;
-}
-function restoreScript( elem ) {
- var match = rscriptTypeMasked.exec( elem.type );
- if ( match ) {
- elem.type = match[1];
- } else {
- elem.removeAttribute("type");
- }
- return elem;
-}
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
- var elem,
- i = 0;
- for ( ; (elem = elems[i]) != null; i++ ) {
- jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
- }
-}
-
-function cloneCopyEvent( src, dest ) {
-
- if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
- return;
- }
-
- var type, i, l,
- oldData = jQuery._data( src ),
- curData = jQuery._data( dest, oldData ),
- events = oldData.events;
-
- if ( events ) {
- delete curData.handle;
- curData.events = {};
-
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
- jQuery.event.add( dest, type, events[ type ][ i ] );
- }
- }
- }
-
- // make the cloned public data object a copy from the original
- if ( curData.data ) {
- curData.data = jQuery.extend( {}, curData.data );
- }
-}
-
-function fixCloneNodeIssues( src, dest ) {
- var nodeName, e, data;
-
- // We do not need to do anything for non-Elements
- if ( dest.nodeType !== 1 ) {
- return;
- }
-
- nodeName = dest.nodeName.toLowerCase();
-
- // IE6-8 copies events bound via attachEvent when using cloneNode.
- if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
- data = jQuery._data( dest );
-
- for ( e in data.events ) {
- jQuery.removeEvent( dest, e, data.handle );
- }
-
- // Event data gets referenced instead of copied if the expando gets copied too
- dest.removeAttribute( jQuery.expando );
- }
-
- // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
- if ( nodeName === "script" && dest.text !== src.text ) {
- disableScript( dest ).text = src.text;
- restoreScript( dest );
-
- // IE6-10 improperly clones children of object elements using classid.
- // IE10 throws NoModificationAllowedError if parent is null, #12132.
- } else if ( nodeName === "object" ) {
- if ( dest.parentNode ) {
- dest.outerHTML = src.outerHTML;
- }
-
- // This path appears unavoidable for IE9. When cloning an object
- // element in IE9, the outerHTML strategy above is not sufficient.
- // If the src has innerHTML and the destination does not,
- // copy the src.innerHTML into the dest.innerHTML. #10324
- if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
- dest.innerHTML = src.innerHTML;
- }
-
- } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
- // IE6-8 fails to persist the checked state of a cloned checkbox
- // or radio button. Worse, IE6-7 fail to give the cloned element
- // a checked appearance if the defaultChecked value isn't also set
-
- dest.defaultChecked = dest.checked = src.checked;
-
- // IE6-7 get confused and end up setting the value of a cloned
- // checkbox/radio button to an empty string instead of "on"
- if ( dest.value !== src.value ) {
- dest.value = src.value;
- }
-
- // IE6-8 fails to return the selected option to the default selected
- // state when cloning options
- } else if ( nodeName === "option" ) {
- dest.defaultSelected = dest.selected = src.defaultSelected;
-
- // IE6-8 fails to set the defaultValue to the correct value when
- // cloning other types of input fields
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
- }
-}
-
-jQuery.extend({
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var destElements, node, clone, i, srcElements,
- inPage = jQuery.contains( elem.ownerDocument, elem );
-
- if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
- clone = elem.cloneNode( true );
-
- // IE<=8 does not properly clone detached, unknown element nodes
- } else {
- fragmentDiv.innerHTML = elem.outerHTML;
- fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
- }
-
- if ( (!support.noCloneEvent || !support.noCloneChecked) &&
- (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
-
- // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
- destElements = getAll( clone );
- srcElements = getAll( elem );
-
- // Fix all IE cloning issues
- for ( i = 0; (node = srcElements[i]) != null; ++i ) {
- // Ensure that the destination node is not null; Fixes #9587
- if ( destElements[i] ) {
- fixCloneNodeIssues( node, destElements[i] );
- }
- }
- }
-
- // Copy the events from the original to the clone
- if ( dataAndEvents ) {
- if ( deepDataAndEvents ) {
- srcElements = srcElements || getAll( elem );
- destElements = destElements || getAll( clone );
-
- for ( i = 0; (node = srcElements[i]) != null; i++ ) {
- cloneCopyEvent( node, destElements[i] );
- }
- } else {
- cloneCopyEvent( elem, clone );
- }
- }
-
- // Preserve script evaluation history
- destElements = getAll( clone, "script" );
- if ( destElements.length > 0 ) {
- setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
- }
-
- destElements = srcElements = node = null;
-
- // Return the cloned set
- return clone;
- },
-
- buildFragment: function( elems, context, scripts, selection ) {
- var j, elem, contains,
- tmp, tag, tbody, wrap,
- l = elems.length,
-
- // Ensure a safe fragment
- safe = createSafeFragment( context ),
-
- nodes = [],
- i = 0;
-
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
-
- if ( elem || elem === 0 ) {
-
- // Add nodes directly
- if ( jQuery.type( elem ) === "object" ) {
- jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
- // Convert non-html into a text node
- } else if ( !rhtml.test( elem ) ) {
- nodes.push( context.createTextNode( elem ) );
-
- // Convert html into DOM nodes
- } else {
- tmp = tmp || safe.appendChild( context.createElement("div") );
-
- // Deserialize a standard representation
- tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
- wrap = wrapMap[ tag ] || wrapMap._default;
-
- tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>$2>" ) + wrap[2];
-
- // Descend through wrappers to the right content
- j = wrap[0];
- while ( j-- ) {
- tmp = tmp.lastChild;
- }
-
- // Manually add leading whitespace removed by IE
- if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
- nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
- }
-
- // Remove IE's autoinserted from table fragments
- if ( !support.tbody ) {
-
- // String was a , *may* have spurious
- elem = tag === "table" && !rtbody.test( elem ) ?
- tmp.firstChild :
-
- // String was a bare or
- wrap[1] === "" && !rtbody.test( elem ) ?
- tmp :
- 0;
-
- j = elem && elem.childNodes.length;
- while ( j-- ) {
- if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
- elem.removeChild( tbody );
- }
- }
- }
-
- jQuery.merge( nodes, tmp.childNodes );
-
- // Fix #12392 for WebKit and IE > 9
- tmp.textContent = "";
-
- // Fix #12392 for oldIE
- while ( tmp.firstChild ) {
- tmp.removeChild( tmp.firstChild );
- }
-
- // Remember the top-level container for proper cleanup
- tmp = safe.lastChild;
- }
- }
- }
-
- // Fix #11356: Clear elements from fragment
- if ( tmp ) {
- safe.removeChild( tmp );
- }
-
- // Reset defaultChecked for any radios and checkboxes
- // about to be appended to the DOM in IE 6/7 (#8060)
- if ( !support.appendChecked ) {
- jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
- }
-
- i = 0;
- while ( (elem = nodes[ i++ ]) ) {
-
- // #4087 - If origin and destination elements are the same, and this is
- // that element, do not do anything
- if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
- continue;
- }
-
- contains = jQuery.contains( elem.ownerDocument, elem );
-
- // Append to fragment
- tmp = getAll( safe.appendChild( elem ), "script" );
-
- // Preserve script evaluation history
- if ( contains ) {
- setGlobalEval( tmp );
- }
-
- // Capture executables
- if ( scripts ) {
- j = 0;
- while ( (elem = tmp[ j++ ]) ) {
- if ( rscriptType.test( elem.type || "" ) ) {
- scripts.push( elem );
- }
- }
- }
- }
-
- tmp = null;
-
- return safe;
- },
-
- cleanData: function( elems, /* internal */ acceptData ) {
- var elem, type, id, data,
- i = 0,
- internalKey = jQuery.expando,
- cache = jQuery.cache,
- deleteExpando = support.deleteExpando,
- special = jQuery.event.special;
-
- for ( ; (elem = elems[i]) != null; i++ ) {
- if ( acceptData || jQuery.acceptData( elem ) ) {
-
- id = elem[ internalKey ];
- data = id && cache[ id ];
-
- if ( data ) {
- if ( data.events ) {
- for ( type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
-
- // This is a shortcut to avoid jQuery.event.remove's overhead
- } else {
- jQuery.removeEvent( elem, type, data.handle );
- }
- }
- }
-
- // Remove cache only if it was not already removed by jQuery.event.remove
- if ( cache[ id ] ) {
-
- delete cache[ id ];
-
- // IE does not allow us to delete expando properties from nodes,
- // nor does it have a removeAttribute function on Document nodes;
- // we must handle all of these cases
- if ( deleteExpando ) {
- delete elem[ internalKey ];
-
- } else if ( typeof elem.removeAttribute !== strundefined ) {
- elem.removeAttribute( internalKey );
-
- } else {
- elem[ internalKey ] = null;
- }
-
- deletedIds.push( id );
- }
- }
- }
- }
- }
-});
-
-jQuery.fn.extend({
- text: function( value ) {
- return access( this, function( value ) {
- return value === undefined ?
- jQuery.text( this ) :
- this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
- }, null, value, arguments.length );
- },
-
- append: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.appendChild( elem );
- }
- });
- },
-
- prepend: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.insertBefore( elem, target.firstChild );
- }
- });
- },
-
- before: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this );
- }
- });
- },
-
- after: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this.nextSibling );
- }
- });
- },
-
- remove: function( selector, keepData /* Internal Use Only */ ) {
- var elem,
- elems = selector ? jQuery.filter( selector, this ) : this,
- i = 0;
-
- for ( ; (elem = elems[i]) != null; i++ ) {
-
- if ( !keepData && elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem ) );
- }
-
- if ( elem.parentNode ) {
- if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
- setGlobalEval( getAll( elem, "script" ) );
- }
- elem.parentNode.removeChild( elem );
- }
- }
-
- return this;
- },
-
- empty: function() {
- var elem,
- i = 0;
-
- for ( ; (elem = this[i]) != null; i++ ) {
- // Remove element nodes and prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem, false ) );
- }
-
- // Remove any remaining nodes
- while ( elem.firstChild ) {
- elem.removeChild( elem.firstChild );
- }
-
- // If this is a select, ensure that it displays empty (#12336)
- // Support: IE<9
- if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
- elem.options.length = 0;
- }
- }
-
- return this;
- },
-
- clone: function( dataAndEvents, deepDataAndEvents ) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
- return this.map(function() {
- return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
- });
- },
-
- html: function( value ) {
- return access( this, function( value ) {
- var elem = this[ 0 ] || {},
- i = 0,
- l = this.length;
-
- if ( value === undefined ) {
- return elem.nodeType === 1 ?
- elem.innerHTML.replace( rinlinejQuery, "" ) :
- undefined;
- }
-
- // See if we can take a shortcut and just use innerHTML
- if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
- ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
- ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
- !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
-
- value = value.replace( rxhtmlTag, "<$1>$2>" );
-
- try {
- for (; i < l; i++ ) {
- // Remove element nodes and prevent memory leaks
- elem = this[i] || {};
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem, false ) );
- elem.innerHTML = value;
- }
- }
-
- elem = 0;
-
- // If using innerHTML throws an exception, use the fallback method
- } catch(e) {}
- }
-
- if ( elem ) {
- this.empty().append( value );
- }
- }, null, value, arguments.length );
- },
-
- replaceWith: function() {
- var arg = arguments[ 0 ];
-
- // Make the changes, replacing each context element with the new content
- this.domManip( arguments, function( elem ) {
- arg = this.parentNode;
-
- jQuery.cleanData( getAll( this ) );
-
- if ( arg ) {
- arg.replaceChild( elem, this );
- }
- });
-
- // Force removal if there was no new content (e.g., from empty arguments)
- return arg && (arg.length || arg.nodeType) ? this : this.remove();
- },
-
- detach: function( selector ) {
- return this.remove( selector, true );
- },
-
- domManip: function( args, callback ) {
-
- // Flatten any nested arrays
- args = concat.apply( [], args );
-
- var first, node, hasScripts,
- scripts, doc, fragment,
- i = 0,
- l = this.length,
- set = this,
- iNoClone = l - 1,
- value = args[0],
- isFunction = jQuery.isFunction( value );
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( isFunction ||
- ( l > 1 && typeof value === "string" &&
- !support.checkClone && rchecked.test( value ) ) ) {
- return this.each(function( index ) {
- var self = set.eq( index );
- if ( isFunction ) {
- args[0] = value.call( this, index, self.html() );
- }
- self.domManip( args, callback );
- });
- }
-
- if ( l ) {
- fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
- first = fragment.firstChild;
-
- if ( fragment.childNodes.length === 1 ) {
- fragment = first;
- }
-
- if ( first ) {
- scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
- hasScripts = scripts.length;
-
- // Use the original fragment for the last item instead of the first because it can end up
- // being emptied incorrectly in certain situations (#8070).
- for ( ; i < l; i++ ) {
- node = fragment;
-
- if ( i !== iNoClone ) {
- node = jQuery.clone( node, true, true );
-
- // Keep references to cloned scripts for later restoration
- if ( hasScripts ) {
- jQuery.merge( scripts, getAll( node, "script" ) );
- }
- }
-
- callback.call( this[i], node, i );
- }
-
- if ( hasScripts ) {
- doc = scripts[ scripts.length - 1 ].ownerDocument;
-
- // Reenable scripts
- jQuery.map( scripts, restoreScript );
-
- // Evaluate executable scripts on first document insertion
- for ( i = 0; i < hasScripts; i++ ) {
- node = scripts[ i ];
- if ( rscriptType.test( node.type || "" ) &&
- !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
-
- if ( node.src ) {
- // Optional AJAX dependency, but won't run scripts if not present
- if ( jQuery._evalUrl ) {
- jQuery._evalUrl( node.src );
- }
- } else {
- jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
- }
- }
- }
- }
-
- // Fix #11809: Avoid leaking memory
- fragment = first = null;
- }
- }
-
- return this;
- }
-});
-
-jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
-}, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var elems,
- i = 0,
- ret = [],
- insert = jQuery( selector ),
- last = insert.length - 1;
-
- for ( ; i <= last; i++ ) {
- elems = i === last ? this : this.clone(true);
- jQuery( insert[i] )[ original ]( elems );
-
- // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
- push.apply( ret, elems.get() );
- }
-
- return this.pushStack( ret );
- };
-});
-
-
-var iframe,
- elemdisplay = {};
-
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
- var style,
- elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
- // getDefaultComputedStyle might be reliably used only on attached element
- display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
-
- // Use of this method is a temporary fix (more like optmization) until something better comes along,
- // since it was removed from specification and supported only in FF
- style.display : jQuery.css( elem[ 0 ], "display" );
-
- // We don't have any data stored on the element,
- // so use "detach" method as fast way to get rid of the element
- elem.detach();
-
- return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
- var doc = document,
- display = elemdisplay[ nodeName ];
-
- if ( !display ) {
- display = actualDisplay( nodeName, doc );
-
- // If the simple way fails, read from inside an iframe
- if ( display === "none" || !display ) {
-
- // Use the already-created iframe if possible
- iframe = (iframe || jQuery( "" )).appendTo( doc.documentElement );
-
- // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
- doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
-
- // Support: IE
- doc.write();
- doc.close();
-
- display = actualDisplay( nodeName, doc );
- iframe.detach();
- }
-
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
- }
-
- return display;
-}
-
-
-(function() {
- var shrinkWrapBlocksVal;
-
- support.shrinkWrapBlocks = function() {
- if ( shrinkWrapBlocksVal != null ) {
- return shrinkWrapBlocksVal;
- }
-
- // Will be changed later if needed.
- shrinkWrapBlocksVal = false;
-
- // Minified: var b,c,d
- var div, body, container;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Test fired too early or in an unsupported environment, exit.
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- // Support: IE6
- // Check if elements with layout shrink-wrap their children
- if ( typeof div.style.zoom !== strundefined ) {
- // Reset CSS: box-sizing; display; margin; border
- div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
- "box-sizing:content-box;display:block;margin:0;border:0;" +
- "padding:1px;width:1px;zoom:1";
- div.appendChild( document.createElement( "div" ) ).style.width = "5px";
- shrinkWrapBlocksVal = div.offsetWidth !== 3;
- }
-
- body.removeChild( container );
-
- return shrinkWrapBlocksVal;
- };
-
-})();
-var rmargin = (/^margin/);
-
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-
-
-var getStyles, curCSS,
- rposition = /^(top|right|bottom|left)$/;
-
-if ( window.getComputedStyle ) {
- getStyles = function( elem ) {
- // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
- // IE throws on elements created in popups
- // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
- if ( elem.ownerDocument.defaultView.opener ) {
- return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
- }
-
- return window.getComputedStyle( elem, null );
- };
-
- curCSS = function( elem, name, computed ) {
- var width, minWidth, maxWidth, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
-
- // getPropertyValue is only needed for .css('filter') in IE9, see #12537
- ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
-
- if ( computed ) {
-
- if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
- ret = jQuery.style( elem, name );
- }
-
- // A tribute to the "awesome hack by Dean Edwards"
- // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
- // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
- // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
- if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
- // Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth;
-
- // Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width;
-
- // Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
- }
- }
-
- // Support: IE
- // IE returns zIndex value as an integer.
- return ret === undefined ?
- ret :
- ret + "";
- };
-} else if ( document.documentElement.currentStyle ) {
- getStyles = function( elem ) {
- return elem.currentStyle;
- };
-
- curCSS = function( elem, name, computed ) {
- var left, rs, rsLeft, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
- ret = computed ? computed[ name ] : undefined;
-
- // Avoid setting ret to empty string here
- // so we don't default to auto
- if ( ret == null && style && style[ name ] ) {
- ret = style[ name ];
- }
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- // but not position css attributes, as those are proportional to the parent element instead
- // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
- if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
-
- // Remember the original values
- left = style.left;
- rs = elem.runtimeStyle;
- rsLeft = rs && rs.left;
-
- // Put in the new values to get a computed value out
- if ( rsLeft ) {
- rs.left = elem.currentStyle.left;
- }
- style.left = name === "fontSize" ? "1em" : ret;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- if ( rsLeft ) {
- rs.left = rsLeft;
- }
- }
-
- // Support: IE
- // IE returns zIndex value as an integer.
- return ret === undefined ?
- ret :
- ret + "" || "auto";
- };
-}
-
-
-
-
-function addGetHookIf( conditionFn, hookFn ) {
- // Define the hook, we'll check on the first run if it's really needed.
- return {
- get: function() {
- var condition = conditionFn();
-
- if ( condition == null ) {
- // The test was not ready at this point; screw the hook this time
- // but check again when needed next time.
- return;
- }
-
- if ( condition ) {
- // Hook not needed (or it's not possible to use it due to missing dependency),
- // remove it.
- // Since there are no other hooks for marginRight, remove the whole object.
- delete this.get;
- return;
- }
-
- // Hook needed; redefine it so that the support test is not executed again.
-
- return (this.get = hookFn).apply( this, arguments );
- }
- };
-}
-
-
-(function() {
- // Minified: var b,c,d,e,f,g, h,i
- var div, style, a, pixelPositionVal, boxSizingReliableVal,
- reliableHiddenOffsetsVal, reliableMarginRightVal;
-
- // Setup
- div = document.createElement( "div" );
- div.innerHTML = " a ";
- a = div.getElementsByTagName( "a" )[ 0 ];
- style = a && a.style;
-
- // Finish early in limited (non-browser) environments
- if ( !style ) {
- return;
- }
-
- style.cssText = "float:left;opacity:.5";
-
- // Support: IE<9
- // Make sure that element opacity exists (as opposed to filter)
- support.opacity = style.opacity === "0.5";
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- support.cssFloat = !!style.cssFloat;
-
- div.style.backgroundClip = "content-box";
- div.cloneNode( true ).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
- style.WebkitBoxSizing === "";
-
- jQuery.extend(support, {
- reliableHiddenOffsets: function() {
- if ( reliableHiddenOffsetsVal == null ) {
- computeStyleTests();
- }
- return reliableHiddenOffsetsVal;
- },
-
- boxSizingReliable: function() {
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
- return boxSizingReliableVal;
- },
-
- pixelPosition: function() {
- if ( pixelPositionVal == null ) {
- computeStyleTests();
- }
- return pixelPositionVal;
- },
-
- // Support: Android 2.3
- reliableMarginRight: function() {
- if ( reliableMarginRightVal == null ) {
- computeStyleTests();
- }
- return reliableMarginRightVal;
- }
- });
-
- function computeStyleTests() {
- // Minified: var b,c,d,j
- var div, body, container, contents;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Test fired too early or in an unsupported environment, exit.
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
- "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
- "border:1px;padding:1px;width:4px;position:absolute";
-
- // Support: IE<9
- // Assume reasonable values in the absence of getComputedStyle
- pixelPositionVal = boxSizingReliableVal = false;
- reliableMarginRightVal = true;
-
- // Check for getComputedStyle so that this code is not run in IE<9.
- if ( window.getComputedStyle ) {
- pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
- boxSizingReliableVal =
- ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
-
- // Support: Android 2.3
- // Div with explicit width and no margin-right incorrectly
- // gets computed margin-right based on width of container (#3333)
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- contents = div.appendChild( document.createElement( "div" ) );
-
- // Reset CSS: box-sizing; display; margin; border; padding
- contents.style.cssText = div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
- "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
- contents.style.marginRight = contents.style.width = "0";
- div.style.width = "1px";
-
- reliableMarginRightVal =
- !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
-
- div.removeChild( contents );
- }
-
- // Support: IE8
- // Check if table cells still have offsetWidth/Height when they are set
- // to display:none and there are still other visible table cells in a
- // table row; if so, offsetWidth/Height are not reliable for use when
- // determining if an element has been hidden directly using
- // display:none (it is still safe to use offsets if a parent element is
- // hidden; don safety goggles and see bug #4512 for more information).
- div.innerHTML = "";
- contents = div.getElementsByTagName( "td" );
- contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
- reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
- if ( reliableHiddenOffsetsVal ) {
- contents[ 0 ].style.display = "";
- contents[ 1 ].style.display = "none";
- reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
- }
-
- body.removeChild( container );
- }
-
-})();
-
-
-// A method for quickly swapping in/out CSS properties to get correct calculations.
-jQuery.swap = function( elem, options, callback, args ) {
- var ret, name,
- old = {};
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.apply( elem, args || [] );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
-};
-
-
-var
- ralpha = /alpha\([^)]*\)/i,
- ropacity = /opacity\s*=\s*([^)]*)/,
-
- // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
- // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
- rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
- rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
-
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
- cssNormalTransform = {
- letterSpacing: "0",
- fontWeight: "400"
- },
-
- cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
-
-
-// return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( style, name ) {
-
- // shortcut for names that are not vendor prefixed
- if ( name in style ) {
- return name;
- }
-
- // check for vendor prefixed names
- var capName = name.charAt(0).toUpperCase() + name.slice(1),
- origName = name,
- i = cssPrefixes.length;
-
- while ( i-- ) {
- name = cssPrefixes[ i ] + capName;
- if ( name in style ) {
- return name;
- }
- }
-
- return origName;
-}
-
-function showHide( elements, show ) {
- var display, elem, hidden,
- values = [],
- index = 0,
- length = elements.length;
-
- for ( ; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
-
- values[ index ] = jQuery._data( elem, "olddisplay" );
- display = elem.style.display;
- if ( show ) {
- // Reset the inline display of this element to learn if it is
- // being hidden by cascaded rules or not
- if ( !values[ index ] && display === "none" ) {
- elem.style.display = "";
- }
-
- // Set elements which have been overridden with display: none
- // in a stylesheet to whatever the default browser style is
- // for such an element
- if ( elem.style.display === "" && isHidden( elem ) ) {
- values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
- }
- } else {
- hidden = isHidden( elem );
-
- if ( display && display !== "none" || !hidden ) {
- jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
- }
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( index = 0; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
- if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
- elem.style.display = show ? values[ index ] || "" : "none";
- }
- }
-
- return elements;
-}
-
-function setPositiveNumber( elem, value, subtract ) {
- var matches = rnumsplit.exec( value );
- return matches ?
- // Guard against undefined "subtract", e.g., when used as in cssHooks
- Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
- value;
-}
-
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
- // If we already have the right measurement, avoid augmentation
- 4 :
- // Otherwise initialize for horizontal or vertical properties
- name === "width" ? 1 : 0,
-
- val = 0;
-
- for ( ; i < 4; i += 2 ) {
- // both box models exclude margin, so add it if we want it
- if ( extra === "margin" ) {
- val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
- }
-
- if ( isBorderBox ) {
- // border-box includes padding, so remove it if we want content
- if ( extra === "content" ) {
- val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
- }
-
- // at this point, extra isn't border nor margin, so remove border
- if ( extra !== "margin" ) {
- val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- } else {
- // at this point, extra isn't content, so add padding
- val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
- // at this point, extra isn't content nor padding, so add border
- if ( extra !== "padding" ) {
- val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- }
- }
-
- return val;
-}
-
-function getWidthOrHeight( elem, name, extra ) {
-
- // Start with offset property, which is equivalent to the border-box value
- var valueIsBorderBox = true,
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
- styles = getStyles( elem ),
- isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
- // some non-html elements return undefined for offsetWidth, so check for null/undefined
- // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
- // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
- if ( val <= 0 || val == null ) {
- // Fall back to computed then uncomputed css if necessary
- val = curCSS( elem, name, styles );
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
- }
-
- // Computed unit is not pixels. Stop here and return.
- if ( rnumnonpx.test(val) ) {
- return val;
- }
-
- // we need the check for style in case a browser which returns unreliable values
- // for getComputedStyle silently falls back to the reliable elem.style
- valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
-
- // Normalize "", auto, and prepare for extra
- val = parseFloat( val ) || 0;
- }
-
- // use the active box-sizing model to add/subtract irrelevant styles
- return ( val +
- augmentWidthOrHeight(
- elem,
- name,
- extra || ( isBorderBox ? "border" : "content" ),
- valueIsBorderBox,
- styles
- )
- ) + "px";
-}
-
-jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
- // We should always get a number back from opacity
- var ret = curCSS( elem, "opacity" );
- return ret === "" ? "1" : ret;
- }
- }
- }
- },
-
- // Don't automatically add "px" to these possibly-unitless properties
- cssNumber: {
- "columnCount": true,
- "fillOpacity": true,
- "flexGrow": true,
- "flexShrink": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "order": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- // normalize float css property
- "float": support.cssFloat ? "cssFloat" : "styleFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, type, hooks,
- origName = jQuery.camelCase( name ),
- style = elem.style;
-
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- type = typeof value;
-
- // convert relative number strings (+= or -=) to relative numbers. #7345
- if ( type === "string" && (ret = rrelNum.exec( value )) ) {
- value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
- // Fixes bug #9237
- type = "number";
- }
-
- // Make sure that null and NaN values aren't set. See: #7116
- if ( value == null || value !== value ) {
- return;
- }
-
- // If a number was passed in, add 'px' to the (except for certain CSS properties)
- if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
- value += "px";
- }
-
- // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
- // but it would mean to define eight (for every problematic property) identical functions
- if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
- style[ name ] = "inherit";
- }
-
- // If a hook was provided, use that value, otherwise just set the specified value
- if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
-
- // Support: IE
- // Swallow errors from 'invalid' CSS values (#5509)
- try {
- style[ name ] = value;
- } catch(e) {}
- }
-
- } else {
- // If a hook was provided get the non-computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra, styles ) {
- var num, val, hooks,
- origName = jQuery.camelCase( name );
-
- // Make sure that we're working with the right name
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks ) {
- val = hooks.get( elem, true, extra );
- }
-
- // Otherwise, if a way to get the computed value exists, use that
- if ( val === undefined ) {
- val = curCSS( elem, name, styles );
- }
-
- //convert "normal" to computed value
- if ( val === "normal" && name in cssNormalTransform ) {
- val = cssNormalTransform[ name ];
- }
-
- // Return, converting to number if forced or a qualifier was provided and val looks numeric
- if ( extra === "" || extra ) {
- num = parseFloat( val );
- return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
- }
- return val;
- }
-});
-
-jQuery.each([ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
- // certain elements can have dimension info if we invisibly show them
- // however, it must have a current display style that would benefit from this
- return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
- jQuery.swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
- }) :
- getWidthOrHeight( elem, name, extra );
- }
- },
-
- set: function( elem, value, extra ) {
- var styles = extra && getStyles( elem );
- return setPositiveNumber( elem, value, extra ?
- augmentWidthOrHeight(
- elem,
- name,
- extra,
- support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
- styles
- ) : 0
- );
- }
- };
-});
-
-if ( !support.opacity ) {
- jQuery.cssHooks.opacity = {
- get: function( elem, computed ) {
- // IE uses filters for opacity
- return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
- ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
- computed ? "1" : "";
- },
-
- set: function( elem, value ) {
- var style = elem.style,
- currentStyle = elem.currentStyle,
- opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
- filter = currentStyle && currentStyle.filter || style.filter || "";
-
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- style.zoom = 1;
-
- // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
- // if value === "", then remove inline opacity #12685
- if ( ( value >= 1 || value === "" ) &&
- jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
- style.removeAttribute ) {
-
- // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
- // if "filter:" is present at all, clearType is disabled, we want to avoid this
- // style.removeAttribute is IE Only, but so apparently is this code path...
- style.removeAttribute( "filter" );
-
- // if there is no filter style applied in a css rule or unset inline opacity, we are done
- if ( value === "" || currentStyle && !currentStyle.filter ) {
- return;
- }
- }
-
- // otherwise, set new filter values
- style.filter = ralpha.test( filter ) ?
- filter.replace( ralpha, opacity ) :
- filter + " " + opacity;
- }
- };
-}
-
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
- function( elem, computed ) {
- if ( computed ) {
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- // Work around by temporarily setting element display to inline-block
- return jQuery.swap( elem, { "display": "inline-block" },
- curCSS, [ elem, "marginRight" ] );
- }
- }
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each({
- margin: "",
- padding: "",
- border: "Width"
-}, function( prefix, suffix ) {
- jQuery.cssHooks[ prefix + suffix ] = {
- expand: function( value ) {
- var i = 0,
- expanded = {},
-
- // assumes a single number if not a string
- parts = typeof value === "string" ? value.split(" ") : [ value ];
-
- for ( ; i < 4; i++ ) {
- expanded[ prefix + cssExpand[ i ] + suffix ] =
- parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
- }
-
- return expanded;
- }
- };
-
- if ( !rmargin.test( prefix ) ) {
- jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
- }
-});
-
-jQuery.fn.extend({
- css: function( name, value ) {
- return access( this, function( elem, name, value ) {
- var styles, len,
- map = {},
- i = 0;
-
- if ( jQuery.isArray( name ) ) {
- styles = getStyles( elem );
- len = name.length;
-
- for ( ; i < len; i++ ) {
- map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
- }
-
- return map;
- }
-
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- }, name, value, arguments.length > 1 );
- },
- show: function() {
- return showHide( this, true );
- },
- hide: function() {
- return showHide( this );
- },
- toggle: function( state ) {
- if ( typeof state === "boolean" ) {
- return state ? this.show() : this.hide();
- }
-
- return this.each(function() {
- if ( isHidden( this ) ) {
- jQuery( this ).show();
- } else {
- jQuery( this ).hide();
- }
- });
- }
-});
-
-
-function Tween( elem, options, prop, end, easing ) {
- return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
- constructor: Tween,
- init: function( elem, options, prop, end, easing, unit ) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || "swing";
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
- },
- cur: function() {
- var hooks = Tween.propHooks[ this.prop ];
-
- return hooks && hooks.get ?
- hooks.get( this ) :
- Tween.propHooks._default.get( this );
- },
- run: function( percent ) {
- var eased,
- hooks = Tween.propHooks[ this.prop ];
-
- if ( this.options.duration ) {
- this.pos = eased = jQuery.easing[ this.easing ](
- percent, this.options.duration * percent, 0, 1, this.options.duration
- );
- } else {
- this.pos = eased = percent;
- }
- this.now = ( this.end - this.start ) * eased + this.start;
-
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- if ( hooks && hooks.set ) {
- hooks.set( this );
- } else {
- Tween.propHooks._default.set( this );
- }
- return this;
- }
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
- _default: {
- get: function( tween ) {
- var result;
-
- if ( tween.elem[ tween.prop ] != null &&
- (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
- return tween.elem[ tween.prop ];
- }
-
- // passing an empty string as a 3rd parameter to .css will automatically
- // attempt a parseFloat and fallback to a string if the parse fails
- // so, simple values such as "10px" are parsed to Float.
- // complex values such as "rotate(1rad)" are returned as is.
- result = jQuery.css( tween.elem, tween.prop, "" );
- // Empty strings, null, undefined and "auto" are converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function( tween ) {
- // use step hook for back compat - use cssHook if its there - use .style if its
- // available and use plain properties where available
- if ( jQuery.fx.step[ tween.prop ] ) {
- jQuery.fx.step[ tween.prop ]( tween );
- } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
- jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
- } else {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- }
-};
-
-// Support: IE <=9
-// Panic based approach to setting things on disconnected nodes
-
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function( tween ) {
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
-};
-
-jQuery.easing = {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return 0.5 - Math.cos( p * Math.PI ) / 2;
- }
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
- fxNow, timerId,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
- rrun = /queueHooks$/,
- animationPrefilters = [ defaultPrefilter ],
- tweeners = {
- "*": [ function( prop, value ) {
- var tween = this.createTween( prop, value ),
- target = tween.cur(),
- parts = rfxnum.exec( value ),
- unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
- // Starting value computation is required for potential unit mismatches
- start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
- rfxnum.exec( jQuery.css( tween.elem, prop ) ),
- scale = 1,
- maxIterations = 20;
-
- if ( start && start[ 3 ] !== unit ) {
- // Trust units reported by jQuery.css
- unit = unit || start[ 3 ];
-
- // Make sure we update the tween properties later on
- parts = parts || [];
-
- // Iteratively approximate from a nonzero starting point
- start = +target || 1;
-
- do {
- // If previous iteration zeroed out, double until we get *something*
- // Use a string for doubling factor so we don't accidentally see scale as unchanged below
- scale = scale || ".5";
-
- // Adjust and apply
- start = start / scale;
- jQuery.style( tween.elem, prop, start + unit );
-
- // Update scale, tolerating zero or NaN from tween.cur()
- // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
- } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
- }
-
- // Update tween properties
- if ( parts ) {
- start = tween.start = +start || +target || 0;
- tween.unit = unit;
- // If a +=/-= token was provided, we're doing a relative animation
- tween.end = parts[ 1 ] ?
- start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
- +parts[ 2 ];
- }
-
- return tween;
- } ]
- };
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
- setTimeout(function() {
- fxNow = undefined;
- });
- return ( fxNow = jQuery.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
- var which,
- attrs = { height: type },
- i = 0;
-
- // if we include width, step value is 1 to do all cssExpand values,
- // if we don't include width, step value is 2 to skip over Left and Right
- includeWidth = includeWidth ? 1 : 0;
- for ( ; i < 4 ; i += 2 - includeWidth ) {
- which = cssExpand[ i ];
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
- }
-
- if ( includeWidth ) {
- attrs.opacity = attrs.width = type;
- }
-
- return attrs;
-}
-
-function createTween( value, prop, animation ) {
- var tween,
- collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
- index = 0,
- length = collection.length;
- for ( ; index < length; index++ ) {
- if ( (tween = collection[ index ].call( animation, prop, value )) ) {
-
- // we're done with this property
- return tween;
- }
- }
-}
-
-function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
- var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
- dataShow = jQuery._data( elem, "fxshow" );
-
- // handle queue: false promises
- if ( !opts.queue ) {
- hooks = jQuery._queueHooks( elem, "fx" );
- if ( hooks.unqueued == null ) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function() {
- if ( !hooks.unqueued ) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
-
- anim.always(function() {
- // doing this makes sure that the complete handler will be called
- // before this completes
- anim.always(function() {
- hooks.unqueued--;
- if ( !jQuery.queue( elem, "fx" ).length ) {
- hooks.empty.fire();
- }
- });
- });
- }
-
- // height/width overflow pass
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE does not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height animated
- display = jQuery.css( elem, "display" );
-
- // Test default display if display is currently "none"
- checkDisplay = display === "none" ?
- jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
-
- if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
-
- // inline-level elements accept inline-block;
- // block-level elements need to be inline with layout
- if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
- style.display = "inline-block";
- } else {
- style.zoom = 1;
- }
- }
- }
-
- if ( opts.overflow ) {
- style.overflow = "hidden";
- if ( !support.shrinkWrapBlocks() ) {
- anim.always(function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- });
- }
- }
-
- // show/hide pass
- for ( prop in props ) {
- value = props[ prop ];
- if ( rfxtypes.exec( value ) ) {
- delete props[ prop ];
- toggle = toggle || value === "toggle";
- if ( value === ( hidden ? "hide" : "show" ) ) {
-
- // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
- if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
- hidden = true;
- } else {
- continue;
- }
- }
- orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-
- // Any non-fx value stops us from restoring the original display value
- } else {
- display = undefined;
- }
- }
-
- if ( !jQuery.isEmptyObject( orig ) ) {
- if ( dataShow ) {
- if ( "hidden" in dataShow ) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = jQuery._data( elem, "fxshow", {} );
- }
-
- // store state if its toggle - enables .stop().toggle() to "reverse"
- if ( toggle ) {
- dataShow.hidden = !hidden;
- }
- if ( hidden ) {
- jQuery( elem ).show();
- } else {
- anim.done(function() {
- jQuery( elem ).hide();
- });
- }
- anim.done(function() {
- var prop;
- jQuery._removeData( elem, "fxshow" );
- for ( prop in orig ) {
- jQuery.style( elem, prop, orig[ prop ] );
- }
- });
- for ( prop in orig ) {
- tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-
- if ( !( prop in dataShow ) ) {
- dataShow[ prop ] = tween.start;
- if ( hidden ) {
- tween.end = tween.start;
- tween.start = prop === "width" || prop === "height" ? 1 : 0;
- }
- }
- }
-
- // If this is a noop like .hide().hide(), restore an overwritten display value
- } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
- style.display = display;
- }
-}
-
-function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
-
- // camelCase, specialEasing and expand cssHook pass
- for ( index in props ) {
- name = jQuery.camelCase( index );
- easing = specialEasing[ name ];
- value = props[ index ];
- if ( jQuery.isArray( value ) ) {
- easing = value[ 1 ];
- value = props[ index ] = value[ 0 ];
- }
-
- if ( index !== name ) {
- props[ name ] = value;
- delete props[ index ];
- }
-
- hooks = jQuery.cssHooks[ name ];
- if ( hooks && "expand" in hooks ) {
- value = hooks.expand( value );
- delete props[ name ];
-
- // not quite $.extend, this wont overwrite keys already present.
- // also - reusing 'index' from above because we have the correct "name"
- for ( index in value ) {
- if ( !( index in props ) ) {
- props[ index ] = value[ index ];
- specialEasing[ index ] = easing;
- }
- }
- } else {
- specialEasing[ name ] = easing;
- }
- }
-}
-
-function Animation( elem, properties, options ) {
- var result,
- stopped,
- index = 0,
- length = animationPrefilters.length,
- deferred = jQuery.Deferred().always( function() {
- // don't match elem in the :animated selector
- delete tick.elem;
- }),
- tick = function() {
- if ( stopped ) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
- // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
-
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( percent );
- }
-
- deferred.notifyWith( elem, [ animation, percent, remaining ]);
-
- if ( percent < 1 && length ) {
- return remaining;
- } else {
- deferred.resolveWith( elem, [ animation ] );
- return false;
- }
- },
- animation = deferred.promise({
- elem: elem,
- props: jQuery.extend( {}, properties ),
- opts: jQuery.extend( true, { specialEasing: {} }, options ),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function( prop, end ) {
- var tween = jQuery.Tween( elem, animation.opts, prop, end,
- animation.opts.specialEasing[ prop ] || animation.opts.easing );
- animation.tweens.push( tween );
- return tween;
- },
- stop: function( gotoEnd ) {
- var index = 0,
- // if we are going to the end, we want to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ? animation.tweens.length : 0;
- if ( stopped ) {
- return this;
- }
- stopped = true;
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( 1 );
- }
-
- // resolve when we played the last frame
- // otherwise, reject
- if ( gotoEnd ) {
- deferred.resolveWith( elem, [ animation, gotoEnd ] );
- } else {
- deferred.rejectWith( elem, [ animation, gotoEnd ] );
- }
- return this;
- }
- }),
- props = animation.props;
-
- propFilter( props, animation.opts.specialEasing );
-
- for ( ; index < length ; index++ ) {
- result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
- if ( result ) {
- return result;
- }
- }
-
- jQuery.map( props, createTween, animation );
-
- if ( jQuery.isFunction( animation.opts.start ) ) {
- animation.opts.start.call( elem, animation );
- }
-
- jQuery.fx.timer(
- jQuery.extend( tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- })
- );
-
- // attach callbacks from options
- return animation.progress( animation.opts.progress )
- .done( animation.opts.done, animation.opts.complete )
- .fail( animation.opts.fail )
- .always( animation.opts.always );
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
- tweener: function( props, callback ) {
- if ( jQuery.isFunction( props ) ) {
- callback = props;
- props = [ "*" ];
- } else {
- props = props.split(" ");
- }
-
- var prop,
- index = 0,
- length = props.length;
-
- for ( ; index < length ; index++ ) {
- prop = props[ index ];
- tweeners[ prop ] = tweeners[ prop ] || [];
- tweeners[ prop ].unshift( callback );
- }
- },
-
- prefilter: function( callback, prepend ) {
- if ( prepend ) {
- animationPrefilters.unshift( callback );
- } else {
- animationPrefilters.push( callback );
- }
- }
-});
-
-jQuery.speed = function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
- // normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function() {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- }
- };
-
- return opt;
-};
-
-jQuery.fn.extend({
- fadeTo: function( speed, to, easing, callback ) {
-
- // show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
-
- // animate to the value specified
- .end().animate({ opacity: to }, speed, easing, callback );
- },
- animate: function( prop, speed, easing, callback ) {
- var empty = jQuery.isEmptyObject( prop ),
- optall = jQuery.speed( speed, easing, callback ),
- doAnimation = function() {
- // Operate on a copy of prop so per-property easing won't be lost
- var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
- // Empty animations, or finishing resolves immediately
- if ( empty || jQuery._data( this, "finish" ) ) {
- anim.stop( true );
- }
- };
- doAnimation.finish = doAnimation;
-
- return empty || optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
- stop: function( type, clearQueue, gotoEnd ) {
- var stopQueue = function( hooks ) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop( gotoEnd );
- };
-
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each(function() {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = jQuery._data( this );
-
- if ( index ) {
- if ( data[ index ] && data[ index ].stop ) {
- stopQueue( data[ index ] );
- }
- } else {
- for ( index in data ) {
- if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
- stopQueue( data[ index ] );
- }
- }
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
- timers[ index ].anim.stop( gotoEnd );
- dequeue = false;
- timers.splice( index, 1 );
- }
- }
-
- // start the next in the queue if the last step wasn't forced
- // timers currently will call their complete callbacks, which will dequeue
- // but only if they were gotoEnd
- if ( dequeue || !gotoEnd ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- finish: function( type ) {
- if ( type !== false ) {
- type = type || "fx";
- }
- return this.each(function() {
- var index,
- data = jQuery._data( this ),
- queue = data[ type + "queue" ],
- hooks = data[ type + "queueHooks" ],
- timers = jQuery.timers,
- length = queue ? queue.length : 0;
-
- // enable finishing flag on private data
- data.finish = true;
-
- // empty the queue first
- jQuery.queue( this, type, [] );
-
- if ( hooks && hooks.stop ) {
- hooks.stop.call( this, true );
- }
-
- // look for any active animations, and finish them
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
- timers[ index ].anim.stop( true );
- timers.splice( index, 1 );
- }
- }
-
- // look for any animations in the old queue and finish them
- for ( index = 0; index < length; index++ ) {
- if ( queue[ index ] && queue[ index ].finish ) {
- queue[ index ].finish.call( this );
- }
- }
-
- // turn off finishing flag
- delete data.finish;
- });
- }
-});
-
-jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
- var cssFn = jQuery.fn[ name ];
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return speed == null || typeof speed === "boolean" ?
- cssFn.apply( this, arguments ) :
- this.animate( genFx( name, true ), speed, easing, callback );
- };
-});
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx("show"),
- slideUp: genFx("hide"),
- slideToggle: genFx("toggle"),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
- var timer,
- timers = jQuery.timers,
- i = 0;
-
- fxNow = jQuery.now();
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
- jQuery.timers.push( timer );
- if ( timer() ) {
- jQuery.fx.start();
- } else {
- jQuery.timers.pop();
- }
-};
-
-jQuery.fx.interval = 13;
-
-jQuery.fx.start = function() {
- if ( !timerId ) {
- timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
- }
-};
-
-jQuery.fx.stop = function() {
- clearInterval( timerId );
- timerId = null;
-};
-
-jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
- type = type || "fx";
-
- return this.queue( type, function( next, hooks ) {
- var timeout = setTimeout( next, time );
- hooks.stop = function() {
- clearTimeout( timeout );
- };
- });
-};
-
-
-(function() {
- // Minified: var a,b,c,d,e
- var input, div, select, a, opt;
-
- // Setup
- div = document.createElement( "div" );
- div.setAttribute( "className", "t" );
- div.innerHTML = " a ";
- a = div.getElementsByTagName("a")[ 0 ];
-
- // First batch of tests.
- select = document.createElement("select");
- opt = select.appendChild( document.createElement("option") );
- input = div.getElementsByTagName("input")[ 0 ];
-
- a.style.cssText = "top:1px";
-
- // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
- support.getSetAttribute = div.className !== "t";
-
- // Get the style information from getAttribute
- // (IE uses .cssText instead)
- support.style = /top/.test( a.getAttribute("style") );
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- support.hrefNormalized = a.getAttribute("href") === "/a";
-
- // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
- support.checkOn = !!input.value;
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- support.optSelected = opt.selected;
-
- // Tests for enctype support on a form (#6743)
- support.enctype = !!document.createElement("form").enctype;
-
- // Make sure that the options inside disabled selects aren't marked as disabled
- // (WebKit marks them as disabled)
- select.disabled = true;
- support.optDisabled = !opt.disabled;
-
- // Support: IE8 only
- // Check if we can trust getAttribute("value")
- input = document.createElement( "input" );
- input.setAttribute( "value", "" );
- support.input = input.getAttribute( "value" ) === "";
-
- // Check if an input maintains its value after becoming a radio
- input.value = "t";
- input.setAttribute( "type", "radio" );
- support.radioValue = input.value === "t";
-})();
-
-
-var rreturn = /\r/g;
-
-jQuery.fn.extend({
- val: function( value ) {
- var hooks, ret, isFunction,
- elem = this[0];
-
- if ( !arguments.length ) {
- if ( elem ) {
- hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
- return ret;
- }
-
- ret = elem.value;
-
- return typeof ret === "string" ?
- // handle most common string cases
- ret.replace(rreturn, "") :
- // handle cases where value is null/undef or number
- ret == null ? "" : ret;
- }
-
- return;
- }
-
- isFunction = jQuery.isFunction( value );
-
- return this.each(function( i ) {
- var val;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call( this, i, jQuery( this ).val() );
- } else {
- val = value;
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
- } else if ( typeof val === "number" ) {
- val += "";
- } else if ( jQuery.isArray( val ) ) {
- val = jQuery.map( val, function( value ) {
- return value == null ? "" : value + "";
- });
- }
-
- hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
- // If set returns undefined, fall back to normal setting
- if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- valHooks: {
- option: {
- get: function( elem ) {
- var val = jQuery.find.attr( elem, "value" );
- return val != null ?
- val :
- // Support: IE10-11+
- // option.text throws exceptions (#14686, #14858)
- jQuery.trim( jQuery.text( elem ) );
- }
- },
- select: {
- get: function( elem ) {
- var value, option,
- options = elem.options,
- index = elem.selectedIndex,
- one = elem.type === "select-one" || index < 0,
- values = one ? null : [],
- max = one ? index + 1 : options.length,
- i = index < 0 ?
- max :
- one ? index : 0;
-
- // Loop through all the selected options
- for ( ; i < max; i++ ) {
- option = options[ i ];
-
- // oldIE doesn't update selected after form reset (#2551)
- if ( ( option.selected || i === index ) &&
- // Don't return options that are disabled or in a disabled optgroup
- ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
- ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
-
- // Get the specific value for the option
- value = jQuery( option ).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- },
-
- set: function( elem, value ) {
- var optionSet, option,
- options = elem.options,
- values = jQuery.makeArray( value ),
- i = options.length;
-
- while ( i-- ) {
- option = options[ i ];
-
- if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
-
- // Support: IE6
- // When new option element is added to select box we need to
- // force reflow of newly added node in order to workaround delay
- // of initialization properties
- try {
- option.selected = optionSet = true;
-
- } catch ( _ ) {
-
- // Will be executed only in IE6
- option.scrollHeight;
- }
-
- } else {
- option.selected = false;
- }
- }
-
- // Force browsers to behave consistently when non-matching value is set
- if ( !optionSet ) {
- elem.selectedIndex = -1;
- }
-
- return options;
- }
- }
- }
-});
-
-// Radios and checkboxes getter/setter
-jQuery.each([ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = {
- set: function( elem, value ) {
- if ( jQuery.isArray( value ) ) {
- return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
- }
- }
- };
- if ( !support.checkOn ) {
- jQuery.valHooks[ this ].get = function( elem ) {
- // Support: Webkit
- // "" is returned instead of "on" if a value isn't specified
- return elem.getAttribute("value") === null ? "on" : elem.value;
- };
- }
-});
-
-
-
-
-var nodeHook, boolHook,
- attrHandle = jQuery.expr.attrHandle,
- ruseDefault = /^(?:checked|selected)$/i,
- getSetAttribute = support.getSetAttribute,
- getSetInput = support.input;
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return access( this, jQuery.attr, name, value, arguments.length > 1 );
- },
-
- removeAttr: function( name ) {
- return this.each(function() {
- jQuery.removeAttr( this, name );
- });
- }
-});
-
-jQuery.extend({
- attr: function( elem, name, value ) {
- var hooks, ret,
- nType = elem.nodeType;
-
- // don't get/set attributes on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- // Fallback to prop when attributes are not supported
- if ( typeof elem.getAttribute === strundefined ) {
- return jQuery.prop( elem, name, value );
- }
-
- // All attributes are lowercase
- // Grab necessary hook if one is defined
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- name = name.toLowerCase();
- hooks = jQuery.attrHooks[ name ] ||
- ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
- }
-
- if ( value !== undefined ) {
-
- if ( value === null ) {
- jQuery.removeAttr( elem, name );
-
- } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
- return ret;
-
- } else {
- elem.setAttribute( name, value + "" );
- return value;
- }
-
- } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
- return ret;
-
- } else {
- ret = jQuery.find.attr( elem, name );
-
- // Non-existent attributes return null, we normalize to undefined
- return ret == null ?
- undefined :
- ret;
- }
- },
-
- removeAttr: function( elem, value ) {
- var name, propName,
- i = 0,
- attrNames = value && value.match( rnotwhite );
-
- if ( attrNames && elem.nodeType === 1 ) {
- while ( (name = attrNames[i++]) ) {
- propName = jQuery.propFix[ name ] || name;
-
- // Boolean attributes get special treatment (#10870)
- if ( jQuery.expr.match.bool.test( name ) ) {
- // Set corresponding property to false
- if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
- elem[ propName ] = false;
- // Support: IE<9
- // Also clear defaultChecked/defaultSelected (if appropriate)
- } else {
- elem[ jQuery.camelCase( "default-" + name ) ] =
- elem[ propName ] = false;
- }
-
- // See #9699 for explanation of this approach (setting first, then removal)
- } else {
- jQuery.attr( elem, name, "" );
- }
-
- elem.removeAttribute( getSetAttribute ? name : propName );
- }
- }
- },
-
- attrHooks: {
- type: {
- set: function( elem, value ) {
- if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
- // Setting the type on a radio button after the value resets the value in IE6-9
- // Reset value to default in case type is set after value during creation
- var val = elem.value;
- elem.setAttribute( "type", value );
- if ( val ) {
- elem.value = val;
- }
- return value;
- }
- }
- }
- }
-});
-
-// Hook for boolean attributes
-boolHook = {
- set: function( elem, value, name ) {
- if ( value === false ) {
- // Remove boolean attributes when set to false
- jQuery.removeAttr( elem, name );
- } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
- // IE<8 needs the *property* name
- elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
-
- // Use defaultChecked and defaultSelected for oldIE
- } else {
- elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
- }
-
- return name;
- }
-};
-
-// Retrieve booleans specially
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
-
- var getter = attrHandle[ name ] || jQuery.find.attr;
-
- attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
- function( elem, name, isXML ) {
- var ret, handle;
- if ( !isXML ) {
- // Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
- ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
- null;
- attrHandle[ name ] = handle;
- }
- return ret;
- } :
- function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem[ jQuery.camelCase( "default-" + name ) ] ?
- name.toLowerCase() :
- null;
- }
- };
-});
-
-// fix oldIE attroperties
-if ( !getSetInput || !getSetAttribute ) {
- jQuery.attrHooks.value = {
- set: function( elem, value, name ) {
- if ( jQuery.nodeName( elem, "input" ) ) {
- // Does not return so that setAttribute is also used
- elem.defaultValue = value;
- } else {
- // Use nodeHook if defined (#1954); otherwise setAttribute is fine
- return nodeHook && nodeHook.set( elem, value, name );
- }
- }
- };
-}
-
-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !getSetAttribute ) {
-
- // Use this for any attribute in IE6/7
- // This fixes almost every IE6/7 issue
- nodeHook = {
- set: function( elem, value, name ) {
- // Set the existing or create a new attribute node
- var ret = elem.getAttributeNode( name );
- if ( !ret ) {
- elem.setAttributeNode(
- (ret = elem.ownerDocument.createAttribute( name ))
- );
- }
-
- ret.value = value += "";
-
- // Break association with cloned elements by also using setAttribute (#9646)
- if ( name === "value" || value === elem.getAttribute( name ) ) {
- return value;
- }
- }
- };
-
- // Some attributes are constructed with empty-string values when not defined
- attrHandle.id = attrHandle.name = attrHandle.coords =
- function( elem, name, isXML ) {
- var ret;
- if ( !isXML ) {
- return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
- ret.value :
- null;
- }
- };
-
- // Fixing value retrieval on a button requires this module
- jQuery.valHooks.button = {
- get: function( elem, name ) {
- var ret = elem.getAttributeNode( name );
- if ( ret && ret.specified ) {
- return ret.value;
- }
- },
- set: nodeHook.set
- };
-
- // Set contenteditable to false on removals(#10429)
- // Setting to empty string throws an error as an invalid value
- jQuery.attrHooks.contenteditable = {
- set: function( elem, value, name ) {
- nodeHook.set( elem, value === "" ? false : value, name );
- }
- };
-
- // Set width and height to auto instead of 0 on empty string( Bug #8150 )
- // This is for removals
- jQuery.each([ "width", "height" ], function( i, name ) {
- jQuery.attrHooks[ name ] = {
- set: function( elem, value ) {
- if ( value === "" ) {
- elem.setAttribute( name, "auto" );
- return value;
- }
- }
- };
- });
-}
-
-if ( !support.style ) {
- jQuery.attrHooks.style = {
- get: function( elem ) {
- // Return undefined in the case of empty string
- // Note: IE uppercases css property names, but if we were to .toLowerCase()
- // .cssText, that would destroy case senstitivity in URL's, like in "background"
- return elem.style.cssText || undefined;
- },
- set: function( elem, value ) {
- return ( elem.style.cssText = value + "" );
- }
- };
-}
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button|object)$/i,
- rclickable = /^(?:a|area)$/i;
-
-jQuery.fn.extend({
- prop: function( name, value ) {
- return access( this, jQuery.prop, name, value, arguments.length > 1 );
- },
-
- removeProp: function( name ) {
- name = jQuery.propFix[ name ] || name;
- return this.each(function() {
- // try/catch handles cases where IE balks (such as removing a property on window)
- try {
- this[ name ] = undefined;
- delete this[ name ];
- } catch( e ) {}
- });
- }
-});
-
-jQuery.extend({
- propFix: {
- "for": "htmlFor",
- "class": "className"
- },
-
- prop: function( elem, name, value ) {
- var ret, hooks, notxml,
- nType = elem.nodeType;
-
- // don't get/set properties on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
- if ( notxml ) {
- // Fix name and attach hooks
- name = jQuery.propFix[ name ] || name;
- hooks = jQuery.propHooks[ name ];
- }
-
- if ( value !== undefined ) {
- return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
- ret :
- ( elem[ name ] = value );
-
- } else {
- return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
- ret :
- elem[ name ];
- }
- },
-
- propHooks: {
- tabIndex: {
- get: function( elem ) {
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- // Use proper attribute retrieval(#12072)
- var tabindex = jQuery.find.attr( elem, "tabindex" );
-
- return tabindex ?
- parseInt( tabindex, 10 ) :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- -1;
- }
- }
- }
-});
-
-// Some attributes require a special call on IE
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !support.hrefNormalized ) {
- // href/src property should get the full normalized URL (#10299/#12915)
- jQuery.each([ "href", "src" ], function( i, name ) {
- jQuery.propHooks[ name ] = {
- get: function( elem ) {
- return elem.getAttribute( name, 4 );
- }
- };
- });
-}
-
-// Support: Safari, IE9+
-// mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !support.optSelected ) {
- jQuery.propHooks.selected = {
- get: function( elem ) {
- var parent = elem.parentNode;
-
- if ( parent ) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- return null;
- }
- };
-}
-
-jQuery.each([
- "tabIndex",
- "readOnly",
- "maxLength",
- "cellSpacing",
- "cellPadding",
- "rowSpan",
- "colSpan",
- "useMap",
- "frameBorder",
- "contentEditable"
-], function() {
- jQuery.propFix[ this.toLowerCase() ] = this;
-});
-
-// IE6/7 call enctype encoding
-if ( !support.enctype ) {
- jQuery.propFix.enctype = "encoding";
-}
-
-
-
-
-var rclass = /[\t\r\n\f]/g;
-
-jQuery.fn.extend({
- addClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- i = 0,
- len = this.length,
- proceed = typeof value === "string" && value;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).addClass( value.call( this, j, this.className ) );
- });
- }
-
- if ( proceed ) {
- // The disjunction here is for better compressibility (see removeClass)
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace( rclass, " " ) :
- " "
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
- cur += clazz + " ";
- }
- }
-
- // only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- i = 0,
- len = this.length,
- proceed = arguments.length === 0 || typeof value === "string" && value;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).removeClass( value.call( this, j, this.className ) );
- });
- }
- if ( proceed ) {
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- // This expression is here for better compressibility (see addClass)
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace( rclass, " " ) :
- ""
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- // Remove *all* instances
- while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
- cur = cur.replace( " " + clazz + " ", " " );
- }
- }
-
- // only assign if different to avoid unneeded rendering.
- finalValue = value ? jQuery.trim( cur ) : "";
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value;
-
- if ( typeof stateVal === "boolean" && type === "string" ) {
- return stateVal ? this.addClass( value ) : this.removeClass( value );
- }
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( i ) {
- jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery( this ),
- classNames = value.match( rnotwhite ) || [];
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space separated list
- if ( self.hasClass( className ) ) {
- self.removeClass( className );
- } else {
- self.addClass( className );
- }
- }
-
- // Toggle whole class name
- } else if ( type === strundefined || type === "boolean" ) {
- if ( this.className ) {
- // store className if set
- jQuery._data( this, "__className__", this.className );
- }
-
- // If the element has a class name or if we're passed "false",
- // then remove the whole classname (if there was one, the above saved it).
- // Otherwise bring back whatever was previously saved (if anything),
- // falling back to the empty string if nothing was stored.
- this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ",
- i = 0,
- l = this.length;
- for ( ; i < l; i++ ) {
- if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
- return true;
- }
- }
-
- return false;
- }
-});
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- return arguments.length > 0 ?
- this.on( name, null, data, fn ) :
- this.trigger( name );
- };
-});
-
-jQuery.fn.extend({
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- },
-
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
- }
-});
-
-
-var nonce = jQuery.now();
-
-var rquery = (/\?/);
-
-
-
-var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
-
-jQuery.parseJSON = function( data ) {
- // Attempt to parse using the native JSON parser first
- if ( window.JSON && window.JSON.parse ) {
- // Support: Android 2.3
- // Workaround failure to string-cast null input
- return window.JSON.parse( data + "" );
- }
-
- var requireNonComma,
- depth = null,
- str = jQuery.trim( data + "" );
-
- // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
- // after removing valid tokens
- return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
-
- // Force termination if we see a misplaced comma
- if ( requireNonComma && comma ) {
- depth = 0;
- }
-
- // Perform no more replacements after returning to outermost depth
- if ( depth === 0 ) {
- return token;
- }
-
- // Commas must not follow "[", "{", or ","
- requireNonComma = open || comma;
-
- // Determine new depth
- // array/object open ("[" or "{"): depth += true - false (increment)
- // array/object close ("]" or "}"): depth += false - true (decrement)
- // other cases ("," or primitive): depth += true - true (numeric cast)
- depth += !close - !open;
-
- // Remove this token
- return "";
- }) ) ?
- ( Function( "return " + str ) )() :
- jQuery.error( "Invalid JSON: " + data );
-};
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
- var xml, tmp;
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- try {
- if ( window.DOMParser ) { // Standard
- tmp = new DOMParser();
- xml = tmp.parseFromString( data, "text/xml" );
- } else { // IE
- xml = new ActiveXObject( "Microsoft.XMLDOM" );
- xml.async = "false";
- xml.loadXML( data );
- }
- } catch( e ) {
- xml = undefined;
- }
- if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
- jQuery.error( "Invalid XML: " + data );
- }
- return xml;
-};
-
-
-var
- // Document location
- ajaxLocParts,
- ajaxLocation,
-
- rhash = /#.*$/,
- rts = /([?&])_=[^&]*/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
-
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
- */
- prefilters = {},
-
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*" if needed
- */
- transports = {},
-
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
- allTypes = "*/".concat("*");
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
- ajaxLocation = location.href;
-} catch( e ) {
- // Use the href attribute of an A element
- // since IE will modify it given document.location
- ajaxLocation = document.createElement( "a" );
- ajaxLocation.href = "";
- ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
- // dataTypeExpression is optional and defaults to "*"
- return function( dataTypeExpression, func ) {
-
- if ( typeof dataTypeExpression !== "string" ) {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
-
- var dataType,
- i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
-
- if ( jQuery.isFunction( func ) ) {
- // For each dataType in the dataTypeExpression
- while ( (dataType = dataTypes[i++]) ) {
- // Prepend if requested
- if ( dataType.charAt( 0 ) === "+" ) {
- dataType = dataType.slice( 1 ) || "*";
- (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
-
- // Otherwise append
- } else {
- (structure[ dataType ] = structure[ dataType ] || []).push( func );
- }
- }
- }
- };
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
- var inspected = {},
- seekingTransport = ( structure === transports );
-
- function inspect( dataType ) {
- var selected;
- inspected[ dataType ] = true;
- jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
- var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
- if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
- options.dataTypes.unshift( dataTypeOrTransport );
- inspect( dataTypeOrTransport );
- return false;
- } else if ( seekingTransport ) {
- return !( selected = dataTypeOrTransport );
- }
- });
- return selected;
- }
-
- return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
- var deep, key,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
- for ( key in src ) {
- if ( src[ key ] !== undefined ) {
- ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
- }
- }
- if ( deep ) {
- jQuery.extend( true, target, deep );
- }
-
- return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
- var firstDataType, ct, finalDataType, type,
- contents = s.contents,
- dataTypes = s.dataTypes;
-
- // Remove auto dataType and get content-type in the process
- while ( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
- }
- }
-
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
- }
- }
- }
-
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
- } else {
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
- }
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
- converters = {},
- // Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice();
-
- // Create converters map with lowercased keys
- if ( dataTypes[ 1 ] ) {
- for ( conv in s.converters ) {
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
- }
- }
-
- current = dataTypes.shift();
-
- // Convert to each sequential dataType
- while ( current ) {
-
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
- }
-
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- prev = current;
- current = dataTypes.shift();
-
- if ( current ) {
-
- // There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
-
- current = prev;
-
- // Convert response if prev dataType is non-auto and differs from current
- } else if ( prev !== "*" && prev !== current ) {
-
- // Seek a direct converter
- conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
- // If none found, seek a pair
- if ( !conv ) {
- for ( conv2 in converters ) {
-
- // If conv2 outputs current
- tmp = conv2.split( " " );
- if ( tmp[ 1 ] === current ) {
-
- // If prev can be converted to accepted input
- conv = converters[ prev + " " + tmp[ 0 ] ] ||
- converters[ "* " + tmp[ 0 ] ];
- if ( conv ) {
- // Condense equivalence converters
- if ( conv === true ) {
- conv = converters[ conv2 ];
-
- // Otherwise, insert the intermediate dataType
- } else if ( converters[ conv2 ] !== true ) {
- current = tmp[ 0 ];
- dataTypes.unshift( tmp[ 1 ] );
- }
- break;
- }
- }
- }
- }
-
- // Apply converter (if not an equivalence)
- if ( conv !== true ) {
-
- // Unless errors are allowed to bubble, catch and return them
- if ( conv && s[ "throws" ] ) {
- response = conv( response );
- } else {
- try {
- response = conv( response );
- } catch ( e ) {
- return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
- }
- }
- }
- }
- }
- }
-
- return { state: "success", data: response };
-}
-
-jQuery.extend({
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
-
- ajaxSettings: {
- url: ajaxLocation,
- type: "GET",
- isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
- global: true,
- processData: true,
- async: true,
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- throws: false,
- traditional: false,
- headers: {},
- */
-
- accepts: {
- "*": allTypes,
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript"
- },
-
- contents: {
- xml: /xml/,
- html: /html/,
- json: /json/
- },
-
- responseFields: {
- xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
- },
-
- // Data converters
- // Keys separate source (or catchall "*") and destination types with a single space
- converters: {
-
- // Convert anything to text
- "* text": String,
-
- // Text to html (true = no transformation)
- "text html": true,
-
- // Evaluate text as a json expression
- "text json": jQuery.parseJSON,
-
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
-
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- url: true,
- context: true
- }
- },
-
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function( target, settings ) {
- return settings ?
-
- // Building a settings object
- ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
- // Extending ajaxSettings
- ajaxExtend( jQuery.ajaxSettings, target );
- },
-
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
- ajaxTransport: addToPrefiltersOrTransports( transports ),
-
- // Main method
- ajax: function( url, options ) {
-
- // If url is an object, simulate pre-1.5 signature
- if ( typeof url === "object" ) {
- options = url;
- url = undefined;
- }
-
- // Force options to be an object
- options = options || {};
-
- var // Cross-domain detection vars
- parts,
- // Loop variable
- i,
- // URL without anti-cache param
- cacheURL,
- // Response headers as string
- responseHeadersString,
- // timeout handle
- timeoutTimer,
-
- // To know if global events are to be dispatched
- fireGlobals,
-
- transport,
- // Response headers
- responseHeaders,
- // Create the final options object
- s = jQuery.ajaxSetup( {}, options ),
- // Callbacks context
- callbackContext = s.context || s,
- // Context for global events is callbackContext if it is a DOM node or jQuery collection
- globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
- jQuery( callbackContext ) :
- jQuery.event,
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks("once memory"),
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
- // The jqXHR state
- state = 0,
- // Default abort message
- strAbort = "canceled",
- // Fake xhr
- jqXHR = {
- readyState: 0,
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
- var match;
- if ( state === 2 ) {
- if ( !responseHeaders ) {
- responseHeaders = {};
- while ( (match = rheaders.exec( responseHeadersString )) ) {
- responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
- }
- }
- match = responseHeaders[ key.toLowerCase() ];
- }
- return match == null ? null : match;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return state === 2 ? responseHeadersString : null;
- },
-
- // Caches the header
- setRequestHeader: function( name, value ) {
- var lname = name.toLowerCase();
- if ( !state ) {
- name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
- requestHeaders[ name ] = value;
- }
- return this;
- },
-
- // Overrides response content-type header
- overrideMimeType: function( type ) {
- if ( !state ) {
- s.mimeType = type;
- }
- return this;
- },
-
- // Status-dependent callbacks
- statusCode: function( map ) {
- var code;
- if ( map ) {
- if ( state < 2 ) {
- for ( code in map ) {
- // Lazy-add the new callback in a way that preserves old ones
- statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
- }
- } else {
- // Execute the appropriate callbacks
- jqXHR.always( map[ jqXHR.status ] );
- }
- }
- return this;
- },
-
- // Cancel the request
- abort: function( statusText ) {
- var finalText = statusText || strAbort;
- if ( transport ) {
- transport.abort( finalText );
- }
- done( 0, finalText );
- return this;
- }
- };
-
- // Attach deferreds
- deferred.promise( jqXHR ).complete = completeDeferred.add;
- jqXHR.success = jqXHR.done;
- jqXHR.error = jqXHR.fail;
-
- // Remove hash character (#7531: and string promotion)
- // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
- // Handle falsy url in the settings object (#10093: consistency with old signature)
- // We also use the url parameter if available
- s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
-
- // Alias method option to type as per ticket #12004
- s.type = options.method || options.type || s.method || s.type;
-
- // Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
-
- // A cross-domain request is in order when we have a protocol:host:port mismatch
- if ( s.crossDomain == null ) {
- parts = rurl.exec( s.url.toLowerCase() );
- s.crossDomain = !!( parts &&
- ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
- ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
- ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
- );
- }
-
- // Convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Apply prefilters
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
- // If request was aborted inside a prefilter, stop there
- if ( state === 2 ) {
- return jqXHR;
- }
-
- // We can fire global events as of now if asked to
- // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
- fireGlobals = jQuery.event && s.global;
-
- // Watch for a new set of requests
- if ( fireGlobals && jQuery.active++ === 0 ) {
- jQuery.event.trigger("ajaxStart");
- }
-
- // Uppercase the type
- s.type = s.type.toUpperCase();
-
- // Determine if request has content
- s.hasContent = !rnoContent.test( s.type );
-
- // Save the URL in case we're toying with the If-Modified-Since
- // and/or If-None-Match header later on
- cacheURL = s.url;
-
- // More options handling for requests with no content
- if ( !s.hasContent ) {
-
- // If data is available, append data to url
- if ( s.data ) {
- cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
- // #9682: remove data so that it's not used in an eventual retry
- delete s.data;
- }
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
- s.url = rts.test( cacheURL ) ?
-
- // If there is already a '_' parameter, set its value
- cacheURL.replace( rts, "$1_=" + nonce++ ) :
-
- // Otherwise add one to the end
- cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
- }
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery.lastModified[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
- }
- if ( jQuery.etag[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
- }
- }
-
- // Set the correct header, if data is being sent
- if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
- }
-
- // Set the Accepts header for the server, depending on the dataType
- jqXHR.setRequestHeader(
- "Accept",
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
- s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
- s.accepts[ "*" ]
- );
-
- // Check for headers option
- for ( i in s.headers ) {
- jqXHR.setRequestHeader( i, s.headers[ i ] );
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
- // Abort if not done already and return
- return jqXHR.abort();
- }
-
- // aborting is no longer a cancellation
- strAbort = "abort";
-
- // Install callbacks on deferreds
- for ( i in { success: 1, error: 1, complete: 1 } ) {
- jqXHR[ i ]( s[ i ] );
- }
-
- // Get transport
- transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
- // If no transport, we auto-abort
- if ( !transport ) {
- done( -1, "No Transport" );
- } else {
- jqXHR.readyState = 1;
-
- // Send global event
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
- }
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = setTimeout(function() {
- jqXHR.abort("timeout");
- }, s.timeout );
- }
-
- try {
- state = 1;
- transport.send( requestHeaders, done );
- } catch ( e ) {
- // Propagate exception as error if not done
- if ( state < 2 ) {
- done( -1, e );
- // Simply rethrow otherwise
- } else {
- throw e;
- }
- }
- }
-
- // Callback for when everything is done
- function done( status, nativeStatusText, responses, headers ) {
- var isSuccess, success, error, response, modified,
- statusText = nativeStatusText;
-
- // Called once
- if ( state === 2 ) {
- return;
- }
-
- // State is "done" now
- state = 2;
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- clearTimeout( timeoutTimer );
- }
-
- // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0;
-
- // Determine if successful
- isSuccess = status >= 200 && status < 300 || status === 304;
-
- // Get response data
- if ( responses ) {
- response = ajaxHandleResponses( s, jqXHR, responses );
- }
-
- // Convert no matter what (that way responseXXX fields are always set)
- response = ajaxConvert( s, response, jqXHR, isSuccess );
-
- // If successful, handle type chaining
- if ( isSuccess ) {
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- modified = jqXHR.getResponseHeader("Last-Modified");
- if ( modified ) {
- jQuery.lastModified[ cacheURL ] = modified;
- }
- modified = jqXHR.getResponseHeader("etag");
- if ( modified ) {
- jQuery.etag[ cacheURL ] = modified;
- }
- }
-
- // if no content
- if ( status === 204 || s.type === "HEAD" ) {
- statusText = "nocontent";
-
- // if not modified
- } else if ( status === 304 ) {
- statusText = "notmodified";
-
- // If we have data, let's convert it
- } else {
- statusText = response.state;
- success = response.data;
- error = response.error;
- isSuccess = !error;
- }
- } else {
- // We extract error from statusText
- // then normalize statusText and status for non-aborts
- error = statusText;
- if ( status || !statusText ) {
- statusText = "error";
- if ( status < 0 ) {
- status = 0;
- }
- }
- }
-
- // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
- // Success/Error
- if ( isSuccess ) {
- deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
- } else {
- deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
- }
-
- // Status-dependent callbacks
- jqXHR.statusCode( statusCode );
- statusCode = undefined;
-
- if ( fireGlobals ) {
- globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
- [ jqXHR, s, isSuccess ? success : error ] );
- }
-
- // Complete
- completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
- // Handle the global AJAX counter
- if ( !( --jQuery.active ) ) {
- jQuery.event.trigger("ajaxStop");
- }
- }
- }
-
- return jqXHR;
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get( url, data, callback, "json" );
- },
-
- getScript: function( url, callback ) {
- return jQuery.get( url, undefined, callback, "script" );
- }
-});
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
- jQuery[ method ] = function( url, data, callback, type ) {
- // shift arguments if data argument was omitted
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = undefined;
- }
-
- return jQuery.ajax({
- url: url,
- type: method,
- dataType: type,
- data: data,
- success: callback
- });
- };
-});
-
-
-jQuery._evalUrl = function( url ) {
- return jQuery.ajax({
- url: url,
- type: "GET",
- dataType: "script",
- async: false,
- global: false,
- "throws": true
- });
-};
-
-
-jQuery.fn.extend({
- wrapAll: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapAll( html.call(this, i) );
- });
- }
-
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
- if ( this[0].parentNode ) {
- wrap.insertBefore( this[0] );
- }
-
- wrap.map(function() {
- var elem = this;
-
- while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
- elem = elem.firstChild;
- }
-
- return elem;
- }).append( this );
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapInner( html.call(this, i) );
- });
- }
-
- return this.each(function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- });
- },
-
- wrap: function( html ) {
- var isFunction = jQuery.isFunction( html );
-
- return this.each(function(i) {
- jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
- });
- },
-
- unwrap: function() {
- return this.parent().each(function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- }).end();
- }
-});
-
-
-jQuery.expr.filters.hidden = function( elem ) {
- // Support: Opera <= 12.12
- // Opera reports offsetWidths and offsetHeights less than zero on some elements
- return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
- (!support.reliableHiddenOffsets() &&
- ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
-};
-
-jQuery.expr.filters.visible = function( elem ) {
- return !jQuery.expr.filters.hidden( elem );
-};
-
-
-
-
-var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
- var name;
-
- if ( jQuery.isArray( obj ) ) {
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
- // Item is non-scalar (array or object), encode its numeric index.
- buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
- }
- });
-
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
- // Serialize object item.
- for ( name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
- }
-
- } else {
- // Serialize scalar item.
- add( prefix, obj );
- }
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
- var prefix,
- s = [],
- add = function( key, value ) {
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form elements.
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- });
-
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( prefix in a ) {
- buildParams( prefix, a[ prefix ], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join( "&" ).replace( r20, "+" );
-};
-
-jQuery.fn.extend({
- serialize: function() {
- return jQuery.param( this.serializeArray() );
- },
- serializeArray: function() {
- return this.map(function() {
- // Can add propHook for "elements" to filter or add form elements
- var elements = jQuery.prop( this, "elements" );
- return elements ? jQuery.makeArray( elements ) : this;
- })
- .filter(function() {
- var type = this.type;
- // Use .is(":disabled") so that fieldset[disabled] works
- return this.name && !jQuery( this ).is( ":disabled" ) &&
- rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
- ( this.checked || !rcheckableType.test( type ) );
- })
- .map(function( i, elem ) {
- var val = jQuery( this ).val();
-
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val ) {
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }).get();
- }
-});
-
-
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
- // Support: IE6+
- function() {
-
- // XHR cannot access local files, always use ActiveX for that case
- return !this.isLocal &&
-
- // Support: IE7-8
- // oldIE XHR does not support non-RFC2616 methods (#13240)
- // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
- // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
- // Although this check for six methods instead of eight
- // since IE also does not support "trace" and "connect"
- /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
-
- createStandardXHR() || createActiveXHR();
- } :
- // For all other browsers, use the standard XMLHttpRequest object
- createStandardXHR;
-
-var xhrId = 0,
- xhrCallbacks = {},
- xhrSupported = jQuery.ajaxSettings.xhr();
-
-// Support: IE<10
-// Open requests must be manually aborted on unload (#5280)
-// See https://support.microsoft.com/kb/2856746 for more info
-if ( window.attachEvent ) {
- window.attachEvent( "onunload", function() {
- for ( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]( undefined, true );
- }
- });
-}
-
-// Determine support properties
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-xhrSupported = support.ajax = !!xhrSupported;
-
-// Create transport if the browser can provide an xhr
-if ( xhrSupported ) {
-
- jQuery.ajaxTransport(function( options ) {
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( !options.crossDomain || support.cors ) {
-
- var callback;
-
- return {
- send: function( headers, complete ) {
- var i,
- xhr = options.xhr(),
- id = ++xhrId;
-
- // Open the socket
- xhr.open( options.type, options.url, options.async, options.username, options.password );
-
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i ];
- }
- }
-
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( options.mimeType );
- }
-
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !options.crossDomain && !headers["X-Requested-With"] ) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- }
-
- // Set headers
- for ( i in headers ) {
- // Support: IE<9
- // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
- // request header to a null-value.
- //
- // To keep consistent with other XHR implementations, cast the value
- // to string and ignore `undefined`.
- if ( headers[ i ] !== undefined ) {
- xhr.setRequestHeader( i, headers[ i ] + "" );
- }
- }
-
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( ( options.hasContent && options.data ) || null );
-
- // Listener
- callback = function( _, isAbort ) {
- var status, statusText, responses;
-
- // Was never called and is aborted or complete
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
- // Clean up
- delete xhrCallbacks[ id ];
- callback = undefined;
- xhr.onreadystatechange = jQuery.noop;
-
- // Abort manually if needed
- if ( isAbort ) {
- if ( xhr.readyState !== 4 ) {
- xhr.abort();
- }
- } else {
- responses = {};
- status = xhr.status;
-
- // Support: IE<10
- // Accessing binary-data responseText throws an exception
- // (#11426)
- if ( typeof xhr.responseText === "string" ) {
- responses.text = xhr.responseText;
- }
-
- // Firefox throws an exception when accessing
- // statusText for faulty cross-domain requests
- try {
- statusText = xhr.statusText;
- } catch( e ) {
- // We normalize with Webkit giving an empty statusText
- statusText = "";
- }
-
- // Filter status for non standard behaviors
-
- // If the request is local and we have data: assume a success
- // (success with no data won't get notified, that's the best we
- // can do given current implementations)
- if ( !status && options.isLocal && !options.crossDomain ) {
- status = responses.text ? 200 : 404;
- // IE - #1450: sometimes returns 1223 when it should be 204
- } else if ( status === 1223 ) {
- status = 204;
- }
- }
- }
-
- // Call complete if needed
- if ( responses ) {
- complete( status, statusText, responses, xhr.getAllResponseHeaders() );
- }
- };
-
- if ( !options.async ) {
- // if we're in sync mode we fire the callback
- callback();
- } else if ( xhr.readyState === 4 ) {
- // (IE6 & IE7) if it's in cache and has been
- // retrieved directly we need to fire the callback
- setTimeout( callback );
- } else {
- // Add to the list of active xhr callbacks
- xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback( undefined, true );
- }
- }
- };
- }
- });
-}
-
-// Functions to create xhrs
-function createStandardXHR() {
- try {
- return new window.XMLHttpRequest();
- } catch( e ) {}
-}
-
-function createActiveXHR() {
- try {
- return new window.ActiveXObject( "Microsoft.XMLHTTP" );
- } catch( e ) {}
-}
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup({
- accepts: {
- script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /(?:java|ecma)script/
- },
- converters: {
- "text script": function( text ) {
- jQuery.globalEval( text );
- return text;
- }
- }
-});
-
-// Handle cache's special case and global
-jQuery.ajaxPrefilter( "script", function( s ) {
- if ( s.cache === undefined ) {
- s.cache = false;
- }
- if ( s.crossDomain ) {
- s.type = "GET";
- s.global = false;
- }
-});
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function(s) {
-
- // This transport only deals with cross domain requests
- if ( s.crossDomain ) {
-
- var script,
- head = document.head || jQuery("head")[0] || document.documentElement;
-
- return {
-
- send: function( _, callback ) {
-
- script = document.createElement("script");
-
- script.async = true;
-
- if ( s.scriptCharset ) {
- script.charset = s.scriptCharset;
- }
-
- script.src = s.url;
-
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function( _, isAbort ) {
-
- if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
-
- // Remove the script
- if ( script.parentNode ) {
- script.parentNode.removeChild( script );
- }
-
- // Dereference the script
- script = null;
-
- // Callback if not abort
- if ( !isAbort ) {
- callback( 200, "success" );
- }
- }
- };
-
- // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
- // Use native DOM manipulation to avoid our domManip AJAX trickery
- head.insertBefore( script, head.firstChild );
- },
-
- abort: function() {
- if ( script ) {
- script.onload( undefined, true );
- }
- }
- };
- }
-});
-
-
-
-
-var oldCallbacks = [],
- rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup({
- jsonp: "callback",
- jsonpCallback: function() {
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
- this[ callback ] = true;
- return callback;
- }
-});
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
- var callbackName, overwritten, responseContainer,
- jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
- "url" :
- typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
- );
-
- // Handle iff the expected data type is "jsonp" or we have a parameter to set
- if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
- // Get callback name, remembering preexisting value associated with it
- callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
- s.jsonpCallback() :
- s.jsonpCallback;
-
- // Insert callback into url or form data
- if ( jsonProp ) {
- s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
- } else if ( s.jsonp !== false ) {
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
- }
-
- // Use data converter to retrieve json after script execution
- s.converters["script json"] = function() {
- if ( !responseContainer ) {
- jQuery.error( callbackName + " was not called" );
- }
- return responseContainer[ 0 ];
- };
-
- // force json dataType
- s.dataTypes[ 0 ] = "json";
-
- // Install callback
- overwritten = window[ callbackName ];
- window[ callbackName ] = function() {
- responseContainer = arguments;
- };
-
- // Clean-up function (fires after converters)
- jqXHR.always(function() {
- // Restore preexisting value
- window[ callbackName ] = overwritten;
-
- // Save back as free
- if ( s[ callbackName ] ) {
- // make sure that re-using the options doesn't screw things around
- s.jsonpCallback = originalSettings.jsonpCallback;
-
- // save the callback name for future use
- oldCallbacks.push( callbackName );
- }
-
- // Call if it was a function and we have a response
- if ( responseContainer && jQuery.isFunction( overwritten ) ) {
- overwritten( responseContainer[ 0 ] );
- }
-
- responseContainer = overwritten = undefined;
- });
-
- // Delegate to script
- return "script";
- }
-});
-
-
-
-
-// data: string of html
-// context (optional): If specified, the fragment will be created in this context, defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html string
-jQuery.parseHTML = function( data, context, keepScripts ) {
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- if ( typeof context === "boolean" ) {
- keepScripts = context;
- context = false;
- }
- context = context || document;
-
- var parsed = rsingleTag.exec( data ),
- scripts = !keepScripts && [];
-
- // Single tag
- if ( parsed ) {
- return [ context.createElement( parsed[1] ) ];
- }
-
- parsed = jQuery.buildFragment( [ data ], context, scripts );
-
- if ( scripts && scripts.length ) {
- jQuery( scripts ).remove();
- }
-
- return jQuery.merge( [], parsed.childNodes );
-};
-
-
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
- }
-
- var selector, response, type,
- self = this,
- off = url.indexOf(" ");
-
- if ( off >= 0 ) {
- selector = jQuery.trim( url.slice( off, url.length ) );
- url = url.slice( 0, off );
- }
-
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
-
- // We assume that it's the callback
- callback = params;
- params = undefined;
-
- // Otherwise, build a param string
- } else if ( params && typeof params === "object" ) {
- type = "POST";
- }
-
- // If we have elements to modify, make the request
- if ( self.length > 0 ) {
- jQuery.ajax({
- url: url,
-
- // if "type" variable is undefined, then "GET" method will be used
- type: type,
- dataType: "html",
- data: params
- }).done(function( responseText ) {
-
- // Save response for use in complete callback
- response = arguments;
-
- self.html( selector ?
-
- // If a selector was specified, locate the right elements in a dummy div
- // Exclude scripts to avoid IE 'Permission Denied' errors
- jQuery("").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- }).complete( callback && function( jqXHR, status ) {
- self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
- });
- }
-
- return this;
-};
-
-
-
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
- jQuery.fn[ type ] = function( fn ) {
- return this.on( type, fn );
- };
-});
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
-};
-
-
-
-
-
-var docElem = window.document.documentElement;
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ?
- elem :
- elem.nodeType === 9 ?
- elem.defaultView || elem.parentWindow :
- false;
-}
-
-jQuery.offset = {
- setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
-
- // set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) &&
- jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
-
- // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
- } else {
- curElem.css( props );
- }
- }
-};
-
-jQuery.fn.extend({
- offset: function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- var docElem, win,
- box = { top: 0, left: 0 },
- elem = this[ 0 ],
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- // If we don't have gBCR, just use 0,0 rather than error
- // BlackBerry 5, iOS 3 (original iPhone)
- if ( typeof elem.getBoundingClientRect !== strundefined ) {
- box = elem.getBoundingClientRect();
- }
- win = getWindow( doc );
- return {
- top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
- left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
- };
- },
-
- position: function() {
- if ( !this[ 0 ] ) {
- return;
- }
-
- var offsetParent, offset,
- parentOffset = { top: 0, left: 0 },
- elem = this[ 0 ];
-
- // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
- // we assume that getBoundingClientRect is available when computed position is fixed
- offset = elem.getBoundingClientRect();
- } else {
- // Get *real* offsetParent
- offsetParent = this.offsetParent();
-
- // Get correct offsets
- offset = this.offset();
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
- parentOffset = offsetParent.offset();
- }
-
- // Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
- }
-
- // Subtract parent offsets and element margins
- // note: when an element has margin: auto the offsetLeft and marginLeft
- // are the same in Safari causing offset.left to incorrectly be 0
- return {
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || docElem;
-
- while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent || docElem;
- });
- }
-});
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
- var top = /Y/.test( prop );
-
- jQuery.fn[ method ] = function( val ) {
- return access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? (prop in win) ? win[ prop ] :
- win.document.documentElement[ method ] :
- elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : jQuery( win ).scrollLeft(),
- top ? val : jQuery( win ).scrollTop()
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length, null );
- };
-});
-
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// getComputedStyle returns percent when specified for top/left/bottom/right
-// rather than make the css module depend on the offset module, we just check for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
- function( elem, computed ) {
- if ( computed ) {
- computed = curCSS( elem, prop );
- // if curCSS returns percentage, fallback to offset
- return rnumnonpx.test( computed ) ?
- jQuery( elem ).position()[ prop ] + "px" :
- computed;
- }
- }
- );
-});
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
- // margin is only for outerHeight, outerWidth
- jQuery.fn[ funcName ] = function( margin, value ) {
- var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
- extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
- return access( this, function( elem, type, value ) {
- var doc;
-
- if ( jQuery.isWindow( elem ) ) {
- // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
- // isn't a whole lot we can do. See pull request at this URL for discussion:
- // https://github.com/jquery/jquery/pull/764
- return elem.document.documentElement[ "client" + name ];
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- doc = elem.documentElement;
-
- // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
- // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
- return Math.max(
- elem.body[ "scroll" + name ], doc[ "scroll" + name ],
- elem.body[ "offset" + name ], doc[ "offset" + name ],
- doc[ "client" + name ]
- );
- }
-
- return value === undefined ?
- // Get width or height on the element, requesting but not forcing parseFloat
- jQuery.css( elem, type, extra ) :
-
- // Set width or height on the element
- jQuery.style( elem, type, value, extra );
- }, type, chainable ? margin : undefined, chainable, null );
- };
- });
-});
-
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
- return this.length;
-};
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function() {
- return jQuery;
- });
-}
-
-
-
-
-var
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$;
-
-jQuery.noConflict = function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in
-// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === strundefined ) {
- window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-
-}));
diff --git a/root/opt/phpsysinfo/js/jQuery/jquery.dataTables.js b/root/opt/phpsysinfo/js/jQuery/jquery.dataTables.js
index a295d17..bea0a3d 100644
--- a/root/opt/phpsysinfo/js/jQuery/jquery.dataTables.js
+++ b/root/opt/phpsysinfo/js/jQuery/jquery.dataTables.js
@@ -1,6 +1,6 @@
/*
* File: jquery.dataTables.js
- * Version: 1.8.2
+ * Version: 1.8.2+jquery1.9fix+parseJSONfix2+bindfix+samesitefix+noeval
* Description: Paginate, search and sort HTML tables
* Author: Allan Jardine (www.sprymedia.co.uk)
* Created: 28/3/2008
@@ -319,7 +319,7 @@
nPaging.appendChild( nPrevious );
nPaging.appendChild( nNext );
- $(nPrevious).bind( 'click.DT', function() {
+ $(nPrevious).on( 'click.DT', function() {
if ( oSettings.oApi._fnPageChange( oSettings, "previous" ) )
{
/* Only draw when the page has actually changed */
@@ -327,7 +327,7 @@
}
} );
- $(nNext).bind( 'click.DT', function() {
+ $(nNext).on( 'click.DT', function() {
if ( oSettings.oApi._fnPageChange( oSettings, "next" ) )
{
fnCallbackDraw( oSettings );
@@ -335,8 +335,8 @@
} );
/* Take the brutal approach to cancelling text selection */
- $(nPrevious).bind( 'selectstart.DT', function () { return false; } );
- $(nNext).bind( 'selectstart.DT', function () { return false; } );
+ $(nPrevious).on( 'selectstart.DT', function () { return false; } );
+ $(nNext).on( 'selectstart.DT', function () { return false; } );
/* ID the first elements only */
if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.p == "undefined" )
@@ -426,28 +426,28 @@
nPaging.appendChild( nNext );
nPaging.appendChild( nLast );
- $(nFirst).bind( 'click.DT', function () {
+ $(nFirst).on( 'click.DT', function () {
if ( oSettings.oApi._fnPageChange( oSettings, "first" ) )
{
fnCallbackDraw( oSettings );
}
} );
- $(nPrevious).bind( 'click.DT', function() {
+ $(nPrevious).on( 'click.DT', function() {
if ( oSettings.oApi._fnPageChange( oSettings, "previous" ) )
{
fnCallbackDraw( oSettings );
}
} );
- $(nNext).bind( 'click.DT', function() {
+ $(nNext).on( 'click.DT', function() {
if ( oSettings.oApi._fnPageChange( oSettings, "next" ) )
{
fnCallbackDraw( oSettings );
}
} );
- $(nLast).bind( 'click.DT', function() {
+ $(nLast).on( 'click.DT', function() {
if ( oSettings.oApi._fnPageChange( oSettings, "last" ) )
{
fnCallbackDraw( oSettings );
@@ -456,8 +456,8 @@
/* Take the brutal approach to cancelling text selection */
$('span', nPaging)
- .bind( 'mousedown.DT', function () { return false; } )
- .bind( 'selectstart.DT', function () { return false; } );
+ .on( 'mousedown.DT', function () { return false; } )
+ .on( 'selectstart.DT', function () { return false; } );
/* ID the first elements only */
if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.p == "undefined" )
@@ -555,8 +555,8 @@
/* Build up the dynamic list forst - html and listeners */
var qjPaginateList = $('span:eq(2)', an[i]);
qjPaginateList.html( sList );
- $('span', qjPaginateList).bind( 'click.DT', fnClick ).bind( 'mousedown.DT', fnFalse )
- .bind( 'selectstart.DT', fnFalse );
+ $('span', qjPaginateList).on( 'click.DT', fnClick ).on( 'mousedown.DT', fnFalse )
+ .on( 'selectstart.DT', fnFalse );
/* Update the 'premanent botton's classes */
anButtons = an[i].getElementsByTagName('span');
@@ -2175,7 +2175,7 @@
}
/* Blitz all DT events */
- $(oSettings.nTableWrapper).find('*').andSelf().unbind('.DT');
+ $(oSettings.nTableWrapper).find('*').andSelf().off('.DT');
/* If there is an 'empty' indicator row, remove it */
$('tbody>tr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove();
@@ -3051,7 +3051,7 @@
_fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
/* Take the brutal approach to cancelling text selection in header */
- $(oSettings.aoColumns[i].nTh).bind( 'mousedown.DT', fnNoSelect );
+ $(oSettings.aoColumns[i].nTh).on( 'mousedown.DT', fnNoSelect );
}
else
{
@@ -3971,7 +3971,7 @@
iWidth, aApplied=[], iSanityWidth,
nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null,
nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null,
- ie67 = $.browser.msie && $.browser.version <= 7;
+ ie67 = (navigator.userAgent.match(/MSIE ([2-7]\.)/) !== null);
/*
* 1. Re-create the table inside the scrolling div
@@ -4288,7 +4288,7 @@
var jqFilter = $("input", nFilter);
jqFilter.val( oSettings.oPreviousSearch.sSearch.replace('"','"') );
- jqFilter.bind( 'keyup.DT', function(e) {
+ jqFilter.on( 'keyup.DT', function(e) {
/* Update all other filter input elements for the new display */
var n = oSettings.aanFeatures.f;
for ( var i=0, iLen=n.length ; i 4096 ) /* Magic 10 for padding */
{
var aCookies =document.cookie.split(';');
+ var sData;
for ( var i=0, iLen=aCookies.length ; i
').addClass( (o && o.position) ? o.position : $.jGrowl.defaults.position ).appendTo('body');
// Create a notification on the container.
@@ -214,21 +214,21 @@
'' + o.closeTemplate + '
' +
'' +
'' + message + '
'
- ).data("jGrowl", o).addClass(o.theme).children('div.jGrowl-close').bind("click.jGrowl", function() {
+ ).data("jGrowl", o).addClass(o.theme).children('div.jGrowl-close').on("click.jGrowl", function() {
$(this).parent().trigger('jGrowl.close');
}).parent();
/** Notification Actions **/
- $(notification).bind("mouseover.jGrowl", function() {
+ $(notification).on("mouseover.jGrowl", function() {
$('div.jGrowl-notification', self.element).data("jGrowl.pause", true);
- }).bind("mouseout.jGrowl", function() {
+ }).on("mouseout.jGrowl", function() {
$('div.jGrowl-notification', self.element).data("jGrowl.pause", false);
- }).bind('jGrowl.beforeOpen', function() {
+ }).on('jGrowl.beforeOpen', function() {
if ( o.beforeOpen.apply( notification , [notification,message,o,self.element] ) != false ) {
$(this).trigger('jGrowl.open');
}
- }).bind('jGrowl.open', function() {
+ }).on('jGrowl.open', function() {
if ( o.open.apply( notification , [notification,message,o,self.element] ) != false ) {
if ( o.glue == 'after' ) {
$('div.jGrowl-notification:last', self.element).after(notification);
@@ -238,7 +238,7 @@
$(this).animate(o.animateOpen, o.openDuration, o.easing, function() {
// Fixes some anti-aliasing issues with IE filters.
- if ($.browser.msie && (parseInt($(this).css('opacity'), 10) === 1 || parseInt($(this).css('opacity'), 10) === 0))
+ if ((navigator.userAgent.match(/MSIE ([1-9])/) !== null) && (parseInt($(this).css('opacity'), 10) === 1 || parseInt($(this).css('opacity'), 10) === 0))
this.style.removeAttribute('filter');
if ( $(this).data("jGrowl") != null ) // Happens when a notification is closing before it's open.
@@ -247,12 +247,12 @@
$(this).trigger('jGrowl.afterOpen');
});
}
- }).bind('jGrowl.afterOpen', function() {
+ }).on('jGrowl.afterOpen', function() {
o.afterOpen.apply( notification , [notification,message,o,self.element] );
- }).bind('jGrowl.beforeClose', function() {
+ }).on('jGrowl.beforeClose', function() {
if ( o.beforeClose.apply( notification , [notification,message,o,self.element] ) != false )
$(this).trigger('jGrowl.close');
- }).bind('jGrowl.close', function() {
+ }).on('jGrowl.close', function() {
// Pause the notification, lest during the course of animation another close event gets called.
$(this).data('jGrowl.pause', true);
$(this).animate(o.animateClose, o.closeDuration, o.easing, function() {
@@ -269,11 +269,11 @@
if ( o.corners != '' && $.fn.corner != undefined ) $(notification).corner( o.corners );
/** Add a Global Closer if more than one notification exists **/
- if ( $('div.jGrowl-notification:parent', self.element).size() > 1 &&
- $('div.jGrowl-closer', self.element).size() == 0 && this.defaults.closer != false ) {
+ if ( $('div.jGrowl-notification:parent', self.element).length > 1 &&
+ $('div.jGrowl-closer', self.element).length == 0 && this.defaults.closer != false ) {
$(this.defaults.closerTemplate).addClass('jGrowl-closer ' + this.defaults.themeState + ' ui-corner-all').addClass(this.defaults.theme)
.appendTo(self.element).animate(this.defaults.animateOpen, this.defaults.speed, this.defaults.easing)
- .bind("click.jGrowl", function() {
+ .on("click.jGrowl", function() {
$(this).siblings().trigger("jGrowl.beforeClose");
if ( $.isFunction( self.defaults.closer ) ) {
@@ -297,10 +297,10 @@
});
if ( this.notifications.length > 0 &&
- (this.defaults.pool == 0 || $(this.element).find('div.jGrowl-notification:parent').size() < this.defaults.pool) )
+ (this.defaults.pool == 0 || $(this.element).find('div.jGrowl-notification:parent').length < this.defaults.pool) )
this.render( this.notifications.shift() );
- if ( $(this.element).find('div.jGrowl-notification:parent').size() < 2 ) {
+ if ( $(this.element).find('div.jGrowl-notification:parent').length < 2 ) {
$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose, this.defaults.speed, this.defaults.easing, function() {
$(this).remove();
});
@@ -314,7 +314,7 @@
$(e).data('jGrowl.instance').update();
}, parseInt(this.defaults.check));
- if ($.browser.msie && parseInt($.browser.version) < 7 && !window["XMLHttpRequest"]) {
+ if ((navigator.userAgent.match(/MSIE ([2-6]\.)/) !== null) && !window["XMLHttpRequest"]) {
$(this.element).addClass('ie6');
}
},
diff --git a/root/opt/phpsysinfo/js/jQuery/jquery.js b/root/opt/phpsysinfo/js/jQuery/jquery.js
index eed1777..b944564 100644
--- a/root/opt/phpsysinfo/js/jQuery/jquery.js
+++ b/root/opt/phpsysinfo/js/jQuery/jquery.js
@@ -1,15 +1,15 @@
/*!
- * jQuery JavaScript Library v2.1.4
+ * jQuery JavaScript Library v1.12.4-ff3fix-ff2fix-CVE_2015_9251fix-CVE_2019_11358fix-CVE_2020_11022fix-CVE_2020_11023fix
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
+ * Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2015-04-28T16:01Z
+ * Date: 2016-05-20T17:17Z
*/
(function( global, factory ) {
@@ -41,17 +41,18 @@
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
-//
+//"use strict";
+var deletedIds = [];
-var arr = [];
+var document = window.document;
-var slice = arr.slice;
+var slice = deletedIds.slice;
-var concat = arr.concat;
+var concat = deletedIds.concat;
-var push = arr.push;
+var push = deletedIds.push;
-var indexOf = arr.indexOf;
+var indexOf = deletedIds.indexOf;
var class2type = {};
@@ -64,19 +65,17 @@ var support = {};
var
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- version = "2.1.4",
+ version = "1.12.4",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
+
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
},
- // Support: Android<4.1
+ // Support: Android<4.1, IE<9
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
@@ -90,6 +89,7 @@ var
};
jQuery.fn = jQuery.prototype = {
+
// The current version of jQuery being used
jquery: version,
@@ -133,16 +133,14 @@ jQuery.fn = jQuery.prototype = {
},
// Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
+ each: function( callback ) {
+ return jQuery.each( this, callback );
},
map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
return callback.call( elem, i, elem );
- }));
+ } ) );
},
slice: function() {
@@ -160,23 +158,23 @@ jQuery.fn = jQuery.prototype = {
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
},
end: function() {
- return this.prevObject || this.constructor(null);
+ return this.prevObject || this.constructor();
},
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
- sort: arr.sort,
- splice: arr.splice
+ sort: deletedIds.sort,
+ splice: deletedIds.splice
};
jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
+ var src, copyIsArray, copy, name, options, clone,
+ target = arguments[ 0 ] || {},
i = 1,
length = arguments.length,
deep = false;
@@ -185,43 +183,48 @@ jQuery.extend = jQuery.fn.extend = function() {
if ( typeof target === "boolean" ) {
deep = target;
- // Skip the boolean and the target
+ // skip the boolean and the target
target = arguments[ i ] || {};
i++;
}
// Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
target = {};
}
- // Extend jQuery itself if only one argument is passed
+ // extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
i--;
}
for ( ; i < length; i++ ) {
+
// Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
+ if ( ( options = arguments[ i ] ) != null ) {
+
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
+ // Prevent Object.prototype pollution
// Prevent never-ending loop
- if ( target === copy ) {
+ if ( name === "__proto__" || target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+
if ( copyIsArray ) {
copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
+ clone = src && jQuery.isArray( src ) ? src : [];
} else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
}
// Never move original objects, clone them
@@ -239,7 +242,8 @@ jQuery.extend = jQuery.fn.extend = function() {
return target;
};
-jQuery.extend({
+jQuery.extend( {
+
// Unique for each copy of jQuery on the page
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
@@ -252,41 +256,30 @@ jQuery.extend({
noop: function() {},
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
+ return jQuery.type( obj ) === "function";
},
- isArray: Array.isArray,
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type( obj ) === "array";
+ },
isWindow: function( obj ) {
- return obj != null && obj === obj.window;
+ /* jshint eqeqeq: false */
+ return obj != null && obj == obj.window;
},
isNumeric: function( obj ) {
+
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
// adding 1 corrects loss of precision from parseFloat (#15100)
- return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
- },
-
- isPlainObject: function( obj ) {
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.constructor &&
- !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
- return false;
- }
-
- // If the function hasn't returned already, we're confident that
- // |obj| is a plain object, created by {} or constructed with new Object
- return true;
+ var realStringObj = obj && obj.toString();
+ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
},
isEmptyObject: function( obj ) {
@@ -297,41 +290,69 @@ jQuery.extend({
return true;
},
+ isPlainObject: function( obj ) {
+ var key;
+
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ try {
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call( obj, "constructor" ) &&
+ !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
+ return false;
+ }
+ } catch ( e ) {
+
+ // IE8,9 Will throw exceptions on certain host objects #9897
+ return false;
+ }
+
+ // Support: IE<9
+ // Handle iteration over inherited properties before own properties.
+ if ( !support.ownFirst ) {
+ for ( key in obj ) {
+ return hasOwn.call( obj, key );
+ }
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
type: function( obj ) {
if ( obj == null ) {
return obj + "";
}
- // Support: Android<4.0, iOS<6 (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call(obj) ] || "object" :
+ class2type[ toString.call( obj ) ] || "object" :
typeof obj;
},
- // Evaluates a script in a global context
- globalEval: function( code ) {
- var script,
- indirect = eval;
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && jQuery.trim( data ) ) {
- code = jQuery.trim( code );
-
- if ( code ) {
- // If the code includes a valid, prologue position
- // strict mode pragma, execute code by injecting a
- // script tag into the document.
- if ( code.indexOf("use strict") === 1 ) {
- script = document.createElement("script");
- script.text = code;
- document.head.appendChild( script ).parentNode.removeChild( script );
- } else {
- // Otherwise, avoid the DOM node creation, insertion
- // and removal by using an indirect global eval
- indirect( code );
- }
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
+ } )( data );
}
},
// Convert dashed to camelCase; used by the css and data modules
- // Support: IE9-11+
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
@@ -341,49 +362,20 @@ jQuery.extend({
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
},
- // args is for internal usage only
- each: function( obj, callback, args ) {
- var value,
- i = 0,
- length = obj.length,
- isArray = isArraylike( obj );
+ each: function( obj, callback ) {
+ var length, i = 0;
- if ( args ) {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
}
}
-
- // A special, fast, case for the most common use of each
} else {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
}
}
}
@@ -391,7 +383,7 @@ jQuery.extend({
return obj;
},
- // Support: Android<4.1
+ // Support: Android<4.1, IE<9
trim: function( text ) {
return text == null ?
"" :
@@ -403,7 +395,7 @@ jQuery.extend({
var ret = results || [];
if ( arr != null ) {
- if ( isArraylike( Object(arr) ) ) {
+ if ( isArrayLike( Object( arr ) ) ) {
jQuery.merge( ret,
typeof arr === "string" ?
[ arr ] : arr
@@ -417,7 +409,26 @@ jQuery.extend({
},
inArray: function( elem, arr, i ) {
- return arr == null ? -1 : indexOf.call( arr, elem, i );
+ var len;
+
+ if ( arr ) {
+ if ( indexOf ) {
+ return indexOf.call( arr, elem, i );
+ }
+
+ len = arr.length;
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+ for ( ; i < len; i++ ) {
+
+ // Skip accessing in sparse arrays
+ if ( i in arr && arr[ i ] === elem ) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
},
merge: function( first, second ) {
@@ -425,8 +436,16 @@ jQuery.extend({
j = 0,
i = first.length;
- for ( ; j < len; j++ ) {
- first[ i++ ] = second[ j ];
+ while ( j < len ) {
+ first[ i++ ] = second[ j++ ];
+ }
+
+ // Support: IE<9
+ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
+ if ( len !== len ) {
+ while ( second[ j ] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
}
first.length = i;
@@ -455,14 +474,13 @@ jQuery.extend({
// arg is for internal usage only
map: function( elems, callback, arg ) {
- var value,
+ var length, value,
i = 0,
- length = elems.length,
- isArray = isArraylike( elems ),
ret = [];
// Go through the array, translating each of the items to their new values
- if ( isArray ) {
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
@@ -492,7 +510,7 @@ jQuery.extend({
// Bind a function to a context, optionally partially applying any
// arguments.
proxy: function( fn, context ) {
- var tmp, args, proxy;
+ var args, proxy, tmp;
if ( typeof context === "string" ) {
tmp = fn[ context ];
@@ -518,48 +536,57 @@ jQuery.extend({
return proxy;
},
- now: Date.now,
+ now: function() {
+ return +( new Date() );
+ },
// jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support: support
-});
+} );
+
+// JSHint would error on this code due to the Symbol not being defined in ES5.
+// Defining this global in .jshintrc would create a danger of using the global
+// unguarded in another place, it seems safer to just disable JSHint for these
+// three lines.
+/* jshint ignore: start */
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
+}
+/* jshint ignore: end */
// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
+} );
-function isArraylike( obj ) {
+function isArrayLike( obj ) {
// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
- var length = "length" in obj && obj.length,
+ var length = !!obj && "length" in obj && obj.length,
type = jQuery.type( obj );
if ( type === "function" || jQuery.isWindow( obj ) ) {
return false;
}
- if ( obj.nodeType === 1 && length ) {
- return true;
- }
-
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
var Sizzle =
/*!
- * Sizzle CSS Selector Engine v2.2.0-pre
+ * Sizzle CSS Selector Engine v2.2.1
* http://sizzlejs.com/
*
- * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
+ * Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2014-12-16
+ * Date: 2015-10-17
*/
(function( window ) {
@@ -627,25 +654,21 @@ var i,
// Regular expressions
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ // http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
// Operator (capture 2)
"*([*^$|!~]?=)" + whitespace +
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
"*\\]",
- pseudos = ":(" + characterEncoding + ")(?:\\((" +
+ pseudos = ":(" + identifier + ")(?:\\((" +
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
// 1. quoted (capture 3; capture 4 or capture 5)
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
@@ -668,9 +691,9 @@ var i,
ridentifier = new RegExp( "^" + identifier + "$" ),
matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
"ATTR": new RegExp( "^" + attributes ),
"PSEUDO": new RegExp( "^" + pseudos ),
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
@@ -748,103 +771,129 @@ try {
}
function Sizzle( selector, context, results, seed ) {
- var match, elem, m, nodeType,
- // QSA vars
- i, groups, old, nid, newContext, newSelector;
+ var m, i, elem, nid, nidselect, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
- context = context || document;
results = results || [];
- nodeType = context.nodeType;
+ // Return early from calls with invalid selector or context
if ( typeof selector !== "string" || !selector ||
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
return results;
}
- if ( !seed && documentIsHTML ) {
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
- // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document (jQuery #6963)
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
results.push( elem );
return results;
}
- } else {
- return results;
}
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && support.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // QSA path
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- nid = old = expando;
- newContext = context;
- newSelector = nodeType !== 1 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + toSelector( groups[i] );
- }
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
+ while ( i-- ) {
+ groups[i] = nidselect + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
}
}
}
@@ -857,7 +906,7 @@ function Sizzle( selector, context, results, seed ) {
/**
* Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
* deleting the oldest entry
*/
@@ -912,7 +961,7 @@ function assert( fn ) {
*/
function addHandle( attrs, handler ) {
var arr = attrs.split("|"),
- i = attrs.length;
+ i = arr.length;
while ( i-- ) {
Expr.attrHandle[ arr[i] ] = handler;
@@ -1025,33 +1074,29 @@ setDocument = Sizzle.setDocument = function( node ) {
var hasCompare, parent,
doc = node ? node.ownerDocument || node : preferredDoc;
- // If no document and documentElement is available, return
+ // Return early if doc is invalid or already selected
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
return document;
}
- // Set our document
+ // Update global variables
document = doc;
- docElem = doc.documentElement;
- parent = doc.defaultView;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
- // Support: IE>8
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
- // IE6-8 do not support the defaultView property so parent will be undefined
- if ( parent && parent !== parent.top ) {
- // IE11 does not have attachEvent, so all must suffer
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( (parent = document.defaultView) && parent.top !== parent ) {
+ // Support: IE 11
if ( parent.addEventListener ) {
parent.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
} else if ( parent.attachEvent ) {
parent.attachEvent( "onunload", unloadHandler );
}
}
- /* Support tests
- ---------------------------------------------------------------------- */
- documentIsHTML = !isXML( doc );
-
/* Attributes
---------------------------------------------------------------------- */
@@ -1068,12 +1113,12 @@ setDocument = Sizzle.setDocument = function( node ) {
// Check if getElementsByTagName("*") returns only elements
support.getElementsByTagName = assert(function( div ) {
- div.appendChild( doc.createComment("") );
+ div.appendChild( document.createComment("") );
return !div.getElementsByTagName("*").length;
});
// Support: IE<9
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
// Support: IE<10
// Check if getElementById returns elements by name
@@ -1081,7 +1126,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// so use a roundabout getElementsByName test
support.getById = assert(function( div ) {
docElem.appendChild( div ).id = expando;
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
});
// ID find and filter
@@ -1089,9 +1134,7 @@ setDocument = Sizzle.setDocument = function( node ) {
Expr.find["ID"] = function( id, context ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [ m ] : [];
+ return m ? [ m ] : [];
}
};
Expr.filter["ID"] = function( id ) {
@@ -1108,7 +1151,8 @@ setDocument = Sizzle.setDocument = function( node ) {
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
return node && node.value === attrId;
};
};
@@ -1148,7 +1192,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( documentIsHTML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
return context.getElementsByClassName( className );
}
};
@@ -1168,7 +1212,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [];
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini
assert(function( div ) {
@@ -1178,7 +1222,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
docElem.appendChild( div ).innerHTML = " " +
- "" +
+ "" +
" ";
// Support: IE8, Opera 11-12.16
@@ -1195,7 +1239,7 @@ setDocument = Sizzle.setDocument = function( node ) {
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
}
- // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
rbuggyQSA.push("~=");
}
@@ -1218,7 +1262,7 @@ setDocument = Sizzle.setDocument = function( node ) {
assert(function( div ) {
// Support: Windows 8 Native Apps
// The type and name attributes are restricted during .innerHTML assignment
- var input = doc.createElement("input");
+ var input = document.createElement("input");
input.setAttribute( "type", "hidden" );
div.appendChild( input ).setAttribute( "name", "D" );
@@ -1266,7 +1310,7 @@ setDocument = Sizzle.setDocument = function( node ) {
hasCompare = rnative.test( docElem.compareDocumentPosition );
// Element contains another
- // Purposefully does not implement inclusive descendent
+ // Purposefully self-exclusive
// As in, an element does not contain itself
contains = hasCompare || rnative.test( docElem.contains ) ?
function( a, b ) {
@@ -1320,10 +1364,10 @@ setDocument = Sizzle.setDocument = function( node ) {
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
// Choose the first element that is related to our preferred document
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
return -1;
}
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
return 1;
}
@@ -1351,8 +1395,8 @@ setDocument = Sizzle.setDocument = function( node ) {
// Parentless nodes are either documents or disconnected
if ( !aup || !bup ) {
- return a === doc ? -1 :
- b === doc ? 1 :
+ return a === document ? -1 :
+ b === document ? 1 :
aup ? -1 :
bup ? 1 :
sortInput ?
@@ -1389,7 +1433,7 @@ setDocument = Sizzle.setDocument = function( node ) {
0;
};
- return doc;
+ return document;
};
Sizzle.matches = function( expr, elements ) {
@@ -1406,6 +1450,7 @@ Sizzle.matchesSelector = function( elem, expr ) {
expr = expr.replace( rattributeQuotes, "='$1']" );
if ( support.matchesSelector && documentIsHTML &&
+ !compilerCache[ expr + " " ] &&
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
@@ -1679,11 +1724,12 @@ Expr = Sizzle.selectors = {
} :
function( elem, context, xml ) {
- var cache, outerCache, node, diff, nodeIndex, start,
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
dir = simple !== forward ? "nextSibling" : "previousSibling",
parent = elem.parentNode,
name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType;
+ useCache = !xml && !ofType,
+ diff = false;
if ( parent ) {
@@ -1692,7 +1738,10 @@ Expr = Sizzle.selectors = {
while ( dir ) {
node = elem;
while ( (node = node[ dir ]) ) {
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
return false;
}
}
@@ -1706,11 +1755,21 @@ Expr = Sizzle.selectors = {
// non-xml :nth-child(...) stores cache data on `parent`
if ( forward && useCache ) {
+
// Seek `elem` from a previously-cached index
- outerCache = parent[ expando ] || (parent[ expando ] = {});
- cache = outerCache[ type ] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = cache[0] === dirruns && cache[2];
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
node = nodeIndex && parent.childNodes[ nodeIndex ];
while ( (node = ++nodeIndex && node && node[ dir ] ||
@@ -1720,29 +1779,55 @@ Expr = Sizzle.selectors = {
// When found, cache indexes on `parent` and break
if ( node.nodeType === 1 && ++diff && node === elem ) {
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
break;
}
}
- // Use previously-cached element index if available
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
- diff = cache[1];
-
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
} else {
- // Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
- // Cache the index of each encountered element
- if ( useCache ) {
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
- }
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
- if ( node === elem ) {
- break;
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
}
}
}
@@ -2104,10 +2189,10 @@ function addCombinator( matcher, combinator, base ) {
// Check against all ancestor/preceding elements
function( elem, context, xml ) {
- var oldCache, outerCache,
+ var oldCache, uniqueCache, outerCache,
newCache = [ dirruns, doneName ];
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
if ( xml ) {
while ( (elem = elem[ dir ]) ) {
if ( elem.nodeType === 1 || checkNonElements ) {
@@ -2120,14 +2205,19 @@ function addCombinator( matcher, combinator, base ) {
while ( (elem = elem[ dir ]) ) {
if ( elem.nodeType === 1 || checkNonElements ) {
outerCache = elem[ expando ] || (elem[ expando ] = {});
- if ( (oldCache = outerCache[ dir ]) &&
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( (oldCache = uniqueCache[ dir ]) &&
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
// Assign to newCache so results back-propagate to previous elements
return (newCache[ 2 ] = oldCache[ 2 ]);
} else {
// Reuse newcache so results back-propagate to previous elements
- outerCache[ dir ] = newCache;
+ uniqueCache[ dir ] = newCache;
// A match means we're done; a fail means we have to keep checking
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
@@ -2352,18 +2442,21 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
len = elems.length;
if ( outermost ) {
- outermostContext = context !== document && context;
+ outermostContext = context === document || context || outermost;
}
// Add elements passing elementMatchers directly to results
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
// Support: IE<9, Safari
// Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
if ( byElement && elem ) {
j = 0;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context, xml ) ) {
+ if ( matcher( elem, context || document, xml) ) {
results.push( elem );
break;
}
@@ -2387,8 +2480,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
}
}
- // Apply set filters to unmatched elements
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
if ( bySet && i !== matchedCount ) {
j = 0;
while ( (matcher = setMatchers[j++]) ) {
@@ -2480,10 +2582,11 @@ select = Sizzle.select = function( selector, context, results, seed ) {
results = results || [];
- // Try to minimize operations if there is no seed and only one group
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
if ( match.length === 1 ) {
- // Take a shortcut and set the context if the root selector is an ID
+ // Reduce context if the leading compound selector is an ID
tokens = match[0] = match[0].slice( 0 );
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
support.getById && context.nodeType === 9 && documentIsHTML &&
@@ -2538,7 +2641,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
context,
!documentIsHTML,
results,
- rsibling.test( selector ) && testContext( context.parentNode ) || context
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
);
return results;
};
@@ -2614,17 +2717,46 @@ return Sizzle;
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
var rneedsContext = jQuery.expr.match.needsContext;
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
+var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
@@ -2636,14 +2768,14 @@ function winnow( elements, qualifier, not ) {
return jQuery.grep( elements, function( elem, i ) {
/* jshint -W018 */
return !!qualifier.call( elem, i, elem ) !== not;
- });
+ } );
}
if ( qualifier.nodeType ) {
return jQuery.grep( elements, function( elem ) {
return ( elem === qualifier ) !== not;
- });
+ } );
}
@@ -2656,8 +2788,8 @@ function winnow( elements, qualifier, not ) {
}
return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
- });
+ return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
+ } );
}
jQuery.filter = function( expr, elems, not ) {
@@ -2671,24 +2803,24 @@ jQuery.filter = function( expr, elems, not ) {
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
return elem.nodeType === 1;
- }));
+ } ) );
};
-jQuery.fn.extend({
+jQuery.fn.extend( {
find: function( selector ) {
var i,
- len = this.length,
ret = [],
- self = this;
+ self = this,
+ len = self.length;
if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter(function() {
+ return this.pushStack( jQuery( selector ).filter( function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
- }) );
+ } ) );
}
for ( i = 0; i < len; i++ ) {
@@ -2701,10 +2833,10 @@ jQuery.fn.extend({
return ret;
},
filter: function( selector ) {
- return this.pushStack( winnow(this, selector || [], false) );
+ return this.pushStack( winnow( this, selector || [], false ) );
},
not: function( selector ) {
- return this.pushStack( winnow(this, selector || [], true) );
+ return this.pushStack( winnow( this, selector || [], true ) );
},
is: function( selector ) {
return !!winnow(
@@ -2718,7 +2850,7 @@ jQuery.fn.extend({
false
).length;
}
-});
+} );
// Initialize a jQuery object
@@ -2732,7 +2864,7 @@ var rootjQuery,
// Strict HTML recognition (#11290: must start with <)
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
- init = jQuery.fn.init = function( selector, context ) {
+ init = jQuery.fn.init = function( selector, context, root ) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
@@ -2740,9 +2872,16 @@ var rootjQuery,
return this;
}
+ // init accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
// Handle HTML strings
if ( typeof selector === "string" ) {
- if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
+ if ( selector.charAt( 0 ) === "<" &&
+ selector.charAt( selector.length - 1 ) === ">" &&
+ selector.length >= 3 ) {
+
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
@@ -2751,23 +2890,24 @@ var rootjQuery,
}
// Match html or make sure no context is specified for #id
- if ( match && (match[1] || !context) ) {
+ if ( match && ( match[ 1 ] || !context ) ) {
// HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ? context[0] : context;
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
- // Option to run scripts is true for back-compat
+ // scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge( this, jQuery.parseHTML(
- match[1],
+ match[ 1 ],
context && context.nodeType ? context.ownerDocument || context : document,
true
) );
// HANDLE: $(html, props)
- if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
for ( match in context ) {
+
// Properties of context are called as methods if possible
if ( jQuery.isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );
@@ -2783,14 +2923,21 @@ var rootjQuery,
// HANDLE: $(#id)
} else {
- elem = document.getElementById( match[2] );
+ elem = document.getElementById( match[ 2 ] );
- // Support: Blackberry 4.6
- // gEBID returns nodes no longer in the document (#6963)
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
- // Inject the element directly into the jQuery object
+
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[ 2 ] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
this.length = 1;
- this[0] = elem;
+ this[ 0 ] = elem;
}
this.context = document;
@@ -2800,7 +2947,7 @@ var rootjQuery,
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector );
+ return ( context || root ).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
@@ -2810,15 +2957,16 @@ var rootjQuery,
// HANDLE: $(DOMElement)
} else if ( selector.nodeType ) {
- this.context = this[0] = selector;
+ this.context = this[ 0 ] = selector;
this.length = 1;
return this;
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
- return typeof rootjQuery.ready !== "undefined" ?
- rootjQuery.ready( selector ) :
+ return typeof root.ready !== "undefined" ?
+ root.ready( selector ) :
+
// Execute immediately if ready is not present
selector( jQuery );
}
@@ -2839,7 +2987,8 @@ rootjQuery = jQuery( document );
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // Methods guaranteed to produce a unique set when starting from a unique set
+
+ // methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = {
children: true,
contents: true,
@@ -2847,48 +2996,19 @@ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
prev: true
};
-jQuery.extend({
- dir: function( elem, dir, until ) {
- var matched = [],
- truncate = until !== undefined;
-
- while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
- }
- }
- return matched;
- },
-
- sibling: function( n, elem ) {
- var matched = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
- }
- }
-
- return matched;
- }
-});
-
-jQuery.fn.extend({
+jQuery.fn.extend( {
has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
+ var i,
+ targets = jQuery( target, this ),
+ len = targets.length;
- return this.filter(function() {
- var i = 0;
- for ( ; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
+ return this.filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
return true;
}
}
- });
+ } );
},
closest: function( selectors, context ) {
@@ -2901,14 +3021,15 @@ jQuery.fn.extend({
0;
for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
// Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
+ if ( cur.nodeType < 11 && ( pos ?
+ pos.index( cur ) > -1 :
// Don't pass non-elements to Sizzle
cur.nodeType === 1 &&
- jQuery.find.matchesSelector(cur, selectors)) ) {
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
matched.push( cur );
break;
@@ -2916,10 +3037,11 @@ jQuery.fn.extend({
}
}
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
},
- // Determine the position of an element within the set
+ // Determine the position of an element within
+ // the matched set of elements
index: function( elem ) {
// No argument, return index in parent
@@ -2927,22 +3049,21 @@ jQuery.fn.extend({
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
}
- // Index in selector
+ // index in selector
if ( typeof elem === "string" ) {
- return indexOf.call( jQuery( elem ), this[ 0 ] );
+ return jQuery.inArray( this[ 0 ], jQuery( elem ) );
}
// Locate the position of the desired element
- return indexOf.call( this,
+ return jQuery.inArray(
// If it receives a jQuery object, the first element is used
- elem.jquery ? elem[ 0 ] : elem
- );
+ elem.jquery ? elem[ 0 ] : elem, this );
},
add: function( selector, context ) {
return this.pushStack(
- jQuery.unique(
+ jQuery.uniqueSort(
jQuery.merge( this.get(), jQuery( selector, context ) )
)
);
@@ -2950,26 +3071,29 @@ jQuery.fn.extend({
addBack: function( selector ) {
return this.add( selector == null ?
- this.prevObject : this.prevObject.filter(selector)
+ this.prevObject : this.prevObject.filter( selector )
);
}
-});
+} );
function sibling( cur, dir ) {
- while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
+ do {
+ cur = cur[ dir ];
+ } while ( cur && cur.nodeType !== 1 );
+
return cur;
}
-jQuery.each({
+jQuery.each( {
parent: function( elem ) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
+ return dir( elem, "parentNode" );
},
parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
+ return dir( elem, "parentNode", until );
},
next: function( elem ) {
return sibling( elem, "nextSibling" );
@@ -2978,66 +3102,66 @@ jQuery.each({
return sibling( elem, "previousSibling" );
},
nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
+ return dir( elem, "nextSibling" );
},
prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
+ return dir( elem, "previousSibling" );
},
nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
+ return dir( elem, "nextSibling", until );
},
prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
+ return dir( elem, "previousSibling", until );
},
siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
},
children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
+ return siblings( elem.firstChild );
},
contents: function( elem ) {
- return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.merge( [], elem.childNodes );
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
+ var ret = jQuery.map( this, fn, until );
if ( name.slice( -5 ) !== "Until" ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
+ ret = jQuery.filter( selector, ret );
}
if ( this.length > 1 ) {
+
// Remove duplicates
if ( !guaranteedUnique[ name ] ) {
- jQuery.unique( matched );
+ ret = jQuery.uniqueSort( ret );
}
// Reverse order for parents* and prev-derivatives
if ( rparentsprev.test( name ) ) {
- matched.reverse();
+ ret = ret.reverse();
}
}
- return this.pushStack( matched );
+ return this.pushStack( ret );
};
-});
-var rnotwhite = (/\S+/g);
+} );
+var rnotwhite = ( /\S+/g );
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in cache
+// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
- var object = optionsCache[ options ] = {};
+ var object = {};
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
object[ flag ] = true;
- });
+ } );
return object;
}
@@ -3068,156 +3192,186 @@ jQuery.Callbacks = function( options ) {
// Convert options from String-formatted to Object-formatted if needed
// (we check in cache first)
options = typeof options === "string" ?
- ( optionsCache[ options ] || createOptions( options ) ) :
+ createOptions( options ) :
jQuery.extend( {}, options );
- var // Last fire value (for non-forgettable lists)
+ var // Flag to know if list is currently firing
+ firing,
+
+ // Last fire value for non-forgettable lists
memory,
+
// Flag to know if list was already fired
fired,
- // Flag to know if list is currently firing
- firing,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if needed)
- firingIndex,
+
+ // Flag to prevent firing
+ locked,
+
// Actual callback list
list = [],
- // Stack of fire calls for repeatable lists
- stack = !options.once && [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
// Fire callbacks
- fire = function( data ) {
- memory = options.memory && data;
- fired = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- firing = true;
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
- if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
- memory = false; // To prevent further calls using add
- break;
+ fire = function() {
+
+ // Enforce single-firing
+ locked = options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
}
}
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
firing = false;
- if ( list ) {
- if ( stack ) {
- if ( stack.length ) {
- fire( stack.shift() );
- }
- } else if ( memory ) {
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
list = [];
+
+ // Otherwise, this object is spent
} else {
- self.disable();
+ list = "";
}
}
},
+
// Actual Callbacks object
self = {
+
// Add a callback or a collection of callbacks to the list
add: function() {
if ( list ) {
- // First, we save the current length
- var start = list.length;
- (function add( args ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
jQuery.each( args, function( _, arg ) {
- var type = jQuery.type( arg );
- if ( type === "function" ) {
+ if ( jQuery.isFunction( arg ) ) {
if ( !options.unique || !self.has( arg ) ) {
list.push( arg );
}
- } else if ( arg && arg.length && type !== "string" ) {
+ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
+
// Inspect recursively
add( arg );
}
- });
- })( arguments );
- // Do we need to add the callbacks to the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away
- } else if ( memory ) {
- firingStart = start;
- fire( memory );
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
}
}
return this;
},
+
// Remove a callback from the list
remove: function() {
- if ( list ) {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
- // Handle firing indexes
- if ( firing ) {
- if ( index <= firingLength ) {
- firingLength--;
- }
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ if ( index <= firingIndex ) {
+ firingIndex--;
}
- });
- }
+ }
+ } );
return this;
},
+
// Check if a given callback is in the list.
// If no argument is given, return whether or not list has callbacks attached.
has: function( fn ) {
- return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+ return fn ?
+ jQuery.inArray( fn, list ) > -1 :
+ list.length > 0;
},
+
// Remove all callbacks from the list
empty: function() {
- list = [];
- firingLength = 0;
+ if ( list ) {
+ list = [];
+ }
return this;
},
- // Have the list do nothing anymore
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
disable: function() {
- list = stack = memory = undefined;
+ locked = queue = [];
+ list = memory = "";
return this;
},
- // Is it disabled?
disabled: function() {
return !list;
},
- // Lock the list in its current state
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
lock: function() {
- stack = undefined;
+ locked = true;
if ( !memory ) {
self.disable();
}
return this;
},
- // Is it locked?
locked: function() {
- return !stack;
+ return !!locked;
},
+
// Call all callbacks with the given context and arguments
fireWith: function( context, args ) {
- if ( list && ( !fired || stack ) ) {
+ if ( !locked ) {
args = args || [];
args = [ context, args.slice ? args.slice() : args ];
- if ( firing ) {
- stack.push( args );
- } else {
- fire( args );
+ queue.push( args );
+ if ( !firing ) {
+ fire();
}
}
return this;
},
+
// Call all the callbacks with the given arguments
fire: function() {
self.fireWith( this, arguments );
return this;
},
+
// To know if the callbacks have already been called at least once
fired: function() {
return !!fired;
@@ -3228,14 +3382,15 @@ jQuery.Callbacks = function( options ) {
};
-jQuery.extend({
+jQuery.extend( {
Deferred: function( func ) {
var tuples = [
+
// action, add listener, listener list, final state
- [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
- [ "notify", "progress", jQuery.Callbacks("memory") ]
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
+ [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
],
state = "pending",
promise = {
@@ -3248,25 +3403,30 @@ jQuery.extend({
},
then: function( /* fnDone, fnFail, fnProgress */ ) {
var fns = arguments;
- return jQuery.Deferred(function( newDefer ) {
+ return jQuery.Deferred( function( newDefer ) {
jQuery.each( tuples, function( i, tuple ) {
var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+
// deferred[ done | fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[1] ](function() {
+ deferred[ tuple[ 1 ] ]( function() {
var returned = fn && fn.apply( this, arguments );
if ( returned && jQuery.isFunction( returned.promise ) ) {
returned.promise()
+ .progress( newDefer.notify )
.done( newDefer.resolve )
- .fail( newDefer.reject )
- .progress( newDefer.notify );
+ .fail( newDefer.reject );
} else {
- newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+ newDefer[ tuple[ 0 ] + "With" ](
+ this === promise ? newDefer.promise() : this,
+ fn ? [ returned ] : arguments
+ );
}
- });
- });
+ } );
+ } );
fns = null;
- }).promise();
+ } ).promise();
},
+
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function( obj ) {
@@ -3284,11 +3444,12 @@ jQuery.extend({
stateString = tuple[ 3 ];
// promise[ done | fail | progress ] = list.add
- promise[ tuple[1] ] = list.add;
+ promise[ tuple[ 1 ] ] = list.add;
// Handle state
if ( stateString ) {
- list.add(function() {
+ list.add( function() {
+
// state = [ resolved | rejected ]
state = stateString;
@@ -3297,12 +3458,12 @@ jQuery.extend({
}
// deferred[ resolve | reject | notify ]
- deferred[ tuple[0] ] = function() {
- deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
return this;
};
- deferred[ tuple[0] + "With" ] = list.fireWith;
- });
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+ } );
// Make the deferred a promise
promise.promise( deferred );
@@ -3323,9 +3484,11 @@ jQuery.extend({
length = resolveValues.length,
// the count of uncompleted subordinates
- remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+ remaining = length !== 1 ||
+ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
- // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+ // the master Deferred.
+ // If resolveValues consist of only a single Deferred, just use that.
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
// Update function for both resolve and progress values
@@ -3335,6 +3498,7 @@ jQuery.extend({
values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
if ( values === progressValues ) {
deferred.notifyWith( contexts, values );
+
} else if ( !( --remaining ) ) {
deferred.resolveWith( contexts, values );
}
@@ -3343,7 +3507,7 @@ jQuery.extend({
progressValues, progressContexts, resolveContexts;
- // Add listeners to Deferred subordinates; treat others as resolved
+ // add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
@@ -3351,36 +3515,38 @@ jQuery.extend({
for ( ; i < length; i++ ) {
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
resolveValues[ i ].promise()
+ .progress( updateFunc( i, progressContexts, progressValues ) )
.done( updateFunc( i, resolveContexts, resolveValues ) )
- .fail( deferred.reject )
- .progress( updateFunc( i, progressContexts, progressValues ) );
+ .fail( deferred.reject );
} else {
--remaining;
}
}
}
- // If we're not waiting on anything, resolve the master
+ // if we're not waiting on anything, resolve the master
if ( !remaining ) {
deferred.resolveWith( resolveContexts, resolveValues );
}
return deferred.promise();
}
-});
+} );
// The deferred used on DOM ready
var readyList;
jQuery.fn.ready = function( fn ) {
+
// Add the callback
jQuery.ready.promise().done( fn );
return this;
};
-jQuery.extend({
+jQuery.extend( {
+
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
@@ -3422,36 +3588,98 @@ jQuery.extend({
jQuery( document ).off( "ready" );
}
}
-});
+} );
+
+/**
+ * Clean-up method for dom ready events
+ */
+function detach() {
+ if ( document.addEventListener ) {
+ document.removeEventListener( "DOMContentLoaded", completed, false );
+ window.removeEventListener( "load", completed, false );
+
+ } else {
+ document.detachEvent( "onreadystatechange", completed );
+ window.detachEvent( "onload", completed );
+ }
+}
/**
* The ready event handler and self cleanup method
*/
function completed() {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
- jQuery.ready();
+
+ // readyState === "complete" is good enough for us to call the dom ready in oldIE
+ if ( document.addEventListener ||
+ window.event.type === "load" ||
+ document.readyState === "complete" ) {
+
+ detach();
+ jQuery.ready();
+ }
}
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
-
readyList = jQuery.Deferred();
- // Catch cases where $(document).ready() is called after the browser event has already occurred.
- // We once tried to use readyState "interactive" here, but it caused issues like the one
- // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- setTimeout( jQuery.ready );
+ // Catch cases where $(document).ready() is called
+ // after the browser event has already occurred.
+ // Support: IE6-10
+ // Older IE sometimes signals "interactive" too soon
+ if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll && (/a/[-1]!=='a') ) ) {
- } else {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+ // Standards-based browsers support DOMContentLoaded
+ } else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed, false );
+
+ // If IE event model is used
+ } else {
+
+ // Ensure firing before onload, maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", completed );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", completed );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var top = false;
+
+ try {
+ top = window.frameElement == null && document.documentElement;
+ } catch ( e ) {}
+
+ if ( top && top.doScroll ) {
+ ( function doScrollCheck() {
+ if ( !jQuery.isReady ) {
+
+ try {
+
+ // Use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ top.doScroll( "left" );
+ } catch ( e ) {
+ return window.setTimeout( doScrollCheck, 50 );
+ }
+
+ // detach all dom ready events
+ detach();
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ } )();
+ }
}
}
return readyList.promise( obj );
@@ -3463,273 +3691,99 @@ jQuery.ready.promise();
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- len = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < len; i++ ) {
- fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- len ? fn( elems[0], key ) : emptyGet;
-};
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( owner ) {
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- /* jshint -W018 */
- return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
-
-
-function Data() {
- // Support: Android<4,
- // Old WebKit does not have Object.preventExtensions/freeze method,
- // return new empty object instead with no [[set]] accessor
- Object.defineProperty( this.cache = {}, 0, {
- get: function() {
- return {};
- }
- });
-
- this.expando = jQuery.expando + Data.uid++;
+// Support: IE<9
+// Iteration over object's inherited properties before its own
+var i;
+for ( i in jQuery( support ) ) {
+ break;
}
+support.ownFirst = i === "0";
-Data.uid = 1;
-Data.accepts = jQuery.acceptData;
+// Note: most support tests are defined in their respective modules.
+// false until the test is run
+support.inlineBlockNeedsLayout = false;
-Data.prototype = {
- key: function( owner ) {
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return the key for a frozen object.
- if ( !Data.accepts( owner ) ) {
- return 0;
- }
+// Execute ASAP in case we need to set body.style.zoom
+jQuery( function() {
- var descriptor = {},
- // Check if the owner object already has a cache key
- unlock = owner[ this.expando ];
+ // Minified: var a,b,c,d
+ var val, div, body, container;
- // If not, create one
- if ( !unlock ) {
- unlock = Data.uid++;
+ body = document.getElementsByTagName( "body" )[ 0 ];
+ if ( !body || !body.style ) {
- // Secure it in a non-enumerable, non-writable property
- try {
- descriptor[ this.expando ] = { value: unlock };
- Object.defineProperties( owner, descriptor );
+ // Return for frameset docs that don't have a body
+ return;
+ }
- // Support: Android<4
- // Fallback to a less secure definition
- } catch ( e ) {
- descriptor[ this.expando ] = unlock;
- jQuery.extend( owner, descriptor );
- }
- }
+ // Setup
+ div = document.createElement( "div" );
+ container = document.createElement( "div" );
+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+ body.appendChild( container ).appendChild( div );
- // Ensure the cache object
- if ( !this.cache[ unlock ] ) {
- this.cache[ unlock ] = {};
- }
+ if ( typeof div.style.zoom !== "undefined" ) {
- return unlock;
- },
- set: function( owner, data, value ) {
- var prop,
- // There may be an unlock assigned to this node,
- // if there is no entry for this "owner", create one inline
- // and set the unlock as though an owner entry had always existed
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
+ // Support: IE<8
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
- // Handle: [ owner, key, value ] args
- if ( typeof data === "string" ) {
- cache[ data ] = value;
+ support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
+ if ( val ) {
- // Handle: [ owner, { properties } ] args
- } else {
- // Fresh assignments by object are shallow copied
- if ( jQuery.isEmptyObject( cache ) ) {
- jQuery.extend( this.cache[ unlock ], data );
- // Otherwise, copy the properties one-by-one to the cache object
- } else {
- for ( prop in data ) {
- cache[ prop ] = data[ prop ];
- }
- }
- }
- return cache;
- },
- get: function( owner, key ) {
- // Either a valid cache is found, or will be created.
- // New caches will be created and the unlock returned,
- // allowing direct access to the newly created
- // empty data object. A valid owner object must be provided.
- var cache = this.cache[ this.key( owner ) ];
-
- return key === undefined ?
- cache : cache[ key ];
- },
- access: function( owner, key, value ) {
- var stored;
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ((key && typeof key === "string") && value === undefined) ) {
-
- stored = this.get( owner, key );
-
- return stored !== undefined ?
- stored : this.get( owner, jQuery.camelCase(key) );
- }
-
- // [*]When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
-
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i, name, camel,
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
-
- if ( key === undefined ) {
- this.cache[ unlock ] = {};
-
- } else {
- // Support array or space separated string of keys
- if ( jQuery.isArray( key ) ) {
- // If "name" is an array of keys...
- // When data is initially created, via ("key", "val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument path.
- name = key.concat( key.map( jQuery.camelCase ) );
- } else {
- camel = jQuery.camelCase( key );
- // Try the string as a key before any manipulation
- if ( key in cache ) {
- name = [ key, camel ];
- } else {
- // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- name = camel;
- name = name in cache ?
- [ name ] : ( name.match( rnotwhite ) || [] );
- }
- }
-
- i = name.length;
- while ( i-- ) {
- delete cache[ name[ i ] ];
- }
- }
- },
- hasData: function( owner ) {
- return !jQuery.isEmptyObject(
- this.cache[ owner[ this.expando ] ] || {}
- );
- },
- discard: function( owner ) {
- if ( owner[ this.expando ] ) {
- delete this.cache[ owner[ this.expando ] ];
+ // Prevent IE 6 from affecting layout for positioned elements #11048
+ // Prevent IE from shrinking the body in IE 7 mode #12869
+ // Support: IE<8
+ body.style.zoom = 1;
}
}
+
+ body.removeChild( container );
+} );
+
+
+( function() {
+ var div = document.createElement( "div" );
+
+ // Support: IE<9
+ support.deleteExpando = true;
+ try {
+ delete div.test;
+ } catch ( e ) {
+ support.deleteExpando = false;
+ }
+
+ // Null elements to avoid leaks in IE.
+ div = null;
+} )();
+var acceptData = function( elem ) {
+ var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
+ nodeType = +elem.nodeType || 1;
+
+ // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
+ return nodeType !== 1 && nodeType !== 9 ?
+ false :
+
+ // Nodes accept data unless otherwise specified; rejection can be conditional
+ !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
};
-var data_priv = new Data();
-
-var data_user = new Data();
-// Implementation Summary
-//
-// 1. Enforce API surface and semantic compatibility with 1.9.x branch
-// 2. Improve the module's maintainability by reducing the storage
-// paths to a single mechanism.
-// 3. Use the same single mechanism to support "private" and "user" data.
-// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
-// 5. Avoid exposing implementation details on user objects (eg. expando properties)
-// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
rmultiDash = /([A-Z])/g;
function dataAttr( elem, key, data ) {
- var name;
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
data = elem.getAttribute( name );
if ( typeof data === "string" ) {
@@ -3737,57 +3791,275 @@ function dataAttr( elem, key, data ) {
data = data === "true" ? true :
data === "false" ? false :
data === "null" ? null :
+
// Only convert to a number if it doesn't change the string
+data + "" === data ? +data :
rbrace.test( data ) ? jQuery.parseJSON( data ) :
data;
- } catch( e ) {}
+ } catch ( e ) {}
// Make sure we set the data so it isn't changed later
- data_user.set( elem, key, data );
+ jQuery.data( elem, key, data );
+
} else {
data = undefined;
}
}
+
return data;
}
-jQuery.extend({
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+ var name;
+ for ( name in obj ) {
+
+ // if the public data object is empty, the private is still empty
+ if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
+ continue;
+ }
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
+ if ( !acceptData( elem ) ) {
+ return;
+ }
+
+ var ret, thisCache,
+ internalKey = jQuery.expando,
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
+ data === undefined && typeof name === "string" ) {
+ return;
+ }
+
+ if ( !id ) {
+
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
+ } else {
+ id = internalKey;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+
+ // Avoid exposing jQuery metadata on plain JS objects when the object
+ // is serialized using JSON.stringify
+ cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ] = jQuery.extend( cache[ id ], name );
+ } else {
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+ }
+ }
+
+ thisCache = cache[ id ];
+
+ // jQuery data() is stored in a separate object inside the object's internal data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data.
+ if ( !pvt ) {
+ if ( !thisCache.data ) {
+ thisCache.data = {};
+ }
+
+ thisCache = thisCache.data;
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( typeof name === "string" ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+ if ( !acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache, i,
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+ if ( thisCache ) {
+
+ // Support array or space separated string names for data keys
+ if ( !jQuery.isArray( name ) ) {
+
+ // try the string as a key before any manipulation
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+
+ // split the camel cased version by spaces unless a key with the spaces exists
+ name = jQuery.camelCase( name );
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+ name = name.split( " " );
+ }
+ }
+ } else {
+
+ // If "name" is an array of keys...
+ // When data is initially created, via ("key", "val") signature,
+ // keys will be converted to camelCase.
+ // Since there is no way to tell _how_ a key was added, remove
+ // both plain key and camelCase key. #12786
+ // This will only penalize the array argument path.
+ name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+ }
+
+ i = name.length;
+ while ( i-- ) {
+ delete thisCache[ name[ i ] ];
+ }
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( !pvt ) {
+ delete cache[ id ].data;
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
+ return;
+ }
+ }
+
+ // Destroy the cache
+ if ( isNode ) {
+ jQuery.cleanData( [ elem ], true );
+
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+ /* jshint eqeqeq: false */
+ } else if ( support.deleteExpando || cache != cache.window ) {
+ /* jshint eqeqeq: true */
+ delete cache[ id ];
+
+ // When all else fails, undefined
+ } else {
+ cache[ id ] = undefined;
+ }
+}
+
+jQuery.extend( {
+ cache: {},
+
+ // The following elements (space-suffixed to avoid Object.prototype collisions)
+ // throw uncatchable exceptions if you attempt to set expando properties
+ noData: {
+ "applet ": true,
+ "embed ": true,
+
+ // ...but Flash objects (which have this classid) *can* handle expandos
+ "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+ },
+
hasData: function( elem ) {
- return data_user.hasData( elem ) || data_priv.hasData( elem );
+ elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
+ return !!elem && !isEmptyDataObject( elem );
},
data: function( elem, name, data ) {
- return data_user.access( elem, name, data );
+ return internalData( elem, name, data );
},
removeData: function( elem, name ) {
- data_user.remove( elem, name );
+ return internalRemoveData( elem, name );
},
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to data_priv methods, these can be deprecated.
+ // For internal use only.
_data: function( elem, name, data ) {
- return data_priv.access( elem, name, data );
+ return internalData( elem, name, data, true );
},
_removeData: function( elem, name ) {
- data_priv.remove( elem, name );
+ return internalRemoveData( elem, name, true );
}
-});
+} );
-jQuery.fn.extend({
+jQuery.fn.extend( {
data: function( key, value ) {
var i, name, data,
elem = this[ 0 ],
attrs = elem && elem.attributes;
+ // Special expections of .data basically thwart jQuery.access,
+ // so implement the relevant behavior ourselves
+
// Gets all values
if ( key === undefined ) {
if ( this.length ) {
- data = data_user.get( elem );
+ data = jQuery.data( elem );
- if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
i = attrs.length;
while ( i-- ) {
@@ -3796,12 +4068,12 @@ jQuery.fn.extend({
if ( attrs[ i ] ) {
name = attrs[ i ].name;
if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice(5) );
+ name = jQuery.camelCase( name.slice( 5 ) );
dataAttr( elem, name, data[ name ] );
}
}
}
- data_priv.set( elem, "hasDataAttrs", true );
+ jQuery._data( elem, "parsedAttrs", true );
}
}
@@ -3810,87 +4082,43 @@ jQuery.fn.extend({
// Sets multiple values
if ( typeof key === "object" ) {
- return this.each(function() {
- data_user.set( this, key );
- });
+ return this.each( function() {
+ jQuery.data( this, key );
+ } );
}
- return access( this, function( value ) {
- var data,
- camelKey = jQuery.camelCase( key );
+ return arguments.length > 1 ?
- // The calling jQuery object (element matches) is not empty
- // (and therefore has an element appears at this[ 0 ]) and the
- // `value` parameter was not undefined. An empty jQuery object
- // will result in `undefined` for elem = this[ 0 ] which will
- // throw an exception if an attempt to read a data cache is made.
- if ( elem && value === undefined ) {
- // Attempt to get data from the cache
- // with the key as-is
- data = data_user.get( elem, key );
- if ( data !== undefined ) {
- return data;
- }
+ // Sets one value
+ this.each( function() {
+ jQuery.data( this, key, value );
+ } ) :
- // Attempt to get data from the cache
- // with the key camelized
- data = data_user.get( elem, camelKey );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, camelKey, undefined );
- if ( data !== undefined ) {
- return data;
- }
-
- // We tried really hard, but the data doesn't exist.
- return;
- }
-
- // Set the data...
- this.each(function() {
- // First, attempt to store a copy or reference of any
- // data that might've been store with a camelCased key.
- var data = data_user.get( this, camelKey );
-
- // For HTML5 data-* attribute interop, we have to
- // store property names with dashes in a camelCase form.
- // This might not apply to all properties...*
- data_user.set( this, camelKey, value );
-
- // *... In the case of properties that might _actually_
- // have dashes, we need to also store a copy of that
- // unchanged property.
- if ( key.indexOf("-") !== -1 && data !== undefined ) {
- data_user.set( this, key, value );
- }
- });
- }, null, value, arguments.length > 1, null, true );
+ // Gets one value
+ // Try to fetch any internally stored data first
+ elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
},
removeData: function( key ) {
- return this.each(function() {
- data_user.remove( this, key );
- });
+ return this.each( function() {
+ jQuery.removeData( this, key );
+ } );
}
-});
+} );
-jQuery.extend({
+jQuery.extend( {
queue: function( elem, type, data ) {
var queue;
if ( elem ) {
type = ( type || "fx" ) + "queue";
- queue = data_priv.get( elem, type );
+ queue = jQuery._data( elem, type );
// Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) {
if ( !queue || jQuery.isArray( data ) ) {
- queue = data_priv.access( elem, type, jQuery.makeArray(data) );
+ queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
} else {
queue.push( data );
}
@@ -3924,7 +4152,7 @@ jQuery.extend({
queue.unshift( "inprogress" );
}
- // Clear up the last queue stop function
+ // clear up the last queue stop function
delete hooks.stop;
fn.call( elem, next, hooks );
}
@@ -3934,18 +4162,20 @@ jQuery.extend({
}
},
- // Not public - generate a queueHooks object, or return the current one
+ // not intended for public consumption - generates a queueHooks object,
+ // or returns the current one
_queueHooks: function( elem, type ) {
var key = type + "queueHooks";
- return data_priv.get( elem, key ) || data_priv.access( elem, key, {
- empty: jQuery.Callbacks("once memory").add(function() {
- data_priv.remove( elem, [ type + "queue", key ] );
- })
- });
+ return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ jQuery._removeData( elem, type + "queue" );
+ jQuery._removeData( elem, key );
+ } )
+ } );
}
-});
+} );
-jQuery.fn.extend({
+jQuery.fn.extend( {
queue: function( type, data ) {
var setter = 2;
@@ -3956,30 +4186,31 @@ jQuery.fn.extend({
}
if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
+ return jQuery.queue( this[ 0 ], type );
}
return data === undefined ?
this :
- this.each(function() {
+ this.each( function() {
var queue = jQuery.queue( this, type, data );
- // Ensure a hooks for this queue
+ // ensure a hooks for this queue
jQuery._queueHooks( this, type );
- if ( type === "fx" && queue[0] !== "inprogress" ) {
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
jQuery.dequeue( this, type );
}
- });
+ } );
},
dequeue: function( type ) {
- return this.each(function() {
+ return this.each( function() {
jQuery.dequeue( this, type );
- });
+ } );
},
clearQueue: function( type ) {
return this.queue( type || "fx", [] );
},
+
// Get a promise resolved when queues of a certain type
// are emptied (fx is the type by default)
promise: function( type, obj ) {
@@ -4001,7 +4232,7 @@ jQuery.fn.extend({
type = type || "fx";
while ( i-- ) {
- tmp = data_priv.get( elements[ i ], type + "queueHooks" );
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
if ( tmp && tmp.empty ) {
count++;
tmp.empty.add( resolve );
@@ -4010,58 +4241,530 @@ jQuery.fn.extend({
resolve();
return defer.promise( obj );
}
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+} );
+
+
+( function() {
+ var shrinkWrapBlocksVal;
+
+ support.shrinkWrapBlocks = function() {
+ if ( shrinkWrapBlocksVal != null ) {
+ return shrinkWrapBlocksVal;
+ }
+
+ // Will be changed later if needed.
+ shrinkWrapBlocksVal = false;
+
+ // Minified: var b,c,d
+ var div, body, container;
+
+ body = document.getElementsByTagName( "body" )[ 0 ];
+ if ( !body || !body.style ) {
+
+ // Test fired too early or in an unsupported environment, exit.
+ return;
+ }
+
+ // Setup
+ div = document.createElement( "div" );
+ container = document.createElement( "div" );
+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+ body.appendChild( container ).appendChild( div );
+
+ // Support: IE6
+ // Check if elements with layout shrink-wrap their children
+ if ( typeof div.style.zoom !== "undefined" ) {
+
+ // Reset CSS: box-sizing; display; margin; border
+ div.style.cssText =
+
+ // Support: Firefox<29, Android 2.3
+ // Vendor-prefix box-sizing
+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
+ "box-sizing:content-box;display:block;margin:0;border:0;" +
+ "padding:1px;width:1px;zoom:1";
+ div.appendChild( document.createElement( "div" ) ).style.width = "5px";
+ shrinkWrapBlocksVal = div.offsetWidth !== 3;
+ }
+
+ body.removeChild( container );
+
+ return shrinkWrapBlocksVal;
+ };
+
+} )();
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
var isHidden = function( elem, el ) {
+
// isHidden might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+ return jQuery.css( elem, "display" ) === "none" ||
+ !jQuery.contains( elem.ownerDocument, elem );
};
-var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted,
+ scale = 1,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() { return tween.cur(); } :
+ function() { return jQuery.css( elem, prop, "" ); },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ do {
+
+ // If previous iteration zeroed out, double until we get *something*.
+ // Use string for doubling so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ initialInUnit = initialInUnit / scale;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+ } while (
+ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+ );
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ length = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < length; i++ ) {
+ fn(
+ elems[ i ],
+ key,
+ raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ return chainable ?
+ elems :
+
+ // Gets
+ bulk ?
+ fn.call( elems ) :
+ length ? fn( elems[ 0 ], key ) : emptyGet;
+};
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([\w:-]+)/ );
+
+var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+
+var rleadingWhitespace = ( /^\s+/ );
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
+ "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
+ "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
-(function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) ),
+function createSafeFragment( document ) {
+ var list = nodeNames.split( "|" ),
+ safeFrag = document.createDocumentFragment();
+
+ if ( safeFrag.createElement ) {
+ while ( list.length ) {
+ safeFrag.createElement(
+ list.pop()
+ );
+ }
+ }
+ return safeFrag;
+}
+
+
+( function() {
+ var div = document.createElement( "div" ),
+ fragment = document.createDocumentFragment(),
input = document.createElement( "input" );
- // Support: Safari<=5.1
- // Check state lost if the name is set (#11217)
+ // Setup
+ div.innerHTML = " a ";
+
+ // IE strips leading whitespace when .innerHTML is used
+ support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ support.tbody = !div.getElementsByTagName( "tbody" ).length;
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
+
+ // Makes sure cloning an html5 element does not cause problems
+ // Where outerHTML is undefined, this still works
+ support.html5Clone =
+ document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>";
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ input.type = "checkbox";
+ input.checked = true;
+ fragment.appendChild( input );
+ support.appendChecked = input.checked;
+
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ // Support: IE6-IE11+
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+
+ // Support: IE <=9 only
+ // IE <=9 replaces tags with their contents when inserted outside of
+ // the select element.
+ div.innerHTML = " ";
+ support.option = !!div.lastChild;
+
+ // #11217 - WebKit loses check when the name is after the checked attribute
+ fragment.appendChild( div );
+
// Support: Windows Web Apps (WWA)
// `name` and `type` must use .setAttribute for WWA (#14901)
+ input = document.createElement( "input" );
input.setAttribute( "type", "radio" );
input.setAttribute( "checked", "checked" );
input.setAttribute( "name", "t" );
div.appendChild( input );
- // Support: Safari<=5.1, Android<4.2
- // Older WebKit doesn't clone checked state correctly in fragments
+ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
+ // old WebKit doesn't clone checked state correctly in fragments
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
- // Support: IE<=11+
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- div.innerHTML = "";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-})();
-var strundefined = typeof undefined;
+ // Support: IE<9
+ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
+ support.noCloneEvent = !!div.addEventListener;
+
+ // Support: IE<9
+ // Since attributes and properties are the same in IE,
+ // cleanData must set properties to undefined rather than use removeAttribute
+ div[ jQuery.expando ] = 1;
+ support.attributes = !div.getAttribute( jQuery.expando );
+} )();
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+// option: [ 1, "", " " ],
+ legend: [ 1, "", " " ],
+ area: [ 1, "", " " ],
-support.focusinBubbles = "onfocusin" in window;
+ // Support: IE8
+ param: [ 1, "", " " ],
+ thead: [ 1, "" ],
+ tr: [ 2, "" ],
+ col: [ 2, "" ],
+ td: [ 3, "" ],
+
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+ // unless wrapped in a div with non-breaking characters in front of it.
+ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X", "
" ]
+};
+
+// Support: IE8-IE9
+//wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// Support: IE <=9 only
+if ( !support.option ) {
+ wrapMap.optgroup = wrapMap.option = [ 1, "", " " ];
+}
+
+function getAll( context, tag ) {
+ var elems, elem,
+ i = 0,
+ found = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== "undefined" ?
+ context.querySelectorAll( tag || "*" ) :
+ undefined;
+
+ if ( !found ) {
+ for ( found = [], elems = context.childNodes || context;
+ ( elem = elems[ i ] ) != null;
+ i++
+ ) {
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
+ found.push( elem );
+ } else {
+ jQuery.merge( found, getAll( elem, tag ) );
+ }
+ }
+ }
+
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], found ) :
+ found;
+}
-var
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var elem,
+ i = 0;
+ for ( ; ( elem = elems[ i ] ) != null; i++ ) {
+ jQuery._data(
+ elem,
+ "globalEval",
+ !refElements || jQuery._data( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/,
+ rtbody = / from table fragments
+ if ( !support.tbody ) {
+
+ // String was a , *may* have spurious
+ elem = tag === "table" && !rtbody.test( elem ) ?
+ tmp.firstChild :
+
+ // String was a bare or
+ wrap[ 1 ] === "" && !rtbody.test( elem ) ?
+ tmp :
+ 0;
+
+ j = elem && elem.childNodes.length;
+ while ( j-- ) {
+ if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
+ !tbody.childNodes.length ) {
+
+ elem.removeChild( tbody );
+ }
+ }
+ }
+
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Fix #12392 for WebKit and IE > 9
+ tmp.textContent = "";
+
+ // Fix #12392 for oldIE
+ while ( tmp.firstChild ) {
+ tmp.removeChild( tmp.firstChild );
+ }
+
+ // Remember the top-level container for proper cleanup
+ tmp = safe.lastChild;
+ }
+ }
+ }
+
+ // Fix #11356: Clear elements from fragment
+ if ( tmp ) {
+ safe.removeChild( tmp );
+ }
+
+ // Reset defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ if ( !support.appendChecked ) {
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+ }
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( safe.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ tmp = null;
+
+ return safe;
+}
+
+
+( function() {
+ var i, eventName,
+ div = document.createElement( "div" );
+
+ // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
+ for ( i in { submit: true, change: true, focusin: true } ) {
+ eventName = "on" + i;
+
+ if ( !( support[ i ] = eventName in window ) ) {
+
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
+ div.setAttribute( eventName, "t" );
+ support[ i ] = div.attributes[ eventName ].expando === false;
+ }
+ }
+
+ // Null elements to avoid leaks in IE.
+ div = null;
+} )();
+
+
+var rformElems = /^(?:input|select|textarea)$/i,
rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
function returnTrue() {
return true;
@@ -4071,12 +4774,75 @@ function returnFalse() {
return false;
}
+// Support: IE9
+// See #13393 for more info
function safeActiveElement() {
try {
return document.activeElement;
} catch ( err ) { }
}
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
/*
* Helper functions for managing events -- not part of the public interface.
* Props to Dean Edwards' addEvent library for many of the ideas.
@@ -4086,11 +4852,10 @@ jQuery.event = {
global: {},
add: function( elem, types, handler, data, selector ) {
-
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.get( elem );
+ var tmp, events, t, handleObjIn,
+ special, eventHandle, handleObj,
+ handlers, type, namespaces, origType,
+ elemData = jQuery._data( elem );
// Don't attach events to noData or text/comment nodes (but allow plain objects)
if ( !elemData ) {
@@ -4110,25 +4875,32 @@ jQuery.event = {
}
// Init the element's event structure and main handler, if this is the first
- if ( !(events = elemData.events) ) {
+ if ( !( events = elemData.events ) ) {
events = elemData.events = {};
}
- if ( !(eventHandle = elemData.handle) ) {
+ if ( !( eventHandle = elemData.handle ) ) {
eventHandle = elemData.handle = function( e ) {
+
// Discard the second event of a jQuery.event.trigger() and
// when an event is called after a page has unloaded
- return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
- jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ return typeof jQuery !== "undefined" &&
+ ( !e || jQuery.event.triggered !== e.type ) ?
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+ undefined;
};
+
+ // Add elem as a property of the handle fn to prevent a memory leak
+ // with IE non-native events
+ eventHandle.elem = elem;
}
// Handle multiple events separated by a space
types = ( types || "" ).match( rnotwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
// There *must* be a type, no attaching namespace-only handlers
if ( !type ) {
@@ -4145,7 +4917,7 @@ jQuery.event = {
special = jQuery.event.special[ type ] || {};
// handleObj is passed to all event handlers
- handleObj = jQuery.extend({
+ handleObj = jQuery.extend( {
type: type,
origType: origType,
data: data,
@@ -4153,18 +4925,24 @@ jQuery.event = {
guid: handler.guid,
selector: selector,
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
+ namespace: namespaces.join( "." )
}, handleObjIn );
// Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
+ if ( !( handlers = events[ type ] ) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
- // Only use addEventListener if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Only use addEventListener/attachEvent if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ // Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
}
}
}
@@ -4188,17 +4966,19 @@ jQuery.event = {
jQuery.event.global[ type ] = true;
}
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
},
// Detach an event or set of events from an element
remove: function( elem, types, handler, selector, mappedTypes ) {
+ var j, handleObj, tmp,
+ origCount, t, events,
+ special, handlers, type,
+ namespaces, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.hasData( elem ) && data_priv.get( elem );
-
- if ( !elemData || !(events = elemData.events) ) {
+ if ( !elemData || !( events = elemData.events ) ) {
return;
}
@@ -4206,9 +4986,9 @@ jQuery.event = {
types = ( types || "" ).match( rnotwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
// Unbind all events (on this namespace, if provided) for the element
if ( !type ) {
@@ -4221,7 +5001,8 @@ jQuery.event = {
special = jQuery.event.special[ type ] || {};
type = ( selector ? special.delegateType : special.bindType ) || type;
handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
// Remove matching events
origCount = j = handlers.length;
@@ -4231,7 +5012,8 @@ jQuery.event = {
if ( ( mappedTypes || origType === handleObj.origType ) &&
( !handler || handler.guid === handleObj.guid ) &&
( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
handlers.splice( j, 1 );
if ( handleObj.selector ) {
@@ -4246,7 +5028,9 @@ jQuery.event = {
// Remove generic event handler if we removed something and no more handlers exist
// (avoids potential for endless recursion during removal of special event handlers)
if ( origCount && !handlers.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
jQuery.removeEvent( elem, type, elemData.handle );
}
@@ -4257,16 +5041,19 @@ jQuery.event = {
// Remove the expando if it's no longer used
if ( jQuery.isEmptyObject( events ) ) {
delete elemData.handle;
- data_priv.remove( elem, "events" );
+
+ // removeData also checks for emptiness and clears the expando if empty
+ // so use it instead of delete
+ jQuery._removeData( elem, "events" );
}
},
trigger: function( event, data, elem, onlyHandlers ) {
-
- var i, cur, tmp, bubbleType, ontype, handle, special,
+ var handle, ontype, cur,
+ bubbleType, special, tmp, i,
eventPath = [ elem || document ],
type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
cur = tmp = elem = elem || document;
@@ -4280,13 +5067,14 @@ jQuery.event = {
return;
}
- if ( type.indexOf(".") >= 0 ) {
+ if ( type.indexOf( "." ) > -1 ) {
+
// Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
+ namespaces = type.split( "." );
type = namespaces.shift();
namespaces.sort();
}
- ontype = type.indexOf(":") < 0 && "on" + type;
+ ontype = type.indexOf( ":" ) < 0 && "on" + type;
// Caller can pass in a jQuery.Event object, Object, or just an event type string
event = event[ jQuery.expando ] ?
@@ -4295,9 +5083,9 @@ jQuery.event = {
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+ event.namespace = namespaces.join( "." );
+ event.rnamespace = event.namespace ?
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
null;
// Clean up the event in case it is being reused
@@ -4331,28 +5119,30 @@ jQuery.event = {
}
// Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
+ if ( tmp === ( elem.ownerDocument || document ) ) {
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
}
}
// Fire handlers on the event path
i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
event.type = i > 1 ?
bubbleType :
special.bindType || type;
// jQuery handler
- handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
+ jQuery._data( cur, "handle" );
+
if ( handle ) {
handle.apply( cur, data );
}
// Native handler
handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
+ if ( handle && handle.apply && acceptData( cur ) ) {
event.result = handle.apply( cur, data );
if ( event.result === false ) {
event.preventDefault();
@@ -4364,12 +5154,16 @@ jQuery.event = {
// If nobody prevented the default action, do it now
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
+ if (
+ ( !special._default ||
+ special._default.apply( eventPath.pop(), data ) === false
+ ) && acceptData( elem )
+ ) {
// Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
// Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
// Don't re-trigger an onFOO event when we call its FOO() method
tmp = elem[ ontype ];
@@ -4380,7 +5174,13 @@ jQuery.event = {
// Prevent re-triggering of the same event, since we already bubbled it above
jQuery.event.triggered = type;
- elem[ type ]();
+ try {
+ elem[ type ]();
+ } catch ( e ) {
+
+ // IE<9 dies on focus/blur to hidden element (#1486,#12518)
+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode
+ }
jQuery.event.triggered = undefined;
if ( tmp ) {
@@ -4401,11 +5201,11 @@ jQuery.event = {
var i, j, ret, matched, handleObj,
handlerQueue = [],
args = slice.call( arguments ),
- handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
+ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
+ args[ 0 ] = event;
event.delegateTarget = this;
// Call the preDispatch hook for the mapped type, and let it bail if desired
@@ -4418,24 +5218,25 @@ jQuery.event = {
// Run delegates first; they may want to stop propagation beneath us
i = 0;
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
// Triggered event must either 1) have no namespace, or 2) have namespace(s)
// a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
if ( ret !== undefined ) {
- if ( (event.result = ret) === false ) {
+ if ( ( event.result = ret ) === false ) {
event.preventDefault();
event.stopPropagation();
}
@@ -4458,15 +5259,22 @@ jQuery.event = {
delegateCount = handlers.delegateCount,
cur = event.target;
+ // Support (at least): Chrome, IE9
// Find delegate handlers
// Black-hole SVG instance trees (#13180)
- // Avoid non-left-click bubbling in Firefox (#3861)
- if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+ //
+ // Support: Firefox<=42+
+ // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
+ if ( delegateCount && cur.nodeType &&
+ ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
- for ( ; cur !== this; cur = cur.parentNode || this ) {
+ /* jshint eqeqeq: false */
+ for ( ; cur != this; cur = cur.parentNode || this ) {
+ /* jshint eqeqeq: true */
+ // Don't check non-elements (#13208)
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.disabled !== true || event.type !== "click" ) {
+ if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
matches = [];
for ( i = 0; i < delegateCount; i++ ) {
handleObj = handlers[ i ];
@@ -4476,7 +5284,7 @@ jQuery.event = {
if ( matches[ sel ] === undefined ) {
matches[ sel ] = handleObj.needsContext ?
- jQuery( sel, this ).index( cur ) >= 0 :
+ jQuery( sel, this ).index( cur ) > -1 :
jQuery.find( sel, this, null, [ cur ] ).length;
}
if ( matches[ sel ] ) {
@@ -4484,7 +5292,7 @@ jQuery.event = {
}
}
if ( matches.length ) {
- handlerQueue.push({ elem: cur, handlers: matches });
+ handlerQueue.push( { elem: cur, handlers: matches } );
}
}
}
@@ -4492,56 +5300,12 @@ jQuery.event = {
// Add the remaining (directly-bound) handlers
if ( delegateCount < handlers.length ) {
- handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+ handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
}
return handlerQueue;
},
- // Includes some event props shared by KeyEvent and MouseEvent
- props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split(" "),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
- filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
fix: function( event ) {
if ( event[ jQuery.expando ] ) {
return event;
@@ -4569,32 +5333,103 @@ jQuery.event = {
event[ prop ] = originalEvent[ prop ];
}
- // Support: Cordova 2.5 (WebKit) (#13255)
- // All events should have a target; Cordova deviceready doesn't
+ // Support: IE<9
+ // Fix target property (#1925)
if ( !event.target ) {
- event.target = document;
+ event.target = originalEvent.srcElement || document;
}
- // Support: Safari 6.0+, Chrome<28
+ // Support: Safari 6-8+
// Target should not be a text node (#504, #13143)
if ( event.target.nodeType === 3 ) {
event.target = event.target.parentNode;
}
+ // Support: IE<9
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+ event.metaKey = !!event.metaKey;
+
return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
},
+ // Includes some event props shared by KeyEvent and MouseEvent
+ props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
+ "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
+
+ fixHooks: {},
+
+ keyHooks: {
+ props: "char charCode key keyCode".split( " " ),
+ filter: function( event, original ) {
+
+ // Add which for key events
+ if ( event.which == null ) {
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
+ }
+
+ return event;
+ }
+ },
+
+ mouseHooks: {
+ props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
+ "pageX pageY screenX screenY toElement" ).split( " " ),
+ filter: function( event, original ) {
+ var body, eventDoc, doc,
+ button = original.button,
+ fromElement = original.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && original.clientX != null ) {
+ eventDoc = event.target.ownerDocument || document;
+ doc = eventDoc.documentElement;
+ body = eventDoc.body;
+
+ event.pageX = original.clientX +
+ ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
+ ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+ event.pageY = original.clientY +
+ ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
+ ( doc && doc.clientTop || body && body.clientTop || 0 );
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && fromElement ) {
+ event.relatedTarget = fromElement === event.target ?
+ original.toElement :
+ fromElement;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && button !== undefined ) {
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+ }
+
+ return event;
+ }
+ },
+
special: {
load: {
+
// Prevent triggered image.load events from bubbling to window.load
noBubble: true
},
focus: {
+
// Fire native event if possible so blur/focus sequence is correct
trigger: function() {
if ( this !== safeActiveElement() && this.focus ) {
- this.focus();
- return false;
+ try {
+ this.focus();
+ return false;
+ } catch ( e ) {
+
+ // Support: IE<9
+ // If we error on focus to hidden element (#1486, #12518),
+ // let .trigger() run the handlers
+ }
}
},
delegateType: "focusin"
@@ -4609,9 +5444,10 @@ jQuery.event = {
delegateType: "focusout"
},
click: {
+
// For checkbox, fire native event so checked state will be right
trigger: function() {
- if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
this.click();
return false;
}
@@ -4635,39 +5471,62 @@ jQuery.event = {
}
},
- simulate: function( type, elem, event, bubble ) {
- // Piggyback on a donor event to simulate a different one.
- // Fake originalEvent to avoid donor's stopPropagation, but if the
- // simulated event prevents default then we do the same on the donor.
+ // Piggyback on a donor event to simulate a different one
+ simulate: function( type, elem, event ) {
var e = jQuery.extend(
new jQuery.Event(),
event,
{
type: type,
- isSimulated: true,
- originalEvent: {}
+ isSimulated: true
+
+ // Previously, `originalEvent: {}` was set here, so stopPropagation call
+ // would not be triggered on donor event, since in our own
+ // jQuery.event.stopPropagation function we had a check for existence of
+ // originalEvent.stopPropagation method, so, consequently it would be a noop.
+ //
+ // Guard for simulated events was moved to jQuery.event.stopPropagation function
+ // since `originalEvent` should point to the original event for the
+ // constancy with other events and for more focused logic
}
);
- if ( bubble ) {
- jQuery.event.trigger( e, null, elem );
- } else {
- jQuery.event.dispatch.call( elem, e );
- }
+
+ jQuery.event.trigger( e, null, elem );
+
if ( e.isDefaultPrevented() ) {
event.preventDefault();
}
}
};
-jQuery.removeEvent = function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
-};
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+
+ // This "if" is needed for plain objects
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ var name = "on" + type;
+
+ if ( elem.detachEvent ) {
+
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8
+ // detachEvent needed property on element, by name of that event,
+ // to properly expose it to GC
+ if ( typeof elem[ name ] === "undefined" ) {
+ elem[ name ] = null;
+ }
+
+ elem.detachEvent( name, handle );
+ }
+ };
jQuery.Event = function( src, props ) {
+
// Allow instantiation without the 'new' keyword
- if ( !(this instanceof jQuery.Event) ) {
+ if ( !( this instanceof jQuery.Event ) ) {
return new jQuery.Event( src, props );
}
@@ -4680,7 +5539,8 @@ jQuery.Event = function( src, props ) {
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
- // Support: Android<4.0
+
+ // Support: IE < 9, Android < 4.0
src.returnValue === false ?
returnTrue :
returnFalse;
@@ -4705,6 +5565,7 @@ jQuery.Event = function( src, props ) {
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
+ constructor: jQuery.Event,
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse,
@@ -4713,9 +5574,18 @@ jQuery.Event.prototype = {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
+ if ( !e ) {
+ return;
+ }
- if ( e && e.preventDefault ) {
+ // If preventDefault exists, run it on the original event
+ if ( e.preventDefault ) {
e.preventDefault();
+
+ // Support: IE
+ // Otherwise set the returnValue property of the original event to false
+ } else {
+ e.returnValue = false;
}
},
stopPropagation: function() {
@@ -4723,9 +5593,18 @@ jQuery.Event.prototype = {
this.isPropagationStopped = returnTrue;
- if ( e && e.stopPropagation ) {
+ if ( !e || this.isSimulated ) {
+ return;
+ }
+
+ // If stopPropagation exists, run it on the original event
+ if ( e.stopPropagation ) {
e.stopPropagation();
}
+
+ // Support: IE
+ // Set the cancelBubble property of the original event to true
+ e.cancelBubble = true;
},
stopImmediatePropagation: function() {
var e = this.originalEvent;
@@ -4741,8 +5620,14 @@ jQuery.Event.prototype = {
};
// Create mouseenter/leave events using mouseover/out and event-time checks
-// Support: Chrome 15+
-jQuery.each({
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://code.google.com/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
mouseenter: "mouseover",
mouseleave: "mouseout",
pointerenter: "pointerover",
@@ -4758,9 +5643,9 @@ jQuery.each({
related = event.relatedTarget,
handleObj = event.handleObj;
- // For mousenter/leave call the handler if related is outside the target.
+ // For mouseenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
event.type = handleObj.origType;
ret = handleObj.handler.apply( this, arguments );
event.type = fix;
@@ -4768,115 +5653,198 @@ jQuery.each({
return ret;
}
};
-});
+} );
-// Support: Firefox, Chrome, Safari
-// Create "bubbling" focus and blur events
-if ( !support.focusinBubbles ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+// IE submit delegation
+if ( !support.submit ) {
+
+ jQuery.event.special.submit = {
+ setup: function() {
+
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+
+ // Node name check avoids a VML-related crash in IE (#9807)
+ var elem = e.target,
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
+
+ // Support: IE <=8
+ // We use jQuery.prop instead of elem.form
+ // to allow fixing the IE8 delegated submit issue (gh-2332)
+ // by 3rd party polyfills/workarounds.
+ jQuery.prop( elem, "form" ) :
+ undefined;
+
+ if ( form && !jQuery._data( form, "submit" ) ) {
+ jQuery.event.add( form, "submit._submit", function( event ) {
+ event._submitBubble = true;
+ } );
+ jQuery._data( form, "submit", true );
+ }
+ } );
+
+ // return undefined since we don't need an event listener
+ },
+
+ postDispatch: function( event ) {
+
+ // If form was submitted by the user, bubble the event up the tree
+ if ( event._submitBubble ) {
+ delete event._submitBubble;
+ if ( this.parentNode && !event.isTrigger ) {
+ jQuery.event.simulate( "submit", this.parentNode, event );
+ }
+ }
+ },
+
+ teardown: function() {
+
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+ jQuery.event.remove( this, "._submit" );
+ }
+ };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !support.change ) {
+
+ jQuery.event.special.change = {
+
+ setup: function() {
+
+ if ( rformElems.test( this.nodeName ) ) {
+
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
+ // after a propertychange. Eat the blur-change in special.change.handle.
+ // This still fires onchange a second time for check/radio after blur.
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ jQuery.event.add( this, "propertychange._change", function( event ) {
+ if ( event.originalEvent.propertyName === "checked" ) {
+ this._justChanged = true;
+ }
+ } );
+ jQuery.event.add( this, "click._change", function( event ) {
+ if ( this._justChanged && !event.isTrigger ) {
+ this._justChanged = false;
+ }
+
+ // Allow triggered, simulated change events (#11500)
+ jQuery.event.simulate( "change", this, event );
+ } );
+ }
+ return false;
+ }
+
+ // Delegated event; lazy-add a change handler on descendant inputs
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
+ var elem = e.target;
+
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
+ jQuery.event.add( elem, "change._change", function( event ) {
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+ jQuery.event.simulate( "change", this.parentNode, event );
+ }
+ } );
+ jQuery._data( elem, "change", true );
+ }
+ } );
+ },
+
+ handle: function( event ) {
+ var elem = event.target;
+
+ // Swallow native change events from checkbox/radio, we already triggered them above
+ if ( this !== elem || event.isSimulated || event.isTrigger ||
+ ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
+
+ return event.handleObj.handler.apply( this, arguments );
+ }
+ },
+
+ teardown: function() {
+ jQuery.event.remove( this, "._change" );
+
+ return !rformElems.test( this.nodeName );
+ }
+ };
+}
+
+// Support: Firefox
+// Firefox doesn't have focus(in | out) events
+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+//
+// Support: Chrome, Safari
+// focus(in | out) events fire after focus & blur events,
+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
+if ( !support.focusin ) {
+ jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
// Attach a single capturing handler on the document while someone wants focusin/focusout
var handler = function( event ) {
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
- };
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
+ };
jQuery.event.special[ fix ] = {
setup: function() {
var doc = this.ownerDocument || this,
- attaches = data_priv.access( doc, fix );
+ attaches = jQuery._data( doc, fix );
if ( !attaches ) {
doc.addEventListener( orig, handler, true );
}
- data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
+ jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
},
teardown: function() {
var doc = this.ownerDocument || this,
- attaches = data_priv.access( doc, fix ) - 1;
+ attaches = jQuery._data( doc, fix ) - 1;
if ( !attaches ) {
doc.removeEventListener( orig, handler, true );
- data_priv.remove( doc, fix );
-
+ jQuery._removeData( doc, fix );
} else {
- data_priv.access( doc, fix, attaches );
+ jQuery._data( doc, fix, attaches );
}
}
};
- });
+ } );
}
-jQuery.fn.extend({
+jQuery.fn.extend( {
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var origFn, type;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- this.on( type, selector, data, types[ type ], one );
- }
- return this;
- }
-
- if ( data == null && fn == null ) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return this;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return this.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- });
+ on: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn );
},
one: function( types, selector, data, fn ) {
- return this.on( types, selector, data, fn, 1 );
+ return on( this, types, selector, data, fn, 1 );
},
off: function( types, selector, fn ) {
var handleObj, type;
if ( types && types.preventDefault && types.handleObj ) {
+
// ( event ) dispatched jQuery.Event
handleObj = types.handleObj;
jQuery( types.delegateTarget ).off(
- handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+ handleObj.namespace ?
+ handleObj.origType + "." + handleObj.namespace :
+ handleObj.origType,
handleObj.selector,
handleObj.handler
);
return this;
}
if ( typeof types === "object" ) {
+
// ( types-object [, selector] )
for ( type in types ) {
this.off( type, selector, types[ type ] );
@@ -4884,6 +5852,7 @@ jQuery.fn.extend({
return this;
}
if ( selector === false || typeof selector === "function" ) {
+
// ( types [, fn] )
fn = selector;
selector = undefined;
@@ -4891,170 +5860,316 @@ jQuery.fn.extend({
if ( fn === false ) {
fn = returnFalse;
}
- return this.each(function() {
+ return this.each( function() {
jQuery.event.remove( this, types, fn, selector );
- });
+ } );
},
trigger: function( type, data ) {
- return this.each(function() {
+ return this.each( function() {
jQuery.event.trigger( type, data, this );
- });
+ } );
},
triggerHandler: function( type, data ) {
- var elem = this[0];
+ var elem = this[ 0 ];
if ( elem ) {
return jQuery.event.trigger( type, data, elem, true );
}
}
-});
+} );
-var
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
- rtagName = /<([\w:]+)/,
- rhtml = /<|?\w+;/,
- rnoInnerhtml = /<(?:script|style|link)/i,
+var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+ rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
+// rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
+
+ // Support: IE 10-11, Edge 10240+
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = / to your HTML
@@ -21,27 +27,23 @@
*/
-var stIsIE = /*@cc_on!@*/false;
-
sorttable = {
init: function() {
// quit if this function has already been called
if (arguments.callee.done) return;
// flag this function so we don't do the same thing twice
arguments.callee.done = true;
- // kill the timer
- if (_timer) clearInterval(_timer);
if (!document.createElement || !document.getElementsByTagName) return;
sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
- forEach(document.getElementsByTagName('table'), function(table) {
- if (table.className.search(/\bsortable\b/) != -1) {
- sorttable.makeSortable(table);
+ allTables=document.getElementsByTagName('table');
+ for (var i=0; i < allTables.length; i++) {
+ if (allTables[i].className.search(/\bsortable\b/) != -1) {
+ sorttable.makeSortable(allTables[i]);
}
- });
-
+ }
},
makeSortable: function(table) {
@@ -105,7 +107,6 @@ sorttable = {
this.removeChild(document.getElementById('sorttable_sortfwdind'+$(this).parent().parent().parent()[0].id));
sortrevind = document.createElement('span');
sortrevind.id = "sorttable_sortrevind"+$(this).parent().parent().parent()[0].id;
-// sortrevind.innerHTML = stIsIE ? ' 5 ' : ' ▴';
sortrevind.innerHTML = ' ▲';
this.appendChild(sortrevind);
return;
@@ -119,7 +120,6 @@ sorttable = {
this.removeChild(document.getElementById('sorttable_sortrevind'+$(this).parent().parent().parent()[0].id));
sortfwdind = document.createElement('span');
sortfwdind.id = "sorttable_sortfwdind"+$(this).parent().parent().parent()[0].id;
-// sortfwdind.innerHTML = stIsIE ? ' 6 ' : ' ▾';
sortfwdind.innerHTML = ' ▼';
this.appendChild(sortfwdind);
return;
@@ -127,12 +127,13 @@ sorttable = {
// remove sorttable_sorted classes
theadrow = this.parentNode;
- forEach(theadrow.childNodes, function(cell) {
- if (cell.nodeType == 1) { // an element
- cell.className = cell.className.replace('sorttable_sorted_reverse','');
- cell.className = cell.className.replace('sorttable_sorted','');
+ for (var i=0; i < theadrow.childNodes.length; i++) {
+ if (theadrow.childNodes[i].nodeType == 1) { // an element
+ theadrow.childNodes[i].className = theadrow.childNodes[i].className.replace('sorttable_sorted_reverse','');
+ theadrow.childNodes[i].className = theadrow.childNodes[i].className.replace('sorttable_sorted','');
}
- });
+ }
+
sortfwdind = document.getElementById('sorttable_sortfwdind'+$(this).parent().parent().parent()[0].id);
if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
sortrevind = document.getElementById('sorttable_sortrevind'+$(this).parent().parent().parent()[0].id);
@@ -141,7 +142,6 @@ sorttable = {
this.className += ' sorttable_sorted';
sortfwdind = document.createElement('span');
sortfwdind.id = "sorttable_sortfwdind"+$(this).parent().parent().parent()[0].id;
-// sortfwdind.innerHTML = stIsIE ? ' 6 ;' : ' ▾';
sortfwdind.innerHTML = ' ▼';
this.appendChild(sortfwdind);
@@ -177,7 +177,7 @@ sorttable = {
for (var i=0; i<\/script>");
- var script = document.getElementById("__ie_onload");
- script.onreadystatechange = function() {
- if (this.readyState == "complete") {
- sorttable.init(); // call the onload handler
- }
- };
-/*@end @*/
-
-/* for Safari */
-if (/WebKit/i.test(navigator.userAgent)) { // sniff
- var _timer = setInterval(function() {
- if (/loaded|complete/.test(document.readyState)) {
- sorttable.init(); // call the onload handler
- }
- }, 10);
-}
-
-/* for other browsers */
-window.onload = sorttable.init;
-
// written by Dean Edwards, 2005
// with input from Tino Zijdel, Matthias Miller, Diego Perini
@@ -446,58 +411,3 @@ fixEvent.preventDefault = function() {
fixEvent.stopPropagation = function() {
this.cancelBubble = true;
};
-
-// Dean's forEach: http://dean.edwards.name/base/forEach.js
-/*
- forEach, version 1.0
- Copyright 2006, Dean Edwards
- License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-// array-like enumeration
-if (!Array.forEach) { // mozilla already supports this
- Array.forEach = function(array, block, context) {
- for (var i = 0; i < array.length; i++) {
- block.call(context, array[i], i, array);
- }
- };
-}
-
-// generic enumeration
-Function.prototype.forEach = function(object, block, context) {
- for (var key in object) {
- if (typeof this.prototype[key] == "undefined") {
- block.call(context, object[key], key, object);
- }
- }
-};
-
-// character enumeration
-String.forEach = function(string, block, context) {
- Array.forEach(string.split(""), function(chr, index) {
- block.call(context, chr, index, string);
- });
-};
-
-// globally resolve forEach enumeration
-var forEach = function(object, block, context) {
- if (object) {
- var resolve = Object; // default
- if (object instanceof Function) {
- // functions have a "length" property
- resolve = Function;
- } else if (object.forEach instanceof Function) {
- // the object implements a custom forEach method so use that
- object.forEach(block, context);
- return;
- } else if (typeof object == "string") {
- // the object is a string
- resolve = String;
- } else if (typeof object.length == "number") {
- // the object is array-like
- resolve = Array;
- }
- resolve.forEach(object, block, context);
- }
-};
-
diff --git a/root/opt/phpsysinfo/js/vendor/sorttable_org.js b/root/opt/phpsysinfo/js/vendor/sorttable_org.js
deleted file mode 100644
index 38b0fc6..0000000
--- a/root/opt/phpsysinfo/js/vendor/sorttable_org.js
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- SortTable
- version 2
- 7th April 2007
- Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-
- Instructions:
- Download this file
- Add to your HTML
- Add class="sortable" to any table you'd like to make sortable
- Click on the headers to sort
-
- Thanks to many, many people for contributions and suggestions.
- Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
- This basically means: do what you want with it.
-*/
-
-
-var stIsIE = /*@cc_on!@*/false;
-
-sorttable = {
- init: function() {
- // quit if this function has already been called
- if (arguments.callee.done) return;
- // flag this function so we don't do the same thing twice
- arguments.callee.done = true;
- // kill the timer
- if (_timer) clearInterval(_timer);
-
- if (!document.createElement || !document.getElementsByTagName) return;
-
- sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-
- forEach(document.getElementsByTagName('table'), function(table) {
- if (table.className.search(/\bsortable\b/) != -1) {
- sorttable.makeSortable(table);
- }
- });
-
- },
-
- makeSortable: function(table) {
- if (table.getElementsByTagName('thead').length == 0) {
- // table doesn't have a tHead. Since it should have, create one and
- // put the first table row in it.
- the = document.createElement('thead');
- the.appendChild(table.rows[0]);
- table.insertBefore(the,table.firstChild);
- }
- // Safari doesn't support table.tHead, sigh
- if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-
- if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-
- // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
- // "total" rows, for example). This is B&R, since what you're supposed
- // to do is put them in a tfoot. So, if there are sortbottom rows,
- // for backwards compatibility, move them to tfoot (creating it if needed).
- sortbottomrows = [];
- for (var i=0; i5' : ' ▴';
- this.appendChild(sortrevind);
- return;
- }
- if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
- // if we're already sorted by this column in reverse, just
- // re-reverse the table, which is quicker
- sorttable.reverse(this.sorttable_tbody);
- this.className = this.className.replace('sorttable_sorted_reverse',
- 'sorttable_sorted');
- this.removeChild(document.getElementById('sorttable_sortrevind'));
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? ' 6 ' : ' ▾';
- this.appendChild(sortfwdind);
- return;
- }
-
- // remove sorttable_sorted classes
- theadrow = this.parentNode;
- forEach(theadrow.childNodes, function(cell) {
- if (cell.nodeType == 1) { // an element
- cell.className = cell.className.replace('sorttable_sorted_reverse','');
- cell.className = cell.className.replace('sorttable_sorted','');
- }
- });
- sortfwdind = document.getElementById('sorttable_sortfwdind');
- if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
- sortrevind = document.getElementById('sorttable_sortrevind');
- if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-
- this.className += ' sorttable_sorted';
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? ' 6 ' : ' ▾';
- this.appendChild(sortfwdind);
-
- // build an array to sort. This is a Schwartzian transform thing,
- // i.e., we "decorate" each row with the actual sort key,
- // sort based on the sort keys, and then put the rows back in order
- // which is a lot faster because you only do getInnerText once per row
- row_array = [];
- col = this.sorttable_columnindex;
- rows = this.sorttable_tbody.rows;
- for (var j=0; j 12) {
- // definitely dd/mm
- return sorttable.sort_ddmm;
- } else if (second > 12) {
- return sorttable.sort_mmdd;
- } else {
- // looks like a date, but we can't tell which, so assume
- // that it's dd/mm (English imperialism!) and keep looking
- sortfn = sorttable.sort_ddmm;
- }
- }
- }
- }
- return sortfn;
- },
-
- getInnerText: function(node) {
- // gets the text we want to use for sorting for a cell.
- // strips leading and trailing whitespace.
- // this is *not* a generic getInnerText function; it's special to sorttable.
- // for example, you can override the cell text with a customkey attribute.
- // it also gets .value for fields.
-
- if (!node) return "";
-
- hasInputs = (typeof node.getElementsByTagName == 'function') &&
- node.getElementsByTagName('input').length;
-
- if (node.getAttribute("sorttable_customkey") != null) {
- return node.getAttribute("sorttable_customkey");
- }
- else if (typeof node.textContent != 'undefined' && !hasInputs) {
- return node.textContent.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.innerText != 'undefined' && !hasInputs) {
- return node.innerText.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.text != 'undefined' && !hasInputs) {
- return node.text.replace(/^\s+|\s+$/g, '');
- }
- else {
- switch (node.nodeType) {
- case 3:
- if (node.nodeName.toLowerCase() == 'input') {
- return node.value.replace(/^\s+|\s+$/g, '');
- }
- case 4:
- return node.nodeValue.replace(/^\s+|\s+$/g, '');
- break;
- case 1:
- case 11:
- var innerText = '';
- for (var i = 0; i < node.childNodes.length; i++) {
- innerText += sorttable.getInnerText(node.childNodes[i]);
- }
- return innerText.replace(/^\s+|\s+$/g, '');
- break;
- default:
- return '';
- }
- }
- },
-
- reverse: function(tbody) {
- // reverse the rows in a tbody
- newrows = [];
- for (var i=0; i=0; i--) {
- tbody.appendChild(newrows[i]);
- }
- delete newrows;
- },
-
- /* sort functions
- each sort function takes two parameters, a and b
- you are comparing a[0] and b[0] */
- sort_numeric: function(a,b) {
- aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
- if (isNaN(aa)) aa = 0;
- bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
- if (isNaN(bb)) bb = 0;
- return aa-bb;
- },
- sort_alpha: function(a,b) {
- if (a[0]==b[0]) return 0;
- if (a[0] 0 ) {
- var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
- swap = true;
- }
- } // for
- t--;
-
- if (!swap) break;
-
- for(var i = t; i > b; --i) {
- if ( comp_func(list[i], list[i-1]) < 0 ) {
- var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
- swap = true;
- }
- } // for
- b++;
-
- } // while(swap)
- }
-}
-
-/* ******************************************************************
- Supporting functions: bundled here to avoid depending on a library
- ****************************************************************** */
-
-// Dean Edwards/Matthias Miller/John Resig
-
-/* for Mozilla/Opera9 */
-if (document.addEventListener) {
- document.addEventListener("DOMContentLoaded", sorttable.init, false);
-}
-
-/* for Internet Explorer */
-/*@cc_on @*/
-/*@if (@_win32)
- document.write("
+
+
+
+
+
+
+
-
-
+
+
+
+
-
-
-
phpSysInfo
-
- Errors
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Template
+
+".$t."\n";
+endforeach;
+} else {
+ echo " ".$bootstraptemplate." \n";
+}?>
+
+
+
+ Language
+
+".$l."\n";
+endforeach;
+} else {
+ echo " ".$language." \n";
+}?>
+
+
+
+
+
+ Your navigator does not support JavaScript (or JavaScript is not activated).
+ In approximatively 2 seconds you will be redirected to the static version of phpSysInfo.
+
+ Click here to switch to the static version
+
-
-
-
-
-
System Vitals
-
-
-
- Hostname
-
-
-
- Listening IP
-
-
-
- Kernel Version
-
-
-
- Distro Name
-
-
-
- Uptime
-
-
-
- Last boot
-
-
-
- Current Users
-
-
-
- Load Averages
-
-
-
- System Language
-
-
-
- Code Page
-
-
-
- Processes
-
-
-
+
+
+
+
+
+
+
+
+
+ Hostname
+
+
+
+ Listening IP
+
+
+
+ Kernel Version
+
+
+
+ Distro Name
+
+
+
+ OS Type
+
+
+
+ Uptime
+
+
+
+ Last boot
+
+
+
+ Current Users
+
+
+
+ Load Averages
+
+
+
+ System Language
+
+
+
+ Code Page
+
+
+
+ Processes
+
+
+
+
+
-
-
-
-
Hardware Information
-
-
-
-
-
-
-
-
-
Memory Usage
-
-
-
-
- Type
- Usage
- Free
- Used
- Size
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mounted Filesystems
-
-
-
-
- Mountpoint
- Type
- Partition
- Usage
- Free
- Used
- Size
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Network Interface
-
-
+
-
-
-
Voltage
-
-
-
-
- Label
- Value
- Min
- Max
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Type
+ Usage
+ Free
+ Used
+ Size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Temperatures
-
-
-
-
- Label
- Value
- Limit
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Mountpoint
+ Type
+ Partition
+ Usage
+ Free
+ Used
+ Size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Fans
-
-
-
-
- Label
- Value
- Min
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Device
+ Receive
+ Send
+ Err/Drop
+
+
+
+
+
-
-
-
Currents
-
-
-
-
- Label
- Value
- Limit
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Label
+ Value
+ Min
+ Max
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Power
-
-
-
-
- Label
- Value
- Limit
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Label
+ Value
+ Min
+ Max
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
UPS Information
-
-
+
+
+
+
+
+
+
+
+ Label
+ Value
+ Limit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Label
+ Value
+ Min
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Label
+ Value
+ Limit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Label
+ Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+if (file_exists(PSI_APP_ROOT . '/plugins/' . $plugin . '/' . $plugin . '_bootstrap.html')) : ?>
+
-
-
+
+
@@ -353,17 +484,14 @@ if (file_exists(APP_ROOT . '/plugins/' . $plugin . '/' . $plugin . '_bootstrap.h
-
-
-
-
+
+
+
diff --git a/root/opt/phpsysinfo/templates/html/index_dynamic.html b/root/opt/phpsysinfo/templates/html/index_dynamic.html
index b5c7eea..445db9c 100644
--- a/root/opt/phpsysinfo/templates/html/index_dynamic.html
+++ b/root/opt/phpsysinfo/templates/html/index_dynamic.html
@@ -5,27 +5,27 @@
-
+
+
-
-
+
+
-
-
+
-
-
+
+
@@ -36,9 +36,22 @@
phpSysInfo
+
+
+
+
+
+
+
+
+
-
Loading... please wait!
-
+
+
+
+
+ Loading... please wait!
+
Your navigator does not support JavaScript (or JavaScript is not activated).
In approximatively 2 seconds you will be redirected to the static version of phpSysInfo.
@@ -47,186 +60,220 @@
-
+
Oh, I'm sorry. Something seems to be wrong.
-
+
-
+
- System information
+ System information
:
( )
- Template
-
-Template
+
+".$t."\n";
+ endforeach;
+} else {
+ echo " ".$template." \n";
+}
?>
- >
-
- Language
-
-Language
+
+".$l."\n";
+ endforeach;
+} else {
+ echo " ".$language." \n";
+}
?>
- >
-
-
-
System vitals
-
-
- Hostname
-
-
-
- Listening IP
-
-
-
- Kernel Version
-
-
-
- Distro Name
-
-
-
- Uptime
-
-
-
- Last boot
-
-
-
- Current Users
-
-
-
- Load Averages
-
-
-
- System Language
-
-
-
- Code Page
-
-
-
- Code Page
-
-
-
- Processes
-
-
-
- Processes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Voltage
-
-
+
+
System vitals
+
+
- Label
- Voltage
- Min
- Max
+ Hostname
+
-
-
-
-
-
-
-
Temperature
-
-
- Label
- Value
- Limit
+ Listening IP
+
-
-
-
-
-
-
-
Fan
-
-
- Label
- Value
- Min
+ Kernel Version
+
-
-
-
-
-
-
-
Current
-
-
- Label
- Value
- Limit
+ Distro Name
+
-
-
-
-
-
-
-
Power
-
-
- Label
- Value
- Limit
+ OS Type
+
-
-
-
-
+
+ Uptime
+
+
+
+ Last boot
+
+
+
+ Current Users
+
+
+
+ Load Averages
+
+
+
+ System Language
+
+
+
+ Code Page
+
+
+
+ Processes
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
Voltage
+
+
+
+
+ Label
+ Value
+ Min
+ Max
+
+
+
+
+
+
+
+
+
Current
+
+
+
+
+ Label
+ Value
+ Min
+ Max
+
+
+
+
+
+
+
+
+
Temperature
+
+
+
+
+ Label
+ Value
+ Limit
+
+
+
+
+
+
+
+
+
Fans
+
+
+
+
+ Label
+ Value
+ Min
+
+
+
+
+
+
+
+
+
Power
+
+
+
+
+ Label
+ Value
+ Limit
+
+
+
+
+
+
+
+
+
Other
+
+
+
+
+ Label
+ Value
+
+
+
+
+
+
+
+
diff --git a/root/opt/phpsysinfo/templates/idash.css b/root/opt/phpsysinfo/templates/idash.css
index ffac6d9..1fb0370 100644
--- a/root/opt/phpsysinfo/templates/idash.css
+++ b/root/opt/phpsysinfo/templates/idash.css
@@ -1,12 +1,12 @@
/* NextGen Remixed by iDash.pl */
a {
text-decoration: none;
- color: #006;
+ color: #5a7000;
}
a:hover {
text-decoration: underline;
- color: #5A7000;
+ color: #5a7000;
}
* {
@@ -14,6 +14,10 @@ a:hover {
padding: 0;
}
+wbr {
+ display: inline-block;
+}
+
html {
height: 100%;
background: url("idash/bg.png") repeat-x scroll center top #111;
@@ -28,14 +32,21 @@ body {
margin: 0 auto;
padding: 20px 20px 0 20px;
font: 0.75em tahoma, arial, sans-serif;
- color: #CCC;
+ color: #ccc;
}
-div#container {
+div#output {
margin: -20px -10px 0 -10px;
padding: 95px 0 0 0;
}
+p {
+ padding: 4px 10px 2px 10px;
+ line-height: 1.6;
+ text-align: left;
+ vertical-align: top;
+}
+
h1 {
position: absolute;
top: 35px;
@@ -44,29 +55,7 @@ h1 {
padding: 0px 10px;
font-size: 2em;
font-weight: normal;
- color: #FFF;
-}
-
-#select {
- position: absolute;
- top: 75px;
- color: #FFF;
- right: 30px;
- width: 370px;
- text-align: right;
-}
-
-#select select {
- width: 100px;
-}
-
-#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
- float: left;
- width: 451px;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #354242;
+ color: #fff;
}
h2 {
@@ -76,28 +65,10 @@ h2 {
font-weight: bold;
letter-spacing: 0.0em;
text-transform: uppercase;
- color: #FFF; /* #7D9100; */
+ color: #fff; /* #7d9100; */
background: #354242;
}
-table {
- width: 100%;
-}
-
-.plugin {
- float: left;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #354242;
-}
-
-.dataTables_wrapper{
- margin: 0 0 0 0 !important;
- border: 0px !important;
-}
-
-
th, td, h3 {
padding: 4px 10px 2px 10px;
text-align: left;
@@ -108,12 +79,50 @@ h3 {
font-size: 120%;
}
-.even {
- background: #333;
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ position: absolute;
+ top: 75px;
+ color: #fff;
+ right: 30px;
+ width: 370px;
+ text-align: right;
+ padding: 0 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #354242;
+}
+
+.fullsize {
+ width: 916px;
+}
+
+.halfsize {
+ width: 451px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
}
#footer {
- color: #777777;
+ color: #777;
clear: both;
margin: 12px;
padding: 13px 25px;
@@ -121,23 +130,32 @@ h3 {
text-align: right;
}
-#memory, #filesystem {
- width: 915px;
+.lang_047 {
+ color:444
+}
+
+.plugin {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #354242;
+}
+
+.even {
+ background: #333;
}
.bar {
- background: #34DA64 url("idash/html.gif");
+ background: #34da64 url("idash/html.gif");
}
.barwarn {
background: #e69575 url("idash/htmlwarn.gif");
}
-p {
- padding: 4px 10px 2px 10px;
- line-height: 1.6;
- text-align: left;
- vertical-align: top;
+.barrest {
+ background: #57da34 url("idash/htmlrest.gif");
}
.right {
@@ -145,7 +163,39 @@ p {
padding-right: 20px;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding: 0px 30px;
+.dataTables_wrapper{
+ margin: 0 0 0 0 !important;
+ border: 0px !important;
+}
+
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
}
-#lang_047{color:444}
diff --git a/root/opt/phpsysinfo/templates/idash/bg.png b/root/opt/phpsysinfo/templates/idash/bg.png
index 60b8e4c..efc4f54 100644
Binary files a/root/opt/phpsysinfo/templates/idash/bg.png and b/root/opt/phpsysinfo/templates/idash/bg.png differ
diff --git a/root/opt/phpsysinfo/templates/idash/htmlrest.gif b/root/opt/phpsysinfo/templates/idash/htmlrest.gif
new file mode 100644
index 0000000..bb1b126
Binary files /dev/null and b/root/opt/phpsysinfo/templates/idash/htmlrest.gif differ
diff --git a/root/opt/phpsysinfo/templates/jstyle_blue.css b/root/opt/phpsysinfo/templates/jstyle_blue.css
index 8e2938b..b31081e 100644
--- a/root/opt/phpsysinfo/templates/jstyle_blue.css
+++ b/root/opt/phpsysinfo/templates/jstyle_blue.css
@@ -8,16 +8,22 @@ a {
a:hover {
text-decoration: underline;
-}* {
+}
+
+* {
margin: 0;
padding: 0;
}
+wbr {
+ display: inline-block;
+}
+
html {
font-size: 100%;
height: 100%;
background-color: #f3f1e9;
- color: #666666;
+ color: #666;
}
body {
@@ -32,6 +38,13 @@ body {
padding: 20px 20px 0 20px;
}
+p {
+ padding: 4px 10px 2px 10px;
+ line-height: 1.6;
+ text-align: left;
+ vertical-align: top;
+}
+
h1 {
margin: 0 10px;
_margin: 0 15px 0 10px; /* ie6 */
@@ -45,22 +58,6 @@ h1 {
color: #326ea1;
}
-#select {
- text-align: right;
-}
-
-#select select {
- width: 100px;
-}
-
-#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
- float: left;
- width: 451px;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
-}
-
h2 {
font-family: Georgia, serif;
font-weight: bold;
@@ -72,10 +69,63 @@ h2 {
border-bottom: 2px solid #326ea1;
}
+th, td, h3 {
+ padding: 4px 10px 2px 10px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 100%;
+}
+
table {
width: 100%;
}
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ text-align: right;
+ padding: 0 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.fullsize {
+ width: 918px;
+}
+
+.halfsize {
+ width: 453px;
+}
+
+#filesystemTable thead tr .header {
+ cursor: pointer;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
+}
+
+#footer {
+ clear: both;
+ color: #5c5c5c;
+ margin: 12px;
+ padding: 13px 25px;
+ line-height: 18px;
+ font-size: 80%;
+ text-align: center;
+}
+
.plugin {
float: left;
margin: 10px 0 0 10px;
@@ -83,29 +133,8 @@ table {
padding: 1px;
}
-th, td, h3 {
- padding: 4px 10px 2px 10px;
- text-align: left;
- vertical-align: top;
- font-size: 100%;
-}
-
.even {
- background: #EBE8DA;
-}
-
-#footer {
- clear: both;
- color: #5C5C5C;
- margin: 12px;
- padding: 13px 25px;
- line-height: 18px;
- font-size: 80%;
- text-align: center;
-}
-
-#memory, #filesystem {
- width: 915px;
+ background: #ebe8da;
}
.bar {
@@ -116,15 +145,8 @@ th, td, h3 {
background-color: #df326e;
}
-p {
- padding: 4px 10px 2px 10px;
- line-height: 1.6;
- text-align: left;
- vertical-align: top;
-}
-
-#filesystemTable thead tr .header {
- cursor: pointer;
+.barrest {
+ background-color: #32c5df;
}
.right {
@@ -132,6 +154,34 @@ p {
padding-right: 20px;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding: 0px 30px;
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
}
diff --git a/root/opt/phpsysinfo/templates/jstyle_green.css b/root/opt/phpsysinfo/templates/jstyle_green.css
index 3594e17..7933063 100644
--- a/root/opt/phpsysinfo/templates/jstyle_green.css
+++ b/root/opt/phpsysinfo/templates/jstyle_green.css
@@ -1,64 +1,126 @@
/*
$Id: jstyle_green.css 518 2011-10-28 08:09:07Z namiltd $
*/
+a {
+ color: #c03000;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
* {
- margin:0;
- padding:0;
+ margin: 0;
+ padding: 0;
+}
+
+wbr {
+ display: inline-block;
}
html {
- background-color:#f3f1e9;
- color:#666;
- font-size:100%;
- height:100%;
+ background-color: #f3f1e9;
+ color: #666;
+ font-size: 100%;
+ height: 100%;
}
body {
- font-family:Verdana, "Bitstream Vera Sans";
- font-size:.75em;
- margin:0 auto;
- min-height:100%;
- overflow:auto;
- padding:20px 20px 0;
- position:relative;
- width:940px;
+ font-family: Verdana, "Bitstream Vera Sans";
+ font-size: .75em;
+ margin: 0 auto;
+ min-height: 100%;
+ overflow: auto;
+ padding: 20px 20px 0;
+ position: relative;
+ width: 940px;
_width: 945px; /* ie6 */
}
+p {
+ line-height: 1.6;
+ padding: 4px 10px 2px;
+ text-align: left;
+ vertical-align: top;
+}
+
h1 {
- color:#693;
- font-family:Georgia, serif;
- font-size:150%;
- font-weight:400;
- line-height:1.5em;
- margin:0 10px;
+ color: #693;
+ font-family: Georgia, serif;
+ font-size: 150%;
+ font-weight: 400;
+ line-height: 1.5em;
+ margin: 0 10px;
_margin: 0 15px 0 10px; /* ie6 */
- padding:10px;
- text-align:center;
+ padding: 10px;
+ text-align: center;
}
h2 {
- border-bottom:2px solid #693;
- color:#693;
- font-family:Georgia, serif;
- font-size:130%;
- font-weight:700;
- line-height:1.5em;
- padding:3px 10px;
- text-transform:uppercase;
+ border-bottom: 2px solid #693;
+ color: #693;
+ font-family: Georgia, serif;
+ font-size: 130%;
+ font-weight: 700;
+ line-height: 1.5em;
+ padding: 3px 10px;
+ text-transform: uppercase;
}
-p {
- line-height:1.6;
- padding:4px 10px 2px;
- text-align:left;
- vertical-align:top;
+th, td, h3 {
+ font-size: 100%;
+ padding: 4px 10px 2px;
+ text-align: left;
+ vertical-align: top;
}
table {
- width:100%;
+ width: 100%;
}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ text-align: right;
+ padding: 0 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.fullsize {
+ width: 918px;
+}
+
+.halfsize {
+ width: 453px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
+}
+
+#footer {
+ clear: both;
+ color: #5C5C5C;
+ font-size: 80%;
+ line-height: 18px;
+ margin: 12px;
+ padding: 13px 25px;
+ text-align: center;
+}
+
.plugin {
float: left;
margin: 10px 0 0 10px;
@@ -66,77 +128,55 @@ table {
padding: 1px;
}
-th,td,h3 {
- font-size:100%;
- padding:4px 10px 2px;
- text-align:left;
- vertical-align:top;
+.even {
+ background: #ebe8da;
}
-a {
- color:#c03000;
- text-decoration:none;
-}
-
-a:hover {
- text-decoration:underline;
-}
-
-/****/
-
.bar {
- background-color:#C1DC70;
+ background-color: #c1dc70;
}
.barwarn {
- background-color:#DC8B70;
+ background-color: #dc8b70;
}
-.even {
- background:#EBE8DA;
+.barrest {
+ background-color: #8bdc70;
}
.right {
- padding-right:20px;
- text-align:right;
+ padding-right: 20px;
+ text-align: right;
}
-/****/
-
-#filesystemTable thead tr .header {
- cursor:pointer;
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding:0 30px;
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
}
-#vitals,#network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
- float:left;
- margin:10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding:1px;
- width:451px;
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
}
-#memory,#filesystem {
- width:915px;
+.tree tr td {
+ cursor: auto;
+ height: 100%;
}
-#select {
- text-align:right;
+.treediv {
+ display: table;
+ height: 100%;
}
-#select select {
- width:100px;
-}
-
-#footer {
- clear:both;
- color:#5C5C5C;
- font-size:80%;
- line-height:18px;
- margin:12px;
- padding:13px 25px;
- text-align:center;
+.tablemain {
+ width: 100%;
+ height: 100%;
}
diff --git a/root/opt/phpsysinfo/templates/lingruby.css b/root/opt/phpsysinfo/templates/lingruby.css
new file mode 100644
index 0000000..ec72ce3
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/lingruby.css
@@ -0,0 +1,169 @@
+/*
+ $Id: two.css 518 2011-10-28 08:09:07Z namiltd $
+ */
+a {
+ text-decoration: none;
+ color: #cc0000;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+wbr {
+ display: inline-block;
+}
+
+html {
+ font-size: 100%;
+ height: 100%;
+ color: #2b2828;
+ background: url("lingruby/background.png") fixed center;
+}
+
+body {
+ font-family: "Comic Sans MS", sans-serif;
+ font-size: .85em;
+ position: relative;
+ width: 940px;
+ _width: 945px; /* ie6 */
+ min-height: 100%;
+ overflow: auto;
+ margin: 0 auto;
+ padding: 20px 20px 0 20px;
+}
+
+h1 {
+ margin: 0 10px;
+ _margin: 0 15px 0 10px; /* ie6 */
+ padding: 10px 10px;
+ text-align: center;
+ color: #fff;
+ font-weight: normal;
+ font-size: 170%;
+ line-height: 1.5em;
+}
+
+h2 {
+ font-weight: bold;
+ font-size: 150%;
+ line-height: 1.5em;
+ color: #fff;
+ border-bottom: 2px solid #fff;
+}
+
+th, td, h3 {
+ padding: 4px 10px 2px 10px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 100%;
+}
+
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ color: #fff;
+ text-align: right;
+ padding: 0 10px 0 10px;
+ margin-bottom: 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.fullsize {
+ width: 918px;
+}
+
+.halfsize {
+ width: 453px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
+}
+
+#footer {
+ clear: both;
+ color: #000;
+ margin: 12px;
+ padding: 13px 25px;
+ line-height: 18px;
+ font-size: 90%;
+ text-align: center;
+}
+
+.plugin {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.bar {
+ background-color: #fff;
+}
+
+.barwarn {
+ background-color: #bbb;
+}
+
+.barrest {
+ background-color: #eaeaea;
+}
+
+.right {
+ text-align: right;
+ padding-right: 20px;
+}
+
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: normal;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/lingruby/background.png b/root/opt/phpsysinfo/templates/lingruby/background.png
new file mode 100644
index 0000000..f184a7c
Binary files /dev/null and b/root/opt/phpsysinfo/templates/lingruby/background.png differ
diff --git a/root/opt/phpsysinfo/templates/misc/emptyfile.css b/root/opt/phpsysinfo/templates/misc/emptyfile.css
new file mode 100644
index 0000000..e69de29
diff --git a/root/opt/phpsysinfo/templates/nextgen.css b/root/opt/phpsysinfo/templates/nextgen.css
index 80998e4..3ddf582 100644
--- a/root/opt/phpsysinfo/templates/nextgen.css
+++ b/root/opt/phpsysinfo/templates/nextgen.css
@@ -3,12 +3,12 @@
*/
a {
text-decoration: none;
- color: #00A;
+ color: #00a;
}
a:hover {
text-decoration: underline;
- color: #7D9100;
+ color: #7d9100;
}
* {
@@ -16,9 +16,13 @@ a:hover {
padding: 0;
}
+wbr {
+ display: inline-block;
+}
+
html {
height: 100%;
- background: url("nextgen/nextgen_bg.png") repeat-x scroll center top #F3F1E9;
+ background: url("nextgen/nextgen_bg.png") repeat-x scroll center top #f3f1e9;
}
body {
@@ -33,11 +37,18 @@ body {
color: #000;
}
-div#container {
+div#output {
margin: -20px -10px 0 -10px;
padding: 116px 0 0 0;
}
+p {
+ padding: 4px 10px 2px 10px;
+ line-height: 1.6;
+ text-align: left;
+ vertical-align: top;
+}
+
h1 {
position: absolute;
top: 35px;
@@ -49,28 +60,6 @@ h1 {
color: #fff;
}
-#select {
- position: absolute;
- top: 75px;
- color: #FFF;
- right: 30px;
- width: 370px;
- text-align: right;
-}
-
-#select select {
- width: 100px;
-}
-
-#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
- float: left;
- width: 451px;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #354242;
-}
-
h2 {
padding: 5px 10px;
font-family: "trebuchet ms";
@@ -78,28 +67,10 @@ h2 {
font-weight: bold;
letter-spacing: 0.0em;
text-transform: uppercase;
- color: #C9DE55; /* #7D9100; */
+ color: #c9de55; /* #7d9100; */
background: #354242;
}
-table {
- width: 100%;
-}
-
-.plugin {
- float: left;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #354242;
-}
-
-.dataTables_wrapper{
- margin: 0 0 0 0 !important;
- border: 0px !important;
-}
-
-
th, td, h3 {
padding: 4px 10px 2px 10px;
text-align: left;
@@ -110,12 +81,50 @@ h3 {
font-size: 120%;
}
-.even {
- background: #DDD;
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ position: absolute;
+ top: 75px;
+ color: #fff;
+ right: 30px;
+ width: 370px;
+ text-align: right;
+ padding: 0 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #354242;
+}
+
+.fullsize {
+ width: 916px;
+}
+
+.halfsize {
+ width: 451px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
}
#footer {
- color: #777777;
+ color: #777;
clear: both;
margin: 12px;
padding: 13px 25px;
@@ -123,23 +132,28 @@ h3 {
text-align: right;
}
-#memory, #filesystem {
- width: 915px;
+.plugin {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #354242;
+}
+
+.even {
+ background: #ddd;
}
.bar {
- background: #C1DC70 url("../gfx/html.gif");
+ background: #c1dc70 url("../gfx/html.gif");
}
.barwarn {
- background: #DC8B70 url("../gfx/htmlwarn.gif");
+ background: #dc8b70 url("../gfx/htmlwarn.gif");
}
-p {
- padding: 4px 10px 2px 10px;
- line-height: 1.6;
- text-align: left;
- vertical-align: top;
+.barrest {
+ background: #dcc170 url("../gfx/htmlrest.gif");
}
.right {
@@ -147,6 +161,39 @@ p {
padding-right: 20px;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding: 0px 30px;
+.dataTables_wrapper{
+ margin: 0 0 0 0 !important;
+ border: 0px !important;
+}
+
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
}
diff --git a/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png b/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png
index d6eb330..ddeb8ae 100644
Binary files a/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png and b/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png differ
diff --git a/root/opt/phpsysinfo/templates/phpsysinfo.css b/root/opt/phpsysinfo/templates/phpsysinfo.css
index a4140d1..2730ac7 100644
--- a/root/opt/phpsysinfo/templates/phpsysinfo.css
+++ b/root/opt/phpsysinfo/templates/phpsysinfo.css
@@ -8,11 +8,17 @@ a {
a:hover {
text-decoration: underline;
-}* {
+}
+
+* {
margin: 0;
padding: 0;
}
+wbr {
+ display: inline-block;
+}
+
html {
height: 100%;
background: url("../gfx/html.gif");
@@ -28,38 +34,27 @@ body {
padding: 20px 20px 0 20px;
font: 0.75em arial, tahoma, helvetica, sans-serif;
color: #000;
- background: #fff url("../gfx/body.png") repeat-y;
+ background: #fff url("../gfx/body.gif") repeat-y;
_bac\kground: #fff; /* ie6 only */
}
+p {
+ padding: 4px 10px 2px 10px;
+ line-height: 1.6;
+ text-align: left;
+ vertical-align: top;
+}
+
h1 {
margin: 0 10px;
_margin: 0 15px 0 10px; /* ie6 */
padding: 10px 10px;
- border-top: 1px solid #8A6E5A;
- border-bottom: 1px solid #8A6E5A;
+ border-top: 1px solid #8a6e5a;
+ border-bottom: 1px solid #8a6e5a;
font-size: 2em;
font-weight: normal;
color: #fff;
- background: #8A6E5A;
-}
-
-#select {
- text-align: right;
- padding: 10px;
-}
-
-#select select {
- width: 100px;
-}
-
-#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
- float: left;
- width: 451px;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #5A7E8A;
+ background: #8a6e5a;
}
h2 {
@@ -70,27 +65,9 @@ h2 {
letter-spacing: 0.0em;
text-transform: uppercase;
color: #fff;
- background: #5A7E8A;
+ background: #5a7e8a;
}
-table {
- width: 100%;
-}
-
-.plugin {
- float: left;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
- border: 1px solid #5A7E8A;
-}
-
-.dataTables_wrapper{
- margin: 0 0 0 0 !important;
- border: 0px !important;
-}
-
-
th, td, h3 {
padding: 4px 10px 2px 10px;
text-align: left;
@@ -101,8 +78,41 @@ h3 {
font-size: 120%;
}
-.even {
- background: #d6d6d6;
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ text-align: right;
+ padding: 10px 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #5a7e8a;
+}
+
+.fullsize {
+ width: 916px;
+}
+
+.halfsize {
+ width: 451px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
}
#footer {
@@ -113,23 +123,28 @@ h3 {
line-height: 18px;
}
-#memory, #filesystem {
- width: 915px;
+.plugin {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+ border: 1px solid #5a7e8a;
+}
+
+.even {
+ background: #d6d6d6;
}
.bar {
- background: #C1DC70 url("../gfx/html.gif");
+ background: #c1dc70 url("../gfx/html.gif");
}
.barwarn {
- background: #DC8B70 url("../gfx/htmlwarn.gif");
+ background: #dc8b70 url("../gfx/htmlwarn.gif");
}
-p {
- padding: 4px 10px 2px 10px;
- line-height: 1.6;
- text-align: left;
- vertical-align: top;
+.barrest {
+ background: #dcc170 url("../gfx/htmlrest.gif");
}
.right {
@@ -137,6 +152,39 @@ p {
padding-right: 20px;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding: 0px 30px;
+.dataTables_wrapper{
+ margin: 0 0 0 0 !important;
+ border: 0px !important;
+}
+
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
}
diff --git a/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css b/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css
index 0729a76..a53030a 100644
--- a/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css
+++ b/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css
@@ -1,10 +1,13 @@
body {
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 13px;
padding-top: 80px;
+ color: #333;
+ background-color: #fff;
}
-.progress {
- margin-bottom: 0;
+wbr {
+ display: inline-block;
}
.table td.rightCell, .table th.rightCell {
@@ -15,53 +18,60 @@ body {
text-align: center;
}
-.panel-primary {
- border: none;
+.card {
+ border-color: #f2f2f2;
}
.navbar {
- background-color: #428bca;
+ background-color: #3b87c8;
+ border-color: #2d6da3;
}
.navbar-brand, .navbar-brand:hover {
color: #fff;
+ margin-right: 0;
}
-.navbar-brand>img {
- display: inline;
+.treegrid-span {
+ display: table-cell;
+}
+
+.treegrid-spanbold {
+ font-weight: bold;
+ display: table-cell;
}
.treegrid-indent {
- width:16px;
+ width: 16px;
height: 16px;
- display: inline;
- position: relative;
+ display: table-cell;
}
.treegrid-expander {
- width:16px;
+ width: 0px;
height: 16px;
- display: inline;
- position: relative;
+ display: table-cell;
cursor: pointer;
}
.normalicon {
- position: relative;
- top: 1px;
- display: inline-block;
- font-style: normal;
- font-weight: normal;
- line-height: 1;
+ width: 16px;
+ height: 16px;
+ position: relative;
+ top: 1px;
+ display: table-cell;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
.normalicon-right:before {
- content: "\25ba";
+ content: "\25ba";
}
.normalicon-down:before {
- content: "\25bc";
+ content: "\25bc";
}
table.sortable thead th {
@@ -72,13 +82,143 @@ table.sortable thead th {
}
table.sortable thead th:hover {
- background: #efefef;
+ background-color: #ececec;
}
-table.borderless td,table.borderless th{
- border: none !important;
+.sorttable_nosort {
+ cursor: auto!important;
}
-.navbar-logo {
+.table-hover > tbody > tr:hover {
+ color: #333;
+ background-color: #ececec;
+}
+
+.table-hover > tfoot > tr:hover {
+ background-color: #ececec;
+}
+
+table.borderless td, table.borderless th, table.noborderattop tr:first-child td, table.noborderattop tr:first-child th {
+ border: none!important;
+}
+
+.table {
+ color: #333;
+ background-color: #fff!important;
+ margin: 0;
+ border: 0;
+}
+
+.logo {
cursor: pointer;
+ width: 32px;
+}
+
+.select {
+ color: #333;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+.template {
+ cursor: pointer;
+ color: #333;
+}
+
+.language {
+ cursor: pointer;
+ color: #333;
+}
+
+.card-header {
+ background-color: #337ab7!important;
+ border-color: #337ab7!important;
+ color: #fff!important;
+}
+
+.progress {
+ margin-bottom: 0;
+ background-color: #f5f5f5;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+
+.modal-content {
+ background-color: #fff;
+}
+
+.list-group {
+ display: block;
+}
+
+.list-group-item {
+ background-color: #fff;
+}
+
+.reload {
+ background-image: url("../gfx/reload.gif");
+ float: right;
+ cursor: pointer;
+ width: 16px;
+ height: 16px;
+}
+
+.container {
+ padding:0;
+}
+
+.table thead th {
+ border-top: none;
+}
+
+a, a:visited {
+ color: #000;
+}
+
+a:hover {
+ text-decoration: underline;
+ color: #000;
+}
+
+.psihref, .psihref:visited {
+ color: #fff;
+}
+
+.psihref:hover {
+ text-decoration: underline;
+ color: #fff;
+}
+
+.col-lg-6, .col-lg-12 {
+ padding-bottom: 20px;
+}
+
+.badge {
+ font-size: 12px;
+ border-radius: 10px;
+ padding: 3px 7px;
+ float: right;
+}
+
+.table-nopadding > tbody > tr > td,
+.table-nopadding > tbody > tr > th {
+ padding: 0;
}
diff --git a/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css b/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css
index 1b1f16c..13a684a 100644
--- a/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css
+++ b/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css
@@ -2,13 +2,13 @@
* DataTables sorting
*/
.sorting_asc {
- background: url('../../gfx/sort_asc.png') no-repeat center right;
+ background: url('../../gfx/sort_asc.gif') no-repeat center right;
}
.sorting_desc {
- background: url('../../gfx/sort_desc.png') no-repeat center right;
+ background: url('../../gfx/sort_desc.gif') no-repeat center right;
}
.sorting {
- background: url('../../gfx/sort_both.png') no-repeat center right;
+ background: url('../../gfx/sort_both.gif') no-repeat center right;
}
\ No newline at end of file
diff --git a/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css b/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css
index c747207..80a2d99 100644
--- a/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css
+++ b/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css
@@ -30,7 +30,6 @@ div#nyroModalFull div#nyroModalWrapper a#closeBut {
right: -13px;
width: 12px;
height: 12px;
- text-indent: -9999em;
background: url(../../gfx/close.gif) no-repeat;
outline: 0;
}
@@ -94,12 +93,12 @@ div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalPrev {
left: 0;
}
div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalPrev:hover {
- background-image: url(../../gfx/prev.png);
+ background-image: url(../../gfx/prev.gif);
}
div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalNext {
right: 0;
background-position: right 20%;
}
div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalNext:hover {
- background-image: url(../../gfx/next.png);
+ background-image: url(../../gfx/next.gif);
}
\ No newline at end of file
diff --git a/root/opt/phpsysinfo/templates/schabau.css b/root/opt/phpsysinfo/templates/schabau.css
new file mode 100644
index 0000000..2a48f48
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/schabau.css
@@ -0,0 +1,183 @@
+/*
+ $Id: schabau.css 518 2011-10-28 08:09:07Z namiltd $
+ */
+a {
+ text-decoration: none;
+ color: #c03000;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+wbr {
+ display: inline-block;
+}
+
+html {
+ font-size: 100%;
+ height: 100%;
+ background-color: #f2f2df;
+ color: #666;
+}
+
+body {
+ font-family: Verdana, "Bitstream Vera Sans";
+ font-size: .75em;
+ position: relative;
+ width: 940px;
+ _width: 945px; /* ie6 */
+ min-height: 100%;
+ overflow: auto;
+ margin: 0 auto;
+ padding: 20px 20px 0 20px;
+}
+
+p {
+ padding: 4px 10px 2px 10px;
+ line-height: 1.6;
+ text-align: left;
+ vertical-align: top;
+}
+
+h1 {
+ margin: 0 10px;
+ _margin: 0 15px 0 10px; /* ie6 */
+ padding: 10px 10px;
+ text-align: center;
+ color: #fff;
+ font-family: Georgia, serif;
+ font-weight: normal;
+ font-size: 150%;
+ line-height: 1.5em;
+ color: #326ea1;
+}
+
+h2 {
+ font-family: Georgia, serif;
+ font-weight: bold;
+ font-size: 130%;
+ padding: 3px 10px;
+ text-transform: uppercase;
+ line-height: 1.5em;
+ color: #326ea1;
+ border-bottom: 2px solid #326ea1;
+}
+
+th, td, h3 {
+ padding: 4px 10px 2px 10px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 100%;
+}
+
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ text-align: right;
+ padding: 0 10px 0 10px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.fullsize {
+ width: 918px;
+}
+
+.halfsize {
+ width: 453px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
+}
+
+#footer {
+ clear: both;
+ color: #5c5c5c;
+ margin: 12px;
+ padding: 13px 25px;
+ line-height: 18px;
+ font-size: 80%;
+ text-align: center;
+}
+
+.plugin {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.even {
+ background: #ebe8da;
+}
+
+.bar {
+ background-color: #326edf;
+}
+
+.barwarn {
+ background-color: #fa5858;
+}
+
+.barrest {
+ background-color: #32c5df;
+}
+
+.right {
+ text-align: right;
+ padding-right: 20px;
+}
+
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/schabau_bootstrap.css b/root/opt/phpsysinfo/templates/schabau_bootstrap.css
new file mode 100644
index 0000000..c702281
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/schabau_bootstrap.css
@@ -0,0 +1,233 @@
+/*
+ $Id: schabau_bootstrap.css $
+*/
+
+body {
+ font-family: Verdana, "Bitstream Vera Sans";
+ font-size: 13px;
+ padding-top: 80px;
+ color: #666;
+ background-color: #f2f2df;
+}
+
+wbr {
+ display: inline-block;
+}
+
+.table td.rightCell, .table th.rightCell {
+ text-align: right;
+}
+
+.percent {
+ text-align: center;
+}
+
+.card {
+ background-color: #f2f2df;
+ border-color: #bcbbb1;
+}
+
+.navbar {
+ font-family: Georgia, serif;
+ background-color: #f2f2df;
+ border-color: #bcbbb1;
+}
+
+.navbar-brand, .navbar-brand:hover {
+ color: #666;
+ margin-right: 0;
+}
+
+.treegrid-span {
+ display: table-cell;
+}
+
+.treegrid-spanbold {
+ font-weight: bold;
+ display: table-cell;
+}
+
+.treegrid-indent {
+ width: 16px;
+ height: 16px;
+ display: table-cell;
+}
+
+.treegrid-expander {
+ width: 0px;
+ height: 16px;
+ display: table-cell;
+ cursor: pointer;
+}
+
+.normalicon {
+ width: 16px;
+ height: 16px;
+ position: relative;
+ top: 1px;
+ display: table-cell;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.normalicon-right:before {
+ content: "\25ba";
+}
+.normalicon-down:before {
+ content: "\25bc";
+}
+
+table.sortable thead th {
+ cursor: pointer;
+ position: relative;
+ top: 0;
+ left: 0;
+}
+
+table.sortable thead th:hover {
+ background-color: #ebe8da;
+}
+
+.sorttable_nosort {
+ cursor: auto!important;
+}
+
+.table-hover > tbody > tr:hover {
+ color: #666;
+ background-color: #ebe8da;
+}
+
+.table-hover > tfoot > tr:hover {
+ background-color: #ebe8da;
+}
+
+table.borderless td, table.borderless th, table.noborderattop tr:first-child td, table.noborderattop tr:first-child th {
+ border: none!important;
+}
+
+.table {
+ color: #666;
+ background-color: #f2f2df!important;
+ margin: 0;
+ border: 0;
+}
+
+.logo {
+ cursor: pointer;
+ width: 32px;
+}
+
+.select {
+ color: #666;
+}
+
+select {
+ background-color: #f2f2df;
+}
+
+.template {
+ cursor: pointer;
+ color: #666;
+}
+
+.language {
+ cursor: pointer;
+ color: #666;
+}
+
+.card-header {
+ font-family: Georgia, serif;
+ font-weight: bold;
+ font-size: 130%;
+ background-color: #326ea1!important;
+ border-color: #326ea1!important;
+ color: #f2f2df!important;
+}
+
+.progress {
+ margin-bottom: 0;
+ background-color: #f2f2df;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+
+.progress-bar-info {
+ background-color: #326edf;
+}
+
+.progress-bar-warning {
+ background-color: #E3CB93;
+}
+
+.progress-bar-danger {
+ background-color: #fa5858;
+}
+
+.modal-content {
+ background-color: #f2f2df;
+}
+
+.list-group {
+ display: block;
+}
+
+.list-group-item {
+ background-color: #f2f2df;
+}
+
+.reload {
+ background-image: url("../gfx/reload.gif");
+ float: right;
+ cursor: pointer;
+ width: 16px;
+ height: 16px;
+}
+
+.container {
+ padding:0;
+}
+
+.table thead th {
+ border-top: none;
+}
+
+a, a:visited {
+ color: #666;
+}
+
+a:hover {
+ text-decoration: underline;
+ color: #666;
+}
+
+.psihref, .psihref:visited {
+ color: #326ea1;
+}
+
+.psihref:hover {
+ text-decoration: underline;
+ color: #326ea1;
+}
+
+.col-lg-6, .col-lg-12 {
+ padding-bottom: 20px;
+}
+
+.badge {
+ font-size: 12px;
+ border-radius: 10px;
+ padding: 3px 7px;
+ float: right;
+}
+
+.table-nopadding > tbody > tr > td,
+.table-nopadding > tbody > tr > th {
+ padding: 0;
+}
diff --git a/root/opt/phpsysinfo/templates/two.css b/root/opt/phpsysinfo/templates/two.css
index e506be6..55eb931 100644
--- a/root/opt/phpsysinfo/templates/two.css
+++ b/root/opt/phpsysinfo/templates/two.css
@@ -8,16 +8,22 @@ a {
a:hover {
text-decoration: underline;
-}* {
+}
+
+* {
margin: 0;
padding: 0;
}
+wbr {
+ display: inline-block;
+}
+
html {
font-size: 100%;
height: 100%;
- color: #2B2828;
- background: url("two/gradient.png") repeat-x #EEF2FE;
+ color: #2b2828;
+ background: url("two/gradient.png") repeat-x #eef2fe;
}
body {
@@ -43,33 +49,12 @@ h1 {
line-height: 1.5em;
}
-#select {
- color: #fff;
- text-align: right;
- margin-bottom: 45px;
-}
-
-#select select {
- width: 100px;
-}
-
h2 {
font-weight: bold;
font-size: 130%;
line-height: 1.5em;
- color: #8B272A;
- border-bottom: 2px solid #8B272A;
-}
-
-table {
- width: 100%;
-}
-
-.plugin {
- float: left;
- margin: 10px 0 0 10px;
- _margin: 10px 5px 0 5px; /* ie6 */
- padding: 1px;
+ color: #8b272a;
+ border-bottom: 2px solid #8b272a;
}
th, td, h3 {
@@ -79,9 +64,47 @@ th, td, h3 {
font-size: 100%;
}
+table {
+ width: 100%;
+}
+
+select {
+ background-color: #fefefe;
+}
+
+#select {
+ color: #fff;
+ text-align: right;
+ padding: 0 10px 0 10px;
+ margin-bottom: 45px;
+}
+
+#select select {
+ width: 100px;
+}
+
+.fullsize, .halfsize {
+ float: left;
+ margin: 10px 0 0 10px;
+ _margin: 10px 5px 0 5px; /* ie6 */
+ padding: 1px;
+}
+
+.fullsize {
+ width: 918px;
+}
+
+.halfsize {
+ width: 453px;
+}
+
+#filesystemTable thead tr th {
+ cursor: pointer;
+}
+
#footer {
clear: both;
- color: #5C5C5C;
+ color: #5c5c5c;
margin: 12px;
padding: 13px 25px;
line-height: 18px;
@@ -89,28 +112,23 @@ th, td, h3 {
text-align: center;
}
-.bar {
- background-color: #8B272A;
-}
-
-.barwarn {
- background-color: #88278B;
-}
-
-#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups {
+.plugin {
float: left;
- width: 451px;
margin: 10px 0 0 10px;
_margin: 10px 5px 0 5px; /* ie6 */
padding: 1px;
}
-#memory, #filesystem {
- width: 915px;
+.bar {
+ background-color: #8b272a;
}
-#filesystemTable thead tr .header {
- cursor: pointer;
+.barwarn {
+ background-color: #88278b;
+}
+
+.barrest {
+ background-color: #8b5627;
}
.right {
@@ -118,6 +136,34 @@ th, td, h3 {
padding-right: 20px;
}
-#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable {
- padding: 0px 30px;
+.treeimg {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+ vertical-align: top;
+}
+
+.treespan {
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.treespanbold {
+ font-weight: bold;
+ display: table-cell;
+ *float: left; /* ie6 ie7 */
+}
+
+.tree tr td {
+ cursor: auto;
+ height: 100%;
+}
+
+.treediv {
+ display: table;
+ height: 100%;
+}
+
+.tablemain {
+ width: 100%;
+ height: 100%;
}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome25.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome25.css
new file mode 100644
index 0000000..d640e21
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome25.css
@@ -0,0 +1,73 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
+.card-header:first-child {
+ border-radius: 3px 3px 0 0;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome28.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome28.css
new file mode 100644
index 0000000..f651791
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-chrome28.css
@@ -0,0 +1,70 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox15.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox15.css
new file mode 100644
index 0000000..ca43462
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox15.css
@@ -0,0 +1,76 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
+.card-header:first-child {
+ border-radius: 3px 3px 0 0;
+}
+*, :after, :before {
+ -moz-box-sizing: border-box;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox20.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox20.css
new file mode 100644
index 0000000..d27a76f
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox20.css
@@ -0,0 +1,73 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
+*, :after, :before {
+ -moz-box-sizing: border-box;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox27.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox27.css
new file mode 100644
index 0000000..2fd5fed
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox27.css
@@ -0,0 +1,78 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.row,
+.container-fluid,
+.container,
+section,
+footer,
+main,
+aside,
+.navbar-nav,
+.navbar-collapse {
+ display: block;
+}
+*, :after, :before {
+ -moz-box-sizing: border-box;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox28.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox28.css
new file mode 100644
index 0000000..b093cc3
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-firefox28.css
@@ -0,0 +1,3 @@
+*, :after, :before {
+ -moz-box-sizing: border-box;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-ie8.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-ie8.css
new file mode 100644
index 0000000..9cef572
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-ie8.css
@@ -0,0 +1,481 @@
+/* Bootstrap 4 for IE8 - v4.3.100 */
+/* https://github.com/namiltd/bootstrap-ie */
+
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.page-link,
+.navbar-brand {
+ float: left;
+}
+.row,
+.container-fluid,
+.container,
+section,
+footer,
+main,
+aside,
+.navbar-nav,
+.navbar-collapse {
+ display: block;
+}
+.modal.fade .modal-dialog {
+ -ms-transform: translate(0, -25%);
+}
+.modal.show .modal-dialog {
+ -ms-transform: translate(0, 0);
+}
+.custom-select {
+ background-image: none;
+ padding-right: .75rem;
+}
+.table-responsive {
+ min-height: 0%;
+} /* see https://github.com/twbs/bootstrap/issues/14837 */
+.progress {
+ display: block;
+}
+.progress-bar {
+ float: left;
+ font-size: 12px;
+ line-height: 20px;
+ width: 0;
+ text-align: center;
+ height: 100%;
+}
+.d-flex,
+.d-sm-flex,
+.d-md-flex,
+.d-lg-flex,
+.d-xl-flex,
+.d-print-flex {
+ display: block !important;
+}
+.d-inline-flex,
+.d-sm-inline-flex,
+.d-md-inline-flex,
+.d-lg-inline-flex,
+.d-xl-inline-flex,
+.d-print-inline-flex {
+ display: inline-block !important;
+}
+.flex-row .div {
+ display: inline-block;
+}
+.flex-row-reverse {
+ text-align: right;
+}
+.flex-row-reverse .div {
+ display: inline-block;
+ float: right;
+}
+.justify-content-start div {
+ display: inline-block;
+}
+.justify-content-end {
+ text-align: right;
+}
+.justify-content-end div {
+ display: inline-block;
+ margin-right: 0;
+ float: right;
+}
+.justify-content-center {
+ text-align: center;
+}
+.justify-content-center div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: center;
+}
+.justify-content-between {
+ text-justify: distribute-all-lines;
+}
+.justify-content-between div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: justify;
+}
+ /* see https://stackoverflow.com/questions/6865194/fluid-width-with-equally-spaced-divs */
+.justify-content-around {
+ text-align: justify;
+ text-justify: distribute-all-lines;
+}
+.justify-content-around div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: justify;
+}
+[class^="justify-content-"] div {
+ display: inline-block;
+}
+/** Carousel - Hide indicators and controls as the carousel doesn't work **/
+.carousel-indicators,
+.carousel-control-prev,
+.carousel-control-next {
+ display: none;
+}
+.btn-link.disabled,
+.btn-link:disabled {
+ text-decoration: none;
+}
+.close {
+ cursor:pointer;
+}
+.close.disabled {
+ cursor: auto;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.btn-group,
+.btn-group-vertical {
+ display: inline;
+ vertical-align: baseline;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group,
+.btn-group-vertical .btn + .btn,
+.btn-group-vertical .btn + .btn-group,
+.btn-group-vertical .btn-group + .btn,
+.btn-group-vertical .btn-group + .btn-group {
+ margin-left: -5px;
+}
+.navbar-expand-sm .navbar-collapse,
+.navbar-expand-md .navbar-collapse,
+.navbar-expand-lg .navbar-collapse,
+.navbar-expand-xl .navbar-collapse,
+.navbar-expand .navbar-collapse {
+ display: block !important;
+}
+.navbar > .container,
+.navbar > .container-fluid,
+.nav,
+.navbar {
+ display: block;
+}
+.nav-link {
+ padding: 0.5rem 1rem;
+ float:none;
+}
+.navbar-expand-sm .nav-link,
+.navbar-expand-md .nav-link,
+.navbar-expand-lg .nav-link,
+.navbar-expand-xl .nav-link,
+.navbar-expand .nav-link {
+ float: left;
+}
+.navbar-light .navbar-nav .nav-link,
+.navbar-light .navbar-nav .nav-link:focus {
+ color: #777;
+}
+.navbar-light .navbar-nav .active .nav-link:hover {
+ color: #000;
+}
+.navbar-light .navbar-nav .nav-link:hover {
+ color: #333;
+}
+.navbar-dark .navbar-nav .nav-link,
+.navbar-dark .navbar-nav .nav-link:focus {
+ color: #aaa;
+}
+.navbar-dark .navbar-nav .active .nav-link:hover {
+ color: #fff;
+}
+.navbar-dark .navbar-nav .nav-link:hover {
+ color: #ddd;
+}
+.row,
+.container-fluid,
+.container,
+section,
+footer,
+aside {
+ clear: both;
+}
+.breadcrumb-item {
+ display: inline-block;
+}
+body {
+ font-size:16px;
+}
+.btn {
+ cursor: pointer;
+}
+.btn-link.disabled {
+ color: #6c757d;
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: auto;
+}
+.modal-content {
+ border:1px solid #ddd;
+}
+.modal-footer {
+ text-align: right;
+}
+.list-group-item {
+ border: 1px solid #ddd;
+}
+.custom-control-input {
+ position: relative;
+}
+.collapse {
+ display:none;
+}
+.collapse.show {
+ display:block;
+}
+.col-1 {
+ width: 8.333333%;
+}
+.col-2 {
+ width: 16.666667%;
+}
+.col-3 {
+ width: 25%;
+}
+.col-4 {
+ width: 33.333333%;
+}
+.col-5 {
+ width: 41.666667%;
+}
+.col-6 {
+ width: 50%;
+}
+.col-7 {
+ width: 58.333333%;
+}
+.col-8 {
+ width: 66.666667%;
+}
+.col-9 {
+ width: 75%;
+}
+.col-10 {
+ width: 83.333333%;
+}
+.col-11 {
+ width: 91.666667%;
+}
+.col-12 {
+ width: 100%;
+}
+@media (min-width: 576px) {
+ .col-sm-1 {
+ width: 8.333333%;
+ }
+ .col-sm-2 {
+ width: 16.666667%;
+ }
+ .col-sm-3 {
+ width:25%;
+ }
+ .col-sm-4 {
+ width: 33.333333%;
+ }
+ .col-sm-5 {
+ width: 41.666667%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-7 {
+ width: 58.333333%;
+ }
+ .col-sm-8 {
+ width: 66.666667%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-10 {
+ width: 83.333333%;
+ }
+ .col-sm-11 {
+ width: 91.666667%;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+}
+@media (min-width: 768px) {
+ .col-md-1 {
+ width: 8.333333%;
+ }
+ .col-md-2 {
+ width: 16.666667%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-4 {
+ width: 33.333333%;
+ }
+ .col-md-5 {
+ width: 41.666667%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-7 {
+ width: 58.333333%;
+ }
+ .col-md-8 {
+ width: 66.666667%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-10 {
+ width: 83.333333%;
+ }
+ .col-md-11 {
+ width: 91.666667%;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+}
+@media (min-width: 992px) {
+ .col-lg-1 {
+ width: 8.333333%;
+ }
+ .col-lg-2 {
+ width: 16.666667%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-4 {
+ width: 33.333333%;
+ }
+ .col-lg-5 {
+ width: 41.666667%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-7 {
+ width: 58.333333%;
+ }
+ .col-lg-8 {
+ width: 66.666667%;
+ }
+ .col-lg-9 {
+ width:75%;
+ }
+ .col-lg-10 {
+ width: 83.333333%;
+ }
+ .col-lg-11 {
+ width: 91.666667%;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+}
+@media (min-width: 1200px) {
+ .col-xl-1 {
+ width: 8.333333%;
+ }
+ .col-xl-2 {
+ width: 16.666667%;
+ }
+ .col-xl-3 {
+ width: 25%;
+ }
+ .col-xl-4 {
+ width: 33.333333%;
+ }
+ .col-xl-5 {
+ width: 41.666667%;
+ }
+ .col-xl-6 {
+ width: 50%;
+ }
+ .col-xl-7 {
+ width: 58.333333%;
+ }
+ .col-xl-8 {
+ width: 66.666667%;
+ }
+ .col-xl-9 {
+ width: 75%;
+ }
+ .col-xl-10 {
+ width: 83.333333%;
+ }
+ .col-xl-11 {
+ width: 91.666667%;
+ }
+ .col-xl-12 {
+ width: 100%;
+ }
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-ie9.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-ie9.css
new file mode 100644
index 0000000..2c2b415
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-ie9.css
@@ -0,0 +1,244 @@
+/* Bootstrap 4 for IE9 - v4.3.100 */
+/* https://github.com/namiltd/bootstrap-ie */
+
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.page-link,
+.navbar-brand {
+ float: left;
+}
+.row,
+.container-fluid,
+.container,
+section,
+footer,
+main,
+aside,
+.navbar-nav,
+.navbar-collapse {
+ display: block;
+}
+.modal.fade .modal-dialog {
+ -ms-transform: translate(0, -25%);
+}
+.modal.show .modal-dialog {
+ -ms-transform: translate(0, 0);
+}
+.custom-select {
+ background-image: none;
+ padding-right: .75rem;
+}
+.table-responsive {
+ min-height: 0%;
+} /* see https://github.com/twbs/bootstrap/issues/14837 */
+.progress {
+ display: block;
+}
+.progress-bar {
+ float: left;
+ font-size: 12px;
+ line-height: 20px;
+ width: 0;
+ text-align: center;
+ height: 100%;
+}
+.d-flex,
+.d-sm-flex,
+.d-md-flex,
+.d-lg-flex,
+.d-xl-flex,
+.d-print-flex {
+ display: block !important;
+}
+.d-inline-flex,
+.d-sm-inline-flex,
+.d-md-inline-flex,
+.d-lg-inline-flex,
+.d-xl-inline-flex,
+.d-print-inline-flex {
+ display: inline-block !important;
+}
+.flex-row .div {
+ display: inline-block;
+}
+.flex-row-reverse {
+ text-align: right;
+}
+.flex-row-reverse .div {
+ display: inline-block;
+ float: right;
+}
+.justify-content-start div {
+ display: inline-block;
+}
+.justify-content-end {
+ text-align: right;
+}
+.justify-content-end div {
+ display: inline-block;
+ margin-right: 0;
+ float: right;
+}
+.justify-content-center {
+ text-align: center;
+}
+.justify-content-center div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: center;
+}
+.justify-content-between {
+ text-justify: distribute-all-lines;
+}
+.justify-content-between div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: justify;
+}
+ /* see https://stackoverflow.com/questions/6865194/fluid-width-with-equally-spaced-divs */
+.justify-content-around {
+ text-align: justify;
+ text-justify: distribute-all-lines;
+}
+.justify-content-around div {
+ display: inline-block;
+ margin-right: auto;
+ margin-left: auto;
+ text-align: justify;
+}
+[class^="justify-content-"] div {
+ display: inline-block;
+}
+/** Carousel - Hide indicators and controls as the carousel doesn't work **/
+.carousel-indicators,
+.carousel-control-prev,
+.carousel-control-next {
+ display: none;
+}
+.btn-link.disabled,
+.btn-link:disabled {
+ text-decoration: none;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.btn-group,
+.btn-group-vertical {
+ display: inline;
+ vertical-align: baseline;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group,
+.btn-group-vertical .btn + .btn,
+.btn-group-vertical .btn + .btn-group,
+.btn-group-vertical .btn-group + .btn,
+.btn-group-vertical .btn-group + .btn-group {
+ margin-left: -5px;
+}
+.navbar-expand-sm .navbar-collapse,
+.navbar-expand-md .navbar-collapse,
+.navbar-expand-lg .navbar-collapse,
+.navbar-expand-xl .navbar-collapse,
+.navbar-expand .navbar-collapse {
+ display: block !important;
+}
+.navbar > .container,
+.navbar > .container-fluid,
+.nav,
+.navbar {
+ display: block;
+}
+.nav-link {
+ padding: 0.5rem 1rem;
+ float:none;
+}
+.navbar-expand-sm .nav-link,
+.navbar-expand-md .nav-link,
+.navbar-expand-lg .nav-link,
+.navbar-expand-xl .nav-link,
+.navbar-expand .nav-link {
+ float: left;
+}
+.row,
+.container-fluid,
+.container,
+section,
+footer,
+aside {
+ clear: both;
+}
+.breadcrumb-item {
+ display: inline-block;
+}
+.modal-footer {
+ text-align: right;
+}
+.img-fluid[src$=".svg"] {
+ width: 100%;
+}
+.custom-switch .custom-control-input:checked ~ .custom-control-label:after {
+ -ms-transform: translateX(0.75rem);
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-midori04.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-midori04.css
new file mode 100644
index 0000000..d640e21
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-midori04.css
@@ -0,0 +1,73 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
+.card-header:first-child {
+ border-radius: 3px 3px 0 0;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-midori05.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-midori05.css
new file mode 100644
index 0000000..f651791
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-midori05.css
@@ -0,0 +1,70 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-opera11.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-opera11.css
new file mode 100644
index 0000000..f651791
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-opera11.css
@@ -0,0 +1,70 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-safari5.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-safari5.css
new file mode 100644
index 0000000..d640e21
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-safari5.css
@@ -0,0 +1,73 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
+.card-header:first-child {
+ border-radius: 3px 3px 0 0;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-safari8.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-safari8.css
new file mode 100644
index 0000000..f651791
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-safari8.css
@@ -0,0 +1,70 @@
+.card-group .card,
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12,
+.col-sm-1,
+.col-sm-2,
+.col-sm-3,
+.col-sm-4,
+.col-sm-5,
+.col-sm-6,
+.col-sm-7,
+.col-sm-8,
+.col-sm-9,
+.col-sm-10,
+.col-sm-11,
+.col-sm-12,
+.col-md-1,
+.col-md-2,
+.col-md-3,
+.col-md-4,
+.col-md-5,
+.col-md-6,
+.col-md-7,
+.col-md-8,
+.col-md-9,
+.col-md-10,
+.col-md-11,
+.col-md-12,
+.col-lg-1,
+.col-lg-2,
+.col-lg-3,
+.col-lg-4,
+.col-lg-5,
+.col-lg-6,
+.col-lg-7,
+.col-lg-8,
+.col-lg-9,
+.col-lg-10,
+.col-lg-11,
+.col-lg-12,
+.col-xl-1,
+.col-xl-2,
+.col-xl-3,
+.col-xl-4,
+.col-xl-5,
+.col-xl-6,
+.col-xl-7,
+.col-xl-8,
+.col-xl-9,
+.col-xl-10,
+.col-xl-11,
+.col-xl-12,
+.navbar-brand {
+ float: left;
+}
+.modal-header .close {
+ margin: -48px -16px -16px auto;
+}
+.progress-bar {
+ height: 100%;
+}
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap-webapp.css b/root/opt/phpsysinfo/templates/vendor/bootstrap-webapp.css
new file mode 100644
index 0000000..480b0e7
--- /dev/null
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap-webapp.css
@@ -0,0 +1,15 @@
+@media (max-width: 575.98px) {
+ .navbar, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,
+ .col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,
+ .col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,
+ .col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,
+ .col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,
+ .col-xl-auto {
+ padding-left: 0;
+ padding-right: 0;
+ }
+ .row {
+ margin-left: 0;
+ margin-right: 0;
+ }
+}
\ No newline at end of file
diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css b/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css
index 28f154d..7c4b857 100644
--- a/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css
+++ b/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css
@@ -1,5 +1,6 @@
/*!
- * Bootstrap v3.3.2 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
+ * Bootstrap v4.3.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 The Bootstrap Authors
+ * Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
\ No newline at end of file
+ */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
diff --git a/root/opt/phpsysinfo/tools/MakeRelease.sh b/root/opt/phpsysinfo/tools/MakeRelease.sh
deleted file mode 100755
index 6cbd4af..0000000
--- a/root/opt/phpsysinfo/tools/MakeRelease.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh -x
-
-if [ $# -ne 1 ]
-then
- echo "Usage : ./tools/MakeRelease
"
- exit
-fi
-
-sed -i "s/PSI_VERSION = '.*'/PSI_VERSION = '$1'/g" includes/class.CommonFunctions.inc.php
-ARCHIVE_NAME="phpsysinfo-$1.tar.gz"
-
-#copy to temp dir
-rm -rf /tmp/phpsysinfo
-mkdir /tmp/phpsysinfo
-cp -R . /tmp/phpsysinfo
-cd /tmp/phpsysinfo
-
-# remove the svn directories
-find . -type d -name .svn -exec rm -fr {} \;
-#or find . -iname ".svn" -print0 | xargs -0 rm -r
-
-#remove some dirs
-rm -rf tools sample
-
-#remove phpsysinfo.ini
-rm -rf phpsysinfo.ini .cvsignore .project
-
-#create archive
-cd ..
-tar -czf $ARCHIVE_NAME phpsysinfo
-
-md5sum $ARCHIVE_NAME
diff --git a/root/opt/phpsysinfo/tools/README b/root/opt/phpsysinfo/tools/README
index 71d6c21..3745b1f 100644
--- a/root/opt/phpsysinfo/tools/README
+++ b/root/opt/phpsysinfo/tools/README
@@ -1,4 +1,5 @@
-check.sh - Script for checking *.php files and reformat them
-MakeRelease.sh - Cleanup the code a bit for a release
-phpsysinfo.ini - Configuration file for generating documentation with phpDocumentor
-lint.bat - run php lint on every php file to check for syntax (windows util)
+checkdistro.php - Tests detection of distribution
+distrotest.php - Generates a txt file for distribution testing
+cputest.php - Displays anonymized /proc/cpuinfo
+phptest.php - Displays information about PHP
+checkpng.php - Tests the display of distribution logos
diff --git a/root/opt/phpsysinfo/tools/aptana/js.xml b/root/opt/phpsysinfo/tools/aptana/js.xml
deleted file mode 100644
index ca19006..0000000
--- a/root/opt/phpsysinfo/tools/aptana/js.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/root/opt/phpsysinfo/tools/aptana/php.xml b/root/opt/phpsysinfo/tools/aptana/php.xml
deleted file mode 100644
index 15fadc4..0000000
--- a/root/opt/phpsysinfo/tools/aptana/php.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/root/opt/phpsysinfo/tools/check.sh b/root/opt/phpsysinfo/tools/check.sh
deleted file mode 100755
index 62d32cb..0000000
--- a/root/opt/phpsysinfo/tools/check.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-FILES=`find ../ \( \( -iwholename '*tool*' -o -iwholename '*lang*' \) -prune -o -iname '*.php' \) -a -type f`
-
-for entry in ${FILES}; do
- php -l ${entry}
- if [ $? -ne 0 ]
- then
- exit;
- fi
-done
-
-for entry in ${FILES}; do
- echo "running phpcs --standard=PEAR on ${entry}"
- phpcs --standard=PEAR ${entry}
-done
diff --git a/root/opt/phpsysinfo/tools/checkdistro.php b/root/opt/phpsysinfo/tools/checkdistro.php
index 7bbd033..f8c05b6 100644
--- a/root/opt/phpsysinfo/tools/checkdistro.php
+++ b/root/opt/phpsysinfo/tools/checkdistro.php
@@ -1,46 +1,32 @@
";
+echo "";
echo " ";
echo " ";
+echo "";
echo "";
-if (PHP_OS != 'Linux') {
- echo "Test works only on Linux";
- echo "";
- die();
-}
-define('APP_ROOT', dirname(__FILE__).'/..');
-require_once APP_ROOT.'/includes/interface/class.PSI_Interface_OS.inc.php';
-require_once APP_ROOT.'/includes/os/class.OS.inc.php';
-require_once APP_ROOT.'/includes/to/class.System.inc.php';
-require_once APP_ROOT.'/includes/os/class.Linux.inc.php';
-define('PSI_USE_VHOST', false);
+define('PSI_APP_ROOT', dirname(__FILE__).'/..');
define('PSI_DEBUG', false);
-define('PSI_LOAD_BAR', false);
+require_once PSI_APP_ROOT.'/includes/interface/class.PSI_Interface_OS.inc.php';
+require_once PSI_APP_ROOT.'/includes/os/class.OS.inc.php';
+require_once PSI_APP_ROOT.'/includes/to/class.System.inc.php';
+require_once PSI_APP_ROOT.'/includes/os/class.Linux.inc.php';
$log_file = "";
$lsb = true; //enable detection lsb_release -a
$lsbfile = true; //enable detection /etc/lsb-release
+$files = true; //enable detection files
+$osfile = true; //enable detection /etc/os-release
+$other = true; //enable other detection
-class Error
+class PSI_Error
{
public static function singleton()
{
}
}
-class Parser
-{
- public static function lspci()
- {
- return array();
- }
- public static function df()
- {
- return array();
- }
-}
-
class CommonFunctions
{
private static function _parse_log_file($string)
@@ -48,6 +34,7 @@ class CommonFunctions
global $log_file;
if (file_exists($log_file)) {
$contents = @file_get_contents($log_file);
+ $contents = preg_replace("/\r\n/", "\n", $contents);
if ($contents && preg_match("/^\-\-\-\-\-\-\-\-\-\-".preg_quote($string, '/')."\-\-\-\-\-\-\-\-\-\-\n/m", $contents, $matches, PREG_OFFSET_CAPTURE)) {
$findIndex = $matches[0][1];
if (preg_match("/\n/m", $contents, $matches, PREG_OFFSET_CAPTURE, $findIndex)) {
@@ -68,9 +55,20 @@ class CommonFunctions
public static function rfts($strFileName, &$strRet, $intLines = 0, $intBytes = 4096, $booErrorRep = true)
{
- global $lsb;
global $lsbfile;
- if ($lsb || $lsbfile || ($strFileName != "/etc/lsb-release")) {
+ global $files;
+ global $osfile;
+ global $other;
+ if ($strFileName=="/etc/lsb-release") {
+ $test = $lsbfile;
+ } elseif ($strFileName=="/etc/os-release") {
+ $test = $osfile;
+ } elseif (($strFileName=="/etc/DISTRO_SPECS") || ($strFileName=="/etc/distro-release")|| ($strFileName=="/etc/system-release") || ($strFileName=="/etc/debian_version") || ($strFileName=="/etc/slackware-version") || ($strFileName=="/etc/config/uLinux.conf")) {
+ $test = $other;
+ } else {
+ $test = $files;
+ }
+ if ($test) {
$strRet=self::_parse_log_file($strFileName);
if ($strRet && ($intLines == 1) && (strpos($strRet, "\n") !== false)) {
$strRet=trim(substr($strRet, 0, strpos($strRet, "\n")));
@@ -82,127 +80,116 @@ class CommonFunctions
}
}
- public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true)
+ public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true, $timeout = 30)
{
global $lsb;
+ global $files;
$strBuffer = '';
if ($strProgramname=='lsb_release') {
return $lsb && ($strBuffer = self::_parse_log_file('lsb_release -a'));
} else {
- return $strBuffer = self::_parse_log_file($strProgramname);
+ return $files && ($strBuffer = self::_parse_log_file($strProgramname));
}
}
public static function fileexists($strFileName)
{
- global $log_file;
- global $lsb;
global $lsbfile;
- if (file_exists($log_file)
- && ($lsb || $lsbfile || ($strFileName != "/etc/lsb-release"))
- && ($contents = @file_get_contents($log_file))
- && preg_match("/^\-\-\-\-\-\-\-\-\-\-".preg_quote($strFileName, '/')."\-\-\-\-\-\-\-\-\-\-\n/m", $contents)) {
- return true;
+ global $files;
+ global $osfile;
+ global $other;
+ global $log_file;
+ if ($strFileName=="/etc/lsb-release") {
+ $test = $lsbfile;
+ } elseif ($strFileName=="/etc/os-release") {
+ $test = $osfile;
+ } elseif (($strFileName=="/etc/DISTRO_SPECS") || ($strFileName=="/etc/distro-release") || ($strFileName=="/etc/system-release") || ($strFileName=="/etc/debian_version") || ($strFileName=="/etc/slackware-version") || ($strFileName=="/etc/config/uLinux.conf")) {
+ $test = $other;
+ } else {
+ $test = $files;
}
-
- return false;
- }
-
- public static function gdc()
- {
- return array();
+ return $test && file_exists($log_file) && ($contents = @file_get_contents($log_file)) && preg_match("/^\-\-\-\-\-\-\-\-\-\-".preg_quote($strFileName, '/')."\-\-\-\-\-\-\-\-\-\-\r?\n/m", $contents);
}
}
-$system = new Linux();
-if ($handle = opendir(APP_ROOT.'/sample/distrotest')) {
- echo "";
- echo "Distrotest sample ";
- echo "Distro Name ";
- echo "Distro Icon ";
- echo "Distro Name (no lsb_release) ";
- echo "Distro Icon (no lsb_release) ";
- echo "Distro Name (no lsb_release and no /etc/lsb-release) ";
- echo "Distro Icon (no lsb_release and no /etc/lsb-release) ";
- echo "";
- while (false !== ($entry = readdir($handle))) {
- if (($entry!=".")&&($entry!="..")) {
- if ($shandle = opendir(APP_ROOT."/sample/distrotest/$entry")) {
- while (false !== ($sentry = readdir($shandle))) {
- if (($sentry!=".")&&($sentry!="..")) {
- $log_file=APP_ROOT.'/sample/distrotest/'.$entry.'/'.$sentry;
+class _Linux extends Linux
+{
+ public function build()
+ {
+ parent::_distro();
+ }
+}
+
+function echodist($entry, $system, $_lsb, $_lsbfile, $_files, $_osfile, $_other)
+{
+ global $lsb;
+ global $lsbfile;
+ global $files;
+ global $osfile;
+ global $other;
+
+ $lsb = $_lsb;
+ $lsbfile = $_lsbfile;
+ $files = $_files;
+ $osfile = $_osfile;
+ $other = $_other;
+
+ $sys = $system->getSys();
+ $distro=$sys->getDistribution();
+ $icon=$sys->getDistributionIcon();
+ if ($icon == '') $icon="unknown.png";
+ echo "";
+
+ if ($icon != $entry.'.png')
+ echo "";
+ else
+ echo "";
+ if ($distro !== 'Linux') {
+ echo " ";
+ echo $distro;
+ }
+ echo " ";
+ $sys->setDistributionIcon("");
+}
+
+$system = new _Linux('none');
+$dirs = scandir(PSI_APP_ROOT.'/sample/distrotest');
+if (($dirs !== false) && (count($dirs) > 0)) {
+ $dirs = array_diff($dirs, array('.', '..'));
+ if (($dirs !== false) && (count($dirs) > 0)) {
+ natcasesort($dirs);
+ echo "";
+ echo "";
+ echo "Distrotest sample ";
+ echo "Distro Name ";
+ echo "Distro Name (lsb_release only) ";
+ echo "Distro Name (/etc/lsb-release only) ";
+ echo "Distro Name (files only) ";
+ echo "Distro Name (os-release only) ";
+ echo "Distro Name (other only) ";
+ echo " ";
+ foreach ($dirs as $entry) {
+ $files = scandir(PSI_APP_ROOT."/sample/distrotest/$entry");
+ if (($files !== false) && (count($files) > 0)) {
+ $files = array_diff($files, array('.', '..'));
+ if (($files !== false) && (count($files) > 0)) {
+ natcasesort($files);
+ foreach ($files as $sentry) {
+ $log_file=PSI_APP_ROOT.'/sample/distrotest/'.$entry.'/'.$sentry;
echo "";
echo "".$entry.'/'.$sentry." ";
-
- $lsb = true;
- $lsbfile = true;
- $sys=$system->getSys();
- $distro=$sys->getDistribution();
- $icon=$sys->getDistributionIcon();
- if ($icon == '') $icon="unknown.png";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo $distro." ";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo " ";
- echo $icon." ";
- $sys->setDistribution("");
- $sys->setDistributionIcon("");
-
- $lsb = false;
- $lsbfile = true;
- $sys=$system->getSys();
- $distro=$sys->getDistribution();
- $icon=$sys->getDistributionIcon();
- if ($icon == '') $icon="unknown.png";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo $distro." ";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo " ";
- echo $icon." ";
- $sys->setDistribution("");
- $sys->setDistributionIcon("");
-
- $lsb = false;
- $lsbfile = false;
- $sys=$system->getSys();
- $distro=$sys->getDistribution();
- $icon=$sys->getDistributionIcon();
- if ($icon == '') $icon="unknown.png";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo $distro." ";
- if ($icon != $entry.'.png')
- echo "";
- else
- echo " ";
- echo " ";
- echo $icon." ";
- $sys->setDistribution("");
- $sys->setDistributionIcon("");
-
+ echodist($entry, $system, true, true, true, true, true);
+ echodist($entry, $system, true, false, false, false, false);
+ echodist($entry, $system, false, true, false, false, false);
+ echodist($entry, $system, false, false, true, false, false);
+ echodist($entry, $system, false, false, false, true, false);
+ echodist($entry, $system, false, false, false, false, true);
echo " ";
}
}
- closedir($shandle);
}
}
+ echo "
";
}
- echo "
";
- closedir($handle);
}
echo "
";
+
+$pngtable = glob('{../gfx/images/*.png,../plugins/*/gfx/*.png}', GLOB_BRACE);
+if (is_array($pngtable) && (($total = count($pngtable)) > 0)) {
+ echo "";
+ echo "";
+ echo "PNG name ";
+ echo "16x16 ";
+ echo "32x32 ";
+ echo "16x16 ";
+ echo "32x32 ";
+ echo "16x16 ";
+ echo "32x32 ";
+ echo " ";
+ for ($i = 0; $i < $total; $i++) {
+ echo "";
+ echo "".$pngtable[$i]." ";
+ echo "";
+ echo "";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ echo " ";
+ echo "";
+ echo " ";
+ }
+ echo "
";
+}
+echo "]*>(.*?)";
diff --git a/root/opt/phpsysinfo/tools/checkpng.php b/root/opt/phpsysinfo/tools/checkpng.php
new file mode 100644
index 0000000..bef2c42
--- /dev/null
+++ b/root/opt/phpsysinfo/tools/checkpng.php
@@ -0,0 +1,79 @@
+";
+echo "
";
diff --git a/root/opt/phpsysinfo/tools/cputest.php b/root/opt/phpsysinfo/tools/cputest.php
new file mode 100644
index 0000000..985a3e6
--- /dev/null
+++ b/root/opt/phpsysinfo/tools/cputest.php
@@ -0,0 +1,12 @@
+0) {
+ if (substr($contents, -1)!="\n") {
+ $contents.="\n";
+ }
+ $contents = preg_replace('/^(\s*serial\s*:\s*)(\S+)/im', '$1xxxxxxxxxxxxxxxx', $contents);
+ echo $contents;
+}
diff --git a/root/opt/phpsysinfo/tools/distrotest.php b/root/opt/phpsysinfo/tools/distrotest.php
index 2b3b891..6b4f449 100644
--- a/root/opt/phpsysinfo/tools/distrotest.php
+++ b/root/opt/phpsysinfo/tools/distrotest.php
@@ -1,5 +1,5 @@
0)&&(substr($contents, -1)!="\n")) {
- echo "\n";
+ $filenames = glob($filemask);
+ if (is_array($filenames)) foreach ($filenames as $filename) {
+ if (!is_dir($filename)) {
+ echo "----------".$filename."----------\n";
+ echo $contents=file_get_contents($filename);
+ if ((strlen($contents)>0)&&(substr($contents, -1)!="\n")) {
+ echo "\n";
+ }
}
}
}
diff --git a/root/opt/phpsysinfo/tools/lint.bat b/root/opt/phpsysinfo/tools/lint.bat
deleted file mode 100644
index b0502ab..0000000
--- a/root/opt/phpsysinfo/tools/lint.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-@echo off
-echo.
-echo Starting SVN Stat + PHP Lint
-echo ============================
-svn stat |findstr /I /R "\.php$ \.phtml$" >lint.txt
-for /F "tokens=2 delims= " %%i in (lint.txt) do q:\php53\php.exe -l %%i |findstr /I /B /V "No syntax errors"
-del lint.txt
-echo.
-echo ============================
-echo Finished SVN Stat + PHP Lint
diff --git a/root/opt/phpsysinfo/tools/phptest.php b/root/opt/phpsysinfo/tools/phptest.php
new file mode 100644
index 0000000..eb6797b
--- /dev/null
+++ b/root/opt/phpsysinfo/tools/phptest.php
@@ -0,0 +1,72 @@
+")) {
+ echo " - PHP 5.1.3 or greater is required!!!";
+}
+echo "\n";
+
+echo "PHP EXTENSIONS:\n";
+$arrReq = array('simplexml', 'pcre', 'xml', 'dom', 'mbstring', 'com_dotnet', 'json', 'xsl', 'snmp', 'pfsense');
+$extensions = get_loaded_extensions();
+$extarray = array();
+foreach ($extensions as $extension) {
+ $extarray[strtolower($extension)] = $extension;
+}
+
+$first = true;
+foreach ($arrReq as $extension) if (isset($extarray[$extension])) {
+ if ($first) {
+ echo " requred loaded:\n";
+ $first = false;
+ }
+ echoinfo($extarray[$extension]);
+}
+$first = true;
+foreach ($arrReq as $extension) if (!isset($extarray[$extension])) {
+ if ($first) {
+ echo " requred not loaded:\n";
+ $first = false;
+ }
+ echoinfo($extension);
+}
+$first = true;
+foreach ($extarray as $extlower=>$extension) if (!in_array($extlower, $arrReq, true)) {
+ if ($first) {
+ echo " others loaded:\n";
+ $first = false;
+ }
+ echoinfo($extension);
+}
diff --git a/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_bin.zip b/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_bin.zip
new file mode 100644
index 0000000..485aec9
Binary files /dev/null and b/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_bin.zip differ
diff --git a/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_src.zip b/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_src.zip
new file mode 100644
index 0000000..7f25b7f
Binary files /dev/null and b/root/opt/phpsysinfo/tools/speedfan/SpeedFanGet_src.zip differ
diff --git a/root/opt/phpsysinfo/xml.php b/root/opt/phpsysinfo/xml.php
index 9d8f10b..c6e829c 100644
--- a/root/opt/phpsysinfo/xml.php
+++ b/root/opt/phpsysinfo/xml.php
@@ -1,5 +1,4 @@
* @copyright 2009 phpSysInfo
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
* @version SVN: $Id: xml.php 614 2012-07-28 09:02:59Z jacky672 $
* @link http://phpsysinfo.sourceforge.net
*/
+header('Access-Control-Allow-Origin: *');
+
/**
* application root path
*
* @var string
*/
-define('APP_ROOT', dirname(__FILE__));
+define('PSI_APP_ROOT', dirname(__FILE__));
-/**
- * internal xml or external
- * external is needed when running in static mode
- *
- * @var boolean
- */
-define('PSI_INTERNAL_XML', true);
+require_once PSI_APP_ROOT.'/includes/autoloader.inc.php';
-require_once APP_ROOT.'/includes/autoloader.inc.php';
-
-// check what xml part should be generated
-if (isset($_GET['plugin'])) {
- $plugin = basename(htmlspecialchars($_GET['plugin']));
- if ($plugin == "complete") {
- $output = new WebpageXML(true, null);
- } elseif ($plugin != "") {
- $output = new WebpageXML(false, $plugin);
- } else {
- unset($output);
- }
+if ((isset($_GET['json']) || isset($_GET['jsonp'])) && !extension_loaded("json")) {
+ echo ' ';
} else {
- $output = new WebpageXML(false, null);
-}
-// if $output is correct generate output in proper type
-if (isset($output) && is_object($output)) {
+ // check what xml part should be generated
+ if (isset($_GET['plugin'])) {
+ $output = new WebpageXML($_GET['plugin']);
+ } else {
+ $output = new WebpageXML();
+ }
+ // generate output in proper type
if (isset($_GET['json']) || isset($_GET['jsonp'])) {
- if (defined('PSI_JSON_ISSUE') && (PSI_JSON_ISSUE)) {
- $json = json_encode(simplexml_load_string(str_replace(">", ">\n", $output->getXMLString()))); // solving json_encode issue
+ header('Cache-Control: no-cache, must-revalidate');
+ $json = $output->getJsonString();
+ if (isset($_GET['jsonp'])) {
+ header('Content-Type: application/javascript');
+ echo !preg_match('/[^\w\?]/', $_GET['callback'])?$_GET['callback']:'';
+ echo '('.$json.')';
} else {
- $json = json_encode(simplexml_load_string($output->getXMLString()));
+ header('Content-Type: application/json');
+ echo $json;
}
- // check for jsonp with callback name restriction
- echo isset($_GET['jsonp']) ? (!preg_match('/[^A-Za-z0-9_\?]/', $_GET['callback'])?$_GET['callback']:'') . '('.$json.')' : $json;
} else {
$output->run();
}
diff --git a/root/usr/share/smanager/lib/SrvMngr/Controller/Phpsysinfo.pm b/root/usr/share/smanager/lib/SrvMngr/Controller/Phpsysinfo.pm
new file mode 100644
index 0000000..6cf310d
--- /dev/null
+++ b/root/usr/share/smanager/lib/SrvMngr/Controller/Phpsysinfo.pm
@@ -0,0 +1,52 @@
+package SrvMngr::Controller::Phpsysinfo;
+
+#----------------------------------------------------------------------
+# heading : Legacy
+# description : System Information
+# navigation : 4000 600
+#----------------------------------------------------------------------
+#----------------------------------------------------------------------
+# name : phpsysinfo, method : get, url : /phpsysinfo, ctlact : Phpsysinfo#main
+#
+# routes : end
+#----------------------------------------------------------------------
+use strict;
+use warnings;
+use Mojo::Base 'Mojolicious::Controller';
+use Locale::gettext;
+use SrvMngr::I18N;
+use SrvMngr qw(theme_list init_session);
+use Mojo::UserAgent;
+my $ua = Mojo::UserAgent->new;
+$ua->insecure(1);
+sub main {
+ my $c = shift;
+ my $title = $c->l('psi_phpsysinfo_panel');
+ my $php_url = 'https://sme11.thereadclan.me.uk/phpsysinfo/index.php?disp=static';
+ #my $first_line = q{ };
+ #my $second_line = q{ };
+ $ua->get($php_url => sub {
+ my ($ua, $tx) = @_;
+ if ($tx->res->is_success) {
+ my $php_content = $tx->res->body;
+ my ($phpsysinfo_html) = $php_content =~ m{