Version Description
- Code rewritten from ground up to make use of latest code standards
- Added support for Dropbox, Amazon S3, Azure Blob and SFTP storage
- Added a new restore script
- Added an improved backup and system logger
- New Setting Panel
- New Manage Backups Panel with the options to Delete, Transfer to Remote Storage, Download and List Backup archive contents
- Added mail notifications for scheduled backups
- Added a new Cron Scheduler to make use of Wordpress System Cron option
- Improved user input sanitization
- Improved recursive file scanning and archiving
- Improved Mysql Backup dump
- Added Multiple Cleanup options both for local storage and remote
- Added Improved Backup Compressing option
Download this release
Release Info
Developer | xcloner |
Plugin | XCloner – Backup and Restore |
Version | 4.0.1 |
Comparing to | |
See all releases |
Code changes from version 3.1.5 to 4.0.1
- license.txt → LICENSE.txt +8 -9
- README.md +58 -0
- README.txt +168 -0
- admin.cloner.html.php +0 -2701
- admin.cloner.php +0 -215
- admin/assets/database-icon.png +0 -0
- admin/assets/file-icon-d.png +0 -0
- admin/assets/file-icon-f.png +0 -0
- admin/assets/file-icon-l.png +0 -0
- admin/assets/file-icon-root.png +0 -0
- admin/assets/table-icon.png +0 -0
- admin/class-xcloner-admin.php +265 -0
- admin/css/jquery.dataTables.min.css +1 -0
- admin/css/materialize.clockpicker.css +25 -0
- admin/css/materialize.min.css +16 -0
- admin/css/responsive.dataTables.css +178 -0
- admin/css/xcloner-admin.css +370 -0
- admin/fonts/roboto/Roboto-Bold.eot +0 -0
- admin/fonts/roboto/Roboto-Bold.ttf +0 -0
- admin/fonts/roboto/Roboto-Bold.woff +0 -0
- admin/fonts/roboto/Roboto-Bold.woff2 +0 -0
- admin/fonts/roboto/Roboto-Light.eot +0 -0
- admin/fonts/roboto/Roboto-Light.ttf +0 -0
- admin/fonts/roboto/Roboto-Light.woff +0 -0
- admin/fonts/roboto/Roboto-Light.woff2 +0 -0
- admin/fonts/roboto/Roboto-Medium.eot +0 -0
- admin/fonts/roboto/Roboto-Medium.ttf +0 -0
- admin/fonts/roboto/Roboto-Medium.woff +0 -0
- admin/fonts/roboto/Roboto-Medium.woff2 +0 -0
- admin/fonts/roboto/Roboto-Regular.eot +0 -0
- admin/fonts/roboto/Roboto-Regular.ttf +0 -0
- admin/fonts/roboto/Roboto-Regular.woff +0 -0
- admin/fonts/roboto/Roboto-Regular.woff2 +0 -0
- admin/fonts/roboto/Roboto-Thin.eot +0 -0
- admin/fonts/roboto/Roboto-Thin.ttf +0 -0
- admin/fonts/roboto/Roboto-Thin.woff +0 -0
- admin/fonts/roboto/Roboto-Thin.woff2 +0 -0
- admin/images/Sorting icons.psd +0 -0
- admin/images/favicon.ico +0 -0
- admin/images/sort_asc.png +0 -0
- admin/images/sort_asc_disabled.png +0 -0
- admin/images/sort_both.png +0 -0
- admin/images/sort_desc.png +0 -0
- admin/images/sort_desc_disabled.png +0 -0
- admin/index.php +1 -0
- admin/js/dataTables.responsive.js +1232 -0
- admin/js/jquery.dataTables.min.js +167 -0
- admin/js/materialize.clockpicker.js +1 -0
- admin/js/materialize.min.js +10 -0
- admin/js/xcloner-admin.js +132 -0
- admin/js/xcloner-backup-class.js +422 -0
- admin/js/xcloner-manage-backups-class.js +257 -0
- admin/js/xcloner-remote-storage-class.js +31 -0
- admin/js/xcloner-restore-class.js +827 -0
- admin/js/xcloner-scheduler-class.js +237 -0
- admin/partials/xcloner_console_page.php +51 -0
- admin/partials/xcloner_generate_backups_page.php +502 -0
- admin/partials/xcloner_init_page.php +237 -0
- admin/partials/xcloner_manage_backups_page.php +135 -0
- admin/partials/xcloner_remote_storage_page.php +593 -0
- admin/partials/xcloner_restore_page.php +331 -0
- admin/partials/xcloner_scheduled_backups_page.php +173 -0
- administrator/.htaccess +0 -2
- administrator/backups/.htaccess +0 -2
- administrator/backups/index.html +0 -0
- administrator/index.html +0 -0
- browser/file.gif +0 -0
- browser/filebrowser.css +0 -34
- browser/files_inpage.php +0 -23
- browser/files_xml.php +0 -266
- browser/folder.gif +0 -0
- browser/timer.gif +0 -0
- browser/xmlhttp.js +0 -156
- classes/.htaccess +0 -2
- classes/DropboxClient.php +0 -672
- classes/OAuthSimple.php +0 -532
- classes/S3.php +0 -1368
- classes/error.class.php +0 -0
- classes/fileRecursion.php +0 -477
- classes/index.html +0 -0
- classes/main.class.php +0 -116
- classes/mysqlBackup.class.php +0 -480
- classes/phpseclib/Crypt/AES.php +0 -594
- classes/phpseclib/Crypt/DES.php +0 -1245
- classes/phpseclib/Crypt/RC4.php +0 -505
- classes/phpseclib/Crypt/Random.php +0 -133
- classes/phpseclib/Crypt/Rijndael.php +0 -837
license.txt → LICENSE.txt
RENAMED
@@ -1,12 +1,12 @@
|
|
1 |
-
|
2 |
-
|
3 |
|
4 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
5 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
Everyone is permitted to copy and distribute verbatim copies
|
7 |
of this license document, but changing it is not allowed.
|
8 |
|
9 |
-
|
10 |
|
11 |
The licenses for most software are designed to take away your
|
12 |
freedom to share and change it. By contrast, the GNU General Public
|
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|
56 |
The precise terms and conditions for copying, distribution and
|
57 |
modification follow.
|
58 |
|
59 |
-
|
60 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
|
62 |
0. This License applies to any program or other work which contains
|
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
|
255 |
of preserving the free status of all derivatives of our free software and
|
256 |
of promoting the sharing and reuse of software generally.
|
257 |
|
258 |
-
|
259 |
|
260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
POSSIBILITY OF SUCH DAMAGES.
|
279 |
|
280 |
-
|
281 |
|
282 |
-
|
283 |
|
284 |
If you develop a new program, and you want it to be of the greatest
|
285 |
possible use to the public, the best way to achieve this is to make it
|
@@ -336,5 +336,4 @@ This General Public License does not permit incorporating your program into
|
|
336 |
proprietary programs. If your program is a subroutine library, you may
|
337 |
consider it more useful to permit linking proprietary applications with the
|
338 |
library. If this is what you want to do, use the GNU Lesser General
|
339 |
-
Public License instead of this License.
|
340 |
-
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
|
4 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
5 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
Everyone is permitted to copy and distribute verbatim copies
|
7 |
of this license document, but changing it is not allowed.
|
8 |
|
9 |
+
Preamble
|
10 |
|
11 |
The licenses for most software are designed to take away your
|
12 |
freedom to share and change it. By contrast, the GNU General Public
|
56 |
The precise terms and conditions for copying, distribution and
|
57 |
modification follow.
|
58 |
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
|
62 |
0. This License applies to any program or other work which contains
|
255 |
of preserving the free status of all derivatives of our free software and
|
256 |
of promoting the sharing and reuse of software generally.
|
257 |
|
258 |
+
NO WARRANTY
|
259 |
|
260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
POSSIBILITY OF SUCH DAMAGES.
|
279 |
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
|
282 |
+
How to Apply These Terms to Your New Programs
|
283 |
|
284 |
If you develop a new program, and you want it to be of the greatest
|
285 |
possible use to the public, the best way to achieve this is to make it
|
336 |
proprietary programs. If your program is a subroutine library, you may
|
337 |
consider it more useful to permit linking proprietary applications with the
|
338 |
library. If this is what you want to do, use the GNU Lesser General
|
339 |
+
Public License instead of this License.
|
|
README.md
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# XCloner Wordpress Plugin - Backup and Restore
|
2 |
+
|
3 |
+
Backup your Wordpress site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
|
4 |
+
|
5 |
+
XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
|
6 |
+
|
7 |
+
XCloner design was specifically created to Generate custom backups of any LAMP website through custom admin inputs, and to be able to Restore the clone on any other location with the help of the automatic Restore script we provide!
|
8 |
+
|
9 |
+
XCloner Backup tool uses Open Source standards like TAR, Mysql and CSV formats so you can rest assured your backups can be restored in a variety of ways, giving you more flexibility and full control.
|
10 |
+
|
11 |
+
## Features
|
12 |
+
|
13 |
+
* Backup and Restore your Wordpress site easily
|
14 |
+
* Create compressed and uncompressed backups using TAR open source format
|
15 |
+
* Create automated backups from your Scheduled Backups Section
|
16 |
+
* Received email notifications of created backups
|
17 |
+
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
18 |
+
* Restore your backups on any other location, XCloner will attempt to extract the backup archive files for you, as well as import the mysql dump and update the Wordpress config details
|
19 |
+
* Upload your backups to Remote Storage locations supporting FTP, SFTP, Dropbox, AWS, Azure Blog and many more to come
|
20 |
+
* Watch every step of XCloner through it's built in debugger
|
21 |
+
* Althrough we have optimized XCloner to run properly on most hosts, we give Developers options to customize it's running speed and avoid backup timeouts, all from the XCloner Config-> System Options
|
22 |
+
* Ability to split backups into multiple smaller parts if a certain size limit is reached
|
23 |
+
|
24 |
+
## Installation
|
25 |
+
|
26 |
+
1. Upload the plugin directory to wp-content/plugins directory
|
27 |
+
2. Activate the plugin
|
28 |
+
3. Access the plugin Dashboard from the Admin Sidebar -> Site Backup Menu
|
29 |
+
|
30 |
+
## UPGRADE
|
31 |
+
|
32 |
+
You can do it easily from the Wordpress backend.
|
33 |
+
|
34 |
+
## Frequently Asked Questions
|
35 |
+
|
36 |
+
<b>Where does XCloner keep it's database backups?</b>
|
37 |
+
|
38 |
+
XCloner stores them in separate mysql dump files, inside a folder called xcloner-XXXXX inside the backup archive root path, where XXXXX is a hash number that is identical with the last 5 characters of the backup name,
|
39 |
+
so if the backup name is backup_localhost-2017-02-16_15-36-sql-1c6c6.tgz , the mysql backup file will be stored in xcloner-1c6c6/ folder.
|
40 |
+
|
41 |
+
<b>How do I restore my backup?</b>
|
42 |
+
|
43 |
+
XCloner provide an easy to use restore script available in the Site Backup -> Restore Backups menu, the process is being described there as well.
|
44 |
+
|
45 |
+
If the XCloner Restore option fails, you can manually restore your backup as follows:
|
46 |
+
|
47 |
+
1. extract the backup archive files to your new location
|
48 |
+
2. locate the xcloner-XXXXX folder inside your backup root folder, and look for the mysql backup in database-sql and import it through phpmyadmin
|
49 |
+
3. update your wp-config.php file to reflect the new mysql details
|
50 |
+
|
51 |
+
<b>How do I know which files were include in the backup?</b>
|
52 |
+
|
53 |
+
The XCloner Manager Backups Panel provides an easy utility to view each backup content files list. It also stores a copy of the archived backup files inside the xcloner-XXXXX/backup_files.csv file in an easy to read CSV format.
|
54 |
+
|
55 |
+
<b>Do you have a log for the created backup?</b>
|
56 |
+
|
57 |
+
Yes, if XCloner Logger option is enabled, it will store a log file inside the xcloner-XXXXX folder inside the backup archive, file is named xcloner-xxxxx.log
|
58 |
+
|
README.txt
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== XCloner - Backup and Restore===
|
2 |
+
Contributors: xcloner
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AAPE8PLAE554S
|
4 |
+
Tags: backup plugin, restore plugin, database backup, full site backup, xcloner, website cloner, wordpress backup, database restore, blog transfer
|
5 |
+
Requires at least: 3.0.1
|
6 |
+
Tested up to: 4.7
|
7 |
+
Stable tag: 4.0.1
|
8 |
+
|
9 |
+
Backup your site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
|
14 |
+
|
15 |
+
[youtube http://www.youtube.com/watch?v=V9iWpPyG1EE]
|
16 |
+
|
17 |
+
XCloner design was specifically created to Generate custom backups of any Wordpress website through custom admin inputs, and to be able to Restore the backup on any other location with the help of the automatic Restore script we provide!
|
18 |
+
|
19 |
+
XCloner Backup tool uses Open Source standards like TAR, Mysql and CSV formats so you can rest assured your backups can be restored in a variety of ways, giving you more flexibility and full control.
|
20 |
+
|
21 |
+
Project is actively maintained through github https://github.com/ovidiul/XCloner-Wordpress/ , all issues can be reported here https://github.com/ovidiul/XCloner-Wordpress/issues .
|
22 |
+
|
23 |
+
<strong>Requirements:</strong>
|
24 |
+
|
25 |
+
PHP 5.4+ with mod CURL installed
|
26 |
+
|
27 |
+
<strong>Features:</strong>
|
28 |
+
|
29 |
+
* Backup and Restore your Wordpress site easily
|
30 |
+
* Create compressed and uncompressed backups using TAR open source format
|
31 |
+
* Create automated backups from your Scheduled Backups Section
|
32 |
+
* Received email notifications of created backups
|
33 |
+
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
34 |
+
* Restore your backups on any other location, XCloner will attempt to extract the backup archive files for you, as well as import the mysql dump and update the Wordpress config details
|
35 |
+
* Upload your backups to Remote Storage locations supporting FTP, SFTP, Dropbox, AWS, Azure Blog, BackBlaze and many more to come
|
36 |
+
* Watch every step of XCloner through it's built in debugger
|
37 |
+
* Althrough we have optimized XCloner to run properly on most hosts, we give Developers options to customize it's running speed and avoid backup timeouts, all from the XCloner Config-> System Options
|
38 |
+
* Ability to split backups into multiple smaller parts if a certain size limit is reached
|
39 |
+
|
40 |
+
== Installation ==
|
41 |
+
|
42 |
+
1. Upload the plugin directory to wp-content/plugins directory
|
43 |
+
2. Activate the plugin
|
44 |
+
3. Access the plugin Dashboard from the Admin Sidebar -> Site Backup Menu
|
45 |
+
|
46 |
+
UPGRADE:
|
47 |
+
|
48 |
+
You can do it easily from the Wordpress backend.
|
49 |
+
|
50 |
+
== Frequently Asked Questions ==
|
51 |
+
|
52 |
+
= Where does XCloner keep it's database backups? =
|
53 |
+
|
54 |
+
XCloner stores them in separate mysql dump files, inside a folder called xcloner-XXXXX inside the backup archive root path, where XXXXX is a hash number that is identical with the last 5 characters of the backup name,
|
55 |
+
so if the backup name is backup_localhost-2017-02-16_15-36-sql-1c6c6.tgz , the mysql backup file will be stored in xcloner-1c6c6/ folder.
|
56 |
+
|
57 |
+
= How do I restore my backup? =
|
58 |
+
|
59 |
+
XCloner provide an easy to use restore script available in the Site Backup -> Restore Backups menu, the process is being described there as well.
|
60 |
+
|
61 |
+
If the XCloner Restore option fails, you can manually restore your backup as follows:
|
62 |
+
|
63 |
+
1. extract the backup archive files to your new location
|
64 |
+
2. locate the xcloner-XXXXX folder inside your backup root folder, and look for the mysql backup in database-sql and import it through phpmyadmin
|
65 |
+
3. update your wp-config.php file to reflect the new mysql details
|
66 |
+
|
67 |
+
= How do I know which files were include in the backup? =
|
68 |
+
|
69 |
+
The XCloner Manager Backups Panel provides an easy utility to view each backup content files list. It also stores a copy of the archived backup files inside the xcloner-XXXXX/backup_files.csv file in an easy to read CSV format.
|
70 |
+
|
71 |
+
= Do you have a log for the created backup? =
|
72 |
+
|
73 |
+
Yes, if XCloner Logger option is enabled, it will store a log file inside the xcloner-XXXXX folder inside the backup archive, file is named xcloner-xxxxx.log
|
74 |
+
|
75 |
+
== Screenshots ==
|
76 |
+
|
77 |
+
1. XCloner Dashboard
|
78 |
+
2. General Backup Settings
|
79 |
+
3. List Backup Content
|
80 |
+
4. Cleanup Options for Local Storage
|
81 |
+
5. Remote Storage Panel supporting ftp, sftp, dropbox, amazon s3, azure blob and many more to come
|
82 |
+
6. Manage Scheduled Backups Panel
|
83 |
+
7. Edit Scheduled Backup
|
84 |
+
8. Generate Backup ->Files Options tab
|
85 |
+
9. Restore Backup Panel
|
86 |
+
10. Generate Backup Process
|
87 |
+
11. Generate Backup Screen
|
88 |
+
|
89 |
+
== Changelog ==
|
90 |
+
|
91 |
+
= 4.0.1 =
|
92 |
+
* Code rewritten from ground up to make use of latest code standards
|
93 |
+
* Added support for Dropbox, Amazon S3, Azure Blob and SFTP storage
|
94 |
+
* Added a new restore script
|
95 |
+
* Added an improved backup and system logger
|
96 |
+
* New Setting Panel
|
97 |
+
* New Manage Backups Panel with the options to Delete, Transfer to Remote Storage, Download and List Backup archive contents
|
98 |
+
* Added mail notifications for scheduled backups
|
99 |
+
* Added a new Cron Scheduler to make use of Wordpress System Cron option
|
100 |
+
* Improved user input sanitization
|
101 |
+
* Improved recursive file scanning and archiving
|
102 |
+
* Improved Mysql Backup dump
|
103 |
+
* Added Multiple Cleanup options both for local storage and remote
|
104 |
+
* Added Improved Backup Compressing option
|
105 |
+
|
106 |
+
= 3.1.5 =
|
107 |
+
* Config variables save sanitization addon
|
108 |
+
|
109 |
+
= 3.1.4 =
|
110 |
+
* DropPHP DropBox library update, upload fixes for files larger than 150MB
|
111 |
+
|
112 |
+
= 3.1.3 =
|
113 |
+
* XSS fix
|
114 |
+
|
115 |
+
= 3.1.2 =
|
116 |
+
* vulnerability fix
|
117 |
+
|
118 |
+
= 3.1.1 =
|
119 |
+
* added CSRF protection
|
120 |
+
|
121 |
+
= 3.1.0 =
|
122 |
+
* added Wordpress login-less integration
|
123 |
+
* plugin settings are now saved to database
|
124 |
+
* security audit and hardening
|
125 |
+
|
126 |
+
= 3.0.8 =
|
127 |
+
* added russian language support
|
128 |
+
|
129 |
+
= 3.0.7 =
|
130 |
+
* added sftp support for backup transfer, thanks Todd Bluhm - dynamicts.com
|
131 |
+
|
132 |
+
= 3.0.6 =
|
133 |
+
* added php 5.4 compatibility
|
134 |
+
|
135 |
+
= 3.0.4 =
|
136 |
+
* LFI vulnerability fix
|
137 |
+
|
138 |
+
= 3.0.3 =
|
139 |
+
* added amazon ssl option box
|
140 |
+
* moved the compress option to the System tab, don't use it unless you know what you are doing!
|
141 |
+
|
142 |
+
= 3.0.1 =
|
143 |
+
* several important security and bug fixes
|
144 |
+
|
145 |
+
= 3.0 =
|
146 |
+
* incremental database backup
|
147 |
+
* incremental file system scan
|
148 |
+
* backup size limit and option to split it into additional archives, default 2GB
|
149 |
+
* exclude files larger than a certain size option
|
150 |
+
* incremental files restore
|
151 |
+
* JQuery Start interface
|
152 |
+
|
153 |
+
= 2.2.1 =
|
154 |
+
* Added JSON AJAX interface to the Generate Backup process
|
155 |
+
* Added incremental filesystem scan
|
156 |
+
* several bug fixes
|
157 |
+
* php >=5.2.0 version check
|
158 |
+
|
159 |
+
= 2.1.2 =
|
160 |
+
* Added Amazon S3 cron storage support
|
161 |
+
|
162 |
+
= 2.1 =
|
163 |
+
* Initial release
|
164 |
+
|
165 |
+
== Upgrade Notice ==
|
166 |
+
|
167 |
+
= 3.0.3 =
|
168 |
+
Please check changelog!
|
admin.cloner.html.php
DELETED
@@ -1,2701 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* admin.cloner.html.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
/** ensure this file is being included by a parent file */
|
25 |
-
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
|
26 |
-
|
27 |
-
class mosTabs{
|
28 |
-
|
29 |
-
function mosTabs($int){
|
30 |
-
|
31 |
-
echo "<div id=\"tabs\">";
|
32 |
-
|
33 |
-
}
|
34 |
-
|
35 |
-
function startTab($name, $class){
|
36 |
-
|
37 |
-
echo "<div id=\"tabs-$class\"><p>";
|
38 |
-
|
39 |
-
|
40 |
-
}
|
41 |
-
|
42 |
-
function endTab(){
|
43 |
-
|
44 |
-
echo "</pp></div>";
|
45 |
-
|
46 |
-
}
|
47 |
-
|
48 |
-
function endPane(){
|
49 |
-
|
50 |
-
echo "</div>";
|
51 |
-
}
|
52 |
-
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* @package Joomla
|
57 |
-
* @subpackage JoomlaCloner
|
58 |
-
*/
|
59 |
-
class HTML_cloner {
|
60 |
-
|
61 |
-
function header(){
|
62 |
-
|
63 |
-
global $mosConfig_live_site, $task;
|
64 |
-
$excl_tasks = array("view", "config","");
|
65 |
-
|
66 |
-
?>
|
67 |
-
|
68 |
-
<script type="text/javascript">
|
69 |
-
|
70 |
-
/* Optional: Temporarily hide the "tabber" class so it does not "flash"
|
71 |
-
on the page as plain HTML. After tabber runs, the class is changed
|
72 |
-
to "tabberlive" and it will appear. */
|
73 |
-
|
74 |
-
document.write('<style type="text/css">.tabber{display:none;}<\/style>');
|
75 |
-
</script>
|
76 |
-
|
77 |
-
<table width='100%' style="padding-left: 3px; padding-right: 4px;align:center;" bgcolor='#ffffff'>
|
78 |
-
<tr><td align='right'>
|
79 |
-
|
80 |
-
</td></tr>
|
81 |
-
|
82 |
-
<tr><td align='center'>
|
83 |
-
|
84 |
-
<div class="status" >
|
85 |
-
<table width='100%' bgcolor='white' class="header">
|
86 |
-
<tr>
|
87 |
-
<td width='auto'>
|
88 |
-
<table><tr><td>
|
89 |
-
<img src="<?php echo plugins_url('images/backup.png', __FILE__) ?>" align="middle">
|
90 |
-
</td><td>
|
91 |
-
<a href="plugins.php?page=xcloner_show"><h2><?php echo LM_COM_TITLE.$_SERVER['HTTP_HOST']; ?></h2>
|
92 |
-
<h1>Backup and Restore</h1>
|
93 |
-
</a>
|
94 |
-
</td></tr>
|
95 |
-
</table>
|
96 |
-
</td>
|
97 |
-
<td align="right">
|
98 |
-
<div id="toolbar" style="display:none">
|
99 |
-
<?php
|
100 |
-
# Generating the buttons...
|
101 |
-
require_once( "toolbar.cloner.php" );
|
102 |
-
?>
|
103 |
-
</div>
|
104 |
-
</td>
|
105 |
-
</tr>
|
106 |
-
</table>
|
107 |
-
</div>
|
108 |
-
|
109 |
-
<br />
|
110 |
-
<table width="100%" cellspacing='3' cellpadding="4" >
|
111 |
-
<tr><td valign='top' width="160" >
|
112 |
-
<table width='100%' cellpadding='5' height='100%' class='menu_table'><tr><td>
|
113 |
-
|
114 |
-
|
115 |
-
<div class="dtree">
|
116 |
-
|
117 |
-
<a href="javascript: d.openAll();"><?php echo LM_MENU_OPEN_ALL?></a> | <a href="javascript: d.closeAll();"><?php echo LM_MENU_CLOSE_ALL?>l</a><br />
|
118 |
-
<br />
|
119 |
-
<script type="text/javascript">
|
120 |
-
<!--
|
121 |
-
|
122 |
-
d = new dTree('d');
|
123 |
-
|
124 |
-
d.add(0,-1,' <?php echo LM_MENU_CLONER;?>','plugins.php?page=xcloner_show&option=com_cloner','','','<?php echo plugins_url('images/logo.gif', __FILE__) ?>');
|
125 |
-
|
126 |
-
d.add(800,0,' <?php echo LM_MENU_ADMINISTRATION;?>','','','','<?php echo plugins_url('images/actions.gif', __FILE__) ?>','<?php echo plugins_url('images/actions.gif', __FILE__) ?>');
|
127 |
-
|
128 |
-
d.add(801,800,' <?php echo LM_MENU_CONFIGURATION;?>','plugins.php?page=xcloner_show&option=com_cloner&task=config','','','<?php echo plugins_url('images/gen_settings.png', __FILE__) ?>');
|
129 |
-
d.add(802,800,' <?php echo LM_MENU_CRON;?>','plugins.php?page=xcloner_show&option=com_cloner&task=cron','','','<?php echo plugins_url('images/templatessm.png', __FILE__) ?>');
|
130 |
-
d.add(803,800,' <?php echo LM_MENU_LANG;?>','plugins.php?page=xcloner_show&option=com_cloner&task=lang','','','<?php echo plugins_url('images/lang.png', __FILE__) ?>');
|
131 |
-
|
132 |
-
|
133 |
-
d.add(840,0,' <?php echo LM_MENU_ACTIONS;?>','','','','<?php echo plugins_url('images/actions.gif', __FILE__) ?>','<?php echo plugins_url('images/actions.gif', __FILE__) ?>');
|
134 |
-
d.add(841,840,' <?php echo LM_MENU_View_backups;?>','plugins.php?page=xcloner_show&option=com_cloner&task=view','','','<?php echo plugins_url('images/editionssm.png', __FILE__) ?>');
|
135 |
-
d.add(842,840,' <?php echo LM_MENU_Generate_backup;?>','plugins.php?page=xcloner_show&option=com_cloner&task=confirm','','','<?php echo plugins_url('images/wizardsm.png', __FILE__) ?>');
|
136 |
-
d.add(843,840,' <?php echo LM_MENU_Restore_backup;?>','plugins.php?page=xcloner_show&option=com_cloner&task=restore','','','<?php echo plugins_url('images/wizardsm_restore.png', __FILE__) ?>');
|
137 |
-
|
138 |
-
d.add(830,0,' <?php echo LM_MENU_SUPPORT;?>','','','','<?php echo plugins_url('images/support.png', __FILE__) ?>','<?php echo plugins_url('images/support.png', __FILE__) ?>');
|
139 |
-
d.add(831,830,' <?php echo LM_MENU_FORUM;?>','http://www.xcloner.com/support/forums/','','_blank','<?php echo plugins_url('images/forum.png', __FILE__) ?>','<?php echo plugins_url('images/forum.png', __FILE__) ?>');
|
140 |
-
d.add(832,830,' <?php echo LM_MENU_WEBSITE;?>','http://www.xcloner.com','','_blank','<?php echo plugins_url('images/website.png', __FILE__) ?>','<?php echo plugins_url('images/website.png', __FILE__) ?>');
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
d.add(820,0,' <?php echo LM_MENU_Documentation;?>','','','','<?php echo plugins_url('images/help.png', __FILE__) ?>','<?php echo plugins_url('images/gen_settings.png', __FILE__) ?>');
|
145 |
-
d.add(821,820,' <?php echo LM_MENU_ABOUT;?>','plugins.php?page=xcloner_show&option=com_cloner&task=about','','','<?php echo plugins_url('images/about.png', __FILE__) ?>','<?php echo plugins_url('images/about.png', __FILE__) ?>');
|
146 |
-
|
147 |
-
document.write(d);
|
148 |
-
|
149 |
-
//-->
|
150 |
-
</script></div> </td></tr></table>
|
151 |
-
<br />
|
152 |
-
<table width='100%' cellpadding='5' height='100%' class='menu_table'><tr><td>
|
153 |
-
<a href="http://www.thinkovi.com/services/website-migration/" target="_blank">
|
154 |
-
<img src="<?php echo plugins_url('images/thinkovi.png', __FILE__) ?>" border="0" />
|
155 |
-
</a>
|
156 |
-
</td></tr></table>
|
157 |
-
|
158 |
-
</td><td valign='top' align='left' style="padding-left: 20px;">
|
159 |
-
|
160 |
-
|
161 |
-
<?php
|
162 |
-
if($_REQUEST['mosmsg']!="")
|
163 |
-
|
164 |
-
echo "<center><h2>".strip_tags($_REQUEST['mosmsg'])."</h2></center>";
|
165 |
-
|
166 |
-
}
|
167 |
-
|
168 |
-
function footer(){
|
169 |
-
|
170 |
-
?>
|
171 |
-
</td></tr></table>
|
172 |
-
<hr><br /><br />
|
173 |
-
<center>
|
174 |
-
<p>Powered by <a href='http://www.xcloner.com' target='_blank'>XCloner</a>. Backup and Restore Made Easy!</p></center>
|
175 |
-
|
176 |
-
</td></tr></table>
|
177 |
-
<script>
|
178 |
-
|
179 |
-
jQuery( "#toolbar" ).show();
|
180 |
-
|
181 |
-
</script>
|
182 |
-
|
183 |
-
|
184 |
-
<?php
|
185 |
-
|
186 |
-
}
|
187 |
-
|
188 |
-
function goRefreshHtml($filename, $perm_lines, $excl_manual){
|
189 |
-
|
190 |
-
global $_CONFIG;
|
191 |
-
|
192 |
-
$f = pathinfo($filename);
|
193 |
-
$backupFile = $f['basename'];
|
194 |
-
|
195 |
-
if (file_exists($filename)) {
|
196 |
-
echo "<h2>Initializing backup...</h2>";
|
197 |
-
echo "<h3 >Backup <b>$filename</b> created, we may continue!</h3><br />";
|
198 |
-
|
199 |
-
$urlReturn = "plugins.php?page=xcloner_show&option=com_cloner&lines=" . $perm_lines . "&task=refresh&backup=$backupFile&excl_manual=$excl_manual";
|
200 |
-
|
201 |
-
if(!$_CONFIG['refresh_mode']){
|
202 |
-
|
203 |
-
echo "<a href=\"".$urlReturn."\" id='cLink'>Please click here to continue!</a>";
|
204 |
-
echo " <strong id='countdown'>5</strong>";
|
205 |
-
echo "<script type='text/javascript'>cLink_load();</script>";
|
206 |
-
|
207 |
-
}else{
|
208 |
-
|
209 |
-
echo "<script>var dbbackup = ".intval($_REQUEST['dbbackup']).";</script>";
|
210 |
-
|
211 |
-
?>
|
212 |
-
<!--Start ProgressBar-->
|
213 |
-
<script type="text/javascript">
|
214 |
-
|
215 |
-
jQuery(document).ready(function() {
|
216 |
-
|
217 |
-
var globalUrl;
|
218 |
-
var step = "r1";
|
219 |
-
var count = 0;
|
220 |
-
var counter = 0;
|
221 |
-
var counter_old = 0;
|
222 |
-
var completeSize = 0;
|
223 |
-
var oldBackupName = "";
|
224 |
-
var parts = 0;
|
225 |
-
var oldSize = 0;
|
226 |
-
|
227 |
-
jQuery("#progressbar").progressbar({ value: 0 });
|
228 |
-
|
229 |
-
jQuery.ajaxSetup({
|
230 |
-
"error":function(request, status, error) {
|
231 |
-
//reset state here;
|
232 |
-
jQuery("#error").show();
|
233 |
-
jQuery("#errorText").append(status+" -- "+error);
|
234 |
-
jQuery("#errorText").append("<br /><br /><strong>JSON url:</strong> "+globalUrl);
|
235 |
-
jQuery("#errorText").append("<br /><br /><strong>Response body:</strong> "+request.responseText);
|
236 |
-
}});
|
237 |
-
|
238 |
-
function getSize(bytes, conv){
|
239 |
-
|
240 |
-
return (parseInt(bytes)/parseInt(conv)).toFixed(2);
|
241 |
-
|
242 |
-
}
|
243 |
-
function appendIcon(icon){
|
244 |
-
|
245 |
-
return '<span class="ui-icon ui-icon-'+icon+'" style="float:left;"></span>';
|
246 |
-
|
247 |
-
}
|
248 |
-
|
249 |
-
function xclonerRecurseMYSQL(url){
|
250 |
-
// create database backup
|
251 |
-
globalUrl = url;
|
252 |
-
step = "r1";
|
253 |
-
|
254 |
-
jQuery.getJSON(url, function(json) {
|
255 |
-
|
256 |
-
if(!json){
|
257 |
-
jQuery("#error").show();
|
258 |
-
jQuery("#errorText").text(url);
|
259 |
-
}
|
260 |
-
|
261 |
-
if(json.dumpsize && !json.endDump){
|
262 |
-
jQuery("#mysqlProcess").append(" ("+getSize(json.dumpsize, 1024*1024)+" MB) <br />");
|
263 |
-
}
|
264 |
-
|
265 |
-
if(json.newDump){
|
266 |
-
count++;
|
267 |
-
//jQuery("#mysqlProcess").append(appendIcon("arrowthick-1-e"));
|
268 |
-
if(json.databaseName!="")
|
269 |
-
jQuery("#mysqlProcess").append("<b>["+json.databaseName+"]</b> <span id='db"+count+"'></span> tables ");
|
270 |
-
counter = parseInt(json.startAtLine);
|
271 |
-
|
272 |
-
}else{
|
273 |
-
jQuery("#db"+count).text(json.startAtLine - counter);
|
274 |
-
}
|
275 |
-
|
276 |
-
if(!parseInt(json.finished)){
|
277 |
-
//get next records
|
278 |
-
|
279 |
-
jQuery("#db"+count).text(json.startAtLine - counter);
|
280 |
-
|
281 |
-
recurseUrl = "admin-ajax.php?action=json_return&task=recurse_database&nohtml=1&dbbackup_comp="+json.dbbackup_comp+"&dbbackup_drop="+json.dbbackup_drop+"&startAtLine="+json.startAtLine+"&startAtRecord="+json.startAtRecord+"&dumpfile="+json.dumpfile;
|
282 |
-
xclonerRecurseMYSQL(recurseUrl);
|
283 |
-
|
284 |
-
}
|
285 |
-
else{
|
286 |
-
|
287 |
-
jQuery("#fileSystem").show();
|
288 |
-
var recurseUrl="admin-ajax.php?action=json_return&task=recurse_files&mode=start&nohtml=1";
|
289 |
-
xclonerRecurseJSON(recurseUrl);
|
290 |
-
|
291 |
-
}
|
292 |
-
|
293 |
-
|
294 |
-
});
|
295 |
-
}
|
296 |
-
|
297 |
-
function xclonerRecurseJSON(url){
|
298 |
-
//scan file system
|
299 |
-
jQuery("#result").hide();
|
300 |
-
|
301 |
-
globalUrl = url;
|
302 |
-
step = "r2";
|
303 |
-
|
304 |
-
jQuery.getJSON(url, function(json) {
|
305 |
-
|
306 |
-
if(!json){
|
307 |
-
jQuery("#error").show();
|
308 |
-
jQuery("#errorText").text(url);
|
309 |
-
}
|
310 |
-
|
311 |
-
if(!parseInt(json.finished)){
|
312 |
-
|
313 |
-
jQuery("#recurseStatus").text(json.tfiles);
|
314 |
-
|
315 |
-
var recurseUrl = "admin-ajax.php?action=json_return&task=recurse_files&mode="+json.mode+"&nohtml=1&files="+json.tfiles;
|
316 |
-
xclonerRecurseJSON(recurseUrl);
|
317 |
-
|
318 |
-
}
|
319 |
-
else{
|
320 |
-
var size = parseFloat(json.size)/(1024*1024);
|
321 |
-
jQuery("#recurseStatus").text(" done! (Estimated size:"+size.toFixed(2)+"MB) in "+json.tfiles+" files");
|
322 |
-
jQuery("#result").show();
|
323 |
-
|
324 |
-
if(json.overlimit.length > 0){
|
325 |
-
jQuery("#overlimit").show();
|
326 |
-
for(var i=0; i < json.overlimit.length; i++){
|
327 |
-
|
328 |
-
jQuery("#overlimit").append("<span class='oversizedFile'></span>"+json.overlimit[i]+"<br />");
|
329 |
-
|
330 |
-
}
|
331 |
-
}
|
332 |
-
|
333 |
-
//xclonerGetJSON("<?php echo $urlReturn;?>");
|
334 |
-
returnUrl = "admin-ajax.php?action=json_return&option=com_cloner&lines="+json.tfiles+"&task=refresh&backup=<?php echo $backupFile; ?>&excl_manual=";
|
335 |
-
xclonerGetJSON(returnUrl);
|
336 |
-
|
337 |
-
}
|
338 |
-
|
339 |
-
|
340 |
-
});
|
341 |
-
}
|
342 |
-
|
343 |
-
function xclonerGetJSON(url){
|
344 |
-
//create backup archive
|
345 |
-
globalUrl = url;
|
346 |
-
step = "r3";
|
347 |
-
|
348 |
-
jQuery.getJSON(url, function(json) {
|
349 |
-
|
350 |
-
if(!json){
|
351 |
-
jQuery("#error").show();
|
352 |
-
jQuery("#errorText").append(url);
|
353 |
-
}
|
354 |
-
|
355 |
-
var percent = parseInt(json.percent);
|
356 |
-
jQuery("#progressbar").progressbar({ value: percent });
|
357 |
-
jQuery("#backupSize").text(getSize(json.backupSize, 1024*1024));
|
358 |
-
jQuery("#nFiles").text(json.startf);
|
359 |
-
jQuery("#percent").text(json.percent);
|
360 |
-
jQuery("#backupName").text(json.backup);
|
361 |
-
if(!json.finished){
|
362 |
-
|
363 |
-
if(oldBackupName != json.backup){
|
364 |
-
oldBackupName = json.backup;
|
365 |
-
completeSize = completeSize + oldSize;
|
366 |
-
parts++;
|
367 |
-
}else{
|
368 |
-
oldSize = parseInt(json.backupSize);
|
369 |
-
}
|
370 |
-
|
371 |
-
var url = "admin-ajax.php?action=json_return&option="+json.option+"&task="+json.task+"&json="+json.json+"&startf="+json.startf+"&lines="+json.lines+"&backup="+json.backup+"&excl_manual="+json.excl_manual;
|
372 |
-
xclonerGetJSON(url);
|
373 |
-
}else{
|
374 |
-
|
375 |
-
//all done
|
376 |
-
url = "admin-ajax.php?action=json_return&task=cleanup&nohtml=1";
|
377 |
-
jQuery.getJSON(url, function(json) {
|
378 |
-
});
|
379 |
-
|
380 |
-
jQuery("#complete").show();
|
381 |
-
jQuery("#nFiles").text(json.lines);
|
382 |
-
if(parts > 0){
|
383 |
-
jQuery("#backupParts").show();
|
384 |
-
jQuery("#backupPartsNr").text(parts);
|
385 |
-
}
|
386 |
-
jQuery("#backupFiles").text(json.lines);
|
387 |
-
jQuery("#backupSizeComplete").append(getSize(completeSize+parseInt(json.backupSize), 1024*1024));
|
388 |
-
jQuery("#backupNameC").text(json.backup);
|
389 |
-
jQuery( "#dialog:ui-dialog" ).dialog( "destroy" );
|
390 |
-
jQuery( "#dialog-message" ).dialog({
|
391 |
-
modal: true,
|
392 |
-
width: 600,
|
393 |
-
buttons: {
|
394 |
-
Close: function() {
|
395 |
-
jQuery( this ).dialog( "close" );
|
396 |
-
}
|
397 |
-
}
|
398 |
-
});
|
399 |
-
|
400 |
-
}
|
401 |
-
|
402 |
-
});
|
403 |
-
|
404 |
-
}
|
405 |
-
|
406 |
-
//Main program here
|
407 |
-
|
408 |
-
jQuery("#retry").click(function(){
|
409 |
-
jQuery("#error").hide();
|
410 |
-
jQuery("#errorText").empty();
|
411 |
-
if(step == "r1"){
|
412 |
-
xclonerRecurseMYSQL(globalUrl);
|
413 |
-
}
|
414 |
-
else
|
415 |
-
if(step == "r2"){
|
416 |
-
xclonerRecurseJSON(globalUrl);
|
417 |
-
}
|
418 |
-
else if(step == "r3"){
|
419 |
-
xclonerGetJSON(globalUrl);
|
420 |
-
}
|
421 |
-
});
|
422 |
-
|
423 |
-
jQuery("#result").hide();
|
424 |
-
jQuery("#fileSystem").hide();
|
425 |
-
|
426 |
-
if(dbbackup){
|
427 |
-
recurseUrl = "admin-ajax.php?action=json_return&task=recurse_database&nohtml=1&dbbackup_comp=<?php echo $_REQUEST['dbbackup_comp']?>&dbbackup_drop=<?php echo $_REQUEST['dbbackup_drop']?>";
|
428 |
-
xclonerRecurseMYSQL(recurseUrl);
|
429 |
-
}else{
|
430 |
-
jQuery("#fileSystem").show();
|
431 |
-
var recurseUrl="admin-ajax.php?action=json_return&task=recurse_files&mode=start&nohtml=1";
|
432 |
-
xclonerRecurseJSON(recurseUrl);
|
433 |
-
|
434 |
-
}
|
435 |
-
|
436 |
-
});
|
437 |
-
</script>
|
438 |
-
|
439 |
-
<?php
|
440 |
-
|
441 |
-
if($_REQUEST['dbbackup']){
|
442 |
-
//lets start the incremental procedure
|
443 |
-
?>
|
444 |
-
|
445 |
-
<div id="mysqlBackup">
|
446 |
-
<h2>Database backup...</h2><br />
|
447 |
-
<div id="mysqlProcess"></div><div id="counter"></div>
|
448 |
-
</div>
|
449 |
-
|
450 |
-
<?php
|
451 |
-
}
|
452 |
-
?>
|
453 |
-
|
454 |
-
<div id="fileSystem">
|
455 |
-
<h2>Filesystem backup...</h2>
|
456 |
-
|
457 |
-
<div id="recurseFiles">
|
458 |
-
<br /><strong>Scanning files system...</strong> <span id="recurseStatus"></span>
|
459 |
-
<br /><div id="overlimit" style="display:none"><b>Excluded oversized files:</b><br /> </div>
|
460 |
-
</div>
|
461 |
-
|
462 |
-
<div id="result">
|
463 |
-
<br /> <strong>Processing Files:</strong> <span id="percent">0</span>% (<span id="nFiles"></span> files)
|
464 |
-
<br /><br /> <strong>Backup Name: </strong><span id="backupName"></span>
|
465 |
-
<br /><br /> <strong>Backup Size: </strong><span id="backupSize"></span>MB
|
466 |
-
<br /><br /> <div id="progressbar"></div>
|
467 |
-
</div>
|
468 |
-
|
469 |
-
<div id="complete">
|
470 |
-
<br /><h2>Backup completed!</h2>
|
471 |
-
|
472 |
-
<form action="" name="adminForm" method="post">
|
473 |
-
<input type=hidden name=files[1] value='<?php echo $backupFile?>'>
|
474 |
-
<input type=hidden name=cid[1] value='<?php echo $backupFile?>'>
|
475 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
476 |
-
<input type="hidden" name="task" value=""/>
|
477 |
-
</form>
|
478 |
-
|
479 |
-
<div id="dialog-message" title="Backup completed">
|
480 |
-
<p>
|
481 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span>
|
482 |
-
<strong>Backup name:</strong> <span id="backupNameC"></span>
|
483 |
-
</p>
|
484 |
-
<p>
|
485 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup size:</strong> <span id="backupSizeComplete"></span>MB
|
486 |
-
</p>
|
487 |
-
<p>
|
488 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Number of files:</strong> <span id="backupFiles"></span>
|
489 |
-
</p>
|
490 |
-
<p class="backupParts">
|
491 |
-
<span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup Parts:</strong> <span id="backupPartsNr"></span>
|
492 |
-
</p>
|
493 |
-
</div>
|
494 |
-
|
495 |
-
</div>
|
496 |
-
</div>
|
497 |
-
|
498 |
-
<div id="error" style="display:none;">
|
499 |
-
<br /><h2 style="color:Red"><?php echo LM_REFRESH_ERROR;?></h2>
|
500 |
-
<br /><b>Details:</b> <span id="errorText"></span>
|
501 |
-
<br /><br />
|
502 |
-
<a href="#" id="retry"><h3>Click to Retry >></h3></a>
|
503 |
-
|
504 |
-
</div>
|
505 |
-
|
506 |
-
<!-- End ProgressBar -->
|
507 |
-
|
508 |
-
<?php
|
509 |
-
|
510 |
-
}
|
511 |
-
return;
|
512 |
-
} else {
|
513 |
-
E_print("Backup failed, please check your tar server utility support!");
|
514 |
-
return;
|
515 |
-
}
|
516 |
-
|
517 |
-
}
|
518 |
-
|
519 |
-
function path_check($path){
|
520 |
-
|
521 |
-
if(!is_dir($path)){
|
522 |
-
$stat['code'] = 1;
|
523 |
-
$stat['message'] = "Invalid directory";
|
524 |
-
return $stat;
|
525 |
-
}
|
526 |
-
|
527 |
-
if(!is_readable($path)){
|
528 |
-
$stat['code'] = 2;
|
529 |
-
$stat['message'] = "Directory is not readable";
|
530 |
-
return $stat;
|
531 |
-
}
|
532 |
-
|
533 |
-
if(!is_writeable($path)){
|
534 |
-
$stat['code'] = 3;
|
535 |
-
$stat['message'] = "Directory not writeable";
|
536 |
-
return $stat;
|
537 |
-
}
|
538 |
-
|
539 |
-
return 0;
|
540 |
-
|
541 |
-
}
|
542 |
-
|
543 |
-
function _FDefault(){
|
544 |
-
global $_CONFIG, $html;
|
545 |
-
?>
|
546 |
-
|
547 |
-
<form action="" method="post" name="adminForm">
|
548 |
-
|
549 |
-
<table class="adminform">
|
550 |
-
<tr><th valign='top' >
|
551 |
-
<?php echo LM_JOOMLAPLUG_CP?>
|
552 |
-
</th>
|
553 |
-
</table>
|
554 |
-
|
555 |
-
<table class="adminform" >
|
556 |
-
<tr><td >
|
557 |
-
<div id="cpanel">
|
558 |
-
|
559 |
-
<div style="float:left;">
|
560 |
-
<div class="icon">
|
561 |
-
|
562 |
-
<a href="plugins.php?page=xcloner_show&option=com_cloner&task=config">
|
563 |
-
<img src="<?php echo plugins_url('images/settings.png', __FILE__) ?>"
|
564 |
-
alt="Settings" align="middle" name="" border="0" />
|
565 |
-
<span><?php echo LM_MAIN_Settings?></span>
|
566 |
-
</a>
|
567 |
-
</div>
|
568 |
-
</div>
|
569 |
-
|
570 |
-
<div style="float:left;">
|
571 |
-
<div class="icon">
|
572 |
-
|
573 |
-
<a href="plugins.php?page=xcloner_show&option=com_cloner&task=view">
|
574 |
-
<img src="<?php echo plugins_url('images/editions.png', __FILE__) ?>"
|
575 |
-
alt="View Backups" align="middle" name="" border="0" />
|
576 |
-
<span><?php echo LM_MAIN_View_Backups?></span>
|
577 |
-
</a>
|
578 |
-
</div>
|
579 |
-
</div>
|
580 |
-
|
581 |
-
<div style="float:left;">
|
582 |
-
<div class="icon">
|
583 |
-
|
584 |
-
<a href="plugins.php?page=xcloner_show&option=com_cloner&task=confirm">
|
585 |
-
<img src="<?php echo plugins_url('images/wizard.png', __FILE__) ?>"
|
586 |
-
alt="MagaGenerate Backup" align="middle" name="" border="0" />
|
587 |
-
<span><?php echo LM_MAIN_Generate_Backup?></span>
|
588 |
-
</a>
|
589 |
-
</div>
|
590 |
-
</div>
|
591 |
-
|
592 |
-
<div style="float:left;">
|
593 |
-
<div class="icon">
|
594 |
-
|
595 |
-
<a href="plugins.php?page=xcloner_show&option=com_cloner&task=about">
|
596 |
-
<img src="<?php echo plugins_url('images/lhelp.png', __FILE__) ?>"
|
597 |
-
alt="MagaGenerate Backup" align="middle" name="" border="0" />
|
598 |
-
<span><?php echo LM_MAIN_Help?></span>
|
599 |
-
</a>
|
600 |
-
</div>
|
601 |
-
</div>
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
</div>
|
607 |
-
</td></tr>
|
608 |
-
<tr><td>
|
609 |
-
|
610 |
-
<?php
|
611 |
-
$error = 0;
|
612 |
-
?>
|
613 |
-
|
614 |
-
<div class="statusCheck">
|
615 |
-
|
616 |
-
<div class="status">
|
617 |
-
<span class="mtext">Backup Start Path Check: </span>
|
618 |
-
<?php
|
619 |
-
$html = new HTML_cloner();
|
620 |
-
$stat = $html->path_check($_CONFIG[backup_start_path]);
|
621 |
-
|
622 |
-
if( $stat['code'] > 0 and $stat['code'] < 3){
|
623 |
-
echo "<span class='error'>".$stat['message']; $error = 1;
|
624 |
-
}
|
625 |
-
else{
|
626 |
-
echo "<span class='success'>OK";
|
627 |
-
if(!is_dir($_CONFIG[backup_start_path]."/administrator/backups")){
|
628 |
-
@mkdir($_CONFIG[backup_start_path]."/administrator");
|
629 |
-
if(@mkdir($_CONFIG[backup_start_path]."/administrator/backups"))
|
630 |
-
echo "<script>window.location='plugins.php?page=xcloner_show'</script";
|
631 |
-
}
|
632 |
-
}
|
633 |
-
echo " ($_CONFIG[backup_start_path])";
|
634 |
-
?>
|
635 |
-
</span></div>
|
636 |
-
|
637 |
-
<div class="status">
|
638 |
-
<span class="mtext">Backup Store Path Check: </span>
|
639 |
-
<?php
|
640 |
-
|
641 |
-
$stat = $html->path_check($_CONFIG[backup_store_path]);
|
642 |
-
|
643 |
-
if( $stat['code'] > 0){
|
644 |
-
echo "<span class='error'>".$stat['message']; $error = 1;
|
645 |
-
}
|
646 |
-
else{
|
647 |
-
echo "<span class='success'>OK";
|
648 |
-
}
|
649 |
-
echo " ($_CONFIG[backup_store_path])";
|
650 |
-
?>
|
651 |
-
</span>
|
652 |
-
</div>
|
653 |
-
|
654 |
-
<div class="status">
|
655 |
-
<span class="mtext">Temporary Path Check: </span>
|
656 |
-
<?php
|
657 |
-
|
658 |
-
$stat = $html->path_check($_CONFIG[temp_dir]);
|
659 |
-
|
660 |
-
if( $stat['code'] > 0){
|
661 |
-
echo "<span class='error'>".$stat['message']; $error = 1;
|
662 |
-
}
|
663 |
-
else{
|
664 |
-
echo "<span class='success'>OK";
|
665 |
-
}
|
666 |
-
echo " ($_CONFIG[temp_dir])";
|
667 |
-
?>
|
668 |
-
</span></div>
|
669 |
-
|
670 |
-
<!--<div class="status">
|
671 |
-
<span class="mtext">Authentication: </span>
|
672 |
-
<?php
|
673 |
-
|
674 |
-
if($_CONFIG['jcpass'] == md5('admin')){
|
675 |
-
#echo "<span class='error'>Change default password 'admin'"; $error = 1;
|
676 |
-
}
|
677 |
-
else{
|
678 |
-
#echo "<span class='success'>OK";
|
679 |
-
}
|
680 |
-
|
681 |
-
?>
|
682 |
-
</span></div>-->
|
683 |
-
|
684 |
-
<div class="status">
|
685 |
-
<span class="mtext">Backup Ready: </span>
|
686 |
-
<?php
|
687 |
-
|
688 |
-
if($error ){
|
689 |
-
echo "<span class='error'>NO"; $error = 1;
|
690 |
-
}
|
691 |
-
else{
|
692 |
-
echo "<span class='success'>YES";
|
693 |
-
}
|
694 |
-
|
695 |
-
?>
|
696 |
-
</span></div>
|
697 |
-
|
698 |
-
</div>
|
699 |
-
</td></tr>
|
700 |
-
</table>
|
701 |
-
<input type="hidden" name="option" value="com_cloner" />
|
702 |
-
<input type="hidden" name="task" value="lang" />
|
703 |
-
</form>
|
704 |
-
|
705 |
-
<?php
|
706 |
-
}
|
707 |
-
|
708 |
-
/*The basic Authentication form*/
|
709 |
-
function Login(){
|
710 |
-
|
711 |
-
?>
|
712 |
-
<center><br />
|
713 |
-
|
714 |
-
<script>
|
715 |
-
jQuery(function() {
|
716 |
-
jQuery( "#login" ).button({
|
717 |
-
icons: {
|
718 |
-
primary: "ui-icon-locked"
|
719 |
-
}
|
720 |
-
})
|
721 |
-
jQuery("#login").click(function() {
|
722 |
-
jQuery("#adminForm")[0].submit();
|
723 |
-
return false;
|
724 |
-
})
|
725 |
-
|
726 |
-
jQuery( "#reset" ).button({
|
727 |
-
icons: {
|
728 |
-
primary: "ui-icon-trash"
|
729 |
-
}
|
730 |
-
})
|
731 |
-
jQuery( "#reset" ).click(function() {
|
732 |
-
jQuery("#username").val('');jQuery("#password").val('');
|
733 |
-
return false;
|
734 |
-
});
|
735 |
-
|
736 |
-
});
|
737 |
-
</script>
|
738 |
-
|
739 |
-
|
740 |
-
<div class="loginform">
|
741 |
-
<form action="" method="post" name="adminForm" id="adminForm">
|
742 |
-
<table class="loginForm">
|
743 |
-
<tr><td align='center'>
|
744 |
-
<table align='center' cellpadding='10' cellspacing='20'>
|
745 |
-
<tr ><td colspan='2' align='center'><b>Authentication Area:</b></td></tr>
|
746 |
-
<tr><td>Username:</td><td><input type='text' size='30' name='username' id='username'></td></tr>
|
747 |
-
<tr><td>Password:</td><td><input type='password' size='30' name='password' id='password'></td></tr>
|
748 |
-
<tr><td> </td><td>
|
749 |
-
<div class="loginform">
|
750 |
-
<button id="login">Login</button>
|
751 |
-
<button id="reset">Reset</button>
|
752 |
-
|
753 |
-
|
754 |
-
</div>
|
755 |
-
</td></tr>
|
756 |
-
<tr><td colspan='2'><?php echo LM_LOGIN_TEXT;?></td></tr>
|
757 |
-
</table>
|
758 |
-
</td></tr>
|
759 |
-
</table>
|
760 |
-
|
761 |
-
<input type="hidden" name="option" value="com_cloner" />
|
762 |
-
<input type="hidden" name="task" value="dologin" />
|
763 |
-
<input type="hidden" name="boxchecked" value="0" />
|
764 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
765 |
-
|
766 |
-
</form>
|
767 |
-
</center>
|
768 |
-
<?php
|
769 |
-
|
770 |
-
}
|
771 |
-
|
772 |
-
function Cron(){
|
773 |
-
global $_CONFIG;
|
774 |
-
?>
|
775 |
-
|
776 |
-
<script>
|
777 |
-
jQuery(function() {
|
778 |
-
jQuery( "#tabs" ).tabs();
|
779 |
-
});
|
780 |
-
</script>
|
781 |
-
|
782 |
-
<div id="tabs">
|
783 |
-
<ul>
|
784 |
-
<li><a href="#tabs-1"><?php echo LM_CRON_TOP?></a></li>
|
785 |
-
</ul>
|
786 |
-
|
787 |
-
<div id="tabs-1"><p>
|
788 |
-
|
789 |
-
<div class="mainText">
|
790 |
-
<?php echo LM_CRON_SUB?>
|
791 |
-
<br /><br />
|
792 |
-
|
793 |
-
<ul>
|
794 |
-
<li><input type="text" value="/usr/bin/php <?php echo dirname(__FILE__);?>/cloner.cron.php custom_cron_config.php" size="150" /></li>
|
795 |
-
</ul>
|
796 |
-
<br /><br />
|
797 |
-
|
798 |
-
For <b>Running Multiple Crons</b>, you need to first create a custom configuration file in the XCloner Configuration -> Cron tab
|
799 |
-
and then replace "cloner.cron.php" with "cloner.cron.php myconfig.php"
|
800 |
-
<br /><br />
|
801 |
-
|
802 |
-
<?php echo LM_CRON_HELP?>
|
803 |
-
</div>
|
804 |
-
|
805 |
-
</p></div>
|
806 |
-
</div>
|
807 |
-
|
808 |
-
<?php
|
809 |
-
}
|
810 |
-
|
811 |
-
|
812 |
-
function Translator_Edit_DEFAULT($option, $content, $file, $lang){
|
813 |
-
global $_CONFIG;
|
814 |
-
?>
|
815 |
-
<form action="" method="post" name="adminForm">
|
816 |
-
<table class="adminlist">
|
817 |
-
<tr>
|
818 |
-
<th align="left"><?php echo LM_LANG_EDIT_FILE?> <?php echo $file?></th>
|
819 |
-
</tr>
|
820 |
-
|
821 |
-
<tr>
|
822 |
-
|
823 |
-
<td><textarea name='def_content' cols='100' rows='30'><?php echo $content;?></textarea></td>
|
824 |
-
|
825 |
-
</tr>
|
826 |
-
|
827 |
-
<input type="hidden" name="option" value="com_cloner" />
|
828 |
-
<input type="hidden" name="language" value="<?php echo $lang?>" />
|
829 |
-
<input type="hidden" name="task" value="lang" />
|
830 |
-
<input type="hidden" name="boxchecked" value="0" />
|
831 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
832 |
-
</form>
|
833 |
-
|
834 |
-
<?php
|
835 |
-
|
836 |
-
}
|
837 |
-
|
838 |
-
function Translator_Add($option){
|
839 |
-
global $_CONFIG;
|
840 |
-
?>
|
841 |
-
<form action="" method="post" name="adminForm">
|
842 |
-
<table class="adminlist">
|
843 |
-
<tr>
|
844 |
-
<th align="left"><?php echo LM_LANG_NEW?></th>
|
845 |
-
</tr>
|
846 |
-
|
847 |
-
<tr>
|
848 |
-
|
849 |
-
<td><input size='40' type=text name='lname' value=''></td>
|
850 |
-
|
851 |
-
</tr>
|
852 |
-
|
853 |
-
<input type="hidden" name="option" value="com_cloner" />
|
854 |
-
<input type="hidden" name="language" value="<?php echo $lang?>" />
|
855 |
-
<input type="hidden" name="task" value="add_lang_new" />
|
856 |
-
<input type="hidden" name="boxchecked" value="0" />
|
857 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
858 |
-
<?php wp_nonce_field('add_lang','csrf'); ?>
|
859 |
-
|
860 |
-
</form>
|
861 |
-
<?php
|
862 |
-
}
|
863 |
-
|
864 |
-
function Translator_Edit($option, $data, $def_data, $file, $lang){
|
865 |
-
global $_CONFIG;
|
866 |
-
?>
|
867 |
-
|
868 |
-
<form action="" method="post" name="adminForm">
|
869 |
-
<table class="adminlist">
|
870 |
-
<tr>
|
871 |
-
<th align="left"><?php echo LM_LANG_EDIT_FILE?> <input type=text name='lfile' size=100 value='<?php echo $file?>'><br />
|
872 |
-
<font color='red'><?php echo LM_LANG_EDIT_FILE_SUB?></font>
|
873 |
-
|
874 |
-
<script language="javascript" type="text/javascript">
|
875 |
-
function submitbutton(pressbutton) {
|
876 |
-
var form = document.adminForm;
|
877 |
-
|
878 |
-
if (pressbutton == 'save_lang_apply') {
|
879 |
-
if(confirm('Before you continue please make sure you are still logged in, else press Cancel and then try again!')){
|
880 |
-
submitform( pressbutton );
|
881 |
-
}
|
882 |
-
return;
|
883 |
-
}
|
884 |
-
else
|
885 |
-
if (pressbutton == 'save_lang') {
|
886 |
-
if(confirm('Before you continue please make sure you are still logged in, else press Cancel and then try again!')){
|
887 |
-
submitform( pressbutton );
|
888 |
-
}
|
889 |
-
return;
|
890 |
-
}
|
891 |
-
else{
|
892 |
-
submitform( pressbutton );
|
893 |
-
}
|
894 |
-
}
|
895 |
-
</script>
|
896 |
-
|
897 |
-
</th>
|
898 |
-
</tr>
|
899 |
-
</table>
|
900 |
-
<?php
|
901 |
-
foreach($data as $key=>$value)
|
902 |
-
if($def_data[$key]!="") {
|
903 |
-
if($i++ %2 == 0)
|
904 |
-
$bgcolor = '#eeeeee';
|
905 |
-
else
|
906 |
-
$bgcolor = '#dddddd';
|
907 |
-
?>
|
908 |
-
<table class="adminlist">
|
909 |
-
<tr>
|
910 |
-
<th width='50%' align="left">Default Variable <?php echo $key?></th>
|
911 |
-
<th width='50%' align="left">Translation <?php echo $key?></th>
|
912 |
-
</tr>
|
913 |
-
<tr bgcolor="<?php echo $bgcolor?>">
|
914 |
-
<td><textarea cols=65 rows=3 ><?php echo stripslashes($def_data[$key])?></textarea></td>
|
915 |
-
|
916 |
-
<td bgcolor='<?php if( trim(str_replace(array("\n","\r"," "),array("","",""),$def_data[$key])) !=
|
917 |
-
trim(str_replace(array("\n","\r"," "),array("","",""),$value)))
|
918 |
-
echo 'green';
|
919 |
-
else
|
920 |
-
echo 'red';?>'>
|
921 |
-
<textarea cols=65 rows=3 name=lang[<?php echo $key?>]><?php echo stripslashes($value)?></textarea></td>
|
922 |
-
</tr>
|
923 |
-
|
924 |
-
<?php
|
925 |
-
}
|
926 |
-
?>
|
927 |
-
|
928 |
-
<input type="hidden" name="option" value="com_cloner" />
|
929 |
-
<input type="hidden" name="language" value="<?php echo $lang?>" />
|
930 |
-
<input type="hidden" name="task" value="lang" />
|
931 |
-
<input type="hidden" name="boxchecked" value="0" />
|
932 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
933 |
-
<?php wp_nonce_field('save_lang','csrf'); ?>
|
934 |
-
</form>
|
935 |
-
|
936 |
-
<?php
|
937 |
-
}
|
938 |
-
|
939 |
-
function Translator($option, $lang_arr){
|
940 |
-
global $_CONFIG;
|
941 |
-
|
942 |
-
?>
|
943 |
-
<script>
|
944 |
-
jQuery(function() {
|
945 |
-
jQuery( "#toggle" ).button();
|
946 |
-
jQuery( "#toggle" ).click(function() { checkJAll(<?php echo count( $lang_arr ); ?>, "toggle", "cb"); });
|
947 |
-
jQuery( "#checklist" ).buttonset();
|
948 |
-
});
|
949 |
-
</script>
|
950 |
-
|
951 |
-
<form action="" method="post" name="adminForm">
|
952 |
-
<div id="checklist">
|
953 |
-
<table class="adminlist">
|
954 |
-
<tr>
|
955 |
-
<th align="center">
|
956 |
-
<input id="toggle" type="checkbox" name="toggle" value="" /><label for="toggle">Check All</label>
|
957 |
-
</th>
|
958 |
-
<th align="left">
|
959 |
-
<?php echo LM_LANG_NAME ?>
|
960 |
-
</th>
|
961 |
-
</tr>
|
962 |
-
|
963 |
-
<?php
|
964 |
-
for($i=0; $i<sizeof($lang_arr); $i++){
|
965 |
-
|
966 |
-
?>
|
967 |
-
|
968 |
-
<tr>
|
969 |
-
<!--<td width="5" align="left"><?php echo ($i+1);?></td>-->
|
970 |
-
<td align="center" width="100">
|
971 |
-
<label for="cb<?php echo $i ?>"><?php echo $i ?></label>
|
972 |
-
<input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
|
973 |
-
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $lang_arr[$i] ?>" />
|
974 |
-
</td>
|
975 |
-
<td align="left" >
|
976 |
-
<a href="plugins.php?page=xcloner_show&option=<?php echo $option;?>&task=edit_lang&langx=<?php echo $lang_arr[$i];?>"><?php echo ucfirst($lang_arr[$i])?>
|
977 |
-
</td>
|
978 |
-
</tr>
|
979 |
-
<?php
|
980 |
-
|
981 |
-
}
|
982 |
-
?>
|
983 |
-
</table></div>
|
984 |
-
<input type="hidden" name="option" value="com_cloner" />
|
985 |
-
<input type="hidden" name="task" value="lang" />
|
986 |
-
<input type="hidden" name="boxchecked" value="0" />
|
987 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
988 |
-
|
989 |
-
</form>
|
990 |
-
<?php
|
991 |
-
}
|
992 |
-
|
993 |
-
function showBackups( &$files, &$sizes, $path, $option ) {
|
994 |
-
// ----------------------------------------------------------
|
995 |
-
// Presentation of the backup set list screen
|
996 |
-
// ----------------------------------------------------------
|
997 |
-
global $baDownloadPath, $_CONFIG;
|
998 |
-
|
999 |
-
?>
|
1000 |
-
|
1001 |
-
<script type="text/javascript">
|
1002 |
-
|
1003 |
-
jQuery(function() {
|
1004 |
-
jQuery( "#toggle" ).button();
|
1005 |
-
jQuery( "#toggle" ).click(function() { checkJAll(<?php echo (count( $files )); ?>, "toggle", "cb"); });
|
1006 |
-
jQuery( "#checklist" ).buttonset();
|
1007 |
-
|
1008 |
-
jQuery( "#Clone, #Rename, #Delete, #Move" ).unbind("click");
|
1009 |
-
jQuery( "#Clone, #Rename, #Delete, #Move" ).click(function(){
|
1010 |
-
if(!jQuery("input:checked").length){
|
1011 |
-
|
1012 |
-
jQuery( "#error-message" ).dialog({
|
1013 |
-
width: 500,
|
1014 |
-
height: 200,
|
1015 |
-
modal: true,
|
1016 |
-
buttons: {
|
1017 |
-
Ok: function() {
|
1018 |
-
jQuery( this ).dialog( "close" );
|
1019 |
-
}
|
1020 |
-
}
|
1021 |
-
});
|
1022 |
-
|
1023 |
-
return false;
|
1024 |
-
}else{
|
1025 |
-
var action = jQuery(this).attr('id').toLowerCase();
|
1026 |
-
document.adminForm.task.value=action;
|
1027 |
-
document.adminForm.submit();
|
1028 |
-
}
|
1029 |
-
})
|
1030 |
-
|
1031 |
-
|
1032 |
-
})
|
1033 |
-
</script>
|
1034 |
-
|
1035 |
-
<div id="error-message" title="Error" style="display:none;">
|
1036 |
-
<p>
|
1037 |
-
<span class="ui-icon ui-icon-circle-check" style="float:left; margin:0 7px 50px 0;"></span>
|
1038 |
-
Please select at least one backup archive.
|
1039 |
-
</p>
|
1040 |
-
|
1041 |
-
</div>
|
1042 |
-
<div id="checklist">
|
1043 |
-
<form action="" method="post" name="adminForm">
|
1044 |
-
<table class="adminlist">
|
1045 |
-
<tr>
|
1046 |
-
<th width="100">
|
1047 |
-
<input type="checkbox" id="toggle" name="toggle" value="" /><label for="toggle">Check All</label>
|
1048 |
-
</th>
|
1049 |
-
<th align="left" width="100px;">
|
1050 |
-
<?php echo LM_COL_DOWNLOAD ?>
|
1051 |
-
</th>
|
1052 |
-
<th width="50%" class="title">
|
1053 |
-
<?php echo LM_COL_FILENAME ?>
|
1054 |
-
</th>
|
1055 |
-
<th align="left" width="10%">
|
1056 |
-
<?php echo LM_COL_SIZE ?>
|
1057 |
-
</th>
|
1058 |
-
<th align="left" width="">
|
1059 |
-
<?php echo LM_COL_DATE ?>
|
1060 |
-
</th>
|
1061 |
-
</tr>
|
1062 |
-
<?php
|
1063 |
-
$k = 0;
|
1064 |
-
for ($i=0; $i <= (count( $files )-1); $i++) {
|
1065 |
-
$date = date ("D jS M Y H:i:s (\G\M\T O)", filemtime($path.'/'.$files[$i]));
|
1066 |
-
$url = "admin-ajax.php?action=json_return&page=xcloner_show&option=com_cloner&task=download&file=".'/'.urlencode($files[$i]);
|
1067 |
-
?>
|
1068 |
-
<tr class="<?php echo "row$k"; ?>">
|
1069 |
-
|
1070 |
-
<td align="center">
|
1071 |
-
<label for="cb<?php echo $i ?>"><?php echo $i ?></label>
|
1072 |
-
<input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
|
1073 |
-
<input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $files[$i] ?>" />
|
1074 |
-
</td>
|
1075 |
-
<td align="left">
|
1076 |
-
<a target='_blank' href="<?php echo $url ?>"><img src="<?php echo plugins_url('images/filesave.png', __FILE__) ?>" border="0" title="<?php echo LM_DOWNLOAD_TITLE." - ".$files[$i] ?>" /></a>
|
1077 |
-
</td>
|
1078 |
-
<td>
|
1079 |
-
<span class="backup_name"><?php echo $files[$i]; ?></span>
|
1080 |
-
<input type="hidden" id="f<?php echo $i ?>" name="f<?php echo $i ?>" value="<?php echo $files[$i]; ?>" >
|
1081 |
-
</td>
|
1082 |
-
|
1083 |
-
<td align="left">
|
1084 |
-
<?php echo $sizes[$i]; ?>
|
1085 |
-
</td >
|
1086 |
-
<td align="left">
|
1087 |
-
<?php echo $date; ?>
|
1088 |
-
</td>
|
1089 |
-
</tr>
|
1090 |
-
<?php
|
1091 |
-
$k = 1 - $k;
|
1092 |
-
}
|
1093 |
-
?>
|
1094 |
-
</table>
|
1095 |
-
</div>
|
1096 |
-
<input type="hidden" name="option" value="com_cloner" />
|
1097 |
-
<input type="hidden" name="task" value="" />
|
1098 |
-
<input type="hidden" name="boxchecked" value="0" />
|
1099 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
1100 |
-
</form>
|
1101 |
-
<br/>
|
1102 |
-
<?php
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
function Config($option){
|
1106 |
-
global $config_file,$_CONFIG, $lang_array, $database, $mosConfig_db;
|
1107 |
-
?>
|
1108 |
-
<form name='adminForm' action='' method='POST'>
|
1109 |
-
|
1110 |
-
<script>
|
1111 |
-
jQuery(function() {
|
1112 |
-
jQuery( "#tabs" ).tabs();
|
1113 |
-
});
|
1114 |
-
|
1115 |
-
jQuery(function() {
|
1116 |
-
jQuery( "#radiog1" ).buttonset();
|
1117 |
-
jQuery( "#radiog2" ).buttonset();
|
1118 |
-
jQuery( "#radiog3" ).buttonset();
|
1119 |
-
jQuery( "#radiog4" ).buttonset();
|
1120 |
-
jQuery( "#radio" ).buttonset();
|
1121 |
-
jQuery( "#radiom" ).buttonset();
|
1122 |
-
jQuery( "#radiob" ).buttonset();
|
1123 |
-
jQuery( "#radioftp" ).buttonset();
|
1124 |
-
jQuery( "#radioftps" ).buttonset();
|
1125 |
-
jQuery( "#radiodebug" ).buttonset();
|
1126 |
-
jQuery( "#radiorefresh" ).buttonset();
|
1127 |
-
jQuery( "#checktar" ).button();
|
1128 |
-
jQuery( "#cron_file_delete_act" ).button();
|
1129 |
-
jQuery( "#cron_sql_drop" ).button();
|
1130 |
-
jQuery( "#cron_amazon_active" ).button();
|
1131 |
-
jQuery( "#cron_dropbox_active" ).button();
|
1132 |
-
jQuery( "#cron_dropbox_authorize" ).button();
|
1133 |
-
jQuery( "#cron_amazon_ssl" ).button();
|
1134 |
-
jQuery( "#cron_ftp_delb" ).button();
|
1135 |
-
jQuery( "#checkmysqldump" ).button();
|
1136 |
-
});
|
1137 |
-
</script>
|
1138 |
-
|
1139 |
-
<?php $tabs = new mosTabs(1);?>
|
1140 |
-
<ul>
|
1141 |
-
|
1142 |
-
<li><a href="#tabs-1"><?php echo LM_TAB_GENERAL;?></a></li>
|
1143 |
-
<li><a href="#tabs-2"><?php echo LM_TAB_MYSQL;?></a></li>
|
1144 |
-
<!--<li><a href="#tabs-3"><?php echo LM_TAB_AUTH;?></a></li>-->
|
1145 |
-
<li><a href="#tabs-4"><?php echo LM_TAB_SYSTEM;?></a></li>
|
1146 |
-
<li><a href="#tabs-5"><?php echo LM_TAB_CRON;?></a></li>
|
1147 |
-
<li><a href="#tabs-6"><?php echo LM_TAB_INFO;?></a></li>
|
1148 |
-
</ul>
|
1149 |
-
|
1150 |
-
<table class='adminform'>
|
1151 |
-
<!--<tr><th colspan='2'>
|
1152 |
-
<?php #echo LM_CONFIG_EDIT?> <?php #echo $config_file?>
|
1153 |
-
</th></tr>-->
|
1154 |
-
</table>
|
1155 |
-
<?php
|
1156 |
-
$tabs->startTab(LM_TAB_GENERAL,"1");
|
1157 |
-
?>
|
1158 |
-
|
1159 |
-
<div id="configtabinside">
|
1160 |
-
|
1161 |
-
<div>
|
1162 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS?></a></h3>
|
1163 |
-
<div><p>
|
1164 |
-
<table class='adminform'>
|
1165 |
-
|
1166 |
-
<tr>
|
1167 |
-
<td>
|
1168 |
-
<?php echo LM_CONFIG_UBPATH?>
|
1169 |
-
</td>
|
1170 |
-
<td>
|
1171 |
-
<input type=text size=100 name='backup_path' value='<?php echo $_CONFIG[backup_path]?>'>
|
1172 |
-
<br /><?php echo LM_CONFIG_UBPATH_SUB?>
|
1173 |
-
</td>
|
1174 |
-
</tr>
|
1175 |
-
|
1176 |
-
<tr>
|
1177 |
-
<td width='250'>
|
1178 |
-
<?php echo LM_CONFIG_BPATH?>
|
1179 |
-
</td>
|
1180 |
-
<td>
|
1181 |
-
<input type=text size=100 name='clonerPath' value='<?php echo $_CONFIG[clonerPath]?>'>
|
1182 |
-
<br /><?php echo LM_CONFIG_BPATH_SUB?>
|
1183 |
-
</td>
|
1184 |
-
</tr>
|
1185 |
-
|
1186 |
-
</table>
|
1187 |
-
</p></div>
|
1188 |
-
</div>
|
1189 |
-
|
1190 |
-
<div>
|
1191 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_OPTIONS?></a></h3>
|
1192 |
-
<div><p>
|
1193 |
-
<table class='adminform'>
|
1194 |
-
|
1195 |
-
<tr>
|
1196 |
-
<td width='250'>
|
1197 |
-
<?php echo LM_CONFIG_MANUAL_BACKUP;?>
|
1198 |
-
</td>
|
1199 |
-
<td>
|
1200 |
-
<div id="radiog1">
|
1201 |
-
<label for="radiog11"><?php echo LM_YES?></label> <input id="radiog11" type=radio size=50 value=1 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==1) echo 'checked';?>>
|
1202 |
-
<label for="radiog12"><?php echo LM_NO?></label> <input id="radiog12" type=radio size=50 value=0 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==0) echo 'checked';?>>
|
1203 |
-
<br><small><?php echo LM_CONFIG_MANUAL_BACKUP_SUB?></small>
|
1204 |
-
</div>
|
1205 |
-
</td>
|
1206 |
-
</tr>
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
<tr>
|
1211 |
-
<td>
|
1212 |
-
<?php echo LM_CRON_DB_BACKUP?>
|
1213 |
-
</td>
|
1214 |
-
<td>
|
1215 |
-
<div id="radiog3">
|
1216 |
-
<label for="radiog31">Yes</label> <input id="radiog31" type=radio size=50 value=1 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==1 or $_CONFIG['disable_mysql']) echo 'checked';?>>
|
1217 |
-
<label for="radiog32">No</label> <input id="radiog32" type=radio size=50 value=0 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==0 and !$_CONFIG['disable_mysql']) echo 'checked';?>>
|
1218 |
-
<br /><?php echo LM_CRON_DB_BACKUP_SUB?>
|
1219 |
-
</div>
|
1220 |
-
|
1221 |
-
</td>
|
1222 |
-
</tr>
|
1223 |
-
|
1224 |
-
<tr>
|
1225 |
-
<td>
|
1226 |
-
<?php echo LM_CONFIG_SYSTEM_MBACKUP?>
|
1227 |
-
</td>
|
1228 |
-
<td>
|
1229 |
-
<div id="radiog4">
|
1230 |
-
<label for="radiog41">Yes</label> <input id="radiog41" type=radio size=50 value=1 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==1) echo 'checked';?>>
|
1231 |
-
<label for="radiog42">No</label> <input id="radiog42" type=radio size=50 value=0 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==0) echo 'checked';?>>
|
1232 |
-
<br /><?php echo LM_CONFIG_SYSTEM_MBACKUP_SUB?>
|
1233 |
-
</td>
|
1234 |
-
</div>
|
1235 |
-
</tr>
|
1236 |
-
|
1237 |
-
</table>
|
1238 |
-
</p></div>
|
1239 |
-
</div>
|
1240 |
-
|
1241 |
-
<div>
|
1242 |
-
<h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_SERVER?></a></h3>
|
1243 |
-
<div><p>
|
1244 |
-
<table class='adminform'>
|
1245 |
-
|
1246 |
-
<tr><td width='250'>
|
1247 |
-
<?php echo LM_CONFIG_MEM?>
|
1248 |
-
</td>
|
1249 |
-
<td align='left'>
|
1250 |
-
<table style="width:auto; margin-bottom: 10px;" cellpadding='0' cellspacing='2' border='0'>
|
1251 |
-
<tr bgcolor='#efefef'><td style="width:70px;">
|
1252 |
-
<label for="checktar"><?php echo LM_ACTIVE;?></label> <input type=checkbox id="checktar" value=1 name='mem' <?php if($_CONFIG[mem]==1) echo 'checked';?>>
|
1253 |
-
</td><td align='left'>
|
1254 |
-
|
1255 |
-
<table width='100%' cellpadding='0' cellspacing='0'>
|
1256 |
-
<tr><td>
|
1257 |
-
<?php echo LM_TAR_PATH;?> <br /><input size='50' type=text name=tarpath value='<?php echo $_CONFIG[tarpath]?>'><br />
|
1258 |
-
<?php echo LM_TAR_PATH_SUB;?>
|
1259 |
-
</td></tr>
|
1260 |
-
|
1261 |
-
</table>
|
1262 |
-
|
1263 |
-
|
1264 |
-
</td></tr>
|
1265 |
-
|
1266 |
-
<tr bgcolor='#dedede'><td>
|
1267 |
-
<label for="checkmysqldump"><?php echo LM_ACTIVE?></label> <input id="checkmysqldump" type=checkbox value=1 name='sql_mem' <?php if($_CONFIG[sql_mem]==1) echo 'checked';?>>
|
1268 |
-
</td><td align='left'>
|
1269 |
-
<?php echo LM_MYSQLDUMP_PATH;?> <br /><input type=text size='50' name='sqldump' value='<?php echo $_CONFIG[sqldump]?>'>
|
1270 |
-
|
1271 |
-
</td></tr>
|
1272 |
-
</table>
|
1273 |
-
|
1274 |
-
<?php echo LM_CONFIG_MEM_SUB?>
|
1275 |
-
|
1276 |
-
</td>
|
1277 |
-
</tr>
|
1278 |
-
</table>
|
1279 |
-
</p></div>
|
1280 |
-
</div>
|
1281 |
-
|
1282 |
-
<!--<div>
|
1283 |
-
<h3><a href="#">Public Key Management</a></h3>
|
1284 |
-
<div><p>
|
1285 |
-
<table class='adminForm'>
|
1286 |
-
|
1287 |
-
<tr><td width="250">
|
1288 |
-
Public Key
|
1289 |
-
</td>
|
1290 |
-
<td>
|
1291 |
-
<input type-text size=50 name='license_code' value="<?php echo $_CONFIG[license_code]?>"/>
|
1292 |
-
<br />Use this code in the MultiSite XCloner Manager <a target='_blank' href='http://www.xcloner.com/'>XCloner.com Members area</a>
|
1293 |
-
<br />Leave it empty to disable it
|
1294 |
-
|
1295 |
-
</td>
|
1296 |
-
</tr>
|
1297 |
-
|
1298 |
-
</table>
|
1299 |
-
</p></div>
|
1300 |
-
</div>-->
|
1301 |
-
|
1302 |
-
</div>
|
1303 |
-
|
1304 |
-
<?php
|
1305 |
-
$tabs->endTab();
|
1306 |
-
$tabs->startTab(LM_TAB_MYSQL,"2");
|
1307 |
-
?>
|
1308 |
-
<div id="configtabinside">
|
1309 |
-
<div>
|
1310 |
-
<h3><a href="#"><?php echo LM_CONFIG_MYSQL?></a></h3>
|
1311 |
-
<div><p>
|
1312 |
-
|
1313 |
-
<table class='adminform'>
|
1314 |
-
|
1315 |
-
<tr>
|
1316 |
-
<td width='250'>
|
1317 |
-
<?php echo LM_CONFIG_MYSQLH?>
|
1318 |
-
</td>
|
1319 |
-
<td>
|
1320 |
-
<input type=text size=50 name='mysql_host' value='<?php echo $_CONFIG[mysql_host]?>'>
|
1321 |
-
<br /><?php echo LM_CONFIG_MYSQLH_SUB?>
|
1322 |
-
</td>
|
1323 |
-
</tr>
|
1324 |
-
|
1325 |
-
<tr>
|
1326 |
-
<td>
|
1327 |
-
<?php echo LM_CONFIG_MYSQLU?>
|
1328 |
-
</td>
|
1329 |
-
<td>
|
1330 |
-
<input type=text size=50 name='mysql_user' value='<?php echo $_CONFIG[mysql_user]?>'>
|
1331 |
-
<br /><?php echo LM_CONFIG_MYSQLU_SUB?>
|
1332 |
-
</td>
|
1333 |
-
</tr>
|
1334 |
-
|
1335 |
-
<tr>
|
1336 |
-
<td>
|
1337 |
-
<?php echo LM_CONFIG_MYSQLP?>
|
1338 |
-
</td>
|
1339 |
-
<td>
|
1340 |
-
<input type=password size=50 name='mysql_pass' value='<?php echo $_CONFIG[mysql_pass]?>'>
|
1341 |
-
<br /><?php echo LM_CONFIG_MYSQLP_SUB?>
|
1342 |
-
</td>
|
1343 |
-
</tr>
|
1344 |
-
|
1345 |
-
<tr>
|
1346 |
-
<td>
|
1347 |
-
<?php echo LM_CONFIG_MYSQLD?>
|
1348 |
-
</td>
|
1349 |
-
<td>
|
1350 |
-
<input type=text size=50 name='mysql_database' value='<?php echo $_CONFIG[mysql_database]?>'>
|
1351 |
-
<br /><?php echo LM_CONFIG_MYSQLD_SUB?>
|
1352 |
-
</td>
|
1353 |
-
</tr>
|
1354 |
-
|
1355 |
-
<tr>
|
1356 |
-
<td width='200'>
|
1357 |
-
<?php echo LM_CONFIG_SYSTEM_MDATABASES?>
|
1358 |
-
</td>
|
1359 |
-
<td>
|
1360 |
-
<div id="radiom">
|
1361 |
-
<label for="radiom1"><?php echo LM_YES?></label> <input id="radiom1" type=radio name='system_mdatabases' value='0' <?php if(abs($_CONFIG[system_mdatabases])==0) echo "checked";?>>
|
1362 |
-
<label for="radiom2"><?php echo LM_NO?></label> <input id="radiom2" type=radio name='system_mdatabases' value='1' <?php if(abs($_CONFIG[system_mdatabases])==1) echo "checked";?>>
|
1363 |
-
<br /> <?php echo LM_CONFIG_SYSTEM_MDATABASES_SUB?>
|
1364 |
-
</div>
|
1365 |
-
</td>
|
1366 |
-
</tr>
|
1367 |
-
|
1368 |
-
</table>
|
1369 |
-
</p></div>
|
1370 |
-
</div>
|
1371 |
-
</div>
|
1372 |
-
<?php
|
1373 |
-
$tabs->endTab();
|
1374 |
-
/*$tabs->startTab(LM_TAB_AUTH,"3");
|
1375 |
-
?>
|
1376 |
-
<div id="configtabinside">
|
1377 |
-
<div>
|
1378 |
-
<h3><a href="#"><?php echo LM_CONFIG_AUTH?></a></h3>
|
1379 |
-
<div><p>
|
1380 |
-
<table class='adminform'>
|
1381 |
-
<tr>
|
1382 |
-
<td width='250'>
|
1383 |
-
<?php echo LM_CONFIG_AUTH_USER?>
|
1384 |
-
</td>
|
1385 |
-
<td>
|
1386 |
-
<input type=text size=30 name='jcuser' value='<?php echo $_CONFIG[jcuser]?>'>
|
1387 |
-
<br /><?php echo LM_CONFIG_AUTH_USER_SUB?>
|
1388 |
-
</td>
|
1389 |
-
</tr>
|
1390 |
-
|
1391 |
-
<tr>
|
1392 |
-
<td>
|
1393 |
-
<?php echo LM_CONFIG_AUTH_PASS?>
|
1394 |
-
</td>
|
1395 |
-
<td>
|
1396 |
-
<input type=text size=30 name='jcpass' value=''> <?php if($_CONFIG['jcpass'] == md5('admin')) echo "<font color=red>please change the default password 'admin'</font>"?>
|
1397 |
-
<br /><?php echo LM_CONFIG_AUTH_PASS_SUB?>
|
1398 |
-
</td>
|
1399 |
-
</tr>
|
1400 |
-
</table>
|
1401 |
-
</p></div>
|
1402 |
-
</div>
|
1403 |
-
</div>
|
1404 |
-
<?php
|
1405 |
-
$tabs->endTab();*/
|
1406 |
-
$tabs->startTab(LM_TAB_SYSTEM,"4");
|
1407 |
-
?>
|
1408 |
-
|
1409 |
-
<div id="configtabinside">
|
1410 |
-
<div>
|
1411 |
-
<h3><a href="#"><?php echo LM_CONFIG_DISPLAY?></a></h3>
|
1412 |
-
<div><p>
|
1413 |
-
<table class='adminform'>
|
1414 |
-
<tr>
|
1415 |
-
<td width='250'>
|
1416 |
-
<?php echo LM_CONFIG_SYSTEM_LANG?>
|
1417 |
-
</td><td>
|
1418 |
-
<select name='select_lang'>
|
1419 |
-
<option value=''><?php echo LM_CONFIG_SYSTEM_LANG_DEFAULT;?></option>
|
1420 |
-
<?php
|
1421 |
-
foreach($lang_array as $value)
|
1422 |
-
if($_CONFIG['select_lang'] == $value)
|
1423 |
-
echo "<option value='$value' selected>$value</option>\n";
|
1424 |
-
else
|
1425 |
-
echo "<option value='$value'>$value</option>\n";
|
1426 |
-
?>
|
1427 |
-
</select>
|
1428 |
-
<br>
|
1429 |
-
<br /><?php echo LM_CONFIG_SYSTEM_LANG_SUB?>
|
1430 |
-
</td></tr>
|
1431 |
-
</table>
|
1432 |
-
</p></div>
|
1433 |
-
</div>
|
1434 |
-
<div>
|
1435 |
-
<h3><a href="#"> <?php echo LM_CONFIG_SYSTEM?></a></h3>
|
1436 |
-
<div><p>
|
1437 |
-
|
1438 |
-
<table class='adminform'>
|
1439 |
-
|
1440 |
-
<tr>
|
1441 |
-
<td width='250'>
|
1442 |
-
<?php echo LM_CONFIG_SYSTEM_FTP?>
|
1443 |
-
</td>
|
1444 |
-
<td>
|
1445 |
-
<div id="radioftp">
|
1446 |
-
<label for="radioftp1">Direct</label><input id="radioftp1" type=radio name='system_ftptransfer' value='0' <?php if(abs($_CONFIG[system_ftptransfer])==0) echo "checked";?>>
|
1447 |
-
<label for="radioftp2">Passive</label><input id="radioftp2" type=radio name='system_ftptransfer' value='1' <?php if(abs($_CONFIG[system_ftptransfer])==1) echo "checked";?>> <br>
|
1448 |
-
<br /><?php echo LM_CONFIG_SYSTEM_FTP_SUB?>
|
1449 |
-
</div>
|
1450 |
-
|
1451 |
-
</td></tr>
|
1452 |
-
<tr><td>
|
1453 |
-
<?php echo LM_FTP_TRANSFER_MORE?>
|
1454 |
-
</td><td>
|
1455 |
-
<div id="radioftps">
|
1456 |
-
<label for="radioftps1">Normal</label><input id="radioftps1" type=radio size=50 value=0 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==0) echo 'checked';?>>
|
1457 |
-
<label for="radioftps2">Secure(SFTP)</label><input id="radioftps2" type=radio size=50 value=1 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==1) echo 'checked';?>>
|
1458 |
-
</td>
|
1459 |
-
</tr>
|
1460 |
-
|
1461 |
-
</table>
|
1462 |
-
</p></div>
|
1463 |
-
</div>
|
1464 |
-
<div>
|
1465 |
-
<h3><a href="#"> <?php echo LM_CONFIG_MANUAL?></a></h3>
|
1466 |
-
<div><p>
|
1467 |
-
|
1468 |
-
<script>
|
1469 |
-
jQuery(function() {
|
1470 |
-
jQuery( "#slider" ).slider({
|
1471 |
-
value:parseInt(<?php echo $_CONFIG[backup_refresh_number];?>),
|
1472 |
-
min: 10,
|
1473 |
-
max: 1000,
|
1474 |
-
step: 10,
|
1475 |
-
slide: function( event, ui ) {
|
1476 |
-
jQuery( "#backup_refresh_number" ).val( ui.value );
|
1477 |
-
}
|
1478 |
-
});
|
1479 |
-
jQuery( "#backup_refresh_number" ).val( jQuery( "#slider" ).slider( "value" ) );
|
1480 |
-
});
|
1481 |
-
jQuery(function() {
|
1482 |
-
jQuery( "#sliderRPS" ).slider({
|
1483 |
-
value:parseInt(<?php echo $_CONFIG[recordsPerSession];?>),
|
1484 |
-
min: 100,
|
1485 |
-
max: 100000,
|
1486 |
-
step: 100,
|
1487 |
-
slide: function( event, ui ) {
|
1488 |
-
jQuery( "#recordsPerSession" ).val( ui.value );
|
1489 |
-
}
|
1490 |
-
});
|
1491 |
-
jQuery( "#recordsPerSession" ).val( jQuery( "#sliderRPS" ).slider( "value" ) );
|
1492 |
-
});
|
1493 |
-
jQuery(function() {
|
1494 |
-
jQuery( "#sliderEFZ" ).slider({
|
1495 |
-
value:parseInt(<?php echo $_CONFIG[excludeFilesSize];?>),
|
1496 |
-
min: -1,
|
1497 |
-
max: 10240,
|
1498 |
-
step: 1,
|
1499 |
-
slide: function( event, ui ) {
|
1500 |
-
jQuery( "#excludeFilesSize" ).val( ui.value );
|
1501 |
-
}
|
1502 |
-
});
|
1503 |
-
jQuery( "#excludeFilesSize" ).val( jQuery( "#sliderEFZ" ).slider( "value" ) );
|
1504 |
-
});
|
1505 |
-
|
1506 |
-
jQuery(function() {
|
1507 |
-
jQuery( "#sliderSBS" ).slider({
|
1508 |
-
value:parseInt(<?php echo $_CONFIG[splitBackupSize];?>),
|
1509 |
-
min: -1,
|
1510 |
-
max: 10000,
|
1511 |
-
step: 1,
|
1512 |
-
slide: function( event, ui ) {
|
1513 |
-
jQuery( "#splitBackupSize" ).val( ui.value );
|
1514 |
-
}
|
1515 |
-
});
|
1516 |
-
jQuery( "#splitBackupSize" ).val( jQuery( "#sliderSBS" ).slider( "value" ) );
|
1517 |
-
});
|
1518 |
-
</script>
|
1519 |
-
|
1520 |
-
<table class='adminform'>
|
1521 |
-
|
1522 |
-
<tr><td width="250">
|
1523 |
-
<?php echo LM_CONFIG_MANUAL_FILES;?>
|
1524 |
-
</td><td>
|
1525 |
-
<div class="sliderContainer">
|
1526 |
-
<div id="slider" style="width:500px;padding:5px 0 0 0;float:left"></div>
|
1527 |
-
<label for="backup_refresh_number"></label>
|
1528 |
-
<input id="backup_refresh_number" type=text size=10 name='backup_refresh_number' value=<?php echo $_CONFIG[backup_refresh_number];?>>
|
1529 |
-
</div>
|
1530 |
-
</td></tr>
|
1531 |
-
|
1532 |
-
<tr><td width="250">
|
1533 |
-
<?php echo LM_CONFIG_DB_RECORDS;?>
|
1534 |
-
</td><td>
|
1535 |
-
<div class="sliderContainer">
|
1536 |
-
<div id="sliderRPS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
|
1537 |
-
<label for="recordsPerSession"></label>
|
1538 |
-
<input id="recordsPerSession" type=text size=10 name='recordsPerSession' value=<?php echo $_CONFIG[recordsPerSession];?>>
|
1539 |
-
</div>
|
1540 |
-
</td></tr>
|
1541 |
-
|
1542 |
-
<tr><td width="250">
|
1543 |
-
<?php echo LM_CONFIG_EXCLUDE_FILES_SIZE;?>
|
1544 |
-
</td><td>
|
1545 |
-
<div class="sliderContainer">
|
1546 |
-
<div id="sliderEFZ" style="width:500px;padding:5px 0 0 0;float:left"></div>
|
1547 |
-
<label for="excludeFilesSize"></label>
|
1548 |
-
<input id="excludeFilesSize" type=text size=10 name='excludeFilesSize' value=<?php echo $_CONFIG[excludeFilesSize];?>> MB
|
1549 |
-
</div>
|
1550 |
-
</td></tr>
|
1551 |
-
|
1552 |
-
<tr><td width="250">
|
1553 |
-
<?php echo LM_CONFIG_SPLIT_BACKUP_SIZE;?>
|
1554 |
-
</td><td>
|
1555 |
-
<div class="sliderContainer">
|
1556 |
-
<div id="sliderSBS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
|
1557 |
-
<label for="splitBackupSize"></label>
|
1558 |
-
<input id="splitBackupSize" type=text size=10 name='splitBackupSize' value=<?php echo $_CONFIG[splitBackupSize];?>> MB
|
1559 |
-
</div>
|
1560 |
-
|
1561 |
-
</td></tr>
|
1562 |
-
|
1563 |
-
<tr><td>
|
1564 |
-
<?php echo LM_CONFIG_MANUAL_REFRESH;?>
|
1565 |
-
</td><td>
|
1566 |
-
<input type=text size=20 name='refresh_time' value=<?php echo $_CONFIG[refresh_time];?>> miliseconds
|
1567 |
-
|
1568 |
-
</td></tr>
|
1569 |
-
|
1570 |
-
<tr>
|
1571 |
-
<td>
|
1572 |
-
<?php echo LM_CRON_COMPRESS?>
|
1573 |
-
</td>
|
1574 |
-
<td>
|
1575 |
-
<div id="radiog2">
|
1576 |
-
<label for="radiog21"><?php echo LM_YES?></label> <input id="radiog21" type=radio size=50 value=1 name='backup_compress' <?php if($_CONFIG[backup_compress]==1) echo 'checked';?>>
|
1577 |
-
<label for="radiog22"><?php echo LM_NO?></label> <input id="radiog22" type=radio size=50 value=0 name='backup_compress' <?php if($_CONFIG[backup_compress]==0) echo 'checked';?>>
|
1578 |
-
<br /> <small>Note: this option might break your backup process if the Manual backup option is also enabled</small>
|
1579 |
-
</div>
|
1580 |
-
</td>
|
1581 |
-
</tr>
|
1582 |
-
|
1583 |
-
<tr><td>
|
1584 |
-
<?php echo LM_REFRESH_MODE?>
|
1585 |
-
</td><td>
|
1586 |
-
<div id="radiorefresh">
|
1587 |
-
<label for="radiorefresh1">Normal</label> <input id="radiorefresh1" type=radio size=50 value=0 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==0) echo 'checked';?>>
|
1588 |
-
<label for="radiorefresh2">AJAX</label> <input id="radiorefresh2" type=radio size=50 value=1 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==1) echo 'checked';?>>
|
1589 |
-
</div>
|
1590 |
-
</td></tr>
|
1591 |
-
|
1592 |
-
<tr><td>
|
1593 |
-
<?php echo LM_DEBUG_MODE?>
|
1594 |
-
</td><td>
|
1595 |
-
<div id="radiodebug">
|
1596 |
-
<label for="radiodebug1">No</label> <input id="radiodebug1" type=radio size=50 value=0 name='debug' <?php if($_CONFIG[debug]==0) echo 'checked';?>>
|
1597 |
-
<label for="radiodebug2">Yes</label> <input id="radiodebug2" type=radio size=50 value=1 name='debug' <?php if($_CONFIG[debug]==1) echo 'checked';?>>
|
1598 |
-
</td></tr>
|
1599 |
-
</table>
|
1600 |
-
|
1601 |
-
</p></div>
|
1602 |
-
</div>
|
1603 |
-
|
1604 |
-
</div>
|
1605 |
-
<?php
|
1606 |
-
$tabs->endTab();
|
1607 |
-
$tabs->startTab(LM_TAB_CRON,"5");
|
1608 |
-
?>
|
1609 |
-
<div id="configtabinside">
|
1610 |
-
|
1611 |
-
<div>
|
1612 |
-
<h3><a href="#"> <?php echo LM_CRON_SETTINGS_M?> - all configs are saved in directory configs/ </a></h3>
|
1613 |
-
<div><p>
|
1614 |
-
<table class='adminform'>
|
1615 |
-
|
1616 |
-
<tr>
|
1617 |
-
<td width='250'>
|
1618 |
-
<?php echo LM_CRON_MCRON?>
|
1619 |
-
</td>
|
1620 |
-
<td>
|
1621 |
-
<input type=text size=30 value="<?php echo $_CONFIG[cron_save_as]?>" name='cron_save_as' >.php <br />
|
1622 |
-
<?php echo LM_CRON_MCRON_SUB?>
|
1623 |
-
</td>
|
1624 |
-
</tr>
|
1625 |
-
|
1626 |
-
<tr>
|
1627 |
-
<td>
|
1628 |
-
<?php echo LM_CRON_MCRON_AVAIL?>
|
1629 |
-
</td>
|
1630 |
-
<td>
|
1631 |
-
<?php
|
1632 |
-
|
1633 |
-
if ($handle = opendir($_CONFIG['multiple_config_dir'])) {
|
1634 |
-
|
1635 |
-
while (false !== ($file = readdir($handle))) {
|
1636 |
-
if( ($file!=".") && ($file!="..") &&($file!="") && (strstr($file, '.php'))){
|
1637 |
-
$fcron = plugins_url('cloner.cron.php', __FILE__)."?config=$file";
|
1638 |
-
|
1639 |
-
echo "<b>$fcron</b>";
|
1640 |
-
|
1641 |
-
echo " - <a href='$fcron' target='_blank'>execute cron</a>";
|
1642 |
-
|
1643 |
-
echo " | <a href='plugins.php?page=xcloner_show&option=com_cloner&task=cron_delete&fconfig=$file'>delete config</a>";
|
1644 |
-
|
1645 |
-
echo "\n<br />";
|
1646 |
-
}
|
1647 |
-
}
|
1648 |
-
|
1649 |
-
closedir($handle);
|
1650 |
-
}
|
1651 |
-
?>
|
1652 |
-
</td>
|
1653 |
-
</tr>
|
1654 |
-
</table>
|
1655 |
-
</p></div>
|
1656 |
-
</div>
|
1657 |
-
|
1658 |
-
<div>
|
1659 |
-
<h3><a href="#"> <?php echo LM_CRON_SETTINGS?></a></h3>
|
1660 |
-
<div><p>
|
1661 |
-
<table class='adminform'>
|
1662 |
-
|
1663 |
-
<tr>
|
1664 |
-
<td width='250'>
|
1665 |
-
<?php echo LM_CRON_SEMAIL?>
|
1666 |
-
</td>
|
1667 |
-
<td>
|
1668 |
-
<input type=text size=30 value="<?php echo $_CONFIG[cron_logemail]?>" name='cron_logemail' > <br />
|
1669 |
-
<?php echo LM_CRON_SEMAIL_SUB?>
|
1670 |
-
</td>
|
1671 |
-
</tr>
|
1672 |
-
|
1673 |
-
<tr>
|
1674 |
-
<td>
|
1675 |
-
<?php echo LM_CRON_MODE?>
|
1676 |
-
</td>
|
1677 |
-
<td>
|
1678 |
-
|
1679 |
-
<div id="radio">
|
1680 |
-
<input id="radio1" type=radio size=50 value=0 name='cron_send' <?php if($_CONFIG[cron_send]==0) echo 'checked';?>>
|
1681 |
-
<label for="radio1"><?php echo LM_CONFIG_CRON_LOCAL?></label>
|
1682 |
-
<input id="radio2" type=radio size=50 value=1 name='cron_send' <?php if($_CONFIG[cron_send]==1) echo 'checked';?>>
|
1683 |
-
<label for="radio2"><?php echo LM_CONFIG_CRON_REMOTE?></label>
|
1684 |
-
<input id="radio3" type=radio size=50 value=2 name='cron_send' <?php if($_CONFIG[cron_send]==2) echo 'checked';?>>
|
1685 |
-
<label for="radio3"><?php echo LM_CONFIG_CRON_EMAIL?></label>
|
1686 |
-
</div>
|
1687 |
-
<?php echo LM_CRON_MODE_INFO?>
|
1688 |
-
</td>
|
1689 |
-
</tr>
|
1690 |
-
|
1691 |
-
|
1692 |
-
<tr>
|
1693 |
-
<td>
|
1694 |
-
<?php echo LM_CRON_TYPE?>
|
1695 |
-
</td>
|
1696 |
-
<td>
|
1697 |
-
<div id="radiob">
|
1698 |
-
<input id="radiob1" type=radio size=50 value=0 name='cron_btype' <?php if($_CONFIG[cron_btype]==0) echo 'checked';?>>
|
1699 |
-
<label for="radiob1"><?php echo LM_CONFIG_CRON_FULL?></label>
|
1700 |
-
<input id="radiob2" type=radio size=50 value=1 name='cron_btype' <?php if($_CONFIG[cron_btype]==1) echo 'checked';?>>
|
1701 |
-
<label for="radiob2"><?php echo LM_CONFIG_CRON_FILES?></label>
|
1702 |
-
<input id="radiob3" type=radio size=50 value=2 name='cron_btype' <?php if($_CONFIG[cron_btype]==2) echo 'checked';?>>
|
1703 |
-
<label for="radiob3"><?php echo LM_CONFIG_CRON_DATABASE?></label>
|
1704 |
-
<?php echo LM_CRON_TYPE_INFO?>
|
1705 |
-
</div>
|
1706 |
-
</td>
|
1707 |
-
</tr>
|
1708 |
-
|
1709 |
-
<tr>
|
1710 |
-
<td>
|
1711 |
-
<?php echo LM_CRON_BNAME?>
|
1712 |
-
</td>
|
1713 |
-
<td>
|
1714 |
-
<input type=text size=50 value="<?php echo $_CONFIG[cron_bname]?>" name='cron_bname' > <br />
|
1715 |
-
<?php echo LM_CRON_BNAME_SUB?>
|
1716 |
-
</td>
|
1717 |
-
</tr>
|
1718 |
-
|
1719 |
-
|
1720 |
-
<!-- <tr>
|
1721 |
-
<td>
|
1722 |
-
<?php echo LM_CRON_IP?>
|
1723 |
-
</td>
|
1724 |
-
<td>
|
1725 |
-
<textarea type=text size=50 name='cron_ip' cols='30' rows='5'><?php echo $_CONFIG[cron_ip]?></textarea> <br />
|
1726 |
-
<?php echo LM_CRON_IP_SUB?>
|
1727 |
-
</td>
|
1728 |
-
</tr>-->
|
1729 |
-
</table>
|
1730 |
-
</p></div>
|
1731 |
-
</div>
|
1732 |
-
|
1733 |
-
<div>
|
1734 |
-
<h3><a href="#"> <?php echo LM_CRON_FTP_DETAILS?></a></h3>
|
1735 |
-
<div><p>
|
1736 |
-
<table class='adminform'>
|
1737 |
-
|
1738 |
-
<tr>
|
1739 |
-
<td width='250'>
|
1740 |
-
<?php echo LM_CRON_FTP_SERVER?>
|
1741 |
-
</td>
|
1742 |
-
<td>
|
1743 |
-
<input type=text size=50 name='cron_ftp_server' value='<?php echo $_CONFIG[cron_ftp_server]?>'>
|
1744 |
-
</td>
|
1745 |
-
</tr>
|
1746 |
-
<tr>
|
1747 |
-
<td>
|
1748 |
-
<?php echo LM_CRON_FTP_USER?>
|
1749 |
-
</td>
|
1750 |
-
<td>
|
1751 |
-
<input type=text size=50 name='cron_ftp_user' value='<?php echo $_CONFIG[cron_ftp_user]?>'>
|
1752 |
-
</td>
|
1753 |
-
</tr>
|
1754 |
-
<tr>
|
1755 |
-
<td>
|
1756 |
-
<?php echo LM_CRON_FTP_PASS?>
|
1757 |
-
</td>
|
1758 |
-
<td>
|
1759 |
-
<input type=password size=50 name='cron_ftp_pass' value='<?php echo $_CONFIG[cron_ftp_pass]?>'>
|
1760 |
-
</td>
|
1761 |
-
</tr>
|
1762 |
-
<tr>
|
1763 |
-
<td>
|
1764 |
-
<?php echo LM_CRON_FTP_PATH?>
|
1765 |
-
</td>
|
1766 |
-
<td>
|
1767 |
-
<input type=text size=50 name='cron_ftp_path' value='<?php echo $_CONFIG[cron_ftp_path]?>'>
|
1768 |
-
</td>
|
1769 |
-
</tr>
|
1770 |
-
<tr>
|
1771 |
-
<td>
|
1772 |
-
<!--<?php echo LM_CRON_FTP_DELB?>-->
|
1773 |
-
</td>
|
1774 |
-
<td>
|
1775 |
-
<input id="cron_ftp_delb" type=checkbox name='cron_ftp_delb' <?php if($_CONFIG[cron_ftp_delb]==1) echo "checked";?> value='1'>
|
1776 |
-
<label for="cron_ftp_delb"><?php echo LM_CRON_FTP_DELB?></label>
|
1777 |
-
</td>
|
1778 |
-
</tr>
|
1779 |
-
</table>
|
1780 |
-
</p></div>
|
1781 |
-
</div>
|
1782 |
-
|
1783 |
-
<div>
|
1784 |
-
<h3><a href="#"> <?php echo LM_AMAZON_S3?></a></h3>
|
1785 |
-
<div><p>
|
1786 |
-
<table class='adminform'>
|
1787 |
-
|
1788 |
-
<tr>
|
1789 |
-
<td width='250'>
|
1790 |
-
<?php #echo LM_AMAZON_S3_ACTIVATE?>
|
1791 |
-
</td>
|
1792 |
-
<td>
|
1793 |
-
<label for="cron_amazon_active"><?php echo LM_AMAZON_S3_ACTIVATE?></label>
|
1794 |
-
<input id="cron_amazon_active" type=checkbox name='cron_amazon_active' <?php if($_CONFIG[cron_amazon_active]==1) echo "checked";?> value='1'>
|
1795 |
-
|
1796 |
-
<label for="cron_amazon_ssl"><?php echo LM_AMAZON_S3_SSL?></label>
|
1797 |
-
<input id="cron_amazon_ssl" type=checkbox name='cron_amazon_ssl' <?php if($_CONFIG[cron_amazon_ssl]==1) echo "checked";?> value='1'>
|
1798 |
-
</td>
|
1799 |
-
</tr>
|
1800 |
-
|
1801 |
-
<tr>
|
1802 |
-
<td>
|
1803 |
-
<?php echo LM_AMAZON_S3_AWSACCESSKEY;?>
|
1804 |
-
</td>
|
1805 |
-
<td>
|
1806 |
-
<input type=text size=50 name='cron_amazon_awsAccessKey' value="<?php echo $_CONFIG['cron_amazon_awsAccessKey'];?>">
|
1807 |
-
</td>
|
1808 |
-
</tr>
|
1809 |
-
|
1810 |
-
<tr>
|
1811 |
-
<td>
|
1812 |
-
<?php echo LM_AMAZON_S3_AWSSECRETKEY;?>
|
1813 |
-
</td>
|
1814 |
-
<td>
|
1815 |
-
<input type=text size=50 name='cron_amazon_awsSecretKey' value="<?php echo $_CONFIG['cron_amazon_awsSecretKey'];?>">
|
1816 |
-
</td>
|
1817 |
-
</tr>
|
1818 |
-
|
1819 |
-
<tr>
|
1820 |
-
<td width='200'>
|
1821 |
-
<?php echo LM_AMAZON_S3_BUCKET;?>
|
1822 |
-
</td>
|
1823 |
-
<td>
|
1824 |
-
<input type=text size=50 name='cron_amazon_bucket' value="<?php echo $_CONFIG['cron_amazon_bucket'];?>">
|
1825 |
-
</td>
|
1826 |
-
</tr>
|
1827 |
-
|
1828 |
-
<tr>
|
1829 |
-
<td>
|
1830 |
-
<?php echo LM_AMAZON_S3_DIRNAME;?>
|
1831 |
-
</td>
|
1832 |
-
<td>
|
1833 |
-
<input type=text size=50 name='cron_amazon_dirname' value="<?php echo $_CONFIG['cron_amazon_dirname'];?>">
|
1834 |
-
</td>
|
1835 |
-
</tr>
|
1836 |
-
</tr>
|
1837 |
-
</table>
|
1838 |
-
</p></div>
|
1839 |
-
</div>
|
1840 |
-
|
1841 |
-
<div>
|
1842 |
-
<h3><a href="#"> <?php echo LM_DROPBOX?></a></h3>
|
1843 |
-
<div><p>
|
1844 |
-
<table class='adminform'>
|
1845 |
-
|
1846 |
-
<tr>
|
1847 |
-
<td width='250'>
|
1848 |
-
<?php #echo LM_AMAZON_S3_ACTIVATE?>
|
1849 |
-
</td>
|
1850 |
-
<td>
|
1851 |
-
<label for="cron_dropbox_active"><?php echo LM_DROPBOX_ACTIVATE?></label>
|
1852 |
-
<input id="cron_dropbox_active" type=checkbox name='cron_dropbox_active' <?php if($_CONFIG['cron_dropbox_active']==1) echo "checked";?> value='1'>
|
1853 |
-
<?php
|
1854 |
-
$access_token = load_token("access");
|
1855 |
-
if(empty($access_token) and $_CONFIG["cron_dropbox_active"]){
|
1856 |
-
?>
|
1857 |
-
<a target="_blank" href="?page=xcloner_show&task=dropbox_authorize"><?php echo LM_DROPBOX_AUTHORIZE?></a>
|
1858 |
-
<?php
|
1859 |
-
}
|
1860 |
-
?>
|
1861 |
-
</td>
|
1862 |
-
</tr>
|
1863 |
-
|
1864 |
-
<tr>
|
1865 |
-
<td>
|
1866 |
-
<?php echo LM_DROPBOX_AWSACCESSKEY;?>
|
1867 |
-
</td>
|
1868 |
-
<td>
|
1869 |
-
<input type=text size=50 name='cron_dropbox_Key' value="<?php echo $_CONFIG['cron_dropbox_Key'];?>">
|
1870 |
-
</td>
|
1871 |
-
</tr>
|
1872 |
-
|
1873 |
-
<tr>
|
1874 |
-
<td>
|
1875 |
-
<?php echo LM_DROPBOX_AWSSECRETKEY;?>
|
1876 |
-
</td>
|
1877 |
-
<td>
|
1878 |
-
<input type=text size=50 name='cron_dropbox_Secret' value="<?php echo $_CONFIG['cron_dropbox_Secret'];?>">
|
1879 |
-
</td>
|
1880 |
-
</tr>
|
1881 |
-
|
1882 |
-
<tr>
|
1883 |
-
<td>
|
1884 |
-
<?php echo LM_DROPBOX_DIRNAME;?>
|
1885 |
-
</td>
|
1886 |
-
<td>
|
1887 |
-
<input type=text size=50 name='cron_dropbox_dirname' value="<?php echo $_CONFIG['cron_dropbox_dirname'];?>">
|
1888 |
-
</td>
|
1889 |
-
</tr>
|
1890 |
-
</tr>
|
1891 |
-
|
1892 |
-
</tr>
|
1893 |
-
</table>
|
1894 |
-
</p></div>
|
1895 |
-
</div>
|
1896 |
-
|
1897 |
-
<div>
|
1898 |
-
<h3><a href="#"> <?php echo LM_CRON_EMAIL_DETAILS?></a></h3>
|
1899 |
-
<div><p>
|
1900 |
-
<table class='adminform'>
|
1901 |
-
|
1902 |
-
<tr>
|
1903 |
-
<td width="250">
|
1904 |
-
<?php echo LM_CRON_EMAIL_ACCOUNT?>
|
1905 |
-
</td>
|
1906 |
-
<td>
|
1907 |
-
<input type=text size=50 name='cron_email_address' value='<?php echo $_CONFIG[cron_email_address]?>'>
|
1908 |
-
</td>
|
1909 |
-
</tr>
|
1910 |
-
</table>
|
1911 |
-
</p></div>
|
1912 |
-
</div>
|
1913 |
-
|
1914 |
-
<div>
|
1915 |
-
<h3><a href="#"> <?php echo LM_CRON_MYSQL_DETAILS?></a></h3>
|
1916 |
-
<div><p>
|
1917 |
-
<table class='adminform'>
|
1918 |
-
|
1919 |
-
<tr bgcolor='#ffffff'>
|
1920 |
-
<td width='250'>
|
1921 |
-
<?php #echo LM_CRON_MYSQL_DROP?>
|
1922 |
-
</td>
|
1923 |
-
<td>
|
1924 |
-
<label for="cron_sql_drop"><?php echo LM_CRON_MYSQL_DROP?></label>
|
1925 |
-
<input id="cron_sql_drop" type=checkbox name='cron_sql_drop' value='1' <?php if($_CONFIG[cron_sql_drop]) echo "checked";?> >
|
1926 |
-
</td>
|
1927 |
-
</tr>
|
1928 |
-
|
1929 |
-
<?php
|
1930 |
-
if((abs($_CONFIG['system_mdatabases'])==0) && ($_CONFIG['enable_db_backup']==1) ){
|
1931 |
-
?>
|
1932 |
-
<tr><td valign='top'>
|
1933 |
-
<?php echo LM_DATABASE_INCLUDE_DATABASES?>
|
1934 |
-
</td><td>
|
1935 |
-
<select name='databases_incl[]' MULTIPLE SIZE=5>
|
1936 |
-
<?php
|
1937 |
-
|
1938 |
-
$curent_dbs = explode(",", $_CONFIG['databases_incl_list']);
|
1939 |
-
|
1940 |
-
$query = @$_CONFIG['mysqli']->query("SHOW databases");
|
1941 |
-
|
1942 |
-
if($query)
|
1943 |
-
while($row = @$query->fetch_array()){
|
1944 |
-
|
1945 |
-
$table = $row[0];
|
1946 |
-
|
1947 |
-
if($table != $_CONFIG['mysql_database'])
|
1948 |
-
|
1949 |
-
if(in_array($table, $curent_dbs)){
|
1950 |
-
|
1951 |
-
echo "<option value='".$table."' selected>$table</option>";
|
1952 |
-
|
1953 |
-
}else{
|
1954 |
-
|
1955 |
-
echo "<option value='".$table."'>$table</option>";
|
1956 |
-
|
1957 |
-
}
|
1958 |
-
}
|
1959 |
-
?>
|
1960 |
-
</select><br />
|
1961 |
-
<?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
|
1962 |
-
</td></tr>
|
1963 |
-
<?php
|
1964 |
-
}
|
1965 |
-
?>
|
1966 |
-
</table>
|
1967 |
-
</p></div>
|
1968 |
-
</div>
|
1969 |
-
|
1970 |
-
<div>
|
1971 |
-
<h3><a href="#"> <?php echo LM_CRON_DELETE_FILES?></a></h3>
|
1972 |
-
<div><p>
|
1973 |
-
|
1974 |
-
<script>
|
1975 |
-
jQuery(function() {
|
1976 |
-
jQuery( "#slider2" ).slider({
|
1977 |
-
value:parseInt(<?php echo (int)$_CONFIG[cron_file_delete];?>),
|
1978 |
-
min: 0,
|
1979 |
-
max: 100,
|
1980 |
-
step: 1,
|
1981 |
-
slide: function( event, ui ) {
|
1982 |
-
jQuery( "#cron_file_delete" ).val( ui.value );
|
1983 |
-
}
|
1984 |
-
});
|
1985 |
-
jQuery( "#cron_file_delete" ).val( jQuery( "#slider2" ).slider( "value" ) );
|
1986 |
-
});
|
1987 |
-
</script>
|
1988 |
-
|
1989 |
-
<table class='adminform'>
|
1990 |
-
|
1991 |
-
<tr>
|
1992 |
-
<td width='250'>
|
1993 |
-
<?php #echo LM_CRON_DELETE_FILES_SUB_ACTIVE?>
|
1994 |
-
</td>
|
1995 |
-
<td>
|
1996 |
-
<label for="cron_file_delete_act"><?php echo LM_CRON_DELETE_FILES_SUB_ACTIVE?></label>
|
1997 |
-
<input id="cron_file_delete_act" type=checkbox name='cron_file_delete_act' <?php if ($_CONFIG['cron_file_delete_act'] == 1) echo 'checked';?> value='1'>
|
1998 |
-
</td>
|
1999 |
-
</tr>
|
2000 |
-
<tr>
|
2001 |
-
<td>
|
2002 |
-
<?php echo LM_CRON_DELETE_FILES_SUB?>
|
2003 |
-
</td>
|
2004 |
-
<td>
|
2005 |
-
<div id="slider2" style="width:300px;padding-top:5px;"></div>
|
2006 |
-
<br /><label for="cron_file_delete"></label>
|
2007 |
-
<input id="cron_file_delete" size=5 name='cron_file_delete' value='<?php echo $_CONFIG[cron_file_delete]?>'> days:
|
2008 |
-
</td>
|
2009 |
-
</tr>
|
2010 |
-
</table>
|
2011 |
-
|
2012 |
-
<table class='adminform'>
|
2013 |
-
<tr>
|
2014 |
-
<th colspan='2'>
|
2015 |
-
<?php echo LM_CRON_EXCLUDE?>
|
2016 |
-
</th>
|
2017 |
-
</tr>
|
2018 |
-
</tr>
|
2019 |
-
<tr>
|
2020 |
-
<td width='250'>
|
2021 |
-
<?php echo LM_CRON_EXCLUDE_DIR?>
|
2022 |
-
</td>
|
2023 |
-
<td>
|
2024 |
-
<textarea cols=50 rows=5 name='cron_exclude'><?php echo $_CONFIG[cron_exclude]?></textarea>
|
2025 |
-
</td>
|
2026 |
-
</tr>
|
2027 |
-
|
2028 |
-
</table>
|
2029 |
-
</p></div>
|
2030 |
-
</div>
|
2031 |
-
|
2032 |
-
</div>
|
2033 |
-
<?php
|
2034 |
-
$tabs->endTab();
|
2035 |
-
$tabs->startTab(LM_TAB_INFO,"6");
|
2036 |
-
?>
|
2037 |
-
|
2038 |
-
<div id="configtabinside">
|
2039 |
-
<div>
|
2040 |
-
<h3><a href="#"><?php echo LM_CONFIG_INFO_PHP?></a></h3>
|
2041 |
-
<div><p>
|
2042 |
-
|
2043 |
-
<table class='adminform'>
|
2044 |
-
|
2045 |
-
<tr>
|
2046 |
-
<td width='250'>
|
2047 |
-
<?php echo LM_CONFIG_INFO_T_VERSION?>
|
2048 |
-
</td>
|
2049 |
-
<td>
|
2050 |
-
<b><?php
|
2051 |
-
$version = phpversion();
|
2052 |
-
$ver = str_replace(".", "", $version);
|
2053 |
-
$val = (version_compare(PHP_VERSION, '5.2.3') < 0)? $version: "Off";
|
2054 |
-
echo HTML_cloner::get_color($version, $val);
|
2055 |
-
?></b>
|
2056 |
-
<br />
|
2057 |
-
<?php echo LM_CONFIG_INFO_VERSION?>
|
2058 |
-
</td>
|
2059 |
-
</tr>
|
2060 |
-
|
2061 |
-
<tr>
|
2062 |
-
<td>
|
2063 |
-
<?php echo LM_CONFIG_INFO_T_SAFEMODE?>
|
2064 |
-
</td>
|
2065 |
-
<td>
|
2066 |
-
<b><?php $val = (ini_get('safe_mode') != "")? ini_get('safe_mode'):"Off";
|
2067 |
-
echo HTML_cloner::get_color($val, 'On');
|
2068 |
-
?></b>
|
2069 |
-
<br />
|
2070 |
-
<?php echo LM_CONFIG_INFO_SAFEMODE?>
|
2071 |
-
</td>
|
2072 |
-
</tr>
|
2073 |
-
|
2074 |
-
<tr>
|
2075 |
-
<td>
|
2076 |
-
<?php echo LM_CONFIG_INFO_T_MTIME?>
|
2077 |
-
</td>
|
2078 |
-
<td>
|
2079 |
-
<b><?php echo (ini_get('max_execution_time') != "")? ini_get('max_execution_time'):"no value";
|
2080 |
-
|
2081 |
-
?></b>
|
2082 |
-
<br />
|
2083 |
-
<?php echo LM_CONFIG_INFO_TIME?>
|
2084 |
-
</td>
|
2085 |
-
</tr>
|
2086 |
-
|
2087 |
-
<tr>
|
2088 |
-
<td>
|
2089 |
-
<?php echo LM_CONFIG_INFO_T_MEML?>
|
2090 |
-
</td>
|
2091 |
-
<td>
|
2092 |
-
<b><?php echo (ini_get('memory_limit') != "")? ini_get('memory_limit'):"no value";?> </b>
|
2093 |
-
<br />
|
2094 |
-
<?php echo LM_CONFIG_INFO_MEMORY?>
|
2095 |
-
</td>
|
2096 |
-
</tr>
|
2097 |
-
|
2098 |
-
<tr>
|
2099 |
-
<td>
|
2100 |
-
<?php echo LM_CONFIG_INFO_T_BDIR?>
|
2101 |
-
</td>
|
2102 |
-
<td>
|
2103 |
-
<b><?php $val = (ini_get('open_basedir') != "")? ini_get('open_basedir'):"no value";
|
2104 |
-
echo HTML_cloner::get_color($val, '/');
|
2105 |
-
?> </b>
|
2106 |
-
<br />
|
2107 |
-
<?php echo LM_CONFIG_INFO_BASEDIR?>
|
2108 |
-
</td>
|
2109 |
-
</tr>
|
2110 |
-
|
2111 |
-
<tr>
|
2112 |
-
<td>
|
2113 |
-
<?php echo LM_CONFIG_INFO_T_EXEC?>
|
2114 |
-
</td>
|
2115 |
-
<td>
|
2116 |
-
<b><?php
|
2117 |
-
|
2118 |
-
$out = "";
|
2119 |
-
if(function_exists("exec")){
|
2120 |
-
|
2121 |
-
$out = @exec("ls -al");
|
2122 |
-
}
|
2123 |
-
|
2124 |
-
$val = ($out != "")? "ENABLED":"<font color='red'>DISABLED</font>";
|
2125 |
-
echo HTML_cloner::get_color($val, 'DISABLED');
|
2126 |
-
?> </b>
|
2127 |
-
<br />
|
2128 |
-
<?php echo LM_CONFIG_INFO_EXEC?>
|
2129 |
-
</td>
|
2130 |
-
</tr>
|
2131 |
-
</table>
|
2132 |
-
</p></div>
|
2133 |
-
</div>
|
2134 |
-
<div>
|
2135 |
-
<h3><a href="#"><?php echo LM_CONFIG_INFO_PATHS?></a></h3>
|
2136 |
-
<div><p>
|
2137 |
-
<table class='adminform'>
|
2138 |
-
|
2139 |
-
<tr>
|
2140 |
-
<td width='250'>
|
2141 |
-
<?php echo LM_CONFIG_INFO_ROOT_BPATH_TMP?>
|
2142 |
-
</td>
|
2143 |
-
<td>
|
2144 |
-
<b><?php $tmp_dir = realpath($_CONFIG['backup_path']."/administrator/backups");
|
2145 |
-
echo (@is_writeable( $tmp_dir ))? $tmp_dir . " is <font color=green>writeable</font>":$tmp_dir. " <font color=red>incorrect or unreadable</font>";?></b>
|
2146 |
-
<br />
|
2147 |
-
<?php echo LM_CONFIG_INFO_ROOT_PATH_TMP_SUB?>
|
2148 |
-
</td>
|
2149 |
-
</tr>
|
2150 |
-
|
2151 |
-
<tr>
|
2152 |
-
<td>
|
2153 |
-
<?php echo LM_CONFIG_INFO_ROOT_BPATH?>
|
2154 |
-
</td>
|
2155 |
-
<td>
|
2156 |
-
<b><?php echo (@is_readable($_CONFIG['backup_path']) )? $_CONFIG['backup_path'] . " is <font color=green>readable</font>":$_CONFIG['backup_path']. " <font color=red>incorrect or unreadable</font>";?></b>
|
2157 |
-
<br />
|
2158 |
-
<?php echo LM_CONFIG_INFO_ROOT_PATH_SUB?>
|
2159 |
-
</td>
|
2160 |
-
</tr>
|
2161 |
-
|
2162 |
-
|
2163 |
-
<tr>
|
2164 |
-
<td>
|
2165 |
-
<?php echo LM_CONFIG_INFO_T_BPATH?>
|
2166 |
-
</td>
|
2167 |
-
<td>
|
2168 |
-
<b><?php echo (@is_writeable($_CONFIG['clonerPath']) )? $_CONFIG['clonerPath'] . " is <font color=green>writeable</font>":$_CONFIG['clonerPath']. " <font color=red>unwriteable</font>";?></b>
|
2169 |
-
<br />
|
2170 |
-
<?php echo LM_CONFIG_INFO_BPATH?>
|
2171 |
-
</td>
|
2172 |
-
</tr>
|
2173 |
-
|
2174 |
-
|
2175 |
-
<tr>
|
2176 |
-
<td>
|
2177 |
-
<?php echo LM_CONFIG_INFO_T_TAR?>
|
2178 |
-
</td>
|
2179 |
-
<td>
|
2180 |
-
<b><?php
|
2181 |
-
if(function_exists('exec')){
|
2182 |
-
$info_tar_path = explode(" ", @exec("whereis tar"));
|
2183 |
-
}
|
2184 |
-
echo ($info_tar_path['1'] != "")? $info_tar_path['1']:"unable to determine";
|
2185 |
-
?> </b>
|
2186 |
-
<br />
|
2187 |
-
<?php echo LM_CONFIG_INFO_TAR?>
|
2188 |
-
</td>
|
2189 |
-
</tr>
|
2190 |
-
|
2191 |
-
|
2192 |
-
<tr>
|
2193 |
-
<td>
|
2194 |
-
<?php echo LM_CONFIG_INFO_T_MSQL?>
|
2195 |
-
</td>
|
2196 |
-
<td>
|
2197 |
-
<b><?php
|
2198 |
-
if(function_exists('exec')){
|
2199 |
-
$info_msql_path = explode(" ", @exec("whereis mysqldump"));
|
2200 |
-
}
|
2201 |
-
echo ($info_msql_path['1'] != "")? $info_msql_path['1']:"unable to determine";
|
2202 |
-
?> </b>
|
2203 |
-
<br />
|
2204 |
-
<?php echo LM_CONFIG_INFO_MSQL?>
|
2205 |
-
</td>
|
2206 |
-
</tr>
|
2207 |
-
|
2208 |
-
</table>
|
2209 |
-
</p></div>
|
2210 |
-
|
2211 |
-
</div></div>
|
2212 |
-
|
2213 |
-
<?php
|
2214 |
-
$tabs->endTab();
|
2215 |
-
$tabs->endPane();
|
2216 |
-
?>
|
2217 |
-
<input type="hidden" name="option" value="com_cloner" />
|
2218 |
-
<input type="hidden" name="task" value="config" />
|
2219 |
-
<input type="hidden" name='action' value='save'>
|
2220 |
-
<?php wp_nonce_field('save','csrf'); ?>
|
2221 |
-
</form>
|
2222 |
-
|
2223 |
-
<?php
|
2224 |
-
}
|
2225 |
-
|
2226 |
-
function get_color($val, $comp){
|
2227 |
-
|
2228 |
-
if(!stristr($val, $comp))
|
2229 |
-
echo "<span style='color:green'>$val</span>";
|
2230 |
-
else
|
2231 |
-
echo "<span style='color:red'>$val</span>";
|
2232 |
-
|
2233 |
-
}
|
2234 |
-
|
2235 |
-
function TransferForm($option, $files){
|
2236 |
-
global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $task;
|
2237 |
-
|
2238 |
-
?>
|
2239 |
-
<form action="" method="POST" name="adminForm">
|
2240 |
-
<script language="javascript" type="text/javascript">
|
2241 |
-
|
2242 |
-
|
2243 |
-
function submitbutton(pressbutton) {
|
2244 |
-
var form = document.adminForm;
|
2245 |
-
if (pressbutton == 'cancel') {
|
2246 |
-
submitform( pressbutton );
|
2247 |
-
return;
|
2248 |
-
}
|
2249 |
-
|
2250 |
-
submitform( pressbutton );
|
2251 |
-
|
2252 |
-
}
|
2253 |
-
|
2254 |
-
function gotocontact( id ) {
|
2255 |
-
var form = document.adminForm;
|
2256 |
-
form.contact_id.value = id;
|
2257 |
-
submitform( 'contact' );
|
2258 |
-
}
|
2259 |
-
</script>
|
2260 |
-
<table class='adminform'>
|
2261 |
-
<tr><td colspan='2'>
|
2262 |
-
<b>Transfer <?php echo $file;?> details:</b>
|
2263 |
-
<br /><b>Attempting to
|
2264 |
-
<?php echo (($_REQUEST[task]=='move')||($_REQUEST[task2]=='move'))?'Move':'Clone';?> backup(s):</b><br /><?php echo implode("<br />",$files)?>
|
2265 |
-
|
2266 |
-
</td></tr>
|
2267 |
-
<tr><td colspan='2'><?php echo LM_CLONE_FORM_TOP?></td></tr>
|
2268 |
-
<?php
|
2269 |
-
if(($_REQUEST[task]=='move')||($_REQUEST[task2]=='move')){
|
2270 |
-
}
|
2271 |
-
else{
|
2272 |
-
|
2273 |
-
?>
|
2274 |
-
<tr>
|
2275 |
-
<td width='110'><b><?php echo LM_TRANSFER_URL?></b> </td>
|
2276 |
-
<td><input type='text' size='30' name='ftp_url' value='<?php echo $_REQUEST[ftp_url]?>'></td>
|
2277 |
-
</tr>
|
2278 |
-
<tr>
|
2279 |
-
<td colspan='2'><?php echo LM_TRANSFER_URL_SUB?></td>
|
2280 |
-
</tr>
|
2281 |
-
<?php } ?>
|
2282 |
-
<tr>
|
2283 |
-
<td width='110'><b><?php echo LM_TRANSFER_FTP_HOST?></b> </td>
|
2284 |
-
<td><input type='text' size='30' name='ftp_server' value='<?php echo $_REQUEST[ftp_server]?>'></td>
|
2285 |
-
</tr>
|
2286 |
-
<tr>
|
2287 |
-
<td colspan='2'><small><?php echo LM_TRANSFER_FTP_HOST_SUB?></small></td></tr>
|
2288 |
-
<tr>
|
2289 |
-
<td width='110'><b><?php echo LM_TRANSFER_FTP_USER?></b> </td>
|
2290 |
-
<td><input type='text' size='30' name='ftp_user' value='<?php echo $_REQUEST[ftp_user]?>'></td>
|
2291 |
-
</tr>
|
2292 |
-
<tr>
|
2293 |
-
<td colspan='2'><small><?php echo LM_TRANSFER_FTP_USER_SUB?></small></td></tr>
|
2294 |
-
<tr>
|
2295 |
-
<td width='110'><b><?php echo LM_TRANSFER_FTP_PASS?></b> </td>
|
2296 |
-
<td><input type='text' size='30' name='ftp_pass' value='<?php echo $_REQUEST[ftp_pass]?>'></td>
|
2297 |
-
</tr>
|
2298 |
-
<tr>
|
2299 |
-
<td colspan='2'><small><?php echo LM_TRANSFER_FTP_PASS_SUB?></small></td></tr>
|
2300 |
-
<tr>
|
2301 |
-
<td width='110'><b><?php echo LM_TRANSFER_FTP_DIR?></b> </td>
|
2302 |
-
<td><input type='text' size='30' name='ftp_dir' value='<?php echo $_REQUEST[ftp_dir]?>'></td>
|
2303 |
-
</tr>
|
2304 |
-
<tr>
|
2305 |
-
<td colspan='2'><small><?php echo LM_TRANSFER_FTP_DIR_SUB?></small></td></tr>
|
2306 |
-
|
2307 |
-
<tr>
|
2308 |
-
<td width='140'><b><?php echo LM_TRANSFER_FTP_INCT?></b> </td>
|
2309 |
-
<td><input type='checkbox' name='ftp_inct' value='1' <?php if($_REQUEST[ftp_inct] ==1 ) echo "checked";?>></td>
|
2310 |
-
</tr>
|
2311 |
-
<tr>
|
2312 |
-
<td colspan='2'><small><?php echo LM_TRANSFER_FTP_INCT_SUB?></small></td></tr>
|
2313 |
-
|
2314 |
-
</table>
|
2315 |
-
<input type="hidden" name="option" value="com_cloner" />
|
2316 |
-
<input type="hidden" name="task" value="" />
|
2317 |
-
<input type="hidden" name="task2" value="<?php if($_REQUEST[task2]!="") echo $_REQUEST[task2]; else echo $task;?>" />
|
2318 |
-
<?php
|
2319 |
-
foreach($files as $key=>$value)
|
2320 |
-
{
|
2321 |
-
?>
|
2322 |
-
<input type="hidden" name="files[<?php echo $key;?>]" value="<?php echo $value?>" />
|
2323 |
-
<input type="hidden" name="cid[<?php echo $key;?>]" value="<?php echo $value?>" />
|
2324 |
-
<?php
|
2325 |
-
}
|
2326 |
-
?>
|
2327 |
-
<input type="hidden" name="action" value="connect" />
|
2328 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
2329 |
-
<?php wp_nonce_field('transfer','csrf'); ?>
|
2330 |
-
</form>
|
2331 |
-
<?php
|
2332 |
-
}
|
2333 |
-
function confirmBackups( &$folders, &$sizes, $path, $option ) {
|
2334 |
-
// ----------------------------------------------------------
|
2335 |
-
// Presentation of the confirmation screen
|
2336 |
-
// ----------------------------------------------------------
|
2337 |
-
global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $_CONFIG, $database, $mosConfig_db;
|
2338 |
-
|
2339 |
-
?>
|
2340 |
-
<form action="" method="post" name="adminForm">
|
2341 |
-
<?php
|
2342 |
-
$tabs = new mosTabs(1);
|
2343 |
-
?>
|
2344 |
-
|
2345 |
-
<script>
|
2346 |
-
jQuery(function() {
|
2347 |
-
jQuery( "#tabs" ).tabs().find( ".ui-tabs-nav" ).sortable({ axis: "x" });
|
2348 |
-
jQuery( "#radio_dbbackup" ).buttonset();
|
2349 |
-
jQuery( "#radio_dbbackup1" ).button( { icons: {primary:'ui-icon-bullet'} } );
|
2350 |
-
jQuery( "#radio_dbbackup2" ).button( { icons: {primary:'ui-icon-bullet'} } );
|
2351 |
-
});
|
2352 |
-
</script>
|
2353 |
-
|
2354 |
-
|
2355 |
-
<ul>
|
2356 |
-
<?php
|
2357 |
-
if($_CONFIG['enable_db_backup']){
|
2358 |
-
?>
|
2359 |
-
<li><a href="#tabs-users-databse-options-tab"><?php echo LM_TAB_G_DATABASE;?></a></li>
|
2360 |
-
<?php }?>
|
2361 |
-
<li><a href="#tabs-users-files-options-tab"><?php echo LM_TAB_G_FILES;?></a></li>
|
2362 |
-
<li><a href="#tabs-users-comments-options-tab"><?php echo LM_TAB_G_COMMENTS;?></a></li>
|
2363 |
-
</ul>
|
2364 |
-
|
2365 |
-
<?php
|
2366 |
-
#$tabs->startPane("BGeneratePane");
|
2367 |
-
if($_CONFIG['enable_db_backup']){
|
2368 |
-
$tabs->startTab(LM_TAB_G_DATABASE,"users-databse-options-tab");
|
2369 |
-
?>
|
2370 |
-
|
2371 |
-
<div id="radio_dbbackup">
|
2372 |
-
<table class="adminform">
|
2373 |
-
<tr>
|
2374 |
-
<td>
|
2375 |
-
<label for="radio_dbbackup1"><?php echo LM_CONFIRM_DATABASE; ?></label>
|
2376 |
-
<input id="radio_dbbackup1" type="checkbox" id="dbbackup" name="dbbackup" checked value="1" />
|
2377 |
-
<label for="radio_dbbackup2">Add DROP SYNTAX</label>
|
2378 |
-
<input id="radio_dbbackup2" type="checkbox" id="dbbackup_drop" name="dbbackup_drop" value="1" />
|
2379 |
-
</td>
|
2380 |
-
</tr>
|
2381 |
-
<tr>
|
2382 |
-
<td><?php echo "Mysql Compatibility"; ?>
|
2383 |
-
<select name='dbbackup_comp'>
|
2384 |
-
<option value=''>Default</option>
|
2385 |
-
<option value='MYSQL40'>MYSQL40</option>
|
2386 |
-
<option balue='MYSQL323'>MYSQL323</option>
|
2387 |
-
</select>
|
2388 |
-
</td>
|
2389 |
-
</tr>
|
2390 |
-
<tr><th colspan=2>
|
2391 |
-
<?php echo LM_DATABASE_EXCLUDE_TABLES?>
|
2392 |
-
</th></tr>
|
2393 |
-
<tr><td>
|
2394 |
-
<?php echo LM_DATABASE_CURRENT?> <b><?php echo $_CONFIG['mysql_database'];?></b><br />
|
2395 |
-
<select name='excltables[]' MULTIPLE SIZE=15>
|
2396 |
-
<?php
|
2397 |
-
|
2398 |
-
$query = $_CONFIG['mysqli']->query("SHOW tables");
|
2399 |
-
while($row = $query->fetch_array()){
|
2400 |
-
|
2401 |
-
echo "<option value='".$row[0]."'>$row[0]</option>";
|
2402 |
-
|
2403 |
-
}
|
2404 |
-
?>
|
2405 |
-
</select>
|
2406 |
-
</td></tr>
|
2407 |
-
|
2408 |
-
<?php
|
2409 |
-
if(abs($_CONFIG[system_mdatabases])==0){
|
2410 |
-
?>
|
2411 |
-
|
2412 |
-
<tr><th colspan=2>
|
2413 |
-
<?php echo LM_DATABASE_INCLUDE_DATABASES?>
|
2414 |
-
</th></tr>
|
2415 |
-
<tr><td>
|
2416 |
-
<select name='databases_incl[]' MULTIPLE SIZE=5>
|
2417 |
-
<?php
|
2418 |
-
|
2419 |
-
$query = $_CONFIG['mysqli']->query("SHOW databases");
|
2420 |
-
|
2421 |
-
if($query)
|
2422 |
-
while($row = $query->fetch_array()){
|
2423 |
-
|
2424 |
-
if($_CONFIG['mysql_database'] != $row[0])
|
2425 |
-
echo "<option value='".$row[0]."'>$row[0]</option>";
|
2426 |
-
|
2427 |
-
}
|
2428 |
-
|
2429 |
-
?>
|
2430 |
-
</select><br />
|
2431 |
-
<?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
|
2432 |
-
</td></tr>
|
2433 |
-
|
2434 |
-
<?php
|
2435 |
-
}
|
2436 |
-
?>
|
2437 |
-
|
2438 |
-
</table>
|
2439 |
-
</div>
|
2440 |
-
<?php
|
2441 |
-
$tabs->endTab();
|
2442 |
-
}
|
2443 |
-
$tabs->startTab(LM_TAB_G_FILES,"users-files-options-tab");
|
2444 |
-
?>
|
2445 |
-
<table class="adminform">
|
2446 |
-
<tr>
|
2447 |
-
<th>
|
2448 |
-
<b><?php echo LM_BACKUP_NAME; ?></b>
|
2449 |
-
</th>
|
2450 |
-
</tr>
|
2451 |
-
<tr>
|
2452 |
-
<td>
|
2453 |
-
<input type=text name='bname' value='' size=100><br/>
|
2454 |
-
<?php echo LM_BACKUP_NAME_SUB?>
|
2455 |
-
</td>
|
2456 |
-
</tr>
|
2457 |
-
|
2458 |
-
<tr>
|
2459 |
-
<td width="50%"><?php echo LM_CONFIRM_INSTRUCTIONS ?></td>
|
2460 |
-
</tr>
|
2461 |
-
</table>
|
2462 |
-
<table class="adminlist" >
|
2463 |
-
<tr>
|
2464 |
-
<th width="200" valign='top' colspan='2' align='left'>
|
2465 |
-
|
2466 |
-
<?php echo LM_COL_FOLDER ?>
|
2467 |
-
<?php
|
2468 |
-
{
|
2469 |
-
?>
|
2470 |
-
<tr><td>
|
2471 |
-
<link href="<?php echo plugins_url('browser/filebrowser.css', __FILE__) ?>" rel="stylesheet" type="text/css">
|
2472 |
-
|
2473 |
-
<script type="text/javascript" src="<?php echo plugins_url('browser/xmlhttp.js', __FILE__) ?>"></script>
|
2474 |
-
|
2475 |
-
|
2476 |
-
<div id="browser">
|
2477 |
-
<?php require_once("browser/files_inpage.php"); ?>
|
2478 |
-
</div>
|
2479 |
-
<script>do_browser()</script>
|
2480 |
-
|
2481 |
-
</td></tr>
|
2482 |
-
<?php
|
2483 |
-
}
|
2484 |
-
?>
|
2485 |
-
|
2486 |
-
</table>
|
2487 |
-
<?php
|
2488 |
-
$tabs->endTab();
|
2489 |
-
$tabs->startTab(LM_TAB_G_COMMENTS,"users-comments-options-tab");
|
2490 |
-
?>
|
2491 |
-
<div class="mainText">
|
2492 |
-
<h2><?php echo LM_TAB_G_COMMENTS_H2?></h2>
|
2493 |
-
<textarea name="backupComments" rows=20 cols=80></textarea>
|
2494 |
-
<br /><small> <?php echo LM_TAB_G_COMMENTS_NOTE?></small>
|
2495 |
-
</div>
|
2496 |
-
<?php
|
2497 |
-
$tabs->endTab();
|
2498 |
-
$tabs->endPane();
|
2499 |
-
?>
|
2500 |
-
<input type="hidden" name="option" value="com_cloner" />
|
2501 |
-
<input type="hidden" name="task" value="" />
|
2502 |
-
<input type="hidden" name="boxchecked" value="0" />
|
2503 |
-
<input type="hidden" name="hidemainmenu" value="0" />
|
2504 |
-
<?php wp_nonce_field('generate','csrf'); ?>
|
2505 |
-
</form>
|
2506 |
-
<br/>
|
2507 |
-
<?php
|
2508 |
-
}
|
2509 |
-
|
2510 |
-
|
2511 |
-
function generateBackup( $archiveName, $archiveSize, $originalSize, $d, $f, $databaseResult, $option ) {
|
2512 |
-
// ----------------------------------------------------------
|
2513 |
-
// Presentation of the final report screen
|
2514 |
-
// ----------------------------------------------------------
|
2515 |
-
|
2516 |
-
|
2517 |
-
?>
|
2518 |
-
<table cellpadding="4" cellspacing="0" border="0" width="100%">
|
2519 |
-
|
2520 |
-
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2521 |
-
</tr>
|
2522 |
-
<tr>
|
2523 |
-
<td width="20%"><strong> </strong></td><td> </td>
|
2524 |
-
</tr>
|
2525 |
-
<tr>
|
2526 |
-
<td><strong> <?php echo LM_ARCHIVE_NAME; ?></strong></td><td><?php echo $archiveName; ?></td>
|
2527 |
-
</tr>
|
2528 |
-
<tr>
|
2529 |
-
<td><strong> <?php echo LM_NUMBER_FILES; ?></strong></td><td><?php echo $f; ?></td>
|
2530 |
-
</tr>
|
2531 |
-
<tr>
|
2532 |
-
<td><strong> <?php echo LM_SIZE_ORIGINAL; ?></strong></td><td><?php echo $originalSize; ?></td>
|
2533 |
-
</tr>
|
2534 |
-
<tr>
|
2535 |
-
<td><strong> <?php echo LM_SIZE_ARCHIVE; ?></strong></td><td><?php echo $archiveSize; ?></td>
|
2536 |
-
</tr>
|
2537 |
-
<tr>
|
2538 |
-
<td><strong> <?php echo LM_DATABASE_ARCHIVE; ?></strong></td><td><?php echo $databaseResult; ?></td>
|
2539 |
-
</tr>
|
2540 |
-
|
2541 |
-
|
2542 |
-
<tr>
|
2543 |
-
<td><strong> </strong></td><td> </td>
|
2544 |
-
</tr>
|
2545 |
-
</table>
|
2546 |
-
<form action="" name="adminForm" method="post">
|
2547 |
-
<input type=hidden name=files[1] value='<?php echo $archiveName?>'>
|
2548 |
-
<input type=hidden name=cid[1] value='<?php echo $archiveName?>'>
|
2549 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2550 |
-
<input type="hidden" name="task" value=""/>
|
2551 |
-
</form>
|
2552 |
-
<?php
|
2553 |
-
}
|
2554 |
-
|
2555 |
-
function generateBackup_text( $archiveName, $archiveSize, $originalSize, $d, $f, $databaseResult, $option ) {
|
2556 |
-
// ----------------------------------------------------------
|
2557 |
-
// Presentation of the final report screen in text mode
|
2558 |
-
// ----------------------------------------------------------
|
2559 |
-
|
2560 |
-
ob_start();
|
2561 |
-
?>
|
2562 |
-
<?php echo LM_ARCHIVE_NAME; ?>: <?php echo $archiveName."\r\n"; ?><br />
|
2563 |
-
<?php echo LM_NUMBER_FILES; ?>: <?php echo $f."\r\n"; ?><br />
|
2564 |
-
<?php echo LM_SIZE_ORIGINAL; ?>: <?php echo $originalSize."\r\n"; ?><br />
|
2565 |
-
<?php echo LM_SIZE_ARCHIVE; ?>: <?php echo $archiveSize."\r\n"; ?><br />
|
2566 |
-
<?php echo LM_DATABASE_ARCHIVE; ?>: <?php echo $databaseResult."\r\n"; ?><br />
|
2567 |
-
### END REPORT
|
2568 |
-
<?php
|
2569 |
-
$content = ob_get_contents();
|
2570 |
-
ob_end_clean();
|
2571 |
-
|
2572 |
-
return $content;
|
2573 |
-
}
|
2574 |
-
|
2575 |
-
function showHelp( $option ) {
|
2576 |
-
?>
|
2577 |
-
<script>
|
2578 |
-
jQuery(function() {
|
2579 |
-
jQuery( "#tabs" ).tabs();
|
2580 |
-
});
|
2581 |
-
</script>
|
2582 |
-
|
2583 |
-
<div id="tabs" >
|
2584 |
-
<ul>
|
2585 |
-
<li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
|
2586 |
-
</ul>
|
2587 |
-
<div id="tabs-1" >
|
2588 |
-
<div class="mainText">
|
2589 |
-
|
2590 |
-
<?php echo LM_CLONER_ABOUT?>
|
2591 |
-
</div>
|
2592 |
-
</div>
|
2593 |
-
</div>
|
2594 |
-
<form action="" name="adminForm" method="post">
|
2595 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2596 |
-
<input type="hidden" name="task" value=""/>
|
2597 |
-
</form>
|
2598 |
-
<?php
|
2599 |
-
}
|
2600 |
-
|
2601 |
-
function Restore( $option ) {
|
2602 |
-
// ----------------------------------------------------------
|
2603 |
-
// Presentation of the Help Screem
|
2604 |
-
// ----------------------------------------------------------
|
2605 |
-
|
2606 |
-
?>
|
2607 |
-
|
2608 |
-
<script>
|
2609 |
-
jQuery(function() {
|
2610 |
-
jQuery( "#tabs" ).tabs();
|
2611 |
-
});
|
2612 |
-
</script>
|
2613 |
-
|
2614 |
-
<div id="tabs">
|
2615 |
-
<ul>
|
2616 |
-
<li><a href="#tabs-1"><?php echo LM_RESTORE_TOP?></a></li>
|
2617 |
-
</ul>
|
2618 |
-
<div id="tabs-1"><p class="mainText">
|
2619 |
-
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2620 |
-
<tr>
|
2621 |
-
<td>
|
2622 |
-
<?php echo LM_CLONER_RESTORE?>
|
2623 |
-
</td>
|
2624 |
-
</tr>
|
2625 |
-
</table>
|
2626 |
-
</p></div>
|
2627 |
-
</div>
|
2628 |
-
<form action="" name="adminForm" method="post">
|
2629 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2630 |
-
<input type="hidden" name="task" value=""/>
|
2631 |
-
</form>
|
2632 |
-
<?php
|
2633 |
-
}
|
2634 |
-
function showCredits( $option ) {
|
2635 |
-
// ----------------------------------------------------------
|
2636 |
-
// Presentation of the Help Screem
|
2637 |
-
// ----------------------------------------------------------
|
2638 |
-
|
2639 |
-
?>
|
2640 |
-
<script>
|
2641 |
-
jQuery(function() {
|
2642 |
-
jQuery( "#tabs" ).tabs();
|
2643 |
-
});
|
2644 |
-
</script>
|
2645 |
-
|
2646 |
-
<div id="tabs">
|
2647 |
-
<ul>
|
2648 |
-
<li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
|
2649 |
-
</ul>
|
2650 |
-
<div id="tabs-1"><p class="mainText">
|
2651 |
-
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2652 |
-
<tr>
|
2653 |
-
<td>
|
2654 |
-
<?echo LM_CLONER_CREDITS?>
|
2655 |
-
</td>
|
2656 |
-
</tr>
|
2657 |
-
</table>
|
2658 |
-
</p></div>
|
2659 |
-
</div>
|
2660 |
-
<form action="" name="adminForm" method="post">
|
2661 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2662 |
-
<input type="hidden" name="task" value=""/>
|
2663 |
-
</form>
|
2664 |
-
<?php
|
2665 |
-
}
|
2666 |
-
|
2667 |
-
|
2668 |
-
function Rename($files, $option){
|
2669 |
-
global $_CONFIG;
|
2670 |
-
|
2671 |
-
?>
|
2672 |
-
<form action="" method="post" name="adminForm">
|
2673 |
-
<table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
|
2674 |
-
<tr><th colspan='2'>
|
2675 |
-
<?php echo LM_RENAME_TOP?>
|
2676 |
-
</th></tr>
|
2677 |
-
<?php
|
2678 |
-
|
2679 |
-
foreach($files as $key=>$file){
|
2680 |
-
echo "<tr>
|
2681 |
-
<td >
|
2682 |
-
".LM_RENAME." <input type=hidden name='cfile[]' value='$file' ><b>$file</b>
|
2683 |
-
</td>
|
2684 |
-
<td align='left'>
|
2685 |
-
".LM_RENAME_TO." <input type=text name='dfile[]' value='$file' size=100>
|
2686 |
-
</td>
|
2687 |
-
</tr>";
|
2688 |
-
}
|
2689 |
-
|
2690 |
-
?>
|
2691 |
-
</table>
|
2692 |
-
<form action="" name="adminForm" method="post">
|
2693 |
-
<input type="hidden" name="option" value="<?php echo $option; ?>"/>
|
2694 |
-
<input type="hidden" name="task" value="rename_save"/>
|
2695 |
-
</form>
|
2696 |
-
|
2697 |
-
<?php
|
2698 |
-
}
|
2699 |
-
|
2700 |
-
}
|
2701 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.cloner.php
DELETED
@@ -1,215 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* admin.cloner.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
defined( '_VALID_MOS' ) or die( 'Restricted access' );
|
25 |
-
|
26 |
-
@set_time_limit("3600");
|
27 |
-
@error_reporting(E_ALL ^ E_NOTICE);
|
28 |
-
|
29 |
-
//load configuration
|
30 |
-
$config_file = __XCLONERDIR__."/cloner.config.php";
|
31 |
-
|
32 |
-
require_once($config_file);
|
33 |
-
|
34 |
-
require_once("restore/TAR.php");
|
35 |
-
require_once("cloner.functions.php");
|
36 |
-
require_once("admin.cloner.html.php");
|
37 |
-
require_once("common.php");
|
38 |
-
|
39 |
-
$option = "xcloner";
|
40 |
-
|
41 |
-
//###########GLOBALS in effect
|
42 |
-
$GLOBALS['lang_dir'] = $lang_dir;
|
43 |
-
//###########
|
44 |
-
$lang_array = get_avalaible_langs();
|
45 |
-
|
46 |
-
|
47 |
-
// retrieve row selection from forms
|
48 |
-
$cid = $_REQUEST['cid'];
|
49 |
-
if (!is_array($cid))
|
50 |
-
{
|
51 |
-
$cid = array(0);
|
52 |
-
}
|
53 |
-
|
54 |
-
if(!$_REQUEST['nohtml'])
|
55 |
-
{
|
56 |
-
if (($task != 'download') and (($_REQUEST['task']!="refresh") or (!$_CONFIG['refresh_mode']))){
|
57 |
-
//HTML_cloner::header();
|
58 |
-
$html = new HTML_cloner();
|
59 |
-
$html->header();
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
//########## SETTING THE GLOBALS VARIABLES #########################
|
64 |
-
|
65 |
-
$GLOBALS['joomla_compatible'] = $joomla_compatible;
|
66 |
-
|
67 |
-
$GLOBALS['_CONFIG'] = $_CONFIG;
|
68 |
-
|
69 |
-
$GLOBALS['clonerPath'] = $clonerPath;
|
70 |
-
|
71 |
-
$GLOBALS['baDownloadPath'] = $baDownloadPath;
|
72 |
-
|
73 |
-
$GLOBALS['config_file'] = $config_file;
|
74 |
-
|
75 |
-
$GLOBALS['lang_array'] = $lang_array;
|
76 |
-
|
77 |
-
openXLog();
|
78 |
-
|
79 |
-
// process the workflow selection
|
80 |
-
switch ($task) {
|
81 |
-
case 'rename_save':
|
82 |
-
case 'rename':
|
83 |
-
clone_rename($option);
|
84 |
-
break;
|
85 |
-
case 'action':
|
86 |
-
xclonerAction($option);
|
87 |
-
break;
|
88 |
-
|
89 |
-
|
90 |
-
case 'dropbox_authorize':
|
91 |
-
authorize_dropbox();
|
92 |
-
break;
|
93 |
-
|
94 |
-
case 'cancel_lang':
|
95 |
-
mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=lang");
|
96 |
-
break;
|
97 |
-
case 'add_lang':
|
98 |
-
case 'add_lang_new':
|
99 |
-
translator_add($option, $task);
|
100 |
-
break;
|
101 |
-
case 'save_lang_apply':
|
102 |
-
case 'save_lang':
|
103 |
-
case 'edit_lang':
|
104 |
-
translator_edit($option, $task);
|
105 |
-
break;
|
106 |
-
|
107 |
-
|
108 |
-
case 'del_lang':
|
109 |
-
case 'lang':
|
110 |
-
translator($option);
|
111 |
-
break;
|
112 |
-
|
113 |
-
case 'recurse_database';
|
114 |
-
goRecurseDatabases();
|
115 |
-
break;
|
116 |
-
|
117 |
-
case 'recurse_files':
|
118 |
-
goRecurseFiles();
|
119 |
-
break;
|
120 |
-
|
121 |
-
case 'cleanup':
|
122 |
-
include_once("classes/main.class.php");
|
123 |
-
$main = new Main();
|
124 |
-
$main->init($_CONFIG);
|
125 |
-
$main->cleanUp();
|
126 |
-
break;
|
127 |
-
|
128 |
-
case 'refresh':
|
129 |
-
generateBackuprefresh($cid, $option, $_REQUEST['backup'], $_CONFIG['refresh_mode']);
|
130 |
-
break;
|
131 |
-
|
132 |
-
case 'generate':
|
133 |
-
if ( empty($_POST) || !wp_verify_nonce($_POST['csrf'],'generate') ){
|
134 |
-
print 'Sorry, your nonce did not verify.';
|
135 |
-
exit;
|
136 |
-
}
|
137 |
-
|
138 |
-
if($_CONFIG['refresh_mode']){
|
139 |
-
$_REQUEST['mode'] = "start";
|
140 |
-
if($_CONFIG['enable_db_backup'])
|
141 |
-
goRecurseDatabases();
|
142 |
-
//initBackup($_REQUEST['bname']);
|
143 |
-
//break;
|
144 |
-
}
|
145 |
-
generateBackup($cid, $option);
|
146 |
-
break;
|
147 |
-
|
148 |
-
case 'confirm':
|
149 |
-
deleteXLog();
|
150 |
-
confirmBackup($option);
|
151 |
-
break;
|
152 |
-
case 'download':
|
153 |
-
$file = pathinfo($_REQUEST['file']);
|
154 |
-
downloadBackup($file['basename']);
|
155 |
-
break;
|
156 |
-
case 'cron':
|
157 |
-
$html->Cron();
|
158 |
-
break;
|
159 |
-
case 'about':
|
160 |
-
case 'credits':
|
161 |
-
showHelp($option);
|
162 |
-
break;
|
163 |
-
case 'restore':
|
164 |
-
$html->Restore($option);
|
165 |
-
break;
|
166 |
-
|
167 |
-
case 'cron_delete':
|
168 |
-
$fconfig = basename($_REQUEST['fconfig']);
|
169 |
-
if (unlink($_CONFIG['multiple_config_dir'] . "/" . $fconfig))
|
170 |
-
$msg = " was deleted";
|
171 |
-
else
|
172 |
-
$msg = " was not deleted, please delete it manually!";
|
173 |
-
|
174 |
-
mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=config", $_REQUEST['fconfig'] . $msg);
|
175 |
-
break;
|
176 |
-
|
177 |
-
case 'delete':
|
178 |
-
case 'remove':
|
179 |
-
deleteBackups($cid, $option);
|
180 |
-
break;
|
181 |
-
case 'continue':
|
182 |
-
case 'move':
|
183 |
-
case 'clone':
|
184 |
-
moveBackup($option);
|
185 |
-
break;
|
186 |
-
|
187 |
-
case 'cancel':
|
188 |
-
mosRedirect('plugins.php?page=xcloner_show&option=' . $option);
|
189 |
-
break;
|
190 |
-
case 'config':
|
191 |
-
config($option);
|
192 |
-
break;
|
193 |
-
case 'rename_cancel':
|
194 |
-
mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=view");
|
195 |
-
break;
|
196 |
-
case 'show':
|
197 |
-
case 'view':
|
198 |
-
showBackups($option);
|
199 |
-
break;
|
200 |
-
case 'logout':
|
201 |
-
doLogout();
|
202 |
-
break;
|
203 |
-
default:
|
204 |
-
fdefault();
|
205 |
-
break;
|
206 |
-
}
|
207 |
-
|
208 |
-
closeXLog();
|
209 |
-
|
210 |
-
if(!$_REQUEST['nohtml'])
|
211 |
-
{
|
212 |
-
$html->footer();
|
213 |
-
}
|
214 |
-
|
215 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/assets/database-icon.png
ADDED
Binary file
|
admin/assets/file-icon-d.png
ADDED
Binary file
|
admin/assets/file-icon-f.png
ADDED
Binary file
|
admin/assets/file-icon-l.png
ADDED
Binary file
|
admin/assets/file-icon-root.png
ADDED
Binary file
|
admin/assets/table-icon.png
ADDED
Binary file
|
admin/class-xcloner-admin.php
ADDED
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The admin-specific functionality of the plugin.
|
5 |
+
*
|
6 |
+
* @link http://www.thinkovi.com
|
7 |
+
* @since 1.0.0
|
8 |
+
*
|
9 |
+
* @package Xcloner
|
10 |
+
* @subpackage Xcloner/admin
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* The admin-specific functionality of the plugin.
|
15 |
+
*
|
16 |
+
* Defines the plugin name, version, and two examples hooks for how to
|
17 |
+
* enqueue the admin-specific stylesheet and JavaScript.
|
18 |
+
*
|
19 |
+
* @package Xcloner
|
20 |
+
* @subpackage Xcloner/admin
|
21 |
+
* @author Liuta Ovidiu <info@thinkovi.com>
|
22 |
+
*/
|
23 |
+
class Xcloner_Admin {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* The ID of this plugin.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @access private
|
30 |
+
* @var string $plugin_name The ID of this plugin.
|
31 |
+
*/
|
32 |
+
private $plugin_name;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* The version of this plugin.
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @access private
|
39 |
+
* @var string $version The current version of this plugin.
|
40 |
+
*/
|
41 |
+
private $version;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Initialize the class and set its properties.
|
45 |
+
*
|
46 |
+
* @since 1.0.0
|
47 |
+
* @param string $plugin_name The name of this plugin.
|
48 |
+
* @param string $version The version of this plugin.
|
49 |
+
*/
|
50 |
+
public function __construct( $plugin_name, $version ) {
|
51 |
+
|
52 |
+
$this->plugin_name = $plugin_name;
|
53 |
+
$this->version = $version;
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Register the stylesheets for the admin area.
|
59 |
+
*
|
60 |
+
* @since 1.0.0
|
61 |
+
*/
|
62 |
+
public function enqueue_styles($hook) {
|
63 |
+
|
64 |
+
if(!stristr($hook, "page_".$this->plugin_name) || (isset($_GET['option']) and $_GET['option']=="com_cloner"))
|
65 |
+
return;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* This function is provided for demonstration purposes only.
|
69 |
+
*
|
70 |
+
* An instance of this class should be passed to the run() function
|
71 |
+
* defined in Xcloner_Loader as all of the hooks are defined
|
72 |
+
* in that particular class.
|
73 |
+
*
|
74 |
+
* The Xcloner_Loader will then create the relationship
|
75 |
+
* between the defined hooks and the functions defined in this
|
76 |
+
* class.
|
77 |
+
*/
|
78 |
+
|
79 |
+
wp_enqueue_style( $this->plugin_name."_materialize", plugin_dir_url( __FILE__ ) . 'css/materialize.min.css', array(), $this->version, 'all' );
|
80 |
+
wp_enqueue_style( $this->plugin_name."_materialize.clockpicker", plugin_dir_url( __FILE__ ) . 'css/materialize.clockpicker.css', array(), $this->version, 'all' );
|
81 |
+
wp_enqueue_style( $this->plugin_name."_materialize.icons", '//fonts.googleapis.com/icon?family=Material+Icons', array(), $this->version, 'all' );
|
82 |
+
wp_enqueue_style( $this->plugin_name."_jquery.datatables", plugin_dir_url( __FILE__ ) . 'css/jquery.dataTables.min.css', array(), $this->version, 'all' );
|
83 |
+
wp_enqueue_style( $this->plugin_name."_jquery.datatables.responsive", plugin_dir_url( __FILE__ ) . 'css/responsive.dataTables.css', array(), $this->version, 'all' );
|
84 |
+
wp_enqueue_style( $this->plugin_name."_jstree", dirname(plugin_dir_url( __FILE__ )) . '/vendor/vakata/jstree/dist/themes/default/style.min.css', array(), '3.3', 'all' );
|
85 |
+
wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/xcloner-admin.css', array(), $this->version, 'all' );
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Register the JavaScript for the admin area.
|
91 |
+
*
|
92 |
+
* @since 1.0.0
|
93 |
+
*/
|
94 |
+
public function enqueue_scripts($hook) {
|
95 |
+
|
96 |
+
if(!stristr($hook, "page_".$this->plugin_name))
|
97 |
+
return;
|
98 |
+
|
99 |
+
/**
|
100 |
+
* This function is provided for demonstration purposes only.
|
101 |
+
*
|
102 |
+
* An instance of this class should be passed to the run() function
|
103 |
+
* defined in Xcloner_Loader as all of the hooks are defined
|
104 |
+
* in that particular class.
|
105 |
+
*
|
106 |
+
* The Xcloner_Loader will then create the relationship
|
107 |
+
* between the defined hooks and the functions defined in this
|
108 |
+
* class.
|
109 |
+
*/
|
110 |
+
|
111 |
+
wp_enqueue_script( $this->plugin_name."_materialize", plugin_dir_url( __FILE__ ) . 'js/materialize.min.js', array( 'jquery' ), $this->version, false );
|
112 |
+
wp_enqueue_script( $this->plugin_name."_materialize.clockpicker", plugin_dir_url( __FILE__ ) . 'js/materialize.clockpicker.js', array( 'jquery' ), $this->version, false );
|
113 |
+
wp_enqueue_script( $this->plugin_name."_jquery.datatables", plugin_dir_url( __FILE__ ) . 'js/jquery.dataTables.min.js', array( 'jquery' ), $this->version, false );
|
114 |
+
wp_enqueue_script( $this->plugin_name."_jquery.datatables.respnsive", plugin_dir_url( __FILE__ ) . 'js/dataTables.responsive.js', array( 'jquery' ), $this->version, false );
|
115 |
+
wp_enqueue_script( $this->plugin_name."_vakata", dirname(plugin_dir_url( __FILE__ )) . '/vendor/vakata/jstree/dist/jstree.min.js', array( 'jquery' ), '3.3', false );
|
116 |
+
wp_enqueue_script( $this->plugin_name."_xcloner-backup-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-backup-class.js', array( 'jquery' ), $this->version, false );
|
117 |
+
wp_enqueue_script( $this->plugin_name."_xcloner-scheduler-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-scheduler-class.js', array( 'jquery' ), $this->version, false );
|
118 |
+
wp_enqueue_script( $this->plugin_name."_xcloner-restore-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-restore-class.js', array( 'jquery' ), $this->version, false );
|
119 |
+
wp_enqueue_script( $this->plugin_name."_xcloner-manage-backups-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-manage-backups-class.js', array( 'jquery' ), $this->version, false );
|
120 |
+
wp_enqueue_script( $this->plugin_name."_xcloner-remote-storage-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-remote-storage-class.js', array( 'jquery' ), $this->version, false );
|
121 |
+
wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/xcloner-admin.js', array( 'jquery' ), $this->version, false );
|
122 |
+
|
123 |
+
|
124 |
+
}
|
125 |
+
|
126 |
+
public function xcloner_init_page()
|
127 |
+
{
|
128 |
+
require_once("partials/xcloner_init_page.php");
|
129 |
+
|
130 |
+
}
|
131 |
+
|
132 |
+
public function xcloner_remote_storage_page()
|
133 |
+
{
|
134 |
+
if(isset($_POST['action']))
|
135 |
+
{
|
136 |
+
$remote_storage = new Xcloner_Remote_Storage();
|
137 |
+
$remote_storage->save($_POST['action']);
|
138 |
+
}
|
139 |
+
require_once("partials/xcloner_remote_storage_page.php");
|
140 |
+
|
141 |
+
}
|
142 |
+
|
143 |
+
public function xcloner_scheduled_backups_page()
|
144 |
+
{
|
145 |
+
$requirements = new XCloner_Requirements();
|
146 |
+
if(!$requirements->check_backup_ready_status())
|
147 |
+
{
|
148 |
+
require_once("partials/xcloner_init_page.php");
|
149 |
+
return false;
|
150 |
+
}
|
151 |
+
|
152 |
+
require_once("partials/xcloner_scheduled_backups_page.php");
|
153 |
+
|
154 |
+
}
|
155 |
+
|
156 |
+
public function xcloner_manage_backups_page()
|
157 |
+
{
|
158 |
+
require_once("partials/xcloner_manage_backups_page.php");
|
159 |
+
|
160 |
+
}
|
161 |
+
|
162 |
+
public function xcloner_debugger_page()
|
163 |
+
{
|
164 |
+
require_once("partials/xcloner_console_page.php");
|
165 |
+
|
166 |
+
}
|
167 |
+
|
168 |
+
public function xcloner_restore_page()
|
169 |
+
{
|
170 |
+
require_once("partials/xcloner_restore_page.php");
|
171 |
+
|
172 |
+
}
|
173 |
+
|
174 |
+
public function xcloner_generate_backups_page()
|
175 |
+
{
|
176 |
+
$requirements = new XCloner_Requirements();
|
177 |
+
if(!$requirements->check_backup_ready_status())
|
178 |
+
{
|
179 |
+
require_once("partials/xcloner_init_page.php");
|
180 |
+
return false;
|
181 |
+
}
|
182 |
+
|
183 |
+
require_once("partials/xcloner_generate_backups_page.php");
|
184 |
+
return;
|
185 |
+
}
|
186 |
+
|
187 |
+
public function xcloner_settings_page()
|
188 |
+
{
|
189 |
+
// check user capabilities
|
190 |
+
if (!current_user_can('manage_options')) {
|
191 |
+
return;
|
192 |
+
}
|
193 |
+
|
194 |
+
// add error/update messages
|
195 |
+
|
196 |
+
// check if the user have submitted the settings
|
197 |
+
// wordpress will add the "settings-updated" $_GET parameter to the url
|
198 |
+
if (isset($_GET['settings-updated'])) {
|
199 |
+
// add settings saved message with the class of "updated"
|
200 |
+
add_settings_error('wporg_messages', 'wporg_message', __('Settings Saved', 'wporg'), 'updated');
|
201 |
+
}
|
202 |
+
|
203 |
+
// show error/update messages
|
204 |
+
settings_errors('wporg_messages');
|
205 |
+
?>
|
206 |
+
|
207 |
+
<?php
|
208 |
+
if( isset( $_GET[ 'tab' ] ) ) {
|
209 |
+
$active_tab = $_GET[ 'tab' ];
|
210 |
+
} // end if
|
211 |
+
else{
|
212 |
+
$active_tab = "general_options";
|
213 |
+
}
|
214 |
+
|
215 |
+
?>
|
216 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
217 |
+
|
218 |
+
<ul class="nav-tab-wrapper row">
|
219 |
+
<li><a href="?page=xcloner_settings_page&tab=general_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'general_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('General Options', 'xcloner-backup-and-restore')?></a></li>
|
220 |
+
<li><a href="?page=xcloner_settings_page&tab=mysql_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'mysql_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Mysql Options', 'xcloner-backup-and-restore')?></a></li>
|
221 |
+
<li><a href="?page=xcloner_settings_page&tab=system_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'system_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('System Options', 'xcloner-backup-and-restore')?></a></li>
|
222 |
+
<li><a href="?page=xcloner_settings_page&tab=cleanup_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cleanup_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Cleanup Options', 'xcloner-backup-and-restore')?></a></li>
|
223 |
+
<!--<li><a href="?page=xcloner_settings_page&tab=cron_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cron_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Cron Options', 'xcloner-backup-and-restore')?></a></li>
|
224 |
+
-->
|
225 |
+
</ul>
|
226 |
+
|
227 |
+
<div class="wrap">
|
228 |
+
|
229 |
+
<form action="options.php" method="post">
|
230 |
+
<?php
|
231 |
+
|
232 |
+
if( $active_tab == 'general_options' ) {
|
233 |
+
|
234 |
+
settings_fields('xcloner_general_settings_group');
|
235 |
+
do_settings_sections('xcloner_settings_page');
|
236 |
+
|
237 |
+
}elseif( $active_tab == 'mysql_options' ) {
|
238 |
+
|
239 |
+
settings_fields('xcloner_mysql_settings_group');
|
240 |
+
do_settings_sections('xcloner_mysql_settings_page');
|
241 |
+
}elseif( $active_tab == 'system_options' ) {
|
242 |
+
|
243 |
+
settings_fields('xcloner_system_settings_group');
|
244 |
+
do_settings_sections('xcloner_system_settings_page');
|
245 |
+
}elseif( $active_tab == 'cleanup_options' ) {
|
246 |
+
|
247 |
+
settings_fields('xcloner_cleanup_settings_group');
|
248 |
+
do_settings_sections('xcloner_cleanup_settings_page');
|
249 |
+
}/*else{
|
250 |
+
|
251 |
+
settings_fields('xcloner_cron_settings_group');
|
252 |
+
do_settings_sections('xcloner_cron_settings_page');
|
253 |
+
}*/
|
254 |
+
|
255 |
+
// output save settings button
|
256 |
+
submit_button('Save Settings');
|
257 |
+
?>
|
258 |
+
</form>
|
259 |
+
|
260 |
+
</div>
|
261 |
+
<?php
|
262 |
+
|
263 |
+
}
|
264 |
+
|
265 |
+
}
|
admin/css/jquery.dataTables.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;*cursor:hand}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}}
|
admin/css/materialize.clockpicker.css
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.shades.black{background-color:#000 !important}.shades-text.text-black{color:#000 !important}.shades.white{background-color:#fff !important}.shades-text.text-white{color:#fff !important}.shades.transparent{background-color:transparent !important}.shades-text.text-transparent{color:transparent !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*!
|
2 |
+
* ClockPicker v0.0.7 for jQuery (http://weareoutman.github.io/clockpicker/)
|
3 |
+
* Copyright 2014 Wang Shenwei.
|
4 |
+
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
|
5 |
+
*
|
6 |
+
* Further modified
|
7 |
+
* Copyright 2015 Ching Yaw Hao.
|
8 |
+
*
|
9 |
+
* Bootstrap v3.1.1 (http://getbootstrap.com)
|
10 |
+
* Copyright 2011-2014 Twitter, Inc.
|
11 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
12 |
+
*/.picker__box{background:#fff}.picker__date-display{background-color:#26a69a}.clockpicker-display{vertical-align:middle;display:inline-block;margin:auto;height:85px;font-size:70px;padding:10px;padding-bottom:0px;color:#b2dfdb}.clockpicker-display-column{float:left}.clockpicker-display-am-pm{padding-left:5px;vertical-align:bottom;height:85px}.clockpicker-span-am-pm{display:inline-block;font-size:23px;line-height:25px;color:#b2dfdb}.clockpicker-span-hours,.clockpicker-span-minutes{-webkit-animation-duration:500ms;animation-duration:500ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-transition:color 500ms;-moz-transition:color 500ms;-ms-transition:color 500ms;-o-transition:color 500ms;transition:color 500ms;cursor:pointer}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-webkit-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-moz-keyframes pulse{from{-moz-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-moz-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-moz-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-ms-keyframes pulse{from{-ms-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-ms-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-ms-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-o-keyframes pulse{from{-o-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-o-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-o-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@keyframes pulse{from{transform:scale3d(1, 1, 1)}50%{transform:scale3d(1.1, 1.1, 1.1)}to{transform:scale3d(1, 1, 1)}}#click-am,#click-pm{cursor:pointer}.clockpicker-span-hours.text-primary,.clockpicker-span-minutes.text-primary,#click-am.text-primary,#click-pm.text-primary{-webkit-animation-name:pulse;animation-name:pulse;color:white}.clockpicker-moving{cursor:move}.clockpicker-plate{background-color:#eeeeee;border-radius:50%;width:270px;height:270px;overflow:visible;position:relative;margin:auto;margin-top:20px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.clockpicker-canvas,.clockpicker-dial{width:270px;height:270px;position:absolute;left:-1px;top:-1px}.clockpicker-minutes{visibility:hidden}.clockpicker-tick{border-radius:50%;color:#666;line-height:40px;text-align:center;width:40px;height:40px;position:absolute;cursor:pointer;-webkit-transition:background-color 300ms;-moz-transition:background-color 300ms;-ms-transition:background-color 300ms;-o-transition:background-color 300ms;transition:background-color 300ms;background-color:rgba(0,150,136,0)}.clockpicker-tick.active,.clockpicker-tick:hover{background-color:rgba(0,150,136,0.25)}.clockpicker-dial{-webkit-transition:-webkit-transform 350ms, opacity 350ms;-moz-transition:-moz-transform 350ms, opacity 350ms;-ms-transition:-ms-transform 350ms, opacity 350ms;-o-transition:-o-transform 350ms, opacity 350ms;transition:transform 350ms, opacity 350ms}.clockpicker-dial-out{opacity:0}.clockpicker-hours.clockpicker-dial-out{-webkit-transform:scale(1.2, 1.2);-moz-transform:scale(1.2, 1.2);-ms-transform:scale(1.2, 1.2);-o-transform:scale(1.2, 1.2);transform:scale(1.2, 1.2)}.clockpicker-minutes.clockpicker-dial-out{-webkit-transform:scale(0.8, 0.8);-moz-transform:scale(0.8, 0.8);-ms-transform:scale(0.8, 0.8);-o-transform:scale(0.8, 0.8);transform:scale(0.8, 0.8)}.clockpicker-canvas{-webkit-transition:opacity 300ms;-moz-transition:opacity 300ms;-ms-transition:opacity 300ms;-o-transition:opacity 300ms;transition:opacity 300ms}.clockpicker-canvas-out{opacity:0.25}.clockpicker-canvas-bearing{stroke:none;fill:rgba(0,77,64,0.75)}.clockpicker-canvas-fg{stroke:none;fill:rgba(0,77,64,0)}.clockpicker-canvas-fg.active{fill:rgba(0,77,64,0.5)}.clockpicker-canvas-bg{stroke:none;fill:rgba(0,150,136,0.25)}.clockpicker-canvas-bg-trans{fill:rgba(0,150,136,0.25)}.clockpicker-canvas line{stroke:rgba(0,150,136,0.25);stroke-width:1;stroke-linecap:round}.clockpicker-am-pm-block{margin-top:-10px;width:100%;height:50px}.clockpicker-button.am-button{height:45px;width:45px;float:left}.clockpicker-button.pm-button{height:45px;width:45px;float:right}button{color:#343434}.btn-floating.btn-flat:focus,.btn-floating.btn-flat:visited{background-color:transparent}.btn-floating.btn-flat:hover{box-shadow:none;background-color:transparent}.btn-floating.btn-flat.active{background-color:rgba(0,150,136,0.25)}.btn-floating.btn-flat:active{background-color:rgba(0,150,136,0.5)}.picker__footer .clockpicker-button{margin:auto;margin-top:15px}.picker__footer .clockpicker-button:focus{background-color:transparent}.picker__footer .clockpicker-button:active{background-color:rgba(0,150,136,0.25)}/*!
|
13 |
+
* ClockPicker v0.0.7 for jQuery (http://weareoutman.github.io/clockpicker/)
|
14 |
+
* Copyright 2014 Wang Shenwei.
|
15 |
+
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
|
16 |
+
*
|
17 |
+
* Further modified
|
18 |
+
* Copyright 2015 Ching Yaw Hao.
|
19 |
+
*
|
20 |
+
* Bootstrap v3.1.1 (http://getbootstrap.com)
|
21 |
+
* Copyright 2011-2014 Twitter, Inc.
|
22 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
23 |
+
*/.darktheme .picker__box{background-color:#212121}.darktheme .picker__date-display{background-color:transparent}.darktheme .clockpicker-display{color:white}.darktheme .clockpicker-span-am-pm{color:white}.darktheme .clockpicker-span-hours.text-primary,.darktheme .clockpicker-span-minutes.text-primary,.darktheme #click-am.text-primary,.darktheme #click-pm.text-primary{color:#ff4081}.darktheme .clockpicker-plate{background-color:transparent}.darktheme .clockpicker-tick{color:white;background-color:rgba(255,64,129,0)}.darktheme .clockpicker-tick.active,.darktheme .clockpicker-tick:hover{background-color:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas-bearing{fill:white}.darktheme .clockpicker-canvas-fg{fill:rgba(255,64,129,0)}.darktheme .clockpicker-canvas-fg.active{fill:rgba(255,64,129,0.5)}.darktheme .clockpicker-canvas-bg{fill:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas-bg-trans{fill:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas line{stroke:rgba(255,64,129,0.25)}.darktheme button{color:white}.darktheme .btn-floating.btn-flat.active{background-color:rgba(255,64,129,0.25)}.darktheme .btn-floating.btn-flat:active{background-color:rgba(255,64,129,0.5)}.darktheme .picker__footer .clockpicker-button:active{background-color:rgba(255,64,129,0.25)}
|
24 |
+
|
25 |
+
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2Jvd2VyX2NvbXBvbmVudHMvTWF0ZXJpYWxpemUvc2Fzcy9jb21wb25lbnRzL19jb2xvci5zY3NzIiwiY29tcG9uZW50cy9fcHJpbWFyeS5zY3NzIiwiY29tcG9uZW50cy9fdmFyaWFibGVzLnNjc3MiLCIuLi8uLi9ib3dlcl9jb21wb25lbnRzL01hdGVyaWFsaXplL3Nhc3MvY29tcG9uZW50cy9fdmFyaWFibGVzLnNjc3MiLCJjb21wb25lbnRzL19kYXJrLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaVhNLGdCQUFBLEFBQWdCLENBQ2QsZ0JBQWdCLENBeFdSLE9BQU8sQ0F3V2dCLFVBQVUsQ0FDMUMsQUFDRCxxQkFBQSxBQUFxQixDQUNuQixLQUFLLENBM1dHLE9BQU8sQ0EyV0ssVUFBVSxDQUMvQixBQUdELGdCQUFnQixVQUFoQixBQUEwQixDQUN4QixnQkFBZ0IsQ0EvV1IsT0FBTyxDQStXZ0IsVUFBVSxDQUMxQyxBQUNELHFCQUFxQixlQUFyQixBQUFvQyxDQUNsQyxLQUFLLENBbFhHLE9BQU8sQ0FrWEssVUFBVSxDQUpoQyxBQUtDLGdCQUxlLFVBQWhCLEFBQTBCLENBQ3hCLGdCQUFnQixDQTlXUixPQUFPLENBOFdnQixVQUFVLENBQzFDLEFBQ0QscUJBQXFCLGVBQXJCLEFBQW9DLENBQ2xDLEtBQUssQ0FqWEcsT0FBTyxDQWlYSyxVQUFVLENBSmhDLEFBS0MsZ0JBTGUsVUFBaEIsQUFBMEIsQ0FDeEIsZ0JBQWdCLENBN1dSLE9BQU8sQ0E2V2dCLFVBQVUsQ0FDMUMsQUFDRCxxQkFBcUIsZUFBckIsQUFBb0MsQ0FDbEMsS0FBSyxDQWhYRyxPQUFPLENBZ1hLLFVBQVUsQ0FKaEMsQUFLQyxnQkFMZSxVQUFoQixBQUEwQixDQUN4QixnQkFBZ0IsQ0E1V1IsT0FBTyxDQTRXZ0IsVUFBVSxDQUMxQyxBQUNELHFCQUFxQixlQUFyQixBQUFvQyxDQUNsQyxLQUFLLENBL1dHLE9BQU8sQ0ErV0ssVUFBVSxDQUpoQyxBQUtDLGdCQUxl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QUMsSUFBSSxBQUFDLENBQ3JCLE1BQU0sQ0FBRSxxQkFBSSxDQTdEcEIsQUE4REssVUE5REssQ0FnRU4sTUFBTSxBQUFDLENBQ0gsS0FBSyxDQUFFLEtBQU0sQ0FqRXJCLEFBa0VLLFVBbEVLLENBb0VOLGFBQWEsU0FBUyxPQUFPLEFBQUMsQ0FDMUIsZ0JBQWdCLENBQUUscUJBQUksQ0FyRTlCLEFBc0VLLFVBdEVLLENBd0VOLGFBQWEsU0FBUyxPQUFPLEFBQUMsQ0FDMUIsZ0JBQWdCLENBQUUsb0JBQUksQ0F6RTlCLEFBMEVLLFVBMUVLLENBNEVOLGVBQWUsQ0FBQyxtQkFBbUIsT0FBTyxBQUFDLENBQ3ZDLGdCQUFnQixDQUFFLHFCQUFJLENBQ3pCIiwiZmlsZSI6Im1hdGVyaWFsaXplLmNsb2NrcGlja2VyLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFV0aWxpdHkgQ29sb3IgQ2xhc3Nlc1xuXG4vLy5zdWNjZXNzIHtcbi8vXG4vL31cblxuLy8gR29vZ2xlIENvbG9yIFBhbGV0dGUgZGVmaW5lZDogaHR0cDovL3d3dy5nb29nbGUuY29tL2Rlc2lnbi9zcGVjL3N0eWxlL2NvbG9yLmh0bWxcblxuXG4kbWF0ZXJpYWxpemUtcmVkOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjZTUxYzIzLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2ZkZWFlYixcbiAgXCJsaWdodGVuLTRcIjogICNmOGMxYzMsXG4gIFwibGlnaHRlbi0zXCI6ICAjZjM5ODliLFxuICBcImxpZ2h0ZW4tMlwiOiAgI2VlNmU3MyxcbiAgXCJsaWdodGVuLTFcIjogICNlYTQ1NGIsXG4gIFwiZGFya2VuLTFcIjogICAjZDAxODFlLFxuICBcImRhcmtlbi0yXCI6ICAgI2I5MTUxYixcbiAgXCJkYXJrZW4tM1wiOiAgICNhMjEzMTgsXG4gIFwiZGFya2VuLTRcIjogICAjOGIxMDE0LFxuKTtcblxuJHJlZDogKFxuICBcImJhc2VcIjogICAgICAgI0Y0NDMzNixcbiAgXCJsaWdodGVuLTVcIjogICNGRkVCRUUsXG4gIFwibGlnaHRlbi00XCI6ICAjRkZDREQyLFxuICBcImxpZ2h0ZW4tM1wiOiAgI0VGOUE5QSxcbiAgXCJsaWdodGVuLTJcIjogICNFNTczNzMsXG4gIFwibGlnaHRlbi0xXCI6ICAjRUY1MzUwLFxuICBcImRhcmtlbi0xXCI6ICAgI0U1MzkzNSxcbiAgXCJkYXJrZW4tMlwiOiAgICNEMzJGMkYsXG4gIFwiZGFya2VuLTNcIjogICAjQzYyODI4LFxuICBcImRhcmtlbi00XCI6ICAgI0I3MUMxQyxcbiAgXCJhY2NlbnQtMVwiOiAgICAjRkY4QTgwLFxuICBcImFjY2VudC0yXCI6ICAgICNGRjUyNTIsXG4gIFwiYWNjZW50LTNcIjogICAgI0ZGMTc0NCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjRDUwMDAwXG4pO1xuXG4kcGluazogKFxuICBcImJhc2VcIjogICAgICAgI2U5MWU2MyxcbiAgXCJsaWdodGVuLTVcIjogICNmY2U0ZWMsXG4gIFwibGlnaHRlbi00XCI6ICAjZjhiYmQwLFxuICBcImxpZ2h0ZW4tM1wiOiAgI2Y0OGZiMSxcbiAgXCJsaWdodGVuLTJcIjogICNmMDYyOTIsXG4gIFwibGlnaHRlbi0xXCI6ICAjZWM0MDdhLFxuICBcImRhcmtlbi0xXCI6ICAgI2Q4MWI2MCxcbiAgXCJkYXJrZW4tMlwiOiAgICNjMjE4NWIsXG4gIFwiZGFya2VuLTNcIjogICAjYWQxNDU3LFxuICBcImRhcmtlbi00XCI6ICAgIzg4MGU0ZixcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmY4MGFiLFxuICBcImFjY2VudC0yXCI6ICAgICNmZjQwODEsXG4gIFwiYWNjZW50LTNcIjogICAgI2Y1MDA1NyxcbiAgXCJhY2NlbnQtNFwiOiAgICAjYzUxMTYyXG4pO1xuXG4kcHVycGxlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjOWMyN2IwLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2YzZTVmNSxcbiAgXCJsaWdodGVuLTRcIjogICNlMWJlZTcsXG4gIFwibGlnaHRlbi0zXCI6ICAjY2U5M2Q4LFxuICBcImxpZ2h0ZW4tMlwiOiAgI2JhNjhjOCxcbiAgXCJsaWdodGVuLTFcIjogICNhYjQ3YmMsXG4gIFwiZGFya2VuLTFcIjogICAjOGUyNGFhLFxuICBcImRhcmtlbi0yXCI6ICAgIzdiMWZhMixcbiAgXCJkYXJrZW4tM1wiOiAgICM2YTFiOWEsXG4gIFwiZGFya2VuLTRcIjogICAjNGExNDhjLFxuICBcImFjY2VudC0xXCI6ICAgICNlYTgwZmMsXG4gIFwiYWNjZW50LTJcIjogICAgI2UwNDBmYixcbiAgXCJhY2NlbnQtM1wiOiAgICAjZDUwMGY5LFxuICBcImFjY2VudC00XCI6ICAgICNhYTAwZmZcbik7XG5cbiRkZWVwLXB1cnBsZTogKFxuICBcImJhc2VcIjogICAgICAgIzY3M2FiNyxcbiAgXCJsaWdodGVuLTVcIjogICNlZGU3ZjYsXG4gIFwibGlnaHRlbi00XCI6ICAjZDFjNGU5LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2IzOWRkYixcbiAgXCJsaWdodGVuLTJcIjogICM5NTc1Y2QsXG4gIFwibGlnaHRlbi0xXCI6ICAjN2U1N2MyLFxuICBcImRhcmtlbi0xXCI6ICAgIzVlMzViMSxcbiAgXCJkYXJrZW4tMlwiOiAgICM1MTJkYTgsXG4gIFwiZGFya2VuLTNcIjogICAjNDUyN2EwLFxuICBcImRhcmtlbi00XCI6ICAgIzMxMWI5MixcbiAgXCJhY2NlbnQtMVwiOiAgICAjYjM4OGZmLFxuICBcImFjY2VudC0yXCI6ICAgICM3YzRkZmYsXG4gIFwiYWNjZW50LTNcIjogICAgIzY1MWZmZixcbiAgXCJhY2NlbnQtNFwiOiAgICAjNjIwMGVhXG4pO1xuXG4kaW5kaWdvOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjM2Y1MWI1LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2U4ZWFmNixcbiAgXCJsaWdodGVuLTRcIjogICNjNWNhZTksXG4gIFwibGlnaHRlbi0zXCI6ICAjOWZhOGRhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzc5ODZjYixcbiAgXCJsaWdodGVuLTFcIjogICM1YzZiYzAsXG4gIFwiZGFya2VuLTFcIjogICAjMzk0OWFiLFxuICBcImRhcmtlbi0yXCI6ICAgIzMwM2Y5ZixcbiAgXCJkYXJrZW4tM1wiOiAgICMyODM1OTMsXG4gIFwiZGFya2VuLTRcIjogICAjMWEyMzdlLFxuICBcImFjY2VudC0xXCI6ICAgICM4YzllZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzUzNmRmZSxcbiAgXCJhY2NlbnQtM1wiOiAgICAjM2Q1YWZlLFxuICBcImFjY2VudC00XCI6ICAgICMzMDRmZmVcbik7XG5cbiRibHVlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMjE5NkYzLFxuICBcImxpZ2h0ZW4tNVwiOiAgI0UzRjJGRCxcbiAgXCJsaWdodGVuLTRcIjogICNCQkRFRkIsXG4gIFwibGlnaHRlbi0zXCI6ICAjOTBDQUY5LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzY0QjVGNixcbiAgXCJsaWdodGVuLTFcIjogICM0MkE1RjUsXG4gIFwiZGFya2VuLTFcIjogICAjMUU4OEU1LFxuICBcImRhcmtlbi0yXCI6ICAgIzE5NzZEMixcbiAgXCJkYXJrZW4tM1wiOiAgICMxNTY1QzAsXG4gIFwiZGFya2VuLTRcIjogICAjMEQ0N0ExLFxuICBcImFjY2VudC0xXCI6ICAgICM4MkIxRkYsXG4gIFwiYWNjZW50LTJcIjogICAgIzQ0OEFGRixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMjk3OUZGLFxuICBcImFjY2VudC00XCI6ICAgICMyOTYyRkZcbik7XG5cbiRsaWdodC1ibHVlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDNhOWY0LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UxZjVmZSxcbiAgXCJsaWdodGVuLTRcIjogICNiM2U1ZmMsXG4gIFwibGlnaHRlbi0zXCI6ICAjODFkNGZhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRmYzNmNyxcbiAgXCJsaWdodGVuLTFcIjogICMyOWI2ZjYsXG4gIFwiZGFya2VuLTFcIjogICAjMDM5YmU1LFxuICBcImRhcmtlbi0yXCI6ICAgIzAyODhkMSxcbiAgXCJkYXJrZW4tM1wiOiAgICMwMjc3YmQsXG4gIFwiZGFya2VuLTRcIjogICAjMDE1NzliLFxuICBcImFjY2VudC0xXCI6ICAgICM4MGQ4ZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzQwYzRmZixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMDBiMGZmLFxuICBcImFjY2VudC00XCI6ICAgICMwMDkxZWFcbik7XG5cbiRjeWFuOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDBiY2Q0LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UwZjdmYSxcbiAgXCJsaWdodGVuLTRcIjogICNiMmViZjIsXG4gIFwibGlnaHRlbi0zXCI6ICAjODBkZWVhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRkZDBlMSxcbiAgXCJsaWdodGVuLTFcIjogICMyNmM2ZGEsXG4gIFwiZGFya2VuLTFcIjogICAjMDBhY2MxLFxuICBcImRhcmtlbi0yXCI6ICAgIzAwOTdhNyxcbiAgXCJkYXJrZW4tM1wiOiAgICMwMDgzOGYsXG4gIFwiZGFya2VuLTRcIjogICAjMDA2MDY0LFxuICBcImFjY2VudC0xXCI6ICAgICM4NGZmZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzE4ZmZmZixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMDBlNWZmLFxuICBcImFjY2VudC00XCI6ICAgICMwMGI4ZDRcbik7XG5cbiR0ZWFsOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDA5Njg4LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UwZjJmMSxcbiAgXCJsaWdodGVuLTRcIjogICNiMmRmZGIsXG4gIFwibGlnaHRlbi0zXCI6ICAjODBjYmM0LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRkYjZhYyxcbiAgXCJsaWdodGVuLTFcIjogICMyNmE2OWEsXG4gIFwiZGFya2VuLTFcIjogICAjMDA4OTdiLFxuICBcImRhcmtlbi0yXCI6ICAgIzAwNzk2YixcbiAgXCJkYXJrZW4tM1wiOiAgICMwMDY5NWMsXG4gIFwiZGFya2VuLTRcIjogICAjMDA0ZDQwLFxuICBcImFjY2VudC0xXCI6ICAgICNhN2ZmZWIsXG4gIFwiYWNjZW50LTJcIjogICAgIzY0ZmZkYSxcbiAgXCJhY2NlbnQtM1wiOiAgICAjMWRlOWI2LFxuICBcImFjY2VudC00XCI6ICAgICMwMGJmYTVcbik7XG5cbiRncmVlbjogKFxuICBcImJhc2VcIjogICAgICAgIzRDQUY1MCxcbiAgXCJsaWdodGVuLTVcIjogICNFOEY1RTksXG4gIFwibGlnaHRlbi00XCI6ICAjQzhFNkM5LFxuICBcImxpZ2h0ZW4tM1wiOiAgI0E1RDZBNyxcbiAgXCJsaWdodGVuLTJcIjogICM4MUM3ODQsXG4gIFwibGlnaHRlbi0xXCI6ICAjNjZCQjZBLFxuICBcImRhcmtlbi0xXCI6ICAgIzQzQTA0NyxcbiAgXCJkYXJrZW4tMlwiOiAgICMzODhFM0MsXG4gIFwiZGFya2VuLTNcIjogICAjMkU3RDMyLFxuICBcImRhcmtlbi00XCI6ICAgIzFCNUUyMCxcbiAgXCJhY2NlbnQtMVwiOiAgICAjQjlGNkNBLFxuICBcImFjY2VudC0yXCI6ICAgICM2OUYwQUUsXG4gIFwiYWNjZW50LTNcIjogICAgIzAwRTY3NixcbiAgXCJhY2NlbnQtNFwiOiAgICAjMDBDODUzXG4pO1xuXG4kbGlnaHQtZ3JlZW46IChcbiAgXCJiYXNlXCI6ICAgICAgICM4YmMzNGEsXG4gIFwibGlnaHRlbi01XCI6ICAjZjFmOGU5LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2RjZWRjOCxcbiAgXCJsaWdodGVuLTNcIjogICNjNWUxYTUsXG4gIFwibGlnaHRlbi0yXCI6ICAjYWVkNTgxLFxuICBcImxpZ2h0ZW4tMVwiOiAgIzljY2M2NSxcbiAgXCJkYXJrZW4tMVwiOiAgICM3Y2IzNDIsXG4gIFwiZGFya2VuLTJcIjogICAjNjg5ZjM4LFxuICBcImRhcmtlbi0zXCI6ICAgIzU1OGIyZixcbiAgXCJkYXJrZW4tNFwiOiAgICMzMzY5MWUsXG4gIFwiYWNjZW50LTFcIjogICAgI2NjZmY5MCxcbiAgXCJhY2NlbnQtMlwiOiAgICAjYjJmZjU5LFxuICBcImFjY2VudC0zXCI6ICAgICM3NmZmMDMsXG4gIFwiYWNjZW50LTRcIjogICAgIzY0ZGQxN1xuKTtcblxuJGxpbWU6IChcbiAgXCJiYXNlXCI6ICAgICAgICNjZGRjMzksXG4gIFwibGlnaHRlbi01XCI6ICAjZjlmYmU3LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2YwZjRjMyxcbiAgXCJsaWdodGVuLTNcIjogICNlNmVlOWMsXG4gIFwibGlnaHRlbi0yXCI6ICAjZGNlNzc1LFxuICBcImxpZ2h0ZW4tMVwiOiAgI2Q0ZTE1NyxcbiAgXCJkYXJrZW4tMVwiOiAgICNjMGNhMzMsXG4gIFwiZGFya2VuLTJcIjogICAjYWZiNDJiLFxuICBcImRhcmtlbi0zXCI6ICAgIzllOWQyNCxcbiAgXCJkYXJrZW4tNFwiOiAgICM4Mjc3MTcsXG4gIFwiYWNjZW50LTFcIjogICAgI2Y0ZmY4MSxcbiAgXCJhY2NlbnQtMlwiOiAgICAjZWVmZjQxLFxuICBcImFjY2VudC0zXCI6ICAgICNjNmZmMDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2FlZWEwMFxuKTtcblxuJHllbGxvdzogKFxuICBcImJhc2VcIjogICAgICAgI2ZmZWIzYixcbiAgXCJsaWdodGVuLTVcIjogICNmZmZkZTcsXG4gIFwibGlnaHRlbi00XCI6ICAjZmZmOWM0LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2ZmZjU5ZCxcbiAgXCJsaWdodGVuLTJcIjogICNmZmYxNzYsXG4gIFwibGlnaHRlbi0xXCI6ICAjZmZlZTU4LFxuICBcImRhcmtlbi0xXCI6ICAgI2ZkZDgzNSxcbiAgXCJkYXJrZW4tMlwiOiAgICNmYmMwMmQsXG4gIFwiZGFya2VuLTNcIjogICAjZjlhODI1LFxuICBcImRhcmtlbi00XCI6ICAgI2Y1N2YxNyxcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmZmZjhkLFxuICBcImFjY2VudC0yXCI6ICAgICNmZmZmMDAsXG4gIFwiYWNjZW50LTNcIjogICAgI2ZmZWEwMCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjZmZkNjAwXG4pO1xuXG4kYW1iZXI6IChcbiAgXCJiYXNlXCI6ICAgICAgICNmZmMxMDcsXG4gIFwibGlnaHRlbi01XCI6ICAjZmZmOGUxLFxuICBcImxpZ2h0ZW4tNFwiOiAgI2ZmZWNiMyxcbiAgXCJsaWdodGVuLTNcIjogICNmZmUwODIsXG4gIFwibGlnaHRlbi0yXCI6ICAjZmZkNTRmLFxuICBcImxpZ2h0ZW4tMVwiOiAgI2ZmY2EyOCxcbiAgXCJkYXJrZW4tMVwiOiAgICNmZmIzMDAsXG4gIFwiZGFya2VuLTJcIjogICAjZmZhMDAwLFxuICBcImRhcmtlbi0zXCI6ICAgI2ZmOGYwMCxcbiAgXCJkYXJrZW4tNFwiOiAgICNmZjZmMDAsXG4gIFwiYWNjZW50LTFcIjogICAgI2ZmZTU3ZixcbiAgXCJhY2NlbnQtMlwiOiAgICAjZmZkNzQwLFxuICBcImFjY2VudC0zXCI6ICAgICNmZmM0MDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2ZmYWIwMFxuKTtcblxuJG9yYW5nZTogKFxuICBcImJhc2VcIjogICAgICAgI2ZmOTgwMCxcbiAgXCJsaWdodGVuLTVcIjogICNmZmYzZTAsXG4gIFwibGlnaHRlbi00XCI6ICAjZmZlMGIyLFxuICBcImxpZ2h0ZW4tM1wiOiAgI2ZmY2M4MCxcbiAgXCJsaWdodGVuLTJcIjogICNmZmI3NGQsXG4gIFwibGlnaHRlbi0xXCI6ICAjZmZhNzI2LFxuICBcImRhcmtlbi0xXCI6ICAgI2ZiOGMwMCxcbiAgXCJkYXJrZW4tMlwiOiAgICNmNTdjMDAsXG4gIFwiZGFya2VuLTNcIjogICAjZWY2YzAwLFxuICBcImRhcmtlbi00XCI6ICAgI2U2NTEwMCxcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmZkMTgwLFxuICBcImFjY2VudC0yXCI6ICAgICNmZmFiNDAsXG4gIFwiYWNjZW50LTNcIjogICAgI2ZmOTEwMCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjZmY2ZDAwXG4pO1xuXG4kZGVlcC1vcmFuZ2U6IChcbiAgXCJiYXNlXCI6ICAgICAgICNmZjU3MjIsXG4gIFwibGlnaHRlbi01XCI6ICAjZmJlOWU3LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2ZmY2NiYyxcbiAgXCJsaWdodGVuLTNcIjogICNmZmFiOTEsXG4gIFwibGlnaHRlbi0yXCI6ICAjZmY4YTY1LFxuICBcImxpZ2h0ZW4tMVwiOiAgI2ZmNzA0MyxcbiAgXCJkYXJrZW4tMVwiOiAgICNmNDUxMWUsXG4gIFwiZGFya2VuLTJcIjogICAjZTY0YTE5LFxuICBcImRhcmtlbi0zXCI6ICAgI2Q4NDMxNSxcbiAgXCJkYXJrZW4tNFwiOiAgICNiZjM2MGMsXG4gIFwiYWNjZW50LTFcIjogICAgI2ZmOWU4MCxcbiAgXCJhY2NlbnQtMlwiOiAgICAjZmY2ZTQwLFxuICBcImFjY2VudC0zXCI6ICAgICNmZjNkMDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2RkMmMwMFxuKTtcblxuJGJyb3duOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjNzk1NTQ4LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2VmZWJlOSxcbiAgXCJsaWdodGVuLTRcIjogICNkN2NjYzgsXG4gIFwibGlnaHRlbi0zXCI6ICAjYmNhYWE0LFxuICBcImxpZ2h0ZW4tMlwiOiAgI2ExODg3ZixcbiAgXCJsaWdodGVuLTFcIjogICM4ZDZlNjMsXG4gIFwiZGFya2VuLTFcIjogICAjNmQ0YzQxLFxuICBcImRhcmtlbi0yXCI6ICAgIzVkNDAzNyxcbiAgXCJkYXJrZW4tM1wiOiAgICM0ZTM0MmUsXG4gIFwiZGFya2VuLTRcIjogICAjM2UyNzIzXG4pO1xuXG4kYmx1ZS1ncmV5OiAoXG4gIFwiYmFzZVwiOiAgICAgICAjNjA3ZDhiLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2VjZWZmMSxcbiAgXCJsaWdodGVuLTRcIjogICNjZmQ4ZGMsXG4gIFwibGlnaHRlbi0zXCI6ICAjYjBiZWM1LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzkwYTRhZSxcbiAgXCJsaWdodGVuLTFcIjogICM3ODkwOWMsXG4gIFwiZGFya2VuLTFcIjogICAjNTQ2ZTdhLFxuICBcImRhcmtlbi0yXCI6ICAgIzQ1NWE2NCxcbiAgXCJkYXJrZW4tM1wiOiAgICMzNzQ3NGYsXG4gIFwiZGFya2VuLTRcIjogICAjMjYzMjM4XG4pO1xuXG4kZ3JleTogKFxuICBcImJhc2VcIjogICAgICAgIzllOWU5ZSxcbiAgXCJsaWdodGVuLTVcIjogICNmYWZhZmEsXG4gIFwibGlnaHRlbi00XCI6ICAjZjVmNWY1LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2VlZWVlZSxcbiAgXCJsaWdodGVuLTJcIjogICNlMGUwZTAsXG4gIFwibGlnaHRlbi0xXCI6ICAjYmRiZGJkLFxuICBcImRhcmtlbi0xXCI6ICAgIzc1NzU3NSxcbiAgXCJkYXJrZW4tMlwiOiAgICM2MTYxNjEsXG4gIFwiZGFya2VuLTNcIjogICAjNDI0MjQyLFxuICBcImRhcmtlbi00XCI6ICAgIzIxMjEyMVxuKTtcblxuJHNoYWRlczogKFxuICBcImJsYWNrXCI6ICAgICAgICAjMDAwMDAwLFxuICBcIndoaXRlXCI6ICAgICAgICAjRkZGRkZGLFxuICBcInRyYW5zcGFyZW50XCI6ICB0cmFuc3BhcmVudFxuKTtcblxuJGNvbG9yczogKFxuICBcIm1hdGVyaWFsaXplLXJlZFwiOiAkbWF0ZXJpYWxpemUtcmVkLFxuICBcInJlZFwiOiAkcmVkLFxuICBcInBpbmtcIjogJHBpbmssXG4gIFwicHVycGxlXCI6ICRwdXJwbGUsXG4gIFwiZGVlcC1wdXJwbGVcIjogJGRlZXAtcHVycGxlLFxuICBcImluZGlnb1wiOiAkaW5kaWdvLFxuICBcImJsdWVcIjogJGJsdWUsXG4gIFwibGlnaHQtYmx1ZVwiOiAkbGlnaHQtYmx1ZSxcbiAgXCJjeWFuXCI6ICRjeWFuLFxuICBcInRlYWxcIjogJHRlYWwsXG4gIFwiZ3JlZW5cIjogJGdyZWVuLFxuICBcImxpZ2h0LWdyZWVuXCI6ICRsaWdodC1ncmVlbixcbiAgXCJsaW1lXCI6ICRsaW1lLFxuICBcInllbGxvd1wiOiAkeWVsbG93LFxuICBcImFtYmVyXCI6ICRhbWJlcixcbiAgXCJvcmFuZ2VcIjogJG9yYW5nZSxcbiAgXCJkZWVwLW9yYW5nZVwiOiAkZGVlcC1vcmFuZ2UsXG4gIFwiYnJvd25cIjogJGJyb3duLFxuICBcImJsdWUtZ3JleVwiOiAkYmx1ZS1ncmV5LFxuICBcImdyZXlcIjogJGdyZXksXG4gIFwic2hhZGVzXCI6ICRzaGFkZXNcbik7XG5cblxuLy8gQ29sb3IgQ2xhc3Nlc1xuXG5AZWFjaCAkY29sb3JfbmFtZSwgJGNvbG9yIGluICRjb2xvcnMge1xuICBAZWFjaCAkY29sb3JfdHlwZSwgJGNvbG9yX3ZhbHVlIGluICRjb2xvciB7XG4gICAgQGlmICRjb2xvcl90eXBlID09IFwiYmFzZVwiIHtcbiAgICAgIC4jeyRjb2xvcl9uYW1lfSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgICAgLiN7JGNvbG9yX25hbWV9LXRleHQge1xuICAgICAgICBjb2xvcjogJGNvbG9yX3ZhbHVlICFpbXBvcnRhbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIEBlbHNlIHtcbiAgICAgIC4jeyRjb2xvcl9uYW1lfS4jeyRjb2xvcl90eXBlfSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgICAgLiN7JGNvbG9yX25hbWV9LXRleHQudGV4dC0jeyRjb2xvcl90eXBlfSB7XG4gICAgICAgIGNvbG9yOiAkY29sb3JfdmFsdWUgIWltcG9ydGFudDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gU2hhZGUgY2xhc3Nlc1xuQGVhY2ggJGNvbG9yLCAkY29sb3JfdmFsdWUgaW4gJHNoYWRlcyB7XG4gIC4jeyRjb2xvcn0ge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICB9XG4gIC4jeyRjb2xvcn0tdGV4dCB7XG4gICAgY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICB9XG59XG5cblxuLy8gdXNhZ2U6IGNvbG9yKFwibmFtZV9vZl9jb2xvclwiLCBcInR5cGVfb2ZfY29sb3JcIilcbi8vIHRvIGF2b2lkIHRvIHJlcGVhdGluZyBtYXAtZ2V0KCRjb2xvcnMsIC4uLilcblxuQGZ1bmN0aW9uIGNvbG9yKCRjb2xvciwgJHR5cGUpIHtcbiAgQGlmIG1hcC1oYXMta2V5KCRjb2xvcnMsICRjb2xvcikge1xuICAgICRjdXJyX2NvbG9yOiBtYXAtZ2V0KCRjb2xvcnMsICRjb2xvcik7XG4gICAgQGlmIG1hcC1oYXMta2V5KCRjdXJyX2NvbG9yLCAkdHlwZSkge1xuICAgICAgQHJldHVybiBtYXAtZ2V0KCRjdXJyX2NvbG9yLCAkdHlwZSk7XG4gICAgfVxuICB9XG4gIEB3YXJuIFwiVW5rbm93biBgI3tuYW1lfWAgaW4gJGNvbG9ycy5cIjtcbiAgQHJldHVybiBudWxsO1xufVxuXG4iLCIvKiFcbiAqIENsb2NrUGlja2VyIHYwLjAuNyBmb3IgalF1ZXJ5IChodHRwOi8vd2VhcmVvdXRtYW4uZ2l0aHViLmlvL2Nsb2NrcGlja2VyLylcbiAqIENvcHlyaWdodCAyMDE0IFdhbmcgU2hlbndlaS5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3dlYXJlb3V0bWFuL2Nsb2NrcGlja2VyL2Jsb2IvZ2gtcGFnZXMvTElDRU5TRSlcbiAqXG4gKiBGdXJ0aGVyIG1vZGlmaWVkXG4gKiBDb3B5cmlnaHQgMjAxNSBDaGluZyBZYXcgSGFvLlxuICpcbiAqIEJvb3RzdHJhcCB2My4xLjEgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNCBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICovXG5cbi5waWNrZXJfX2JveCB7XG4gICAgYmFja2dyb3VuZDogJGNsb2NrcGlja2VyLXBpY2tlci1ib3gtYmFja2dyb3VuZDtcbn1cblxuLnBpY2tlcl9fZGF0ZS1kaXNwbGF5IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY2xvY2twaWNrZXItcGlja2VyLWJveC1kYXRlLWRpc3BsYXktYmFja2dyb3VuZC1jb2xvcjtcbn1cblxuLmNsb2NrcGlja2VyLWRpc3BsYXkge1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbjogYXV0bztcbiAgICBoZWlnaHQ6IDg1cHg7XG4gICAgZm9udC1zaXplOiA3MHB4O1xuICAgIHBhZGRpbmc6IDEwcHg7XG4gICAgcGFkZGluZy1ib3R0b206IDBweDtcbiAgICBjb2xvcjogJGNsb2NrcGlja2VyLXByaW1hcnktY29sb3I7XG59XG5cbi5jbG9ja3BpY2tlci1kaXNwbGF5LWNvbHVtbiB7XG4gICAgZmxvYXQ6IGxlZnQ7XG59XG5cbi5jbG9ja3BpY2tlci1kaXNwbGF5LWFtLXBtIHtcbiAgICBwYWRkaW5nLWxlZnQ6IDVweDtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogYm90dG9tO1xuICAgIGhlaWdodDogODVweDtcbn1cblxuLmNsb2NrcGlja2VyLXNwYW4tYW0tcG0ge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBmb250LXNpemU6IDIzcHg7XG4gICAgbGluZS1oZWlnaHQ6IDI1cHg7XG4gICAgY29sb3I6ICRjbG9ja3BpY2tlci1wcmltYXJ5LWNvbG9yO1xufVxuXG4uY2xvY2twaWNrZXItc3Bhbi1ob3Vycyxcbi5jbG9ja3BpY2tlci1zcGFuLW1pbnV0ZXMge1xuICAgIC13ZWJraXQtYW5pbWF0aW9uLWR1cmF0aW9uOiA1MDBtcztcbiAgICBhbmltYXRpb24tZHVyYXRpb246IDUwMG1zO1xuICAgIC13ZWJraXQtYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcbiAgICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgLW1vei10cmFuc2l0aW9uOiBjb2xvciA1MDBtcztcbiAgICAtbXMtdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgLW8tdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG5ALXdlYmtpdC1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5ALW1vei1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtbW96LXRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICAtbW96LXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC1tb3otdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5ALW1zLWtleWZyYW1lcyBwdWxzZSB7XG4gICAgZnJvbSB7XG4gICAgICAgIC1tcy10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgLW1zLXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC1tcy10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG59XG5cbkAtby1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtby10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgLW8tdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMS4xLCAxLjEsIDEuMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgLW8tdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5Aa2V5ZnJhbWVzIHB1bHNlIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMS4xLCAxLjEsIDEuMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbn1cblxuI2NsaWNrLWFtLFxuI2NsaWNrLXBtIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5jbG9ja3BpY2tlci1zcGFuLWhvdXJzLFxuLmNsb2NrcGlja2VyLXNwYW4tbWludXRlcyxcbiNjbGljay1hbSxcbiNjbGljay1wbSB7XG4gICAgJi50ZXh0LXByaW1hcnkge1xuICAgICAgICAtd2Via2l0LWFuaW1hdGlvbi1uYW1lOiBwdWxzZTtcbiAgICAgICAgYW5pbWF0aW9uLW5hbWU6IHB1bHNlO1xuICAgICAgICBjb2xvcjogd2hpdGU7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItbW92aW5nIHtcbiAgICBjdXJzb3I6IG1vdmU7XG59XG5cbi5jbG9ja3BpY2tlci1wbGF0ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2VlZWVlZTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgd2lkdGg6IDI3MHB4O1xuICAgIGhlaWdodDogMjcwcHg7XG4gICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1hcmdpbjogYXV0bztcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xuICAgIC8qIERpc2FibGUgdGV4dCBzZWxlY3Rpb24gaGlnaGxpZ2h0aW5nLiBUaGFua3MgdG8gSGVybWFueWEgKi9cbiAgICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6IG5vbmU7XG4gICAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMsXG4uY2xvY2twaWNrZXItZGlhbCB7XG4gICAgd2lkdGg6IDI3MHB4O1xuICAgIGhlaWdodDogMjcwcHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IC0xcHg7XG4gICAgdG9wOiAtMXB4O1xufVxuXG4uY2xvY2twaWNrZXItbWludXRlcyB7XG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xufVxuXG4uY2xvY2twaWNrZXItdGljayB7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGNvbG9yOiAkY2xvY2twaWNrZXItdGljay1jb2xvcjtcbiAgICBsaW5lLWhlaWdodDogNDBweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgaGVpZ2h0OiA0MHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDMwMG1zO1xuICAgIC1tb3otdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciAzMDBtcztcbiAgICAtbXMtdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciAzMDBtcztcbiAgICAtby10cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDMwMG1zO1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgMzAwbXM7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvcjtcbiAgICAmLmFjdGl2ZSxcbiAgICAmOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvci1hY3RpdmU7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItZGlhbCB7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uOiAtd2Via2l0LXRyYW5zZm9ybSAzNTBtcywgb3BhY2l0eSAzNTBtcztcbiAgICAtbW96LXRyYW5zaXRpb246IC1tb3otdHJhbnNmb3JtIDM1MG1zLCBvcGFjaXR5IDM1MG1zO1xuICAgIC1tcy10cmFuc2l0aW9uOiAtbXMtdHJhbnNmb3JtIDM1MG1zLCBvcGFjaXR5IDM1MG1zO1xuICAgIC1vLXRyYW5zaXRpb246IC1vLXRyYW5zZm9ybSAzNTBtcywgb3BhY2l0eSAzNTBtcztcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMzUwbXMsIG9wYWNpdHkgMzUwbXM7XG59XG5cbi5jbG9ja3BpY2tlci1kaWFsLW91dCB7XG4gICAgb3BhY2l0eTogMDtcbn1cblxuLmNsb2NrcGlja2VyLWhvdXJzLmNsb2NrcGlja2VyLWRpYWwtb3V0IHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIC1tb3otdHJhbnNmb3JtOiBzY2FsZSgxLjIsIDEuMik7XG4gICAgLW1zLXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIC1vLXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xufVxuXG4uY2xvY2twaWNrZXItbWludXRlcy5jbG9ja3BpY2tlci1kaWFsLW91dCB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgLW1vei10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgLW1zLXRyYW5zZm9ybTogc2NhbGUoLjgsIC44KTtcbiAgICAtby10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSguOCwgLjgpO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzIHtcbiAgICAtd2Via2l0LXRyYW5zaXRpb246IG9wYWNpdHkgMzAwbXM7XG4gICAgLW1vei10cmFuc2l0aW9uOiBvcGFjaXR5IDMwMG1zO1xuICAgIC1tcy10cmFuc2l0aW9uOiBvcGFjaXR5IDMwMG1zO1xuICAgIC1vLXRyYW5zaXRpb246IG9wYWNpdHkgMzAwbXM7XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcztcbn1cblxuLmNsb2NrcGlja2VyLWNhbnZhcy1vdXQge1xuICAgIG9wYWNpdHk6IDAuMjU7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZyB7XG4gICAgc3Ryb2tlOiBub25lO1xuICAgIGZpbGw6ICRjbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZy1maWxsO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWZnIHtcbiAgICBzdHJva2U6IG5vbmU7XG4gICAgZmlsbDogcmdiYSgkY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGwsIDApO1xuICAgICYuYWN0aXZlIHtcbiAgICAgICAgZmlsbDogcmdiYSgkY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGwsIDAuNSk7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWJnIHtcbiAgICBzdHJva2U6IG5vbmU7XG4gICAgZmlsbDogJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1maWxsO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWJnLXRyYW5zIHtcbiAgICBmaWxsOiAkY2xvY2twaWNrZXItY2FudmFzLWJnLWZpbGw7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMgbGluZSB7XG4gICAgc3Ryb2tlOiAkY2xvY2twaWNrZXItY2FudmFzLWJnLXN0cm9rZTtcbiAgICBzdHJva2Utd2lkdGg6IDE7XG4gICAgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kO1xuICAgIC8qc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyovXG59XG5cbi5jbG9ja3BpY2tlci1hbS1wbS1ibG9jayB7XG4gICAgbWFyZ2luLXRvcDogLTEwcHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiA1MHB4O1xufVxuXG4vL0FNIFBNIGJ1dHRvbnNcbi5jbG9ja3BpY2tlci1idXR0b24ge1xuICAgICYuYW0tYnV0dG9uIHtcbiAgICAgICAgaGVpZ2h0OiA0NXB4O1xuICAgICAgICB3aWR0aDogNDVweDtcbiAgICAgICAgZmxvYXQ6IGxlZnQ7XG4gICAgfVxuICAgICYucG0tYnV0dG9uIHtcbiAgICAgICAgaGVpZ2h0OiA0NXB4O1xuICAgICAgICB3aWR0aDogNDVweDtcbiAgICAgICAgZmxvYXQ6IHJpZ2h0O1xuICAgIH1cbn1cblxuYnV0dG9uIHtcbiAgICBjb2xvcjogJGNsb2NrcGlja2VyLWJ1dHRvbi1jb2xvcjtcbn1cblxuLy9idXR0b25zXG4uYnRuLWZsb2F0aW5nIHtcbiAgICAmLmJ0bi1mbGF0IHtcbiAgICAgICAgJjpmb2N1cyxcbiAgICAgICAgJjp2aXNpdGVkIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICB9XG4gICAgICAgICY6aG92ZXIge1xuICAgICAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICB9XG4gICAgICAgICYuYWN0aXZlIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoJGNsb2NrcGlja2VyLWJ1dHRvbi1iYWNrZ3JvdW5kLWNvbG9yLCAwLjI1KTtcbiAgICAgICAgfVxuICAgICAgICAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCRjbG9ja3BpY2tlci1idXR0b24tYmFja2dyb3VuZC1jb2xvciwgMC41KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy9mb290ZXJcbi5waWNrZXJfX2Zvb3RlciB7XG4gICAgLmNsb2NrcGlja2VyLWJ1dHRvbiB7XG4gICAgICAgIG1hcmdpbjogYXV0bztcbiAgICAgICAgbWFyZ2luLXRvcDogMTVweDtcbiAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICAgICAgfVxuICAgICAgICAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCRjbG9ja3BpY2tlci1idXR0b24tYmFja2dyb3VuZC1jb2xvciwgMC4yNSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvL2JveFxuJGNsb2NrcGlja2VyLXBpY2tlci1ib3gtYmFja2dyb3VuZDogI2ZmZiAhZGVmYXVsdDtcbiRjbG9ja3BpY2tlci1waWNrZXItYm94LWRhdGUtZGlzcGxheS1iYWNrZ3JvdW5kLWNvbG9yOiBjb2xvcihcInRlYWxcIiwgXCJsaWdodGVuLTFcIikgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItcHJpbWFyeS1jb2xvcjogY29sb3IoXCJ0ZWFsXCIsIFwibGlnaHRlbi00XCIpICFkZWZhdWx0O1xuLy90aWNrXG4kY2xvY2twaWNrZXItdGljay1iYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKGNvbG9yKFwidGVhbFwiLCBcImJhc2VcIiksIDApICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvci1hY3RpdmU6IHJnYmEoY29sb3IoXCJ0ZWFsXCIsIFwiYmFzZVwiKSwgMC4yNSkgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItdGljay1jb2xvcjogIzY2NiAhZGVmYXVsdDtcbi8vY2FudmFzXG4kY2xvY2twaWNrZXItY2FudmFzLWJlYXJpbmctZmlsbDogcmdiYShjb2xvcihcInRlYWxcIiwgXCJkYXJrZW4tNFwiKSwgMC43NSkgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGw6IGNvbG9yKFwidGVhbFwiLCBcImRhcmtlbi00XCIpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1maWxsOiByZ2JhKGNvbG9yKFwidGVhbFwiLCBcImJhc2VcIiksIDAuMjUpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1zdHJva2U6ICRjbG9ja3BpY2tlci1jYW52YXMtYmctZmlsbCAhZGVmYXVsdDtcbi8vYnV0dG9uc1xuJGNsb2NrcGlja2VyLWJ1dHRvbi1iYWNrZ3JvdW5kLWNvbG9yOiBjb2xvcihcInRlYWxcIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWJ1dHRvbi1jb2xvcjogJGJ1dHRvbi1mbGF0LWNvbG9yICFkZWZhdWx0OyIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICBNYXRlcmlhbGl6ZSB2YXJpYWJsZXNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG4vKipcbiAqIFRhYmxlIG9mIENvbnRlbnRzOlxuICpcbiAqICAxLiBDb2xvcnNcbiAqICAyLiBCYWRnZXNcbiAqICAzLiBCdXR0b25zXG4gKiAgNC4gQ2FyZHNcbiAqICA1LiBDb2xsYXBzaWJsZVxuICogIDYuIENoaXBzXG4gKiAgNy4gRGF0ZSBQaWNrZXJcbiAqICA4LiBEcm9wZG93blxuICogIDEwLiBGb3Jtc1xuICogIDExLiBHbG9iYWxcbiAqICAxMi4gR3JpZFxuICogIDEzLiBOYXZpZ2F0aW9uIEJhclxuICogIDE0LiBTaWRlIE5hdmlnYXRpb25cbiAqICAxNS4gUGhvdG8gU2xpZGVyXG4gKiAgMTYuIFNwaW5uZXJzIHwgTG9hZGVyc1xuICogIDE3LiBUYWJzXG4gKiAgMTguIFRhYmxlc1xuICogIDE5LiBUb2FzdHNcbiAqICAyMC4gVHlwb2dyYXBoeVxuICogIDIxLiBGb290ZXJcbiAqICAyMi4gRmxvdyBUZXh0XG4gKiAgMjMuIENvbGxlY3Rpb25zXG4gKiAgMjQuIFByb2dyZXNzIEJhclxuICovXG5cblxuLyogMS4gQ29sb3JzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kcHJpbWFyeS1jb2xvcjogY29sb3IoXCJtYXRlcmlhbGl6ZS1yZWRcIiwgXCJsaWdodGVuLTJcIikgIWRlZmF1bHQ7XG4kcHJpbWFyeS1jb2xvci1saWdodDogbGlnaHRlbigkcHJpbWFyeS1jb2xvciwgMTUlKSAhZGVmYXVsdDtcbiRwcmltYXJ5LWNvbG9yLWRhcms6IGRhcmtlbigkcHJpbWFyeS1jb2xvciwgMTUlKSAhZGVmYXVsdDtcblxuJHNlY29uZGFyeS1jb2xvcjogY29sb3IoXCJ0ZWFsXCIsIFwibGlnaHRlbi0xXCIpICFkZWZhdWx0O1xuJHN1Y2Nlc3MtY29sb3I6IGNvbG9yKFwiZ3JlZW5cIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGVycm9yLWNvbG9yOiBjb2xvcihcInJlZFwiLCBcImJhc2VcIikgIWRlZmF1bHQ7XG4kbGluay1jb2xvcjogY29sb3IoXCJsaWdodC1ibHVlXCIsIFwiZGFya2VuLTFcIikgIWRlZmF1bHQ7XG5cblxuLyogMi4gQmFkZ2VzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kYmFkZ2UtYmctY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG5cblxuLyogMy4gQnV0dG9uc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLy8gU2hhcmVkIHN0eWxlc1xuJGJ1dHRvbi1ib3JkZXI6IG5vbmUgIWRlZmF1bHQ7XG4kYnV0dG9uLWJhY2tncm91bmQtZm9jdXM6IGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgNCUpICFkZWZhdWx0O1xuJGJ1dHRvbi1mb250LXNpemU6IDEuM3JlbSAhZGVmYXVsdDtcbiRidXR0b24taGVpZ2h0OiAzNnB4ICFkZWZhdWx0O1xuJGJ1dHRvbi1wYWRkaW5nOiAwIDJyZW0gIWRlZmF1bHQ7XG4kYnV0dG9uLXJhZGl1czogMnB4ICFkZWZhdWx0O1xuXG4vLyBEaXNhYmxlZCBzdHlsZXNcbiRidXR0b24tZGlzYWJsZWQtYmFja2dyb3VuZDogI0RGREZERiAhZGVmYXVsdDtcbiRidXR0b24tZGlzYWJsZWQtY29sb3I6ICM5RjlGOUYgIWRlZmF1bHQ7XG5cbi8vIFJhaXNlZCBidXR0b25zXG4kYnV0dG9uLXJhaXNlZC1iYWNrZ3JvdW5kOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGJ1dHRvbi1yYWlzZWQtYmFja2dyb3VuZC1ob3ZlcjogbGlnaHRlbigkYnV0dG9uLXJhaXNlZC1iYWNrZ3JvdW5kLCA1JSkgIWRlZmF1bHQ7XG4kYnV0dG9uLXJhaXNlZC1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcblxuLy8gTGFyZ2UgYnV0dG9uc1xuJGJ1dHRvbi1sYXJnZS1pY29uLWZvbnQtc2l6ZTogMS42cmVtICFkZWZhdWx0O1xuJGJ1dHRvbi1sYXJnZS1oZWlnaHQ6ICRidXR0b24taGVpZ2h0ICogMS41ICFkZWZhdWx0O1xuXG4vLyBGbGF0IGJ1dHRvbnNcbiRidXR0b24tZmxhdC1jb2xvcjogIzM0MzQzNCAhZGVmYXVsdDtcbiRidXR0b24tZmxhdC1kaXNhYmxlZC1jb2xvcjogbGlnaHRlbigjOTk5LCAxMCUpICFkZWZhdWx0O1xuXG4vLyBGbG9hdGluZyBidXR0b25zXG4kYnV0dG9uLWZsb2F0aW5nLWJhY2tncm91bmQ6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLWJhY2tncm91bmQtaG92ZXI6ICRidXR0b24tZmxvYXRpbmctYmFja2dyb3VuZCAhZGVmYXVsdDtcbiRidXR0b24tZmxvYXRpbmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLXNpemU6IDM3cHggIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLWxhcmdlLXNpemU6ICRidXR0b24tZmxvYXRpbmctc2l6ZSAqIDEuNSAhZGVmYXVsdDtcbiRidXR0b24tZmxvYXRpbmctcmFkaXVzOiA1MCUgIWRlZmF1bHQ7XG5cblxuLyogNC4gQ2FyZHNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRjYXJkLXBhZGRpbmc6IDIwcHggIWRlZmF1bHQ7XG4kY2FyZC1iZy1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcbiRjYXJkLWxpbmstY29sb3I6IGNvbG9yKFwib3JhbmdlXCIsIFwiYWNjZW50LTJcIikgIWRlZmF1bHQ7XG4kY2FyZC1saW5rLWNvbG9yLWxpZ2h0OiBsaWdodGVuKCRjYXJkLWxpbmstY29sb3IsIDIwJSkgIWRlZmF1bHQ7XG5cblxuLyogNS4gQ29sbGFwc2libGVcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRjb2xsYXBzaWJsZS1oZWlnaHQ6IDNyZW0gIWRlZmF1bHQ7XG4kY29sbGFwc2libGUtaGVhZGVyLWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuJGNvbGxhcHNpYmxlLWJvcmRlci1jb2xvcjogI2RkZCAhZGVmYXVsdDtcblxuXG4vKiA2LiBDaGlwc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGNoaXAtYmctY29sb3I6ICNlNGU0ZTQgIWRlZmF1bHQ7XG5cblxuLyogNy4gRGF0ZSBQaWNrZXJcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRkYXRlcGlja2VyLXdlZWtkYXktYmc6IGRhcmtlbigkc2Vjb25kYXJ5X2NvbG9yLCA3JSkgIWRlZmF1bHQ7XG4kZGF0ZXBpY2tlci1kYXRlLWJnOiAkc2Vjb25kYXJ5X2NvbG9yICFkZWZhdWx0O1xuJGRhdGVwaWNrZXIteWVhcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAuNCkgIWRlZmF1bHQ7XG4kZGF0ZXBpY2tlci1mb2N1czogcmdiYSgwLDAsMCwgLjA1KSAhZGVmYXVsdDtcbiRkYXRlcGlja2VyLXNlbGVjdGVkOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGRhdGVwaWNrZXItc2VsZWN0ZWQtb3V0Zm9jdXM6IGRlc2F0dXJhdGUobGlnaHRlbigkc2Vjb25kYXJ5LWNvbG9yLCAzNSUpLCAxNSUpICFkZWZhdWx0O1xuXG5cbi8qIDguIERyb3Bkb3duXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kZHJvcGRvd24tYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kZHJvcGRvd24taG92ZXItYmctY29sb3I6ICNlZWUgIWRlZmF1bHQ7XG4kZHJvcGRvd24tY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kZHJvcGRvd24taXRlbS1oZWlnaHQ6IDUwcHggIWRlZmF1bHQ7XG5cblxuLyogOS4gRm9udHNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRyb2JvdG8tZm9udC1wYXRoOiBcIi4uL2ZvbnRzL3JvYm90by9cIiAhZGVmYXVsdDtcblxuXG4vKiAxMC4gRm9ybXNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbi8vIFRleHQgSW5wdXRzICsgVGV4dGFyZWFcbiRpbnB1dC1oZWlnaHQ6IDNyZW0gIWRlZmF1bHQ7XG4kaW5wdXQtYm9yZGVyLWNvbG9yOiBjb2xvcihcImdyZXlcIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGlucHV0LWJvcmRlcjogMXB4IHNvbGlkICRpbnB1dC1ib3JkZXItY29sb3IgIWRlZmF1bHQ7XG4kaW5wdXQtYmFja2dyb3VuZDogI2ZmZiAhZGVmYXVsdDtcbiRpbnB1dC1lcnJvci1jb2xvcjogJGVycm9yLWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LXN1Y2Nlc3MtY29sb3I6ICRzdWNjZXNzLWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LWZvY3VzLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LWZvbnQtc2l6ZTogMXJlbSAhZGVmYXVsdDtcbiRpbnB1dC1tYXJnaW46IDAgMCAxNXB4IDAgIWRlZmF1bHQ7XG4kaW5wdXQtcGFkZGluZzogMCAhZGVmYXVsdDtcbiRpbnB1dC10cmFuc2l0aW9uOiBhbGwgLjNzICFkZWZhdWx0O1xuJGxhYmVsLWZvbnQtc2l6ZTogLjhyZW0gIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtY29sb3I6IHJnYmEoMCwwLDAsIC4yNikgIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtc29saWQtY29sb3I6ICNCREJEQkQgIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtYm9yZGVyOiAxcHggZG90dGVkICRpbnB1dC1kaXNhYmxlZC1jb2xvciAhZGVmYXVsdDtcbiRpbnB1dC1pbnZhbGlkLWJvcmRlcjogMXB4IHNvbGlkICRpbnB1dC1lcnJvci1jb2xvciAhZGVmYXVsdDtcbiRwbGFjZWhvbGRlci10ZXh0LWNvbG9yOiBsaWdodGVuKCRpbnB1dC1ib3JkZXItY29sb3IsIDIwJSkgIWRlZmF1bHQ7XG5cbi8vIFJhZGlvIEJ1dHRvbnNcbiRyYWRpby1maWxsLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJHJhZGlvLWVtcHR5LWNvbG9yOiAjNWE1YTVhICFkZWZhdWx0O1xuJHJhZGlvLWJvcmRlcjogMnB4IHNvbGlkICRyYWRpby1maWxsLWNvbG9yICFkZWZhdWx0O1xuXG4vLyBSYW5nZVxuJHJhbmdlLWhlaWdodDogMTRweCAhZGVmYXVsdDtcbiRyYW5nZS13aWR0aDogMTRweCAhZGVmYXVsdDtcbiR0cmFjay1oZWlnaHQ6IDNweCAhZGVmYXVsdDtcblxuLy8gU2VsZWN0XG4kc2VsZWN0LWJvcmRlcjogMXB4IHNvbGlkICNmMmYyZjIgIWRlZmF1bHQ7XG4kc2VsZWN0LWJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45MCkgIWRlZmF1bHQ7XG4kc2VsZWN0LWZvY3VzOiAxcHggc29saWQgbGlnaHRlbigkc2Vjb25kYXJ5LWNvbG9yLCA0NyUpICFkZWZhdWx0O1xuJHNlbGVjdC1wYWRkaW5nOiA1cHggIWRlZmF1bHQ7XG4kc2VsZWN0LXJhZGl1czogMnB4ICFkZWZhdWx0O1xuJHNlbGVjdC1kaXNhYmxlZC1jb2xvcjogcmdiYSgwLDAsMCwuMykgIWRlZmF1bHQ7XG5cbi8vIFN3aXRjaGVzXG4kc3dpdGNoLWJnLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJHN3aXRjaC1jaGVja2VkLWxldmVyLWJnOiBkZXNhdHVyYXRlKGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgMjUlKSwgMjUlKSAhZGVmYXVsdDtcbiRzd2l0Y2gtdW5jaGVja2VkLWJnOiAjRjFGMUYxICFkZWZhdWx0O1xuJHN3aXRjaC11bmNoZWNrZWQtbGV2ZXItYmc6ICM4MTgxODEgIWRlZmF1bHQ7XG4kc3dpdGNoLXJhZGl1czogMTVweCAhZGVmYXVsdDtcblxuXG4vKiAxMS4gR2xvYmFsXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vLyBNZWRpYSBRdWVyeSBSYW5nZXNcbiRzbWFsbC1zY3JlZW4tdXA6IDYwMXB4ICFkZWZhdWx0O1xuJG1lZGl1bS1zY3JlZW4tdXA6IDk5M3B4ICFkZWZhdWx0O1xuJGxhcmdlLXNjcmVlbi11cDogMTIwMXB4ICFkZWZhdWx0O1xuJHNtYWxsLXNjcmVlbjogNjAwcHggIWRlZmF1bHQ7XG4kbWVkaXVtLXNjcmVlbjogOTkycHggIWRlZmF1bHQ7XG4kbGFyZ2Utc2NyZWVuOiAxMjAwcHggIWRlZmF1bHQ7XG5cbiRtZWRpdW0tYW5kLXVwOiBcIm9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoIDogI3skc21hbGwtc2NyZWVuLXVwfSlcIiAhZGVmYXVsdDtcbiRsYXJnZS1hbmQtdXA6IFwib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGggOiAjeyRtZWRpdW0tc2NyZWVuLXVwfSlcIiAhZGVmYXVsdDtcbiRzbWFsbC1hbmQtZG93bjogXCJvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aCA6ICN7JHNtYWxsLXNjcmVlbn0pXCIgIWRlZmF1bHQ7XG4kbWVkaXVtLWFuZC1kb3duOiBcIm9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoIDogI3skbWVkaXVtLXNjcmVlbn0pXCIgIWRlZmF1bHQ7XG4kbWVkaXVtLW9ubHk6IFwib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGggOiAjeyRzbWFsbC1zY3JlZW4tdXB9KSBhbmQgKG1heC13aWR0aCA6ICN7JG1lZGl1bS1zY3JlZW59KVwiICFkZWZhdWx0O1xuXG5cbi8qIDEyLiBHcmlkXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kbnVtLWNvbHM6IDEyICFkZWZhdWx0O1xuJGd1dHRlci13aWR0aDogMS41cmVtICFkZWZhdWx0O1xuJGVsZW1lbnQtdG9wLW1hcmdpbjogJGd1dHRlci13aWR0aC8zICFkZWZhdWx0O1xuJGVsZW1lbnQtYm90dG9tLW1hcmdpbjogKCRndXR0ZXItd2lkdGgqMikvMyAhZGVmYXVsdDtcblxuXG4vKiAxMy4gTmF2aWdhdGlvbiBCYXJcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRuYXZiYXItaGVpZ2h0OiA2NHB4ICFkZWZhdWx0O1xuJG5hdmJhci1oZWlnaHQtbW9iaWxlOiA1NnB4ICFkZWZhdWx0O1xuJG5hdmJhci1mb250LWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuJG5hdmJhci1icmFuZC1mb250LXNpemU6IDIuMXJlbSAhZGVmYXVsdDtcblxuXG4vKiAxNC4gU2lkZSBOYXZpZ2F0aW9uXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kc2lkZW5hdi1mb250LWNvbG9yOiAjNDQ0ICFkZWZhdWx0O1xuJHNpZGVuYXYtYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kc2lkZW5hdi1wYWRkaW5nLXJpZ2h0OiAzMHB4ICFkZWZhdWx0O1xuJHNpZGVuYXYtaXRlbS1oZWlnaHQ6IDY0cHggIWRlZmF1bHQ7XG5cblxuLyogMTUuIFBob3RvIFNsaWRlclxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHNsaWRlci1iZy1jb2xvcjogY29sb3IoJ2dyZXknLCAnYmFzZScpICFkZWZhdWx0O1xuJHNsaWRlci1iZy1jb2xvci1saWdodDogY29sb3IoJ2dyZXknLCAnbGlnaHRlbi0yJykgIWRlZmF1bHQ7XG4kc2xpZGVyLWluZGljYXRvci1jb2xvcjogY29sb3IoJ2dyZWVuJywgJ2Jhc2UnKSAhZGVmYXVsdDtcblxuXG4vKiAxNi4gU3Bpbm5lcnMgfCBMb2FkZXJzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kc3Bpbm5lci1kZWZhdWx0LWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuXG5cbi8qIDE3LiBUYWJzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kdGFicy11bmRlcmxpbmUtY29sb3I6ICRwcmltYXJ5LWNvbG9yLWxpZ2h0ICFkZWZhdWx0O1xuJHRhYnMtdGV4dC1jb2xvcjogJHByaW1hcnktY29sb3IgIWRlZmF1bHQ7XG4kdGFicy1iZy1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcblxuXG4vKiAxOC4gVGFibGVzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kdGFibGUtYm9yZGVyLWNvbG9yOiAjZDBkMGQwICFkZWZhdWx0O1xuJHRhYmxlLXN0cmlwZWQtY29sb3I6ICNmMmYyZjIgIWRlZmF1bHQ7XG5cblxuLyogMTkuIFRvYXN0c1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHRvYXN0LWhlaWdodDogNDhweCAhZGVmYXVsdDtcbiR0b2FzdC1jb2xvcjogIzMyMzIzMiAhZGVmYXVsdDtcbiR0b2FzdC10ZXh0LWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuXG5cbi8qIDIwLiBUeXBvZ3JhcGh5XG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kb2ZmLWJsYWNrOiByZ2JhKDAsIDAsIDAsIDAuODcpICFkZWZhdWx0O1xuLy8gSGVhZGVyIFN0eWxlc1xuJGgxLWZvbnRzaXplOiA0LjJyZW0gIWRlZmF1bHQ7XG4kaDItZm9udHNpemU6IDMuNTZyZW0gIWRlZmF1bHQ7XG4kaDMtZm9udHNpemU6IDIuOTJyZW0gIWRlZmF1bHQ7XG4kaDQtZm9udHNpemU6IDIuMjhyZW0gIWRlZmF1bHQ7XG4kaDUtZm9udHNpemU6IDEuNjRyZW0gIWRlZmF1bHQ7XG4kaDYtZm9udHNpemU6IDFyZW0gIWRlZmF1bHQ7XG5cblxuLyogMjEuIEZvb3RlclxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGZvb3Rlci1iZy1jb2xvcjogJHByaW1hcnktY29sb3IgIWRlZmF1bHQ7XG5cblxuLyogMjIuIEZsb3cgVGV4dFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHJhbmdlIDogJGxhcmdlLXNjcmVlbiAtICRzbWFsbC1zY3JlZW4gIWRlZmF1bHQ7XG4kaW50ZXJ2YWxzOiAyMCAhZGVmYXVsdDtcbiRpbnRlcnZhbC1zaXplOiAkcmFuZ2UgLyAkaW50ZXJ2YWxzICFkZWZhdWx0O1xuXG5cbi8qIDIzLiBDb2xsZWN0aW9uc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGNvbGxlY3Rpb24tYm9yZGVyLWNvbG9yOiAjZTBlMGUwICFkZWZhdWx0O1xuJGNvbGxlY3Rpb24tYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kY29sbGVjdGlvbi1hY3RpdmUtYmctY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kY29sbGVjdGlvbi1hY3RpdmUtY29sb3I6IGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgNTUlKSAhZGVmYXVsdDtcbiRjb2xsZWN0aW9uLWhvdmVyLWJnLWNvbG9yOiAjZGRkICFkZWZhdWx0O1xuJGNvbGxlY3Rpb24tbGluay1jb2xvcjogJHNlY29uZGFyeS1jb2xvciAhZGVmYXVsdDtcblxuXG4vKiAyNC4gUHJvZ3Jlc3MgQmFyXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kcHJvZ3Jlc3MtYmFyLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuIiwiLyohXG4gKiBDbG9ja1BpY2tlciB2MC4wLjcgZm9yIGpRdWVyeSAoaHR0cDovL3dlYXJlb3V0bWFuLmdpdGh1Yi5pby9jbG9ja3BpY2tlci8pXG4gKiBDb3B5cmlnaHQgMjAxNCBXYW5nIFNoZW53ZWkuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS93ZWFyZW91dG1hbi9jbG9ja3BpY2tlci9ibG9iL2doLXBhZ2VzL0xJQ0VOU0UpXG4gKlxuICogRnVydGhlciBtb2RpZmllZFxuICogQ29weXJpZ2h0IDIwMTUgQ2hpbmcgWWF3IEhhby5cbiAqXG4gKiBCb290c3RyYXAgdjMuMS4xIChodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbSlcbiAqIENvcHlyaWdodCAyMDExLTIwMTQgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqL1xuLmRhcmt0aGVtZSB7XG4gICAgLnBpY2tlcl9fYm94IHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzIxMjEyMTtcbiAgICB9XG5cbiAgICAucGlja2VyX19kYXRlLWRpc3BsYXkge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItZGlzcGxheSB7XG4gICAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItc3Bhbi1hbS1wbSB7XG4gICAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItc3Bhbi1ob3VycyxcbiAgICAuY2xvY2twaWNrZXItc3Bhbi1taW51dGVzLFxuICAgICNjbGljay1hbSxcbiAgICAjY2xpY2stcG0ge1xuICAgICAgICAmLnRleHQtcHJpbWFyeSB7XG4gICAgICAgICAgICBjb2xvcjogI2ZmNDA4MTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1wbGF0ZSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci10aWNrIHtcbiAgICAgICAgY29sb3I6IHdoaXRlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjQsIDEyOSwgMCk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLXRpY2suYWN0aXZlLFxuICAgIC5jbG9ja3BpY2tlci10aWNrOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZyB7XG4gICAgICAgIGZpbGw6IHdoaXRlO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtZmcge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMCk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLWNhbnZhcy1mZy5hY3RpdmUge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC41KTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItY2FudmFzLWJnIHtcbiAgICAgICAgZmlsbDogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtYmctdHJhbnMge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC4yNSk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLWNhbnZhcyBsaW5lIHtcbiAgICAgICAgc3Ryb2tlOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC4yNSk7XG4gICAgfVxuXG4gICAgYnV0dG9uIHtcbiAgICAgICAgY29sb3I6IHdoaXRlO1xuICAgIH1cblxuICAgIC5idG4tZmxvYXRpbmcuYnRuLWZsYXQuYWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5idG4tZmxvYXRpbmcuYnRuLWZsYXQ6YWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuNSk7XG4gICAgfVxuXG4gICAgLnBpY2tlcl9fZm9vdGVyIC5jbG9ja3BpY2tlci1idXR0b246YWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cbn0iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0= */
|
admin/css/materialize.min.css
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Materialize v0.97.8 (http://materializecss.com)
|
3 |
+
* Copyright 2014-2015 Materialize
|
4 |
+
* MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
|
5 |
+
*/
|
6 |
+
.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-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:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}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{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{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-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default) li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.valign-wrapper .valign{display:block}.clearfix{clear:both}.z-depth-0{box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-floating,.dropdown-content,.collapsible,.side-nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 1px 5px 0 rgba(0,0,0,0.12),0 3px 1px -2px rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-floating:hover{box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{box-shadow:0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.3)}.z-depth-4,.modal{box-shadow:0 8px 10px 1px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.3)}.z-depth-5{box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -5px rgba(0,0,0,0.3)}.hoverable{transition:box-shadow .25s;box-shadow:0}.hoverable:hover{transition:box-shadow .25s;box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax img{display:none;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}footer.page-footer{margin-top:20px;padding-top:20px;background-color:#ee6e73}footer.page-footer .footer-copyright{overflow:hidden;height:50px;line-height:50px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table}table.bordered>thead>tr,table.bordered>tbody>tr{border-bottom:1px solid #d0d0d0}table.striped>tbody>tr:nth-child(odd){background-color:#f2f2f2}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:#f2f2f2}table.centered thead tr th,table.centered tbody tr td{text-align:center}thead{border-bottom:1px solid #d0d0d0}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid #d0d0d0}table.responsive-table.bordered th{border-bottom:0;border-left:0}table.responsive-table.bordered td{border-left:0;border-right:0;border-bottom:0}table.responsive-table.bordered tr{border:0}table.responsive-table.bordered tbody tr{border-right:1px solid #d0d0d0}}.collection{margin:0.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar .circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:inherit;color:#757575;float:right;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px}.side-nav span.badge.new,.collapsible span.badge.new{position:relative;background-color:transparent}.side-nav span.badge.new::before,.collapsible span.badge.new::before{content:'';position:absolute;top:10px;right:0;bottom:10px;left:0;background-color:#26a69a;border-radius:2px;z-index:-1}.collapsible span.badge.new{z-index:1}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:0.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.container .row{margin-left:-0.75rem;margin-right:-0.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;box-sizing:border-box;padding:0 0.75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{height:auto}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.button-collapse{display:none}}nav .button-collapse{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .button-collapse i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0;white-space:nowrap}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav ul{margin:0}nav ul li{transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);transition:color .3s}nav .input-field label.active i{color:#fff}nav .input-field label.active{-webkit-transform:translateY(0);transform:translateY(0)}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav,nav .nav-wrapper i,nav a.button-collapse,nav a.button-collapse i{height:64px;line-height:64px}.navbar-fixed{height:64px}}@font-face{font-family:"Roboto";src:local(Roboto Thin),url("../fonts/roboto/Roboto-Thin.eot");src:url("../fonts/roboto/Roboto-Thin.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Thin.woff2") format("woff2"),url("../fonts/roboto/Roboto-Thin.woff") format("woff"),url("../fonts/roboto/Roboto-Thin.ttf") format("truetype");font-weight:200}@font-face{font-family:"Roboto";src:local(Roboto Light),url("../fonts/roboto/Roboto-Light.eot");src:url("../fonts/roboto/Roboto-Light.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Light.woff2") format("woff2"),url("../fonts/roboto/Roboto-Light.woff") format("woff"),url("../fonts/roboto/Roboto-Light.ttf") format("truetype");font-weight:300}@font-face{font-family:"Roboto";src:local(Roboto Regular),url("../fonts/roboto/Roboto-Regular.eot");src:url("../fonts/roboto/Roboto-Regular.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Regular.woff2") format("woff2"),url("../fonts/roboto/Roboto-Regular.woff") format("woff"),url("../fonts/roboto/Roboto-Regular.ttf") format("truetype");font-weight:400}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Medium.eot");src:url("../fonts/roboto/Roboto-Medium.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Medium.woff2") format("woff2"),url("../fonts/roboto/Roboto-Medium.woff") format("woff"),url("../fonts/roboto/Roboto-Medium.ttf") format("truetype");font-weight:500}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Bold.eot");src:url("../fonts/roboto/Roboto-Bold.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Bold.woff2") format("woff2"),url("../fonts/roboto/Roboto-Bold.woff") format("woff"),url("../fonts/roboto/Roboto-Bold.ttf") format("truetype");font-weight:700}a{text-decoration:none}html{line-height:1.5;font-family:"Roboto", sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.1}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.1rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:1.78rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.46rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.14rem 0 0.912rem 0}h5{font-size:1.64rem;line-height:110%;margin:0.82rem 0 0.656rem 0}h6{font-size:1rem;line-height:110%;margin:0.5rem 0 0.4rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light,footer.page-footer .footer-copyright{font-weight:300}.thin{font-weight:200}.flow-text{font-weight:300}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.card-panel{transition:box-shadow .25s;padding:20px;margin:0.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:0.5rem 0 1rem 0;background-color:#fff;transition:box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;padding:20px}.card .card-content{padding:20px;border-radius:0 0 2px 2px}.card .card-content p{margin:0;color:inherit}.card .card-content .card-title{line-height:48px}.card .card-action{position:relative;background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);padding:20px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:20px;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:20px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:0;width:auto;clear:both;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;word-break:break-all;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.toast .btn,.toast .btn-large,.toast .btn-flat{margin:0;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}@media only screen and (min-width: 601px) and (max-width: 992px){.toast{float:left}}@media only screen and (min-width: 993px){.toast{float:right}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;transition:color .28s ease}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.7);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;display:none;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none}.backdrop{position:absolute;opacity:0;display:none;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.btn,.btn-large,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 2rem;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.btn-floating.disabled,.btn-large.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-flat:disabled,.btn[disabled],[disabled].btn-large,.btn-floating[disabled],.btn-large[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,[disabled].btn-large:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-floating,.btn-large,.btn-flat{outline:0}.btn i,.btn-large i,.btn-floating i,.btn-large i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;transition:.2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;transition:.3s;cursor:pointer;vertical-align:middle}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px}.btn-floating.btn-large i{line-height:56px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:998}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.horizontal{padding:0 0 0 15px}.fixed-action-btn.horizontal ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.horizontal ul li{display:inline-block;margin:15px 15px 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0}.fixed-action-btn.toolbar ul li{-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;transition:background-color .2s}.btn-flat:focus,.btn-flat:active{background-color:transparent}.btn-flat:focus,.btn-flat:hover{background-color:rgba(0,0,0,0.1);box-shadow:none}.btn-flat:active{background-color:rgba(0,0,0,0.2)}.btn-flat.disabled{background-color:transparent !important;color:#b3b3b3 !important;cursor:default}.btn-large{height:54px;line-height:54px}.btn-large i{font-size:1.6rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;max-height:650px;overflow-y:auto;opacity:0;position:absolute;z-index:999;will-change:width, height}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left;text-transform:none}.dropdown-content li:hover,.dropdown-content li.active,.dropdown-content li.selected{background-color:#eee}.dropdown-content li.active.selected{background-color:#e1e1e1}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px}/*!
|
7 |
+
* Waves v0.6.0
|
8 |
+
* http://fian.my.id/Waves
|
9 |
+
*
|
10 |
+
* Copyright 2014 Alfiana E. Sibuea and other contributors
|
11 |
+
* Released under the MIT license
|
12 |
+
* https://github.com/fians/Waves/blob/master/LICENSE
|
13 |
+
*/.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;will-change:opacity, transform;transition:.3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);transition:all 0.7s ease-out;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;-webkit-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-effect input[type="button"],.waves-effect input[type="reset"],.waves-effect input[type="submit"]{border:0;font-style:normal;font-size:inherit;text-transform:inherit;background:none}.waves-effect img{position:relative;z-index:-1}.waves-notransition{transition:none !important}.waves-circle{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, #fff 100%, #000 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;border-radius:2px;will-change:top, opacity}@media only screen and (max-width: 992px){.modal{width:80%}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-close{cursor:pointer}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-flat{float:right;margin:6px 0}.modal-overlay{position:fixed;z-index:999;top:-100px;left:0;bottom:0;right:0;height:125%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:absolute;height:calc(100% - 56px);max-height:100%;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:absolute;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:0.5rem 0 1rem 0}.collapsible-header{display:block;cursor:pointer;min-height:3rem;line-height:3rem;padding:0 1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header i{width:2rem;font-size:1.6rem;line-height:3rem;display:block;float:left;text-align:center;margin-right:1rem}.collapsible-body{display:none;border-bottom:1px solid #ddd;box-sizing:border-box}.collapsible-body p{margin:0;padding:2rem}.side-nav .collapsible,.side-nav.fixed .collapsible{border:none;box-shadow:none}.side-nav .collapsible li,.side-nav.fixed .collapsible li{padding:0}.side-nav .collapsible-header,.side-nav.fixed .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;padding:0 16px}.side-nav .collapsible-header:hover,.side-nav.fixed .collapsible-header:hover{background-color:rgba(0,0,0,0.05)}.side-nav .collapsible-header i,.side-nav.fixed .collapsible-header i{line-height:inherit}.side-nav .collapsible-body,.side-nav.fixed .collapsible-body{border:0;background-color:#fff}.side-nav .collapsible-body li a,.side-nav.fixed .collapsible-body li a{padding:0 23.5px 0 31px}.collapsible.popout{border:none;box-shadow:none}.collapsible.popout>li{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);margin:0 24px;transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0}.chip{display:inline-block;height:32px;font-size:13px;font-weight:500;color:rgba(0,0,0,0.6);line-height:32px;padding:0 12px;border-radius:16px;background-color:#e4e4e4;margin-bottom:5px;margin-right:5px}.chip img{float:left;margin:0 8px 0 -12px;height:32px;width:32px;border-radius:50%}.chip .close{cursor:pointer;float:right;font-size:16px;line-height:32px;padding-left:8px}.chips{border:none;border-bottom:1px solid #9e9e9e;box-shadow:none;margin:0 0 20px 0;min-height:45px;outline:none;transition:all .3s}.chips.focus{border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}.chips:hover{cursor:text}.chips .chip.selected{background-color:#26a69a;color:#fff}.chips .input{background:none;border:0;color:rgba(0,0,0,0.6);display:inline-block;font-size:1rem;height:3rem;line-height:32px;outline:0;margin:0;padding:0 !important;width:120px !important}.chips .input:focus{border:0 !important;box-shadow:none !important}.prefix ~ .chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty ~ label{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;transition:opacity .4s}.materialboxed:hover{will-change:left, top, width, height}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#292929;z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:0.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}:-moz-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}input:not([type]),input[type=text],input[type=password],input[type=email],input[type=url],input[type=time],input[type=date],input[type=datetime],input[type=datetime-local],input[type=tel],input[type=number],input[type=search],textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;box-shadow:none;box-sizing:content-box;transition:all 0.3s}input:not([type]):disabled,input:not([type])[readonly="readonly"],input[type=text]:disabled,input[type=text][readonly="readonly"],input[type=password]:disabled,input[type=password][readonly="readonly"],input[type=email]:disabled,input[type=email][readonly="readonly"],input[type=url]:disabled,input[type=url][readonly="readonly"],input[type=time]:disabled,input[type=time][readonly="readonly"],input[type=date]:disabled,input[type=date][readonly="readonly"],input[type=datetime]:disabled,input[type=datetime][readonly="readonly"],input[type=datetime-local]:disabled,input[type=datetime-local][readonly="readonly"],input[type=tel]:disabled,input[type=tel][readonly="readonly"],input[type=number]:disabled,input[type=number][readonly="readonly"],input[type=search]:disabled,input[type=search][readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.26);border-bottom:1px dotted rgba(0,0,0,0.26)}input:not([type]):disabled+label,input:not([type])[readonly="readonly"]+label,input[type=text]:disabled+label,input[type=text][readonly="readonly"]+label,input[type=password]:disabled+label,input[type=password][readonly="readonly"]+label,input[type=email]:disabled+label,input[type=email][readonly="readonly"]+label,input[type=url]:disabled+label,input[type=url][readonly="readonly"]+label,input[type=time]:disabled+label,input[type=time][readonly="readonly"]+label,input[type=date]:disabled+label,input[type=date][readonly="readonly"]+label,input[type=datetime]:disabled+label,input[type=datetime][readonly="readonly"]+label,input[type=datetime-local]:disabled+label,input[type=datetime-local][readonly="readonly"]+label,input[type=tel]:disabled+label,input[type=tel][readonly="readonly"]+label,input[type=number]:disabled+label,input[type=number][readonly="readonly"]+label,input[type=search]:disabled+label,input[type=search][readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.26)}input:not([type]):focus:not([readonly]),input[type=text]:focus:not([readonly]),input[type=password]:focus:not([readonly]),input[type=email]:focus:not([readonly]),input[type=url]:focus:not([readonly]),input[type=time]:focus:not([readonly]),input[type=date]:focus:not([readonly]),input[type=datetime]:focus:not([readonly]),input[type=datetime-local]:focus:not([readonly]),input[type=tel]:focus:not([readonly]),input[type=number]:focus:not([readonly]),input[type=search]:focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}input:not([type]):focus:not([readonly])+label,input[type=text]:focus:not([readonly])+label,input[type=password]:focus:not([readonly])+label,input[type=email]:focus:not([readonly])+label,input[type=url]:focus:not([readonly])+label,input[type=time]:focus:not([readonly])+label,input[type=date]:focus:not([readonly])+label,input[type=datetime]:focus:not([readonly])+label,input[type=datetime-local]:focus:not([readonly])+label,input[type=tel]:focus:not([readonly])+label,input[type=number]:focus:not([readonly])+label,input[type=search]:focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input:not([type]).valid,input:not([type]):focus.valid,input[type=text].valid,input[type=text]:focus.valid,input[type=password].valid,input[type=password]:focus.valid,input[type=email].valid,input[type=email]:focus.valid,input[type=url].valid,input[type=url]:focus.valid,input[type=time].valid,input[type=time]:focus.valid,input[type=date].valid,input[type=date]:focus.valid,input[type=datetime].valid,input[type=datetime]:focus.valid,input[type=datetime-local].valid,input[type=datetime-local]:focus.valid,input[type=tel].valid,input[type=tel]:focus.valid,input[type=number].valid,input[type=number]:focus.valid,input[type=search].valid,input[type=search]:focus.valid,textarea.materialize-textarea.valid,textarea.materialize-textarea:focus.valid{border-bottom:1px solid #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input:not([type]).valid+label:after,input:not([type]):focus.valid+label:after,input[type=text].valid+label:after,input[type=text]:focus.valid+label:after,input[type=password].valid+label:after,input[type=password]:focus.valid+label:after,input[type=email].valid+label:after,input[type=email]:focus.valid+label:after,input[type=url].valid+label:after,input[type=url]:focus.valid+label:after,input[type=time].valid+label:after,input[type=time]:focus.valid+label:after,input[type=date].valid+label:after,input[type=date]:focus.valid+label:after,input[type=datetime].valid+label:after,input[type=datetime]:focus.valid+label:after,input[type=datetime-local].valid+label:after,input[type=datetime-local]:focus.valid+label:after,input[type=tel].valid+label:after,input[type=tel]:focus.valid+label:after,input[type=number].valid+label:after,input[type=number]:focus.valid+label:after,input[type=search].valid+label:after,input[type=search]:focus.valid+label:after,textarea.materialize-textarea.valid+label:after,textarea.materialize-textarea:focus.valid+label:after{content:attr(data-success);color:#4CAF50;opacity:1}input:not([type]).invalid,input:not([type]):focus.invalid,input[type=text].invalid,input[type=text]:focus.invalid,input[type=password].invalid,input[type=password]:focus.invalid,input[type=email].invalid,input[type=email]:focus.invalid,input[type=url].invalid,input[type=url]:focus.invalid,input[type=time].invalid,input[type=time]:focus.invalid,input[type=date].invalid,input[type=date]:focus.invalid,input[type=datetime].invalid,input[type=datetime]:focus.invalid,input[type=datetime-local].invalid,input[type=datetime-local]:focus.invalid,input[type=tel].invalid,input[type=tel]:focus.invalid,input[type=number].invalid,input[type=number]:focus.invalid,input[type=search].invalid,input[type=search]:focus.invalid,textarea.materialize-textarea.invalid,textarea.materialize-textarea:focus.invalid{border-bottom:1px solid #F44336;box-shadow:0 1px 0 0 #F44336}input:not([type]).invalid+label:after,input:not([type]):focus.invalid+label:after,input[type=text].invalid+label:after,input[type=text]:focus.invalid+label:after,input[type=password].invalid+label:after,input[type=password]:focus.invalid+label:after,input[type=email].invalid+label:after,input[type=email]:focus.invalid+label:after,input[type=url].invalid+label:after,input[type=url]:focus.invalid+label:after,input[type=time].invalid+label:after,input[type=time]:focus.invalid+label:after,input[type=date].invalid+label:after,input[type=date]:focus.invalid+label:after,input[type=datetime].invalid+label:after,input[type=datetime]:focus.invalid+label:after,input[type=datetime-local].invalid+label:after,input[type=datetime-local]:focus.invalid+label:after,input[type=tel].invalid+label:after,input[type=tel]:focus.invalid+label:after,input[type=number].invalid+label:after,input[type=number]:focus.invalid+label:after,input[type=search].invalid+label:after,input[type=search]:focus.invalid+label:after,textarea.materialize-textarea.invalid+label:after,textarea.materialize-textarea:focus.invalid+label:after{content:attr(data-error);color:#F44336;opacity:1}input:not([type]).validate+label,input[type=text].validate+label,input[type=password].validate+label,input[type=email].validate+label,input[type=url].validate+label,input[type=time].validate+label,input[type=date].validate+label,input[type=datetime].validate+label,input[type=datetime-local].validate+label,input[type=tel].validate+label,input[type=number].validate+label,input[type=search].validate+label,textarea.materialize-textarea.validate+label{width:100%;pointer-events:none}input:not([type])+label:after,input[type=text]+label:after,input[type=password]+label:after,input[type=email]+label:after,input[type=url]+label:after,input[type=time]+label:after,input[type=date]+label:after,input[type=datetime]+label:after,input[type=datetime-local]+label:after,input[type=tel]+label:after,input[type=number]+label:after,input[type=search]+label:after,textarea.materialize-textarea+label:after{display:block;content:"";position:absolute;top:60px;opacity:0;transition:.2s opacity ease-out, .2s color ease-out}.input-field{position:relative;margin-top:1rem}.input-field.inline{display:inline-block;vertical-align:middle;margin-left:5px}.input-field.inline input,.input-field.inline .select-dropdown{margin-bottom:1rem}.input-field.col label{left:0.75rem}.input-field.col .prefix ~ label,.input-field.col .prefix ~ .validate ~ label{width:calc(100% - 3rem - 1.5rem)}.input-field label{color:#9e9e9e;position:absolute;top:0.8rem;left:0;font-size:1rem;cursor:text;transition:.2s ease-out}.input-field label.active{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;transition:color .2s}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea,.input-field .prefix ~ label,.input-field .prefix ~ .validate ~ label,.input-field .prefix ~ .autocomplete-content{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width: 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width: 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;padding-left:4rem;width:calc(100% - 4rem)}.input-field input[type=search]:focus{background-color:#fff;border:0;box-shadow:none;color:#444}.input-field input[type=search]:focus+label i,.input-field input[type=search]:focus ~ .mdi-navigation-close,.input-field input[type=search]:focus ~ .material-icons{color:#444}.input-field input[type=search]+label{left:1rem}.input-field input[type=search] ~ .mdi-navigation-close,.input-field input[type=search] ~ .material-icons{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{overflow-y:hidden;padding:.8rem 0 1.6rem 0;resize:none;min-height:3rem}.hiddendiv{display:none;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem}.autocomplete-content{margin-top:-15px;display:block;opacity:1;position:static}.autocomplete-content li .highlight{color:#444}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;left:-9999px;opacity:0}[type="radio"]:not(:checked)+label,[type="radio"]:checked+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="radio"]+label:before,[type="radio"]+label:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;transition:.28s ease}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after,[type="radio"]:checked+label:before,[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border-radius:50%}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after{border:2px solid #5a5a5a}[type="radio"]:not(:checked)+label:after{-webkit-transform:scale(0);transform:scale(0)}[type="radio"]:checked+label:before{border:2px solid transparent}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border:2px solid #26a69a}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:after{background-color:#26a69a}[type="radio"]:checked+label:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+label:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type="radio"].tabbed:focus+label:before{box-shadow:0 0 0 10px rgba(0,0,0,0.1)}[type="radio"].with-gap:disabled:checked+label:before{border:2px solid rgba(0,0,0,0.26)}[type="radio"].with-gap:disabled:checked+label:after{border:none;background-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before,[type="radio"]:disabled:checked+label:before{background-color:transparent;border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled+label{color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before{border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:checked+label:after{background-color:rgba(0,0,0,0.26);border-color:#BDBDBD}form p{margin-bottom:10px;text-align:left}form p:last-child{margin-bottom:0}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;left:-9999px;opacity:0}[type="checkbox"]+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="checkbox"]+label:before,[type="checkbox"]:not(.filled-in)+label:after{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:2px;transition:.2s}[type="checkbox"]:not(.filled-in)+label:after{border:0;-webkit-transform:scale(0);transform:scale(0)}[type="checkbox"]:not(:checked):disabled+label:before{border:none;background-color:rgba(0,0,0,0.26)}[type="checkbox"].tabbed:focus+label:after{-webkit-transform:scale(1);transform:scale(1);border:0;border-radius:50%;box-shadow:0 0 0 10px rgba(0,0,0,0.1);background-color:rgba(0,0,0,0.1)}[type="checkbox"]:checked+label:before{top:-4px;left:-5px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);border-bottom:2px solid rgba(0,0,0,0.26)}[type="checkbox"]:indeterminate+label:before{top:-11px;left:-12px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);background-color:transparent}[type="checkbox"].filled-in+label:after{border-radius:2px}[type="checkbox"].filled-in+label:before,[type="checkbox"].filled-in+label:after{content:'';left:0;position:absolute;transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+label:before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:20% 40%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+label:after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+label:before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+label:after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in.tabbed:focus+label:after{border-radius:2px;border-color:#5a5a5a;background-color:rgba(0,0,0,0.1)}[type="checkbox"].filled-in.tabbed:checked:focus+label:after{border-radius:2px;background-color:#26a69a;border-color:#26a69a}[type="checkbox"].filled-in:disabled:not(:checked)+label:before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+label:after{border-color:transparent;background-color:#BDBDBD}[type="checkbox"].filled-in:disabled:checked+label:before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+label:after{background-color:#BDBDBD;border-color:#BDBDBD}.switch,.switch *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a;left:24px}.switch label .lever{content:"";display:inline-block;position:relative;width:40px;height:15px;background-color:#818181;border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:after{content:"";position:absolute;display:inline-block;width:21px;height:21px;background-color:#F1F1F1;border-radius:21px;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-3px;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease}input[type=checkbox]:checked:not(:disabled) ~ .lever:active::after,input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(38,166,154,0.1)}input[type=checkbox]:not(:disabled) ~ .lever:active:after,input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.08)}.switch input[type=checkbox][disabled]+.lever{cursor:default}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#BDBDBD}select{display:none}select.browser-default{display:block}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;display:block}.select-wrapper span.caret{color:initial;position:absolute;right:0;top:0;bottom:0;height:10px;margin:auto 0;font-size:10px;line-height:10px}.select-wrapper span.caret.disabled{color:rgba(0,0,0,0.26)}.select-wrapper+label{position:absolute;top:-14px;font-size:0.8rem}select:disabled{color:rgba(0,0,0,0.3)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.3);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;border-bottom:1px solid rgba(0,0,0,0.3)}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:rgba(0,0,0,0.3);background-color:transparent}.prefix ~ .select-wrapper{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.prefix ~ label{margin-left:3rem}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;float:right}.select-dropdown li.optgroup{border-top:1px solid #eee}.select-dropdown li.optgroup.selected>span{color:rgba(0,0,0,0.7)}.select-dropdown li.optgroup>span{color:rgba(0,0,0,0.4)}.select-dropdown li.optgroup ~ li.optgroup-option{padding-left:1rem}.file-field{position:relative}.file-field .file-path-wrapper{overflow:hidden;padding-left:10px}.file-field input.file-path{width:100%}.file-field .btn,.file-field .btn-large{float:left;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0;padding:0}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;top:10px;margin-left:-6px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:14px;width:14px;border-radius:50%;background-color:#26a69a;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0;transition:.3s}input[type=range]:focus::-webkit-slider-runnable-track{background:#ccc}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#ddd;border:none}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input[type=range]:focus::-moz-range-track{background:#ccc}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a}input[type=range]:focus::-ms-fill-lower{background:#888}input[type=range]:focus::-ms-fill-upper{background:#ccc}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:20px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:19px;border-left:1px solid #ea4a4f}.table-of-contents a.active{font-weight:500;padding-left:18px;border-left:2px solid #ea4a4f}.side-nav{position:fixed;width:300px;left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#fff;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.side-nav .collapsible{margin:0}.side-nav li{float:none;line-height:48px}.side-nav li.active{background-color:rgba(0,0,0,0.05)}.side-nav a{color:rgba(0,0,0,0.87);display:block;font-size:14px;font-weight:500;height:48px;line-height:48px;padding:0 32px}.side-nav a:hover{background-color:rgba(0,0,0,0.05)}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-flat,.side-nav a.btn-floating{margin:10px 15px}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-floating{color:#fff}.side-nav a.btn-flat{color:#343434}.side-nav a.btn:hover,.side-nav a.btn-large:hover,.side-nav a.btn-large:hover{background-color:#2bbbad}.side-nav a.btn-floating:hover{background-color:#26a69a}.side-nav li>a>i,.side-nav li>a>[class^="mdi-"],.side-nav li>a>[class*="mdi-"],.side-nav li>a>i.material-icons{float:left;height:48px;line-height:48px;margin:0 32px 0 0;width:24px;color:rgba(0,0,0,0.54)}.side-nav .divider{margin:8px 0 0 0}.side-nav .subheader{cursor:initial;pointer-events:none;color:rgba(0,0,0,0.54);font-size:14px;font-weight:500;line-height:48px}.side-nav .subheader:hover{background-color:transparent}.side-nav .userView{position:relative;padding:32px 32px 0;margin-bottom:8px}.side-nav .userView>a{height:auto;padding:0}.side-nav .userView>a:hover{background-color:transparent}.side-nav .userView .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.side-nav .userView .circle,.side-nav .userView .name,.side-nav .userView .email{display:block}.side-nav .userView .circle{height:64px;width:64px}.side-nav .userView .name,.side-nav .userView .email{font-size:14px;line-height:24px}.side-nav .userView .name{margin-top:16px;font-weight:500}.side-nav .userView .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.side-nav.fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.side-nav.fixed.right-aligned{right:0;left:auto}@media only screen and (max-width: 992px){.side-nav.fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.side-nav a{padding:0 16px}.side-nav .userView{padding:16px 16px 0}}.side-nav .collapsible-body>ul:not(.collapsible)>li.active,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active{background-color:#ee6e73}.side-nav .collapsible-body>ul:not(.collapsible)>li.active a,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active a{color:#fff}#sidenav-overlay{position:fixed;top:0;left:0;right:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;will-change:opacity}.preloader-wrapper{display:inline-block;position:relative;width:48px;height:48px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:#26a69a}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.carousel{overflow:hidden;position:relative;width:100%;height:400px;-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0;height:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:400px;position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{display:none;width:200px;height:400px;position:absolute;top:0;left:0}.carousel .carousel-item img{width:100%}.carousel .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:rgba(255,255,255,0.5);transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:#fff}.picker{font-size:16px;text-align:left;line-height:1.2;color:#000000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
|
14 |
+
* Default mobile-first, responsive styling for pickadate.js
|
15 |
+
* Demo: http://amsul.github.io/pickadate.js
|
16 |
+
*/.picker__holder,.picker__frame{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;transition:background 0.15s ease-out, top 0s 0.15s;-webkit-backface-visibility:hidden}.picker__frame{position:absolute;margin:0 auto;min-width:256px;width:300px;max-height:350px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all 0.15s ease-out}@media (min-height: 28.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height: 40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height: 28.875em){.picker__wrap{display:block}}.picker__box{background:#ffffff;display:table-cell;vertical-align:middle}@media (min-height: 28.875em){.picker__box{display:block;border:1px solid #777777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,0.24)}}.picker--opened .picker__holder{top:0;background:transparent;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";zoom:1;background:rgba(0,0,0,0.32);transition:background 0.15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height: 35.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__input.picker__input--active{border-color:#E3F2FD}.picker__frame{margin:0 auto;max-width:325px}@media (min-height: 38.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{display:inline-block;margin-left:.25em;margin-right:.25em}.picker__select--month,.picker__select--year{height:2em;padding:0;margin-left:.25em;margin-right:.25em}.picker__select--month.browser-default{display:inline;background-color:#FFFFFF;width:40%}.picker__select--year.browser-default{display:inline;background-color:#FFFFFF;width:26%}.picker__select--month:focus,.picker__select--year:focus{border-color:rgba(0,0,0,0.05)}.picker__nav--prev,.picker__nav--next{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-0.25em}.picker__nav--prev{left:-1em;padding-right:1.25em}.picker__nav--next{right:-1em;padding-left:1.25em}.picker__nav--disabled,.picker__nav--disabled:hover,.picker__nav--disabled:before,.picker__nav--disabled:before:hover{cursor:default;background:none;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:1rem;width:100%;margin-top:.75em;margin-bottom:.5em}.picker__table th,.picker__table td{text-align:center}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999999;font-weight:500}@media (min-height: 33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day--today{position:relative;color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day--disabled:before{border-top-color:#aaaaaa}.picker__day--infocus:hover{cursor:pointer;color:#000;font-weight:500}.picker__day--outfocus{display:none;padding:.75rem 0;color:#fff}.picker__day--outfocus:hover{cursor:pointer;color:#dddddd;font-weight:500}.picker__day--highlighted:hover,.picker--focused .picker__day--highlighted{cursor:pointer}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.75);transform:scale(0.75);background:#0089ec;color:#ffffff}.picker__day--disabled,.picker__day--disabled:hover,.picker--focused .picker__day--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbbbbb}.picker__footer{text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.picker__button--today,.picker__button--clear,.picker__button--close{border:1px solid #ffffff;background:#ffffff;font-size:.8em;padding:.66em 0;font-weight:bold;width:33%;display:inline-block;vertical-align:bottom}.picker__button--today:hover,.picker__button--clear:hover,.picker__button--close:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--today:focus,.picker__button--clear:focus,.picker__button--close:focus{background:#b1dcfb;border-color:rgba(0,0,0,0.05);outline:none}.picker__button--today:before,.picker__button--clear:before,.picker__button--close:before{position:relative;display:inline-block;height:0}.picker__button--today:before,.picker__button--clear:before{content:" ";margin-right:.45em}.picker__button--today:before{top:-0.05em;width:0;border-top:0.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{top:-0.25em;width:.66em;border-top:3px solid #ee2200}.picker__button--close:before{content:"\D7";top:-0.1em;vertical-align:top;font-size:1.1em;margin-right:.35em;color:#777777}.picker__button--today[disabled],.picker__button--today[disabled]:hover{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__button--today[disabled]:before{border-top-color:#aaaaaa}.picker__box{border-radius:2px;overflow:hidden}.picker__date-display{text-align:center;background-color:#26a69a;color:#fff;padding-bottom:15px;font-weight:300}.picker__nav--prev:hover,.picker__nav--next:hover{cursor:pointer;color:#000000;background:#a1ded8}.picker__weekday-display{background-color:#1f897f;padding:10px;font-weight:200;letter-spacing:.5;font-size:1rem;margin-bottom:15px}.picker__month-display{text-transform:uppercase;font-size:2rem}.picker__day-display{font-size:4.5rem;font-weight:400}.picker__year-display{font-size:1.8rem;color:rgba(255,255,255,0.4)}.picker__box{padding:0}.picker__calendar-container{padding:0 1rem}.picker__calendar-container thead{border:none}.picker__table{margin-top:0;margin-bottom:.5em}.picker__day--infocus{color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day.picker__day--today{color:#26a69a}.picker__day.picker__day--today.picker__day--selected{color:#fff}.picker__weekday{font-size:.9rem}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.9);transform:scale(0.9);background-color:#26a69a;color:#ffffff}.picker__day--selected.picker__day--outfocus,.picker__day--selected:hover.picker__day--outfocus,.picker--focused .picker__day--selected.picker__day--outfocus{background-color:#a1ded8}.picker__footer{text-align:right;padding:5px 10px}.picker__close,.picker__today{font-size:1.1rem;padding:0 1rem;color:#26a69a}.picker__nav--prev:before,.picker__nav--next:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:0.75em solid #676767;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:0.75em solid #676767}button.picker__today:focus,button.picker__clear:focus,button.picker__close:focus{background-color:#a1ded8}.picker__list{list-style:none;padding:0.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #dddddd;border-top:1px solid #dddddd;margin-bottom:-1px;position:relative;background:#ffffff;padding:.75em 1.25em}@media (min-height: 46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker__list-item--highlighted:hover,.picker--focused .picker__list-item--highlighted{cursor:pointer;color:#000000;background:#b1dcfb}.picker__list-item--selected,.picker__list-item--selected:hover,.picker--focused .picker__list-item--selected{background:#0089ec;color:#ffffff;z-index:10}.picker__list-item--disabled,.picker__list-item--disabled:hover,.picker--focused .picker__list-item--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default;border-color:#dddddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:none;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:hover,.picker--time .picker__button--clear:focus{color:#000000;background:#b1dcfb;background:#ee2200;border-color:#ee2200;cursor:pointer;color:#ffffff;outline:none}.picker--time .picker__button--clear:before{top:-0.25em;color:#666;font-size:1.25em;font-weight:bold}.picker--time .picker__button--clear:hover:before,.picker--time .picker__button--clear:focus:before{color:#ffffff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height: 40.125em){.picker--time .picker__box{margin-bottom:5em}}
|
admin/css/responsive.dataTables.css
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
|
2 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
|
3 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty {
|
4 |
+
cursor: default !important;
|
5 |
+
}
|
6 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child:before,
|
7 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child:before,
|
8 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty:before {
|
9 |
+
display: none !important;
|
10 |
+
}
|
11 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,
|
12 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {
|
13 |
+
position: relative;
|
14 |
+
padding-left: 30px;
|
15 |
+
cursor: pointer;
|
16 |
+
}
|
17 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,
|
18 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {
|
19 |
+
top: 9px;
|
20 |
+
left: 4px;
|
21 |
+
height: 14px;
|
22 |
+
width: 14px;
|
23 |
+
display: block;
|
24 |
+
position: absolute;
|
25 |
+
color: white;
|
26 |
+
border: 2px solid white;
|
27 |
+
border-radius: 14px;
|
28 |
+
box-shadow: 0 0 3px #444;
|
29 |
+
box-sizing: content-box;
|
30 |
+
text-align: center;
|
31 |
+
font-family: 'Courier New', Courier, monospace;
|
32 |
+
line-height: 14px;
|
33 |
+
content: '+';
|
34 |
+
background-color: #31b131;
|
35 |
+
}
|
36 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,
|
37 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {
|
38 |
+
content: '-';
|
39 |
+
background-color: #d33333;
|
40 |
+
}
|
41 |
+
table.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {
|
42 |
+
display: none;
|
43 |
+
}
|
44 |
+
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,
|
45 |
+
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {
|
46 |
+
padding-left: 27px;
|
47 |
+
}
|
48 |
+
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,
|
49 |
+
table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {
|
50 |
+
top: 5px;
|
51 |
+
left: 4px;
|
52 |
+
height: 14px;
|
53 |
+
width: 14px;
|
54 |
+
border-radius: 14px;
|
55 |
+
line-height: 14px;
|
56 |
+
text-indent: 3px;
|
57 |
+
}
|
58 |
+
table.dataTable.dtr-column > tbody > tr > td.control,
|
59 |
+
table.dataTable.dtr-column > tbody > tr > th.control {
|
60 |
+
position: relative;
|
61 |
+
cursor: pointer;
|
62 |
+
}
|
63 |
+
table.dataTable.dtr-column > tbody > tr > td.control:before,
|
64 |
+
table.dataTable.dtr-column > tbody > tr > th.control:before {
|
65 |
+
top: 50%;
|
66 |
+
left: 50%;
|
67 |
+
height: 16px;
|
68 |
+
width: 16px;
|
69 |
+
margin-top: -10px;
|
70 |
+
margin-left: -10px;
|
71 |
+
display: block;
|
72 |
+
position: absolute;
|
73 |
+
color: white;
|
74 |
+
border: 2px solid white;
|
75 |
+
border-radius: 14px;
|
76 |
+
box-shadow: 0 0 3px #444;
|
77 |
+
box-sizing: content-box;
|
78 |
+
text-align: center;
|
79 |
+
font-family: 'Courier New', Courier, monospace;
|
80 |
+
line-height: 14px;
|
81 |
+
content: '+';
|
82 |
+
background-color: #31b131;
|
83 |
+
}
|
84 |
+
table.dataTable.dtr-column > tbody > tr.parent td.control:before,
|
85 |
+
table.dataTable.dtr-column > tbody > tr.parent th.control:before {
|
86 |
+
content: '-';
|
87 |
+
background-color: #d33333;
|
88 |
+
}
|
89 |
+
table.dataTable > tbody > tr.child {
|
90 |
+
padding: 0.5em 1em;
|
91 |
+
}
|
92 |
+
table.dataTable > tbody > tr.child:hover {
|
93 |
+
background: transparent !important;
|
94 |
+
}
|
95 |
+
table.dataTable > tbody > tr.child ul {
|
96 |
+
display: inline-block;
|
97 |
+
list-style-type: none;
|
98 |
+
margin: 0;
|
99 |
+
padding: 0;
|
100 |
+
}
|
101 |
+
table.dataTable > tbody > tr.child ul li {
|
102 |
+
border-bottom: 1px solid #efefef;
|
103 |
+
padding: 0.5em 0;
|
104 |
+
}
|
105 |
+
table.dataTable > tbody > tr.child ul li:first-child {
|
106 |
+
padding-top: 0;
|
107 |
+
}
|
108 |
+
table.dataTable > tbody > tr.child ul li:last-child {
|
109 |
+
border-bottom: none;
|
110 |
+
}
|
111 |
+
table.dataTable > tbody > tr.child span.dtr-title {
|
112 |
+
display: inline-block;
|
113 |
+
min-width: 75px;
|
114 |
+
font-weight: bold;
|
115 |
+
}
|
116 |
+
|
117 |
+
div.dtr-modal {
|
118 |
+
position: fixed;
|
119 |
+
box-sizing: border-box;
|
120 |
+
top: 0;
|
121 |
+
left: 0;
|
122 |
+
height: 100%;
|
123 |
+
width: 100%;
|
124 |
+
z-index: 100;
|
125 |
+
padding: 10em 1em;
|
126 |
+
}
|
127 |
+
div.dtr-modal div.dtr-modal-display {
|
128 |
+
position: absolute;
|
129 |
+
top: 0;
|
130 |
+
left: 0;
|
131 |
+
bottom: 0;
|
132 |
+
right: 0;
|
133 |
+
width: 50%;
|
134 |
+
height: 50%;
|
135 |
+
overflow: auto;
|
136 |
+
margin: auto;
|
137 |
+
z-index: 102;
|
138 |
+
overflow: auto;
|
139 |
+
background-color: #f5f5f7;
|
140 |
+
border: 1px solid black;
|
141 |
+
border-radius: 0.5em;
|
142 |
+
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6);
|
143 |
+
}
|
144 |
+
div.dtr-modal div.dtr-modal-content {
|
145 |
+
position: relative;
|
146 |
+
padding: 1em;
|
147 |
+
}
|
148 |
+
div.dtr-modal div.dtr-modal-close {
|
149 |
+
position: absolute;
|
150 |
+
top: 6px;
|
151 |
+
right: 6px;
|
152 |
+
width: 22px;
|
153 |
+
height: 22px;
|
154 |
+
border: 1px solid #eaeaea;
|
155 |
+
background-color: #f9f9f9;
|
156 |
+
text-align: center;
|
157 |
+
border-radius: 3px;
|
158 |
+
cursor: pointer;
|
159 |
+
z-index: 12;
|
160 |
+
}
|
161 |
+
div.dtr-modal div.dtr-modal-close:hover {
|
162 |
+
background-color: #eaeaea;
|
163 |
+
}
|
164 |
+
div.dtr-modal div.dtr-modal-background {
|
165 |
+
position: fixed;
|
166 |
+
top: 0;
|
167 |
+
left: 0;
|
168 |
+
right: 0;
|
169 |
+
bottom: 0;
|
170 |
+
z-index: 101;
|
171 |
+
background: rgba(0, 0, 0, 0.6);
|
172 |
+
}
|
173 |
+
|
174 |
+
@media screen and (max-width: 767px) {
|
175 |
+
div.dtr-modal div.dtr-modal-display {
|
176 |
+
width: 95%;
|
177 |
+
}
|
178 |
+
}
|
admin/css/xcloner-admin.css
ADDED
@@ -0,0 +1,370 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* All of the CSS for your admin-specific functionality should be
|
3 |
+
* included in this file.
|
4 |
+
*/
|
5 |
+
/* fallback */
|
6 |
+
|
7 |
+
html {
|
8 |
+
font-family: GillSans, Calibri, Trebuchet, sans-serif;
|
9 |
+
}
|
10 |
+
/*
|
11 |
+
@font-face {
|
12 |
+
font-family: 'Material Icons';
|
13 |
+
font-style: normal;
|
14 |
+
font-weight: 400;
|
15 |
+
src: url(../fonts/MaterialIcons-Regular.eot);
|
16 |
+
src: local('Material Icons'),
|
17 |
+
local('MaterialIcons-Regular'),
|
18 |
+
url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
19 |
+
url(../fonts/MaterialIcons-Regular.woff) format('woff'),
|
20 |
+
url(../fontsMaterialIcons-Regular.ttf) format('truetype');
|
21 |
+
}*/
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
h1{
|
26 |
+
font-size: 23px;
|
27 |
+
}
|
28 |
+
|
29 |
+
h2{
|
30 |
+
font-size: 18px;
|
31 |
+
}
|
32 |
+
|
33 |
+
.input-field{
|
34 |
+
margin-top: 0px;
|
35 |
+
}
|
36 |
+
|
37 |
+
td, th {
|
38 |
+
padding-top: 0px !important;
|
39 |
+
}
|
40 |
+
|
41 |
+
.form-table th {
|
42 |
+
padding-top: 10px !important;
|
43 |
+
}
|
44 |
+
|
45 |
+
a.nav-tab.col {
|
46 |
+
padding: 10px;
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
span.shorten_string{
|
51 |
+
cursor: pointer;
|
52 |
+
}
|
53 |
+
|
54 |
+
.card-panel{
|
55 |
+
min-height: 60px;
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
.dashboard .additional_system_info{
|
60 |
+
display: none;
|
61 |
+
}
|
62 |
+
|
63 |
+
.nav-tab-wrapper li{
|
64 |
+
margin-bottom: 0px;
|
65 |
+
}
|
66 |
+
|
67 |
+
.nav-tab-wrapper-content .tab-content{
|
68 |
+
display: none;
|
69 |
+
}
|
70 |
+
|
71 |
+
.nav-tab-wrapper-content .tab-content.active{
|
72 |
+
display: block;
|
73 |
+
}
|
74 |
+
|
75 |
+
.input-field label.active {
|
76 |
+
font-size: 1rem;
|
77 |
+
}
|
78 |
+
|
79 |
+
.xcloner-debugger .console{
|
80 |
+
height: 450px;
|
81 |
+
min-height: 300px;
|
82 |
+
overflow: auto;
|
83 |
+
}
|
84 |
+
|
85 |
+
#error_modal textarea{
|
86 |
+
height: 150px;
|
87 |
+
}
|
88 |
+
|
89 |
+
#error_modal .msg{
|
90 |
+
font-size: 14px;
|
91 |
+
}
|
92 |
+
|
93 |
+
#generate_backup .backup-status, #generate_backup ul.backup-status > li{
|
94 |
+
display: none;
|
95 |
+
}
|
96 |
+
|
97 |
+
ul.backup-name{
|
98 |
+
margin-top: 1.78rem;
|
99 |
+
}
|
100 |
+
|
101 |
+
#generate_backup .status-body ul.backup-name li, #generate_backup ul.logged-databases li{
|
102 |
+
font-weight: bold;
|
103 |
+
}
|
104 |
+
|
105 |
+
#generate_backup .backup-done .collapsible-body {
|
106 |
+
margin-top: 1.83rem;
|
107 |
+
}
|
108 |
+
|
109 |
+
#generate_backup .status-body > ul, #generate_backup .status-body ul.logged-tables{
|
110 |
+
margin: 5px 10px;
|
111 |
+
max-height: 200px;
|
112 |
+
overflow-y: auto;
|
113 |
+
margin-top: 1.78rem;
|
114 |
+
}
|
115 |
+
|
116 |
+
#generate_backup .action-buttons .cancel,
|
117 |
+
#generate_backup .action-buttons .restart{
|
118 |
+
display: none;
|
119 |
+
}
|
120 |
+
|
121 |
+
.modal-footer .modal-close.btn-flat{
|
122 |
+
color: #fff;
|
123 |
+
}
|
124 |
+
|
125 |
+
.collapsible-body{
|
126 |
+
padding: 0px 10px;
|
127 |
+
}
|
128 |
+
|
129 |
+
.select-wrapper+label {
|
130 |
+
font-size: 1rem;
|
131 |
+
}
|
132 |
+
|
133 |
+
#schedule_backup .server-time h2{
|
134 |
+
color: #fff;
|
135 |
+
}
|
136 |
+
|
137 |
+
#schedule_backup_success{
|
138 |
+
display: none;
|
139 |
+
}
|
140 |
+
|
141 |
+
#scheduled_backups_wrapper .dataTables_length,
|
142 |
+
#manage_backups_wrapper .dataTables_length{
|
143 |
+
display: none;
|
144 |
+
}
|
145 |
+
|
146 |
+
table#scheduled_backups{
|
147 |
+
font-size: 16px;
|
148 |
+
}
|
149 |
+
|
150 |
+
#scheduled_backups td, #scheduled_backups th{
|
151 |
+
padding-top: 8px !important;
|
152 |
+
}
|
153 |
+
|
154 |
+
#scheduled_backups i.status{
|
155 |
+
color: #fff;
|
156 |
+
}
|
157 |
+
|
158 |
+
.site-backup_page_xcloner_scheduled_backups_page #server_time h2 {
|
159 |
+
color: #fff;
|
160 |
+
margin: 9px 0px;
|
161 |
+
padding: 10px 10px 5px 10px;
|
162 |
+
}
|
163 |
+
|
164 |
+
textarea.materialize-textarea{
|
165 |
+
overflow: auto;
|
166 |
+
resize: auto;
|
167 |
+
}
|
168 |
+
|
169 |
+
#scheduled_backups .edit, #scheduled_backups .status.active, #scheduled_backups .delete,
|
170 |
+
#manage_backups .download, #manage_backups .cloud-upload, #manage_backups .delete, #manage_backups .list-backup-content,
|
171 |
+
.backup-done .download, .backup-done .cloud-upload, .backup-done .delete, .backup-done .list-backup-content{
|
172 |
+
color: #4db6ac;
|
173 |
+
}
|
174 |
+
|
175 |
+
#scheduled_backups .status.inactive{
|
176 |
+
color: #d32f2f ;
|
177 |
+
}
|
178 |
+
|
179 |
+
table.dataTable thead th, table.dataTable tfoot th{
|
180 |
+
padding-left: 10px;
|
181 |
+
}
|
182 |
+
|
183 |
+
table.dataTable tr.odd { background-color: #fff; }
|
184 |
+
table.dataTable tr.even { background-color: #f3f3f3; }
|
185 |
+
|
186 |
+
#manage_backups ul.multipart{
|
187 |
+
margin-left: 20px;
|
188 |
+
display: none;
|
189 |
+
}
|
190 |
+
|
191 |
+
#manage_backups ul.multipart li{
|
192 |
+
padding: 5px;
|
193 |
+
list-style-type: square;
|
194 |
+
}
|
195 |
+
|
196 |
+
a.expand-multipart.remove{
|
197 |
+
display: none;
|
198 |
+
}
|
199 |
+
|
200 |
+
.remote-storage .label label{
|
201 |
+
font-size:16px;
|
202 |
+
}
|
203 |
+
.remote-storage .label{
|
204 |
+
padding-top: 25px;
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
#manage_backups td.checkbox{
|
209 |
+
vertical-align: top;
|
210 |
+
}
|
211 |
+
|
212 |
+
#remote_storage_modal{
|
213 |
+
min-height: 350px;
|
214 |
+
}
|
215 |
+
|
216 |
+
#remote_storage_modal .label label{
|
217 |
+
font-size: 16px;
|
218 |
+
}
|
219 |
+
|
220 |
+
#remote_storage_modal .label{
|
221 |
+
padding-top: 25px;
|
222 |
+
}
|
223 |
+
|
224 |
+
#remote_storage_modal .status{
|
225 |
+
display: none;
|
226 |
+
}
|
227 |
+
|
228 |
+
#remote_storage_modal .status-text.error{
|
229 |
+
color: red;
|
230 |
+
}
|
231 |
+
|
232 |
+
#remote_storage_modal .status-text{
|
233 |
+
font-weight: bold;
|
234 |
+
}
|
235 |
+
|
236 |
+
#backup-status h5{
|
237 |
+
font-size: 18px;
|
238 |
+
}
|
239 |
+
|
240 |
+
#backup-status .row .item .title{
|
241 |
+
width: 100px;
|
242 |
+
display: inline-block;
|
243 |
+
font-weight: bold;
|
244 |
+
}
|
245 |
+
|
246 |
+
.xcloner-restore li.steps{
|
247 |
+
display: none;
|
248 |
+
}
|
249 |
+
|
250 |
+
.xcloner-restore .steps.show{
|
251 |
+
display: block;
|
252 |
+
}
|
253 |
+
|
254 |
+
.xcloner-restore li .collapsible-body{
|
255 |
+
padding: 25px 10px 15px 10px;
|
256 |
+
}
|
257 |
+
|
258 |
+
.xcloner-restore select.browser-default{
|
259 |
+
height: 36px;
|
260 |
+
font-size: 18px;
|
261 |
+
}
|
262 |
+
|
263 |
+
.xcloner-restore .steps .progress{
|
264 |
+
display: none;
|
265 |
+
}
|
266 |
+
|
267 |
+
.xcloner-restore .status > div{
|
268 |
+
margin: 10px 0px 0px 0px;
|
269 |
+
}
|
270 |
+
|
271 |
+
.xcloner-restore .toggler{
|
272 |
+
display: inline-block;
|
273 |
+
}
|
274 |
+
|
275 |
+
.xcloner-restore .toggler .normal{
|
276 |
+
display: block;
|
277 |
+
}
|
278 |
+
|
279 |
+
.xcloner-restore .toggler .cancel{
|
280 |
+
display: none;
|
281 |
+
}
|
282 |
+
|
283 |
+
.xcloner-restore .toggler.cancel .normal{
|
284 |
+
display: none;
|
285 |
+
}
|
286 |
+
|
287 |
+
.xcloner-restore .toggler.cancel .cancel{
|
288 |
+
display: block;
|
289 |
+
}
|
290 |
+
|
291 |
+
.xcloner-restore ul.text-steps li{
|
292 |
+
list-style-type: decimal;
|
293 |
+
}
|
294 |
+
|
295 |
+
.xcloner-restore ul.text-steps ul li{
|
296 |
+
list-style-type: disc;
|
297 |
+
}
|
298 |
+
|
299 |
+
.xcloner-restore ul.text-steps ul{
|
300 |
+
margin: 10px;
|
301 |
+
}
|
302 |
+
|
303 |
+
.xcloner-restore ul.text-steps{
|
304 |
+
margin-left: 20px;
|
305 |
+
}
|
306 |
+
|
307 |
+
.xcloner-restore .restore-remote-backup-step .files-list{
|
308 |
+
max-height: 250px;
|
309 |
+
overflow: auto;
|
310 |
+
margin: 10px 5px;
|
311 |
+
}
|
312 |
+
|
313 |
+
#backup_cotent_modal .modal-content .files-list span{
|
314 |
+
cursor: pointer;
|
315 |
+
}
|
316 |
+
|
317 |
+
.xcloner-restore .query-box{
|
318 |
+
display: none;
|
319 |
+
}
|
320 |
+
|
321 |
+
.xcloner-restore .query-box .query-list{
|
322 |
+
height: 10rem;
|
323 |
+
}
|
324 |
+
|
325 |
+
.xcloner-restore .restore-remote-database-step h5{
|
326 |
+
margin-top: -10px;
|
327 |
+
margin-bottom: 25px;
|
328 |
+
}
|
329 |
+
|
330 |
+
|
331 |
+
.regex_pattern{
|
332 |
+
cursor: pointer;
|
333 |
+
font-weight: bold;
|
334 |
+
}
|
335 |
+
|
336 |
+
.jstree-icon.jstree-checkbox.jstree-checkbox-disabled{
|
337 |
+
opacity: 0.3;
|
338 |
+
}
|
339 |
+
|
340 |
+
#xcloner_regex_exclude{
|
341 |
+
height: 5rem;
|
342 |
+
}
|
343 |
+
|
344 |
+
ul.xcloner_regex_exclude_limit li:nth-of-type(n+2) {
|
345 |
+
display:none;
|
346 |
+
}
|
347 |
+
|
348 |
+
.xcloner-restore .btn.waves-effect.waves-light.grey{
|
349 |
+
margin-top: -2px;
|
350 |
+
}
|
351 |
+
|
352 |
+
.xcloner-restore #xcloner_restore_finish{
|
353 |
+
display: none;
|
354 |
+
}
|
355 |
+
|
356 |
+
ul.files-list li{
|
357 |
+
padding: 0px;
|
358 |
+
white-space: pre;
|
359 |
+
}
|
360 |
+
|
361 |
+
#manage_backups_wrapper #manage_backups_filter{
|
362 |
+
min-width: 250px;
|
363 |
+
}
|
364 |
+
|
365 |
+
|
366 |
+
@media only screen and (min-width: 993px){
|
367 |
+
.dashboard .backup-ready{
|
368 |
+
float: right;
|
369 |
+
}
|
370 |
+
}
|
admin/fonts/roboto/Roboto-Bold.eot
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Bold.ttf
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Bold.woff
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Bold.woff2
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Light.eot
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Light.ttf
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Light.woff
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Light.woff2
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Medium.eot
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Medium.ttf
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Medium.woff
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Medium.woff2
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Regular.eot
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Regular.ttf
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Regular.woff
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Regular.woff2
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Thin.eot
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Thin.ttf
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Thin.woff
ADDED
Binary file
|
admin/fonts/roboto/Roboto-Thin.woff2
ADDED
Binary file
|
admin/images/Sorting icons.psd
ADDED
Binary file
|
admin/images/favicon.ico
ADDED
Binary file
|
admin/images/sort_asc.png
ADDED
Binary file
|
admin/images/sort_asc_disabled.png
ADDED
Binary file
|
admin/images/sort_both.png
ADDED
Binary file
|
admin/images/sort_desc.png
ADDED
Binary file
|
admin/images/sort_desc_disabled.png
ADDED
Binary file
|
admin/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
admin/js/dataTables.responsive.js
ADDED
@@ -0,0 +1,1232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! Responsive 2.1.0
|
2 |
+
* 2014-2016 SpryMedia Ltd - datatables.net/license
|
3 |
+
*/
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @summary Responsive
|
7 |
+
* @description Responsive tables plug-in for DataTables
|
8 |
+
* @version 2.1.0
|
9 |
+
* @file dataTables.responsive.js
|
10 |
+
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11 |
+
* @contact www.sprymedia.co.uk/contact
|
12 |
+
* @copyright Copyright 2014-2016 SpryMedia Ltd.
|
13 |
+
*
|
14 |
+
* This source file is free software, available under the following license:
|
15 |
+
* MIT license - http://datatables.net/license/mit
|
16 |
+
*
|
17 |
+
* This source file is distributed in the hope that it will be useful, but
|
18 |
+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
19 |
+
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
20 |
+
*
|
21 |
+
* For details please refer to: http://www.datatables.net
|
22 |
+
*/
|
23 |
+
(function( factory ){
|
24 |
+
if ( typeof define === 'function' && define.amd ) {
|
25 |
+
// AMD
|
26 |
+
define( ['jquery', 'datatables.net'], function ( $ ) {
|
27 |
+
return factory( $, window, document );
|
28 |
+
} );
|
29 |
+
}
|
30 |
+
else if ( typeof exports === 'object' ) {
|
31 |
+
// CommonJS
|
32 |
+
module.exports = function (root, $) {
|
33 |
+
if ( ! root ) {
|
34 |
+
root = window;
|
35 |
+
}
|
36 |
+
|
37 |
+
if ( ! $ || ! $.fn.dataTable ) {
|
38 |
+
$ = require('datatables.net')(root, $).$;
|
39 |
+
}
|
40 |
+
|
41 |
+
return factory( $, root, root.document );
|
42 |
+
};
|
43 |
+
}
|
44 |
+
else {
|
45 |
+
// Browser
|
46 |
+
factory( jQuery, window, document );
|
47 |
+
}
|
48 |
+
}(function( $, window, document, undefined ) {
|
49 |
+
'use strict';
|
50 |
+
var DataTable = $.fn.dataTable;
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Responsive is a plug-in for the DataTables library that makes use of
|
55 |
+
* DataTables' ability to change the visibility of columns, changing the
|
56 |
+
* visibility of columns so the displayed columns fit into the table container.
|
57 |
+
* The end result is that complex tables will be dynamically adjusted to fit
|
58 |
+
* into the viewport, be it on a desktop, tablet or mobile browser.
|
59 |
+
*
|
60 |
+
* Responsive for DataTables has two modes of operation, which can used
|
61 |
+
* individually or combined:
|
62 |
+
*
|
63 |
+
* * Class name based control - columns assigned class names that match the
|
64 |
+
* breakpoint logic can be shown / hidden as required for each breakpoint.
|
65 |
+
* * Automatic control - columns are automatically hidden when there is no
|
66 |
+
* room left to display them. Columns removed from the right.
|
67 |
+
*
|
68 |
+
* In additional to column visibility control, Responsive also has built into
|
69 |
+
* options to use DataTables' child row display to show / hide the information
|
70 |
+
* from the table that has been hidden. There are also two modes of operation
|
71 |
+
* for this child row display:
|
72 |
+
*
|
73 |
+
* * Inline - when the control element that the user can use to show / hide
|
74 |
+
* child rows is displayed inside the first column of the table.
|
75 |
+
* * Column - where a whole column is dedicated to be the show / hide control.
|
76 |
+
*
|
77 |
+
* Initialisation of Responsive is performed by:
|
78 |
+
*
|
79 |
+
* * Adding the class `responsive` or `dt-responsive` to the table. In this case
|
80 |
+
* Responsive will automatically be initialised with the default configuration
|
81 |
+
* options when the DataTable is created.
|
82 |
+
* * Using the `responsive` option in the DataTables configuration options. This
|
83 |
+
* can also be used to specify the configuration options, or simply set to
|
84 |
+
* `true` to use the defaults.
|
85 |
+
*
|
86 |
+
* @class
|
87 |
+
* @param {object} settings DataTables settings object for the host table
|
88 |
+
* @param {object} [opts] Configuration options
|
89 |
+
* @requires jQuery 1.7+
|
90 |
+
* @requires DataTables 1.10.3+
|
91 |
+
*
|
92 |
+
* @example
|
93 |
+
* $('#example').DataTable( {
|
94 |
+
* responsive: true
|
95 |
+
* } );
|
96 |
+
* } );
|
97 |
+
*/
|
98 |
+
var Responsive = function ( settings, opts ) {
|
99 |
+
// Sanity check that we are using DataTables 1.10 or newer
|
100 |
+
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.3' ) ) {
|
101 |
+
throw 'DataTables Responsive requires DataTables 1.10.3 or newer';
|
102 |
+
}
|
103 |
+
|
104 |
+
this.s = {
|
105 |
+
dt: new DataTable.Api( settings ),
|
106 |
+
columns: [],
|
107 |
+
current: []
|
108 |
+
};
|
109 |
+
|
110 |
+
// Check if responsive has already been initialised on this table
|
111 |
+
if ( this.s.dt.settings()[0].responsive ) {
|
112 |
+
return;
|
113 |
+
}
|
114 |
+
|
115 |
+
// details is an object, but for simplicity the user can give it as a string
|
116 |
+
// or a boolean
|
117 |
+
if ( opts && typeof opts.details === 'string' ) {
|
118 |
+
opts.details = { type: opts.details };
|
119 |
+
}
|
120 |
+
else if ( opts && opts.details === false ) {
|
121 |
+
opts.details = { type: false };
|
122 |
+
}
|
123 |
+
else if ( opts && opts.details === true ) {
|
124 |
+
opts.details = { type: 'inline' };
|
125 |
+
}
|
126 |
+
|
127 |
+
this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
|
128 |
+
settings.responsive = this;
|
129 |
+
this._constructor();
|
130 |
+
};
|
131 |
+
|
132 |
+
$.extend( Responsive.prototype, {
|
133 |
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
134 |
+
* Constructor
|
135 |
+
*/
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Initialise the Responsive instance
|
139 |
+
*
|
140 |
+
* @private
|
141 |
+
*/
|
142 |
+
_constructor: function ()
|
143 |
+
{
|
144 |
+
var that = this;
|
145 |
+
var dt = this.s.dt;
|
146 |
+
var dtPrivateSettings = dt.settings()[0];
|
147 |
+
var oldWindowWidth = $(window).width();
|
148 |
+
|
149 |
+
dt.settings()[0]._responsive = this;
|
150 |
+
|
151 |
+
// Use DataTables' throttle function to avoid processor thrashing on
|
152 |
+
// resize
|
153 |
+
$(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
|
154 |
+
// iOS has a bug whereby resize can fire when only scrolling
|
155 |
+
// See: http://stackoverflow.com/questions/8898412
|
156 |
+
var width = $(window).width();
|
157 |
+
|
158 |
+
if ( width !== oldWindowWidth ) {
|
159 |
+
that._resize();
|
160 |
+
oldWindowWidth = width;
|
161 |
+
}
|
162 |
+
} ) );
|
163 |
+
|
164 |
+
// DataTables doesn't currently trigger an event when a row is added, so
|
165 |
+
// we need to hook into its private API to enforce the hidden rows when
|
166 |
+
// new data is added
|
167 |
+
dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
|
168 |
+
if ( $.inArray( false, that.s.current ) !== -1 ) {
|
169 |
+
$('td, th', tr).each( function ( i ) {
|
170 |
+
var idx = dt.column.index( 'toData', i );
|
171 |
+
|
172 |
+
if ( that.s.current[idx] === false ) {
|
173 |
+
$(this).css('display', 'none');
|
174 |
+
}
|
175 |
+
} );
|
176 |
+
}
|
177 |
+
} );
|
178 |
+
|
179 |
+
// Destroy event handler
|
180 |
+
dt.on( 'destroy.dtr', function () {
|
181 |
+
dt.off( '.dtr' );
|
182 |
+
$( dt.table().body() ).off( '.dtr' );
|
183 |
+
$(window).off( 'resize.dtr orientationchange.dtr' );
|
184 |
+
|
185 |
+
// Restore the columns that we've hidden
|
186 |
+
$.each( that.s.current, function ( i, val ) {
|
187 |
+
if ( val === false ) {
|
188 |
+
that._setColumnVis( i, true );
|
189 |
+
}
|
190 |
+
} );
|
191 |
+
} );
|
192 |
+
|
193 |
+
// Reorder the breakpoints array here in case they have been added out
|
194 |
+
// of order
|
195 |
+
this.c.breakpoints.sort( function (a, b) {
|
196 |
+
return a.width < b.width ? 1 :
|
197 |
+
a.width > b.width ? -1 : 0;
|
198 |
+
} );
|
199 |
+
|
200 |
+
this._classLogic();
|
201 |
+
this._resizeAuto();
|
202 |
+
|
203 |
+
// Details handler
|
204 |
+
var details = this.c.details;
|
205 |
+
|
206 |
+
if ( details.type !== false ) {
|
207 |
+
that._detailsInit();
|
208 |
+
|
209 |
+
// DataTables will trigger this event on every column it shows and
|
210 |
+
// hides individually
|
211 |
+
dt.on( 'column-visibility.dtr', function (e, ctx, col, vis) {
|
212 |
+
that._classLogic();
|
213 |
+
that._resizeAuto();
|
214 |
+
that._resize();
|
215 |
+
} );
|
216 |
+
|
217 |
+
// Redraw the details box on each draw which will happen if the data
|
218 |
+
// has changed. This is used until DataTables implements a native
|
219 |
+
// `updated` event for rows
|
220 |
+
dt.on( 'draw.dtr', function () {
|
221 |
+
that._redrawChildren();
|
222 |
+
} );
|
223 |
+
|
224 |
+
$(dt.table().node()).addClass( 'dtr-'+details.type );
|
225 |
+
}
|
226 |
+
|
227 |
+
dt.on( 'column-reorder.dtr', function (e, settings, details) {
|
228 |
+
that._classLogic();
|
229 |
+
that._resizeAuto();
|
230 |
+
that._resize();
|
231 |
+
} );
|
232 |
+
|
233 |
+
// Change in column sizes means we need to calc
|
234 |
+
dt.on( 'column-sizing.dtr', function () {
|
235 |
+
that._resizeAuto();
|
236 |
+
that._resize();
|
237 |
+
});
|
238 |
+
|
239 |
+
dt.on( 'init.dtr', function (e, settings, details) {
|
240 |
+
that._resizeAuto();
|
241 |
+
that._resize();
|
242 |
+
|
243 |
+
// If columns were hidden, then DataTables needs to adjust the
|
244 |
+
// column sizing
|
245 |
+
if ( $.inArray( false, that.s.current ) ) {
|
246 |
+
dt.columns.adjust();
|
247 |
+
}
|
248 |
+
} );
|
249 |
+
|
250 |
+
// First pass - draw the table for the current viewport size
|
251 |
+
this._resize();
|
252 |
+
},
|
253 |
+
|
254 |
+
|
255 |
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
256 |
+
* Private methods
|
257 |
+
*/
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Calculate the visibility for the columns in a table for a given
|
261 |
+
* breakpoint. The result is pre-determined based on the class logic if
|
262 |
+
* class names are used to control all columns, but the width of the table
|
263 |
+
* is also used if there are columns which are to be automatically shown
|
264 |
+
* and hidden.
|
265 |
+
*
|
266 |
+
* @param {string} breakpoint Breakpoint name to use for the calculation
|
267 |
+
* @return {array} Array of boolean values initiating the visibility of each
|
268 |
+
* column.
|
269 |
+
* @private
|
270 |
+
*/
|
271 |
+
_columnsVisiblity: function ( breakpoint )
|
272 |
+
{
|
273 |
+
var dt = this.s.dt;
|
274 |
+
var columns = this.s.columns;
|
275 |
+
var i, ien;
|
276 |
+
|
277 |
+
// Create an array that defines the column ordering based first on the
|
278 |
+
// column's priority, and secondly the column index. This allows the
|
279 |
+
// columns to be removed from the right if the priority matches
|
280 |
+
var order = columns
|
281 |
+
.map( function ( col, idx ) {
|
282 |
+
return {
|
283 |
+
columnIdx: idx,
|
284 |
+
priority: col.priority
|
285 |
+
};
|
286 |
+
} )
|
287 |
+
.sort( function ( a, b ) {
|
288 |
+
if ( a.priority !== b.priority ) {
|
289 |
+
return a.priority - b.priority;
|
290 |
+
}
|
291 |
+
return a.columnIdx - b.columnIdx;
|
292 |
+
} );
|
293 |
+
|
294 |
+
// Class logic - determine which columns are in this breakpoint based
|
295 |
+
// on the classes. If no class control (i.e. `auto`) then `-` is used
|
296 |
+
// to indicate this to the rest of the function
|
297 |
+
var display = $.map( columns, function ( col ) {
|
298 |
+
return col.auto && col.minWidth === null ?
|
299 |
+
false :
|
300 |
+
col.auto === true ?
|
301 |
+
'-' :
|
302 |
+
$.inArray( breakpoint, col.includeIn ) !== -1;
|
303 |
+
} );
|
304 |
+
|
305 |
+
// Auto column control - first pass: how much width is taken by the
|
306 |
+
// ones that must be included from the non-auto columns
|
307 |
+
var requiredWidth = 0;
|
308 |
+
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
309 |
+
if ( display[i] === true ) {
|
310 |
+
requiredWidth += columns[i].minWidth;
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
// Second pass, use up any remaining width for other columns. For
|
315 |
+
// scrolling tables we need to subtract the width of the scrollbar. It
|
316 |
+
// may not be requires which makes this sub-optimal, but it would
|
317 |
+
// require another full redraw to make complete use of those extra few
|
318 |
+
// pixels
|
319 |
+
var scrolling = dt.settings()[0].oScroll;
|
320 |
+
var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
|
321 |
+
var widthAvailable = dt.table().container().offsetWidth - bar;
|
322 |
+
var usedWidth = widthAvailable - requiredWidth;
|
323 |
+
|
324 |
+
// Control column needs to always be included. This makes it sub-
|
325 |
+
// optimal in terms of using the available with, but to stop layout
|
326 |
+
// thrashing or overflow. Also we need to account for the control column
|
327 |
+
// width first so we know how much width is available for the other
|
328 |
+
// columns, since the control column might not be the first one shown
|
329 |
+
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
330 |
+
if ( columns[i].control ) {
|
331 |
+
usedWidth -= columns[i].minWidth;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
// Allow columns to be shown (counting by priority and then right to
|
336 |
+
// left) until we run out of room
|
337 |
+
var empty = false;
|
338 |
+
for ( i=0, ien=order.length ; i<ien ; i++ ) {
|
339 |
+
var colIdx = order[i].columnIdx;
|
340 |
+
|
341 |
+
if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
|
342 |
+
// Once we've found a column that won't fit we don't let any
|
343 |
+
// others display either, or columns might disappear in the
|
344 |
+
// middle of the table
|
345 |
+
if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
|
346 |
+
empty = true;
|
347 |
+
display[colIdx] = false;
|
348 |
+
}
|
349 |
+
else {
|
350 |
+
display[colIdx] = true;
|
351 |
+
}
|
352 |
+
|
353 |
+
usedWidth -= columns[colIdx].minWidth;
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
// Determine if the 'control' column should be shown (if there is one).
|
358 |
+
// This is the case when there is a hidden column (that is not the
|
359 |
+
// control column). The two loops look inefficient here, but they are
|
360 |
+
// trivial and will fly through. We need to know the outcome from the
|
361 |
+
// first , before the action in the second can be taken
|
362 |
+
var showControl = false;
|
363 |
+
|
364 |
+
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
365 |
+
if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
|
366 |
+
showControl = true;
|
367 |
+
break;
|
368 |
+
}
|
369 |
+
}
|
370 |
+
|
371 |
+
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
372 |
+
if ( columns[i].control ) {
|
373 |
+
display[i] = showControl;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
// Finally we need to make sure that there is at least one column that
|
378 |
+
// is visible
|
379 |
+
if ( $.inArray( true, display ) === -1 ) {
|
380 |
+
display[0] = true;
|
381 |
+
}
|
382 |
+
|
383 |
+
return display;
|
384 |
+
},
|
385 |
+
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Create the internal `columns` array with information about the columns
|
389 |
+
* for the table. This includes determining which breakpoints the column
|
390 |
+
* will appear in, based upon class names in the column, which makes up the
|
391 |
+
* vast majority of this method.
|
392 |
+
*
|
393 |
+
* @private
|
394 |
+
*/
|
395 |
+
_classLogic: function ()
|
396 |
+
{
|
397 |
+
var that = this;
|
398 |
+
var calc = {};
|
399 |
+
var breakpoints = this.c.breakpoints;
|
400 |
+
var dt = this.s.dt;
|
401 |
+
var columns = dt.columns().eq(0).map( function (i) {
|
402 |
+
var column = this.column(i);
|
403 |
+
var className = column.header().className;
|
404 |
+
var priority = dt.settings()[0].aoColumns[i].responsivePriority;
|
405 |
+
|
406 |
+
if ( priority === undefined ) {
|
407 |
+
var dataPriority = $(column.header()).data('priority');
|
408 |
+
|
409 |
+
priority = dataPriority !== undefined ?
|
410 |
+
dataPriority * 1 :
|
411 |
+
10000;
|
412 |
+
}
|
413 |
+
|
414 |
+
return {
|
415 |
+
className: className,
|
416 |
+
includeIn: [],
|
417 |
+
auto: false,
|
418 |
+
control: false,
|
419 |
+
never: className.match(/\bnever\b/) ? true : false,
|
420 |
+
priority: priority
|
421 |
+
};
|
422 |
+
} );
|
423 |
+
|
424 |
+
// Simply add a breakpoint to `includeIn` array, ensuring that there are
|
425 |
+
// no duplicates
|
426 |
+
var add = function ( colIdx, name ) {
|
427 |
+
var includeIn = columns[ colIdx ].includeIn;
|
428 |
+
|
429 |
+
if ( $.inArray( name, includeIn ) === -1 ) {
|
430 |
+
includeIn.push( name );
|
431 |
+
}
|
432 |
+
};
|
433 |
+
|
434 |
+
var column = function ( colIdx, name, operator, matched ) {
|
435 |
+
var size, i, ien;
|
436 |
+
|
437 |
+
if ( ! operator ) {
|
438 |
+
columns[ colIdx ].includeIn.push( name );
|
439 |
+
}
|
440 |
+
else if ( operator === 'max-' ) {
|
441 |
+
// Add this breakpoint and all smaller
|
442 |
+
size = that._find( name ).width;
|
443 |
+
|
444 |
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
445 |
+
if ( breakpoints[i].width <= size ) {
|
446 |
+
add( colIdx, breakpoints[i].name );
|
447 |
+
}
|
448 |
+
}
|
449 |
+
}
|
450 |
+
else if ( operator === 'min-' ) {
|
451 |
+
// Add this breakpoint and all larger
|
452 |
+
size = that._find( name ).width;
|
453 |
+
|
454 |
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
455 |
+
if ( breakpoints[i].width >= size ) {
|
456 |
+
add( colIdx, breakpoints[i].name );
|
457 |
+
}
|
458 |
+
}
|
459 |
+
}
|
460 |
+
else if ( operator === 'not-' ) {
|
461 |
+
// Add all but this breakpoint
|
462 |
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
463 |
+
if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
|
464 |
+
add( colIdx, breakpoints[i].name );
|
465 |
+
}
|
466 |
+
}
|
467 |
+
}
|
468 |
+
};
|
469 |
+
|
470 |
+
// Loop over each column and determine if it has a responsive control
|
471 |
+
// class
|
472 |
+
columns.each( function ( col, i ) {
|
473 |
+
var classNames = col.className.split(' ');
|
474 |
+
var hasClass = false;
|
475 |
+
|
476 |
+
// Split the class name up so multiple rules can be applied if needed
|
477 |
+
for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
|
478 |
+
var className = $.trim( classNames[k] );
|
479 |
+
|
480 |
+
if ( className === 'all' ) {
|
481 |
+
// Include in all
|
482 |
+
hasClass = true;
|
483 |
+
col.includeIn = $.map( breakpoints, function (a) {
|
484 |
+
return a.name;
|
485 |
+
} );
|
486 |
+
return;
|
487 |
+
}
|
488 |
+
else if ( className === 'none' || col.never ) {
|
489 |
+
// Include in none (default) and no auto
|
490 |
+
hasClass = true;
|
491 |
+
return;
|
492 |
+
}
|
493 |
+
else if ( className === 'control' ) {
|
494 |
+
// Special column that is only visible, when one of the other
|
495 |
+
// columns is hidden. This is used for the details control
|
496 |
+
hasClass = true;
|
497 |
+
col.control = true;
|
498 |
+
return;
|
499 |
+
}
|
500 |
+
|
501 |
+
$.each( breakpoints, function ( j, breakpoint ) {
|
502 |
+
// Does this column have a class that matches this breakpoint?
|
503 |
+
var brokenPoint = breakpoint.name.split('-');
|
504 |
+
var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
|
505 |
+
var match = className.match( re );
|
506 |
+
|
507 |
+
if ( match ) {
|
508 |
+
hasClass = true;
|
509 |
+
|
510 |
+
if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
|
511 |
+
// Class name matches breakpoint name fully
|
512 |
+
column( i, breakpoint.name, match[1], match[2]+match[3] );
|
513 |
+
}
|
514 |
+
else if ( match[2] === brokenPoint[0] && ! match[3] ) {
|
515 |
+
// Class name matched primary breakpoint name with no qualifier
|
516 |
+
column( i, breakpoint.name, match[1], match[2] );
|
517 |
+
}
|
518 |
+
}
|
519 |
+
} );
|
520 |
+
}
|
521 |
+
|
522 |
+
// If there was no control class, then automatic sizing is used
|
523 |
+
if ( ! hasClass ) {
|
524 |
+
col.auto = true;
|
525 |
+
}
|
526 |
+
} );
|
527 |
+
|
528 |
+
this.s.columns = columns;
|
529 |
+
},
|
530 |
+
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Show the details for the child row
|
534 |
+
*
|
535 |
+
* @param {DataTables.Api} row API instance for the row
|
536 |
+
* @param {boolean} update Update flag
|
537 |
+
* @private
|
538 |
+
*/
|
539 |
+
_detailsDisplay: function ( row, update )
|
540 |
+
{
|
541 |
+
var that = this;
|
542 |
+
var dt = this.s.dt;
|
543 |
+
var details = this.c.details;
|
544 |
+
|
545 |
+
if ( details && details.type !== false ) {
|
546 |
+
var res = details.display( row, update, function () {
|
547 |
+
return details.renderer(
|
548 |
+
dt, row[0], that._detailsObj(row[0])
|
549 |
+
);
|
550 |
+
} );
|
551 |
+
|
552 |
+
if ( res === true || res === false ) {
|
553 |
+
$(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
|
554 |
+
}
|
555 |
+
}
|
556 |
+
},
|
557 |
+
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Initialisation for the details handler
|
561 |
+
*
|
562 |
+
* @private
|
563 |
+
*/
|
564 |
+
_detailsInit: function ()
|
565 |
+
{
|
566 |
+
var that = this;
|
567 |
+
var dt = this.s.dt;
|
568 |
+
var details = this.c.details;
|
569 |
+
|
570 |
+
// The inline type always uses the first child as the target
|
571 |
+
if ( details.type === 'inline' ) {
|
572 |
+
details.target = 'td:first-child, th:first-child';
|
573 |
+
}
|
574 |
+
|
575 |
+
// Keyboard accessibility
|
576 |
+
dt.on( 'draw.dtr', function () {
|
577 |
+
that._tabIndexes();
|
578 |
+
} );
|
579 |
+
that._tabIndexes(); // Initial draw has already happened
|
580 |
+
|
581 |
+
$( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
|
582 |
+
if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
|
583 |
+
$(this).click();
|
584 |
+
}
|
585 |
+
} );
|
586 |
+
|
587 |
+
// type.target can be a string jQuery selector or a column index
|
588 |
+
var target = details.target;
|
589 |
+
var selector = typeof target === 'string' ? target : 'td, th';
|
590 |
+
|
591 |
+
// Click handler to show / hide the details rows when they are available
|
592 |
+
$( dt.table().body() )
|
593 |
+
.on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
|
594 |
+
// If the table is not collapsed (i.e. there is no hidden columns)
|
595 |
+
// then take no action
|
596 |
+
if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
|
597 |
+
return;
|
598 |
+
}
|
599 |
+
|
600 |
+
// Check that the row is actually a DataTable's controlled node
|
601 |
+
if ( ! dt.row( $(this).closest('tr') ).length ) {
|
602 |
+
return;
|
603 |
+
}
|
604 |
+
|
605 |
+
// For column index, we determine if we should act or not in the
|
606 |
+
// handler - otherwise it is already okay
|
607 |
+
if ( typeof target === 'number' ) {
|
608 |
+
var targetIdx = target < 0 ?
|
609 |
+
dt.columns().eq(0).length + target :
|
610 |
+
target;
|
611 |
+
|
612 |
+
if ( dt.cell( this ).index().column !== targetIdx ) {
|
613 |
+
return;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
// $().closest() includes itself in its check
|
618 |
+
var row = dt.row( $(this).closest('tr') );
|
619 |
+
|
620 |
+
// Check event type to do an action
|
621 |
+
if ( e.type === 'click' ) {
|
622 |
+
// The renderer is given as a function so the caller can execute it
|
623 |
+
// only when they need (i.e. if hiding there is no point is running
|
624 |
+
// the renderer)
|
625 |
+
that._detailsDisplay( row, false );
|
626 |
+
}
|
627 |
+
else if ( e.type === 'mousedown' ) {
|
628 |
+
// For mouse users, prevent the focus ring from showing
|
629 |
+
$(this).css('outline', 'none');
|
630 |
+
}
|
631 |
+
else if ( e.type === 'mouseup' ) {
|
632 |
+
// And then re-allow at the end of the click
|
633 |
+
$(this).blur().css('outline', '');
|
634 |
+
}
|
635 |
+
} );
|
636 |
+
},
|
637 |
+
|
638 |
+
|
639 |
+
/**
|
640 |
+
* Get the details to pass to a renderer for a row
|
641 |
+
* @param {int} rowIdx Row index
|
642 |
+
* @private
|
643 |
+
*/
|
644 |
+
_detailsObj: function ( rowIdx )
|
645 |
+
{
|
646 |
+
var that = this;
|
647 |
+
var dt = this.s.dt;
|
648 |
+
|
649 |
+
return $.map( this.s.columns, function( col, i ) {
|
650 |
+
// Never and control columns should not be passed to the renderer
|
651 |
+
if ( col.never || col.control ) {
|
652 |
+
return;
|
653 |
+
}
|
654 |
+
|
655 |
+
return {
|
656 |
+
title: dt.settings()[0].aoColumns[ i ].sTitle,
|
657 |
+
data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
|
658 |
+
hidden: dt.column( i ).visible() && !that.s.current[ i ],
|
659 |
+
columnIndex: i,
|
660 |
+
rowIndex: rowIdx
|
661 |
+
};
|
662 |
+
} );
|
663 |
+
},
|
664 |
+
|
665 |
+
|
666 |
+
/**
|
667 |
+
* Find a breakpoint object from a name
|
668 |
+
*
|
669 |
+
* @param {string} name Breakpoint name to find
|
670 |
+
* @return {object} Breakpoint description object
|
671 |
+
* @private
|
672 |
+
*/
|
673 |
+
_find: function ( name )
|
674 |
+
{
|
675 |
+
var breakpoints = this.c.breakpoints;
|
676 |
+
|
677 |
+
for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
678 |
+
if ( breakpoints[i].name === name ) {
|
679 |
+
return breakpoints[i];
|
680 |
+
}
|
681 |
+
}
|
682 |
+
},
|
683 |
+
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Re-create the contents of the child rows as the display has changed in
|
687 |
+
* some way.
|
688 |
+
*
|
689 |
+
* @private
|
690 |
+
*/
|
691 |
+
_redrawChildren: function ()
|
692 |
+
{
|
693 |
+
var that = this;
|
694 |
+
var dt = this.s.dt;
|
695 |
+
|
696 |
+
dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
|
697 |
+
var row = dt.row( idx );
|
698 |
+
|
699 |
+
that._detailsDisplay( dt.row( idx ), true );
|
700 |
+
} );
|
701 |
+
},
|
702 |
+
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Alter the table display for a resized viewport. This involves first
|
706 |
+
* determining what breakpoint the window currently is in, getting the
|
707 |
+
* column visibilities to apply and then setting them.
|
708 |
+
*
|
709 |
+
* @private
|
710 |
+
*/
|
711 |
+
_resize: function ()
|
712 |
+
{
|
713 |
+
var that = this;
|
714 |
+
var dt = this.s.dt;
|
715 |
+
var width = $(window).width();
|
716 |
+
var breakpoints = this.c.breakpoints;
|
717 |
+
var breakpoint = breakpoints[0].name;
|
718 |
+
var columns = this.s.columns;
|
719 |
+
var i, ien;
|
720 |
+
var oldVis = this.s.current.slice();
|
721 |
+
|
722 |
+
// Determine what breakpoint we are currently at
|
723 |
+
for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
|
724 |
+
if ( width <= breakpoints[i].width ) {
|
725 |
+
breakpoint = breakpoints[i].name;
|
726 |
+
break;
|
727 |
+
}
|
728 |
+
}
|
729 |
+
|
730 |
+
// Show the columns for that break point
|
731 |
+
var columnsVis = this._columnsVisiblity( breakpoint );
|
732 |
+
this.s.current = columnsVis;
|
733 |
+
|
734 |
+
// Set the class before the column visibility is changed so event
|
735 |
+
// listeners know what the state is. Need to determine if there are
|
736 |
+
// any columns that are not visible but can be shown
|
737 |
+
var collapsedClass = false;
|
738 |
+
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
739 |
+
if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control ) {
|
740 |
+
collapsedClass = true;
|
741 |
+
break;
|
742 |
+
}
|
743 |
+
}
|
744 |
+
|
745 |
+
$( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
|
746 |
+
|
747 |
+
var changed = false;
|
748 |
+
|
749 |
+
dt.columns().eq(0).each( function ( colIdx, i ) {
|
750 |
+
if ( columnsVis[i] !== oldVis[i] ) {
|
751 |
+
changed = true;
|
752 |
+
that._setColumnVis( colIdx, columnsVis[i] );
|
753 |
+
}
|
754 |
+
} );
|
755 |
+
|
756 |
+
if ( changed ) {
|
757 |
+
this._redrawChildren();
|
758 |
+
|
759 |
+
// Inform listeners of the change
|
760 |
+
$(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
|
761 |
+
}
|
762 |
+
},
|
763 |
+
|
764 |
+
|
765 |
+
/**
|
766 |
+
* Determine the width of each column in the table so the auto column hiding
|
767 |
+
* has that information to work with. This method is never going to be 100%
|
768 |
+
* perfect since column widths can change slightly per page, but without
|
769 |
+
* seriously compromising performance this is quite effective.
|
770 |
+
*
|
771 |
+
* @private
|
772 |
+
*/
|
773 |
+
_resizeAuto: function ()
|
774 |
+
{
|
775 |
+
var dt = this.s.dt;
|
776 |
+
var columns = this.s.columns;
|
777 |
+
|
778 |
+
// Are we allowed to do auto sizing?
|
779 |
+
if ( ! this.c.auto ) {
|
780 |
+
return;
|
781 |
+
}
|
782 |
+
|
783 |
+
// Are there any columns that actually need auto-sizing, or do they all
|
784 |
+
// have classes defined
|
785 |
+
if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
|
786 |
+
return;
|
787 |
+
}
|
788 |
+
|
789 |
+
// Clone the table with the current data in it
|
790 |
+
var tableWidth = dt.table().node().offsetWidth;
|
791 |
+
var columnWidths = dt.columns;
|
792 |
+
var clonedTable = dt.table().node().cloneNode( false );
|
793 |
+
var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
|
794 |
+
var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
|
795 |
+
|
796 |
+
// Header
|
797 |
+
var headerCells = dt.columns()
|
798 |
+
.header()
|
799 |
+
.filter( function (idx) {
|
800 |
+
return dt.column(idx).visible();
|
801 |
+
} )
|
802 |
+
.to$()
|
803 |
+
.clone( false )
|
804 |
+
.css( 'display', 'table-cell' );
|
805 |
+
|
806 |
+
// Body rows - we don't need to take account of DataTables' column
|
807 |
+
// visibility since we implement our own here (hence the `display` set)
|
808 |
+
$(clonedBody)
|
809 |
+
.append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
|
810 |
+
.find( 'th, td' ).css( 'display', '' );
|
811 |
+
|
812 |
+
// Footer
|
813 |
+
var footer = dt.table().footer();
|
814 |
+
if ( footer ) {
|
815 |
+
var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
|
816 |
+
var footerCells = dt.columns()
|
817 |
+
.footer()
|
818 |
+
.filter( function (idx) {
|
819 |
+
return dt.column(idx).visible();
|
820 |
+
} )
|
821 |
+
.to$()
|
822 |
+
.clone( false )
|
823 |
+
.css( 'display', 'table-cell' );
|
824 |
+
|
825 |
+
$('<tr/>')
|
826 |
+
.append( footerCells )
|
827 |
+
.appendTo( clonedFooter );
|
828 |
+
}
|
829 |
+
|
830 |
+
$('<tr/>')
|
831 |
+
.append( headerCells )
|
832 |
+
.appendTo( clonedHeader );
|
833 |
+
|
834 |
+
// In the inline case extra padding is applied to the first column to
|
835 |
+
// give space for the show / hide icon. We need to use this in the
|
836 |
+
// calculation
|
837 |
+
if ( this.c.details.type === 'inline' ) {
|
838 |
+
$(clonedTable).addClass( 'dtr-inline collapsed' );
|
839 |
+
}
|
840 |
+
|
841 |
+
// It is unsafe to insert elements with the same name into the DOM
|
842 |
+
// multiple times. For example, cloning and inserting a checked radio
|
843 |
+
// clears the chcecked state of the original radio.
|
844 |
+
$( clonedTable ).find( '[name]' ).removeAttr( 'name' );
|
845 |
+
|
846 |
+
var inserted = $('<div/>')
|
847 |
+
.css( {
|
848 |
+
width: 1,
|
849 |
+
height: 1,
|
850 |
+
overflow: 'hidden'
|
851 |
+
} )
|
852 |
+
.append( clonedTable );
|
853 |
+
|
854 |
+
inserted.insertBefore( dt.table().node() );
|
855 |
+
|
856 |
+
// The cloned header now contains the smallest that each column can be
|
857 |
+
headerCells.each( function (i) {
|
858 |
+
var idx = dt.column.index( 'fromVisible', i );
|
859 |
+
columns[ idx ].minWidth = this.offsetWidth || 0;
|
860 |
+
} );
|
861 |
+
|
862 |
+
inserted.remove();
|
863 |
+
},
|
864 |
+
|
865 |
+
/**
|
866 |
+
* Set a column's visibility.
|
867 |
+
*
|
868 |
+
* We don't use DataTables' column visibility controls in order to ensure
|
869 |
+
* that column visibility can Responsive can no-exist. Since only IE8+ is
|
870 |
+
* supported (and all evergreen browsers of course) the control of the
|
871 |
+
* display attribute works well.
|
872 |
+
*
|
873 |
+
* @param {integer} col Column index
|
874 |
+
* @param {boolean} showHide Show or hide (true or false)
|
875 |
+
* @private
|
876 |
+
*/
|
877 |
+
_setColumnVis: function ( col, showHide )
|
878 |
+
{
|
879 |
+
var dt = this.s.dt;
|
880 |
+
var display = showHide ? '' : 'none'; // empty string will remove the attr
|
881 |
+
|
882 |
+
$( dt.column( col ).header() ).css( 'display', display );
|
883 |
+
$( dt.column( col ).footer() ).css( 'display', display );
|
884 |
+
dt.column( col ).nodes().to$().css( 'display', display );
|
885 |
+
},
|
886 |
+
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Update the cell tab indexes for keyboard accessibility. This is called on
|
890 |
+
* every table draw - that is potentially inefficient, but also the least
|
891 |
+
* complex option given that column visibility can change on the fly. Its a
|
892 |
+
* shame user-focus was removed from CSS 3 UI, as it would have solved this
|
893 |
+
* issue with a single CSS statement.
|
894 |
+
*
|
895 |
+
* @private
|
896 |
+
*/
|
897 |
+
_tabIndexes: function ()
|
898 |
+
{
|
899 |
+
var dt = this.s.dt;
|
900 |
+
var cells = dt.cells( { page: 'current' } ).nodes().to$();
|
901 |
+
var ctx = dt.settings()[0];
|
902 |
+
var target = this.c.details.target;
|
903 |
+
|
904 |
+
cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
|
905 |
+
|
906 |
+
var selector = typeof target === 'number' ?
|
907 |
+
':eq('+target+')' :
|
908 |
+
target;
|
909 |
+
|
910 |
+
$( selector, dt.rows( { page: 'current' } ).nodes() )
|
911 |
+
.attr( 'tabIndex', ctx.iTabIndex )
|
912 |
+
.data( 'dtr-keyboard', 1 );
|
913 |
+
}
|
914 |
+
} );
|
915 |
+
|
916 |
+
|
917 |
+
/**
|
918 |
+
* List of default breakpoints. Each item in the array is an object with two
|
919 |
+
* properties:
|
920 |
+
*
|
921 |
+
* * `name` - the breakpoint name.
|
922 |
+
* * `width` - the breakpoint width
|
923 |
+
*
|
924 |
+
* @name Responsive.breakpoints
|
925 |
+
* @static
|
926 |
+
*/
|
927 |
+
Responsive.breakpoints = [
|
928 |
+
{ name: 'desktop', width: Infinity },
|
929 |
+
{ name: 'tablet-l', width: 1024 },
|
930 |
+
{ name: 'tablet-p', width: 768 },
|
931 |
+
{ name: 'mobile-l', width: 480 },
|
932 |
+
{ name: 'mobile-p', width: 320 }
|
933 |
+
];
|
934 |
+
|
935 |
+
|
936 |
+
/**
|
937 |
+
* Display methods - functions which define how the hidden data should be shown
|
938 |
+
* in the table.
|
939 |
+
*
|
940 |
+
* @namespace
|
941 |
+
* @name Responsive.defaults
|
942 |
+
* @static
|
943 |
+
*/
|
944 |
+
Responsive.display = {
|
945 |
+
childRow: function ( row, update, render ) {
|
946 |
+
if ( update ) {
|
947 |
+
if ( $(row.node()).hasClass('parent') ) {
|
948 |
+
row.child( render(), 'child' ).show();
|
949 |
+
|
950 |
+
return true;
|
951 |
+
}
|
952 |
+
}
|
953 |
+
else {
|
954 |
+
if ( ! row.child.isShown() ) {
|
955 |
+
row.child( render(), 'child' ).show();
|
956 |
+
$( row.node() ).addClass( 'parent' );
|
957 |
+
|
958 |
+
return true;
|
959 |
+
}
|
960 |
+
else {
|
961 |
+
row.child( false );
|
962 |
+
$( row.node() ).removeClass( 'parent' );
|
963 |
+
|
964 |
+
return false;
|
965 |
+
}
|
966 |
+
}
|
967 |
+
},
|
968 |
+
|
969 |
+
childRowImmediate: function ( row, update, render ) {
|
970 |
+
if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
|
971 |
+
// User interaction and the row is show, or nothing to show
|
972 |
+
row.child( false );
|
973 |
+
$( row.node() ).removeClass( 'parent' );
|
974 |
+
|
975 |
+
return false;
|
976 |
+
}
|
977 |
+
else {
|
978 |
+
// Display
|
979 |
+
row.child( render(), 'child' ).show();
|
980 |
+
$( row.node() ).addClass( 'parent' );
|
981 |
+
|
982 |
+
return true;
|
983 |
+
}
|
984 |
+
},
|
985 |
+
|
986 |
+
// This is a wrapper so the modal options for Bootstrap and jQuery UI can
|
987 |
+
// have options passed into them. This specific one doesn't need to be a
|
988 |
+
// function but it is for consistency in the `modal` name
|
989 |
+
modal: function ( options ) {
|
990 |
+
return function ( row, update, render ) {
|
991 |
+
if ( ! update ) {
|
992 |
+
// Show a modal
|
993 |
+
var close = function () {
|
994 |
+
modal.remove(); // will tidy events for us
|
995 |
+
$(document).off( 'keypress.dtr' );
|
996 |
+
};
|
997 |
+
|
998 |
+
var modal = $('<div class="dtr-modal"/>')
|
999 |
+
.append( $('<div class="dtr-modal-display"/>')
|
1000 |
+
.append( $('<div class="dtr-modal-content"/>')
|
1001 |
+
.append( render() )
|
1002 |
+
)
|
1003 |
+
.append( $('<div class="dtr-modal-close">×</div>' )
|
1004 |
+
.click( function () {
|
1005 |
+
close();
|
1006 |
+
} )
|
1007 |
+
)
|
1008 |
+
)
|
1009 |
+
.append( $('<div class="dtr-modal-background"/>')
|
1010 |
+
.click( function () {
|
1011 |
+
close();
|
1012 |
+
} )
|
1013 |
+
)
|
1014 |
+
.appendTo( 'body' );
|
1015 |
+
|
1016 |
+
$(document).on( 'keyup.dtr', function (e) {
|
1017 |
+
if ( e.keyCode === 27 ) {
|
1018 |
+
e.stopPropagation();
|
1019 |
+
|
1020 |
+
close();
|
1021 |
+
}
|
1022 |
+
} );
|
1023 |
+
}
|
1024 |
+
else {
|
1025 |
+
$('div.dtr-modal-content')
|
1026 |
+
.empty()
|
1027 |
+
.append( render() );
|
1028 |
+
}
|
1029 |
+
|
1030 |
+
if ( options && options.header ) {
|
1031 |
+
$('div.dtr-modal-content').prepend(
|
1032 |
+
'<h2>'+options.header( row )+'</h2>'
|
1033 |
+
);
|
1034 |
+
}
|
1035 |
+
};
|
1036 |
+
}
|
1037 |
+
};
|
1038 |
+
|
1039 |
+
|
1040 |
+
/**
|
1041 |
+
* Display methods - functions which define how the hidden data should be shown
|
1042 |
+
* in the table.
|
1043 |
+
*
|
1044 |
+
* @namespace
|
1045 |
+
* @name Responsive.defaults
|
1046 |
+
* @static
|
1047 |
+
*/
|
1048 |
+
Responsive.renderer = {
|
1049 |
+
listHidden: function () {
|
1050 |
+
return function ( api, rowIdx, columns ) {
|
1051 |
+
var data = $.map( columns, function ( col ) {
|
1052 |
+
return col.hidden ?
|
1053 |
+
'<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
|
1054 |
+
'<span class="dtr-title">'+
|
1055 |
+
col.title+
|
1056 |
+
'</span> '+
|
1057 |
+
'<span class="dtr-data">'+
|
1058 |
+
col.data+
|
1059 |
+
'</span>'+
|
1060 |
+
'</li>' :
|
1061 |
+
'';
|
1062 |
+
} ).join('');
|
1063 |
+
|
1064 |
+
return data ?
|
1065 |
+
$('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
|
1066 |
+
false;
|
1067 |
+
}
|
1068 |
+
},
|
1069 |
+
|
1070 |
+
tableAll: function ( options ) {
|
1071 |
+
options = $.extend( {
|
1072 |
+
tableClass: ''
|
1073 |
+
}, options );
|
1074 |
+
|
1075 |
+
return function ( api, rowIdx, columns ) {
|
1076 |
+
var data = $.map( columns, function ( col ) {
|
1077 |
+
return '<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
|
1078 |
+
'<td>'+col.title+':'+'</td> '+
|
1079 |
+
'<td>'+col.data+'</td>'+
|
1080 |
+
'</tr>';
|
1081 |
+
} ).join('');
|
1082 |
+
|
1083 |
+
return $('<table class="'+options.tableClass+'" width="100%"/>').append( data );
|
1084 |
+
}
|
1085 |
+
}
|
1086 |
+
};
|
1087 |
+
|
1088 |
+
/**
|
1089 |
+
* Responsive default settings for initialisation
|
1090 |
+
*
|
1091 |
+
* @namespace
|
1092 |
+
* @name Responsive.defaults
|
1093 |
+
* @static
|
1094 |
+
*/
|
1095 |
+
Responsive.defaults = {
|
1096 |
+
/**
|
1097 |
+
* List of breakpoints for the instance. Note that this means that each
|
1098 |
+
* instance can have its own breakpoints. Additionally, the breakpoints
|
1099 |
+
* cannot be changed once an instance has been creased.
|
1100 |
+
*
|
1101 |
+
* @type {Array}
|
1102 |
+
* @default Takes the value of `Responsive.breakpoints`
|
1103 |
+
*/
|
1104 |
+
breakpoints: Responsive.breakpoints,
|
1105 |
+
|
1106 |
+
/**
|
1107 |
+
* Enable / disable auto hiding calculations. It can help to increase
|
1108 |
+
* performance slightly if you disable this option, but all columns would
|
1109 |
+
* need to have breakpoint classes assigned to them
|
1110 |
+
*
|
1111 |
+
* @type {Boolean}
|
1112 |
+
* @default `true`
|
1113 |
+
*/
|
1114 |
+
auto: true,
|
1115 |
+
|
1116 |
+
/**
|
1117 |
+
* Details control. If given as a string value, the `type` property of the
|
1118 |
+
* default object is set to that value, and the defaults used for the rest
|
1119 |
+
* of the object - this is for ease of implementation.
|
1120 |
+
*
|
1121 |
+
* The object consists of the following properties:
|
1122 |
+
*
|
1123 |
+
* * `display` - A function that is used to show and hide the hidden details
|
1124 |
+
* * `renderer` - function that is called for display of the child row data.
|
1125 |
+
* The default function will show the data from the hidden columns
|
1126 |
+
* * `target` - Used as the selector for what objects to attach the child
|
1127 |
+
* open / close to
|
1128 |
+
* * `type` - `false` to disable the details display, `inline` or `column`
|
1129 |
+
* for the two control types
|
1130 |
+
*
|
1131 |
+
* @type {Object|string}
|
1132 |
+
*/
|
1133 |
+
details: {
|
1134 |
+
display: Responsive.display.childRow,
|
1135 |
+
|
1136 |
+
renderer: Responsive.renderer.listHidden(),
|
1137 |
+
|
1138 |
+
target: 0,
|
1139 |
+
|
1140 |
+
type: 'inline'
|
1141 |
+
},
|
1142 |
+
|
1143 |
+
/**
|
1144 |
+
* Orthogonal data request option. This is used to define the data type
|
1145 |
+
* requested when Responsive gets the data to show in the child row.
|
1146 |
+
*
|
1147 |
+
* @type {String}
|
1148 |
+
*/
|
1149 |
+
orthogonal: 'display'
|
1150 |
+
};
|
1151 |
+
|
1152 |
+
|
1153 |
+
/*
|
1154 |
+
* API
|
1155 |
+
*/
|
1156 |
+
var Api = $.fn.dataTable.Api;
|
1157 |
+
|
1158 |
+
// Doesn't do anything - work around for a bug in DT... Not documented
|
1159 |
+
Api.register( 'responsive()', function () {
|
1160 |
+
return this;
|
1161 |
+
} );
|
1162 |
+
|
1163 |
+
Api.register( 'responsive.index()', function ( li ) {
|
1164 |
+
li = $(li);
|
1165 |
+
|
1166 |
+
return {
|
1167 |
+
column: li.data('dtr-index'),
|
1168 |
+
row: li.parent().data('dtr-index')
|
1169 |
+
};
|
1170 |
+
} );
|
1171 |
+
|
1172 |
+
Api.register( 'responsive.rebuild()', function () {
|
1173 |
+
return this.iterator( 'table', function ( ctx ) {
|
1174 |
+
if ( ctx._responsive ) {
|
1175 |
+
ctx._responsive._classLogic();
|
1176 |
+
}
|
1177 |
+
} );
|
1178 |
+
} );
|
1179 |
+
|
1180 |
+
Api.register( 'responsive.recalc()', function () {
|
1181 |
+
return this.iterator( 'table', function ( ctx ) {
|
1182 |
+
if ( ctx._responsive ) {
|
1183 |
+
ctx._responsive._resizeAuto();
|
1184 |
+
ctx._responsive._resize();
|
1185 |
+
}
|
1186 |
+
} );
|
1187 |
+
} );
|
1188 |
+
|
1189 |
+
Api.register( 'responsive.hasHidden()', function () {
|
1190 |
+
var ctx = this.context[0];
|
1191 |
+
|
1192 |
+
return ctx._responsive ?
|
1193 |
+
$.inArray( false, ctx._responsive.s.current ) !== -1 :
|
1194 |
+
false;
|
1195 |
+
} );
|
1196 |
+
|
1197 |
+
|
1198 |
+
/**
|
1199 |
+
* Version information
|
1200 |
+
*
|
1201 |
+
* @name Responsive.version
|
1202 |
+
* @static
|
1203 |
+
*/
|
1204 |
+
Responsive.version = '2.1.0';
|
1205 |
+
|
1206 |
+
|
1207 |
+
$.fn.dataTable.Responsive = Responsive;
|
1208 |
+
$.fn.DataTable.Responsive = Responsive;
|
1209 |
+
|
1210 |
+
// Attach a listener to the document which listens for DataTables initialisation
|
1211 |
+
// events so we can automatically initialise
|
1212 |
+
$(document).on( 'preInit.dt.dtr', function (e, settings, json) {
|
1213 |
+
if ( e.namespace !== 'dt' ) {
|
1214 |
+
return;
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
if ( $(settings.nTable).hasClass( 'responsive' ) ||
|
1218 |
+
$(settings.nTable).hasClass( 'dt-responsive' ) ||
|
1219 |
+
settings.oInit.responsive ||
|
1220 |
+
DataTable.defaults.responsive
|
1221 |
+
) {
|
1222 |
+
var init = settings.oInit.responsive;
|
1223 |
+
|
1224 |
+
if ( init !== false ) {
|
1225 |
+
new Responsive( settings, $.isPlainObject( init ) ? init : {} );
|
1226 |
+
}
|
1227 |
+
}
|
1228 |
+
} );
|
1229 |
+
|
1230 |
+
|
1231 |
+
return Responsive;
|
1232 |
+
}));
|
admin/js/jquery.dataTables.min.js
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
DataTables 1.10.13
|
3 |
+
©2008-2016 SpryMedia Ltd - datatables.net/license
|
4 |
+
*/
|
5 |
+
(function(h){"function"===typeof define&&define.amd?define(["jquery"],function(E){return h(E,window,document)}):"object"===typeof exports?module.exports=function(E,H){E||(E=window);H||(H="undefined"!==typeof window?require("jquery"):require("jquery")(E));return h(H,E,E.document)}:h(jQuery,window,document)})(function(h,E,H,k){function Y(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()),
|
6 |
+
d[c]=e,"o"===b[1]&&Y(a[e])});a._hungarianMap=d}function J(a,b,c){a._hungarianMap||Y(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),J(a[d],b[d],c)):b[d]=b[e]})}function Fa(a){var b=m.defaults.oLanguage,c=a.sZeroRecords;!a.sEmptyTable&&(c&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(c&&"Loading..."===b.sLoadingRecords)&&F(a,a,"sZeroRecords","sLoadingRecords");
|
7 |
+
a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&fb(a)}function gb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":"");"boolean"===typeof a.scrollX&&(a.scrollX=
|
8 |
+
a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&J(m.models.oSearch,a[b])}function hb(a){A(a,"orderable","bSortable");A(a,"orderData","aDataSort");A(a,"orderSequence","asSorting");A(a,"orderDataType","sortDataType");var b=a.aDataSort;b&&!h.isArray(b)&&(a.aDataSort=[b])}function ib(a){if(!m.__browser){var b={};m.__browser=b;var c=h("<div/>").css({position:"fixed",top:0,left:-1*h(E).scrollLeft(),height:1,width:1,overflow:"hidden"}).append(h("<div/>").css({position:"absolute",
|
9 |
+
top:1,left:1,width:100,overflow:"scroll"}).append(h("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,m.__browser);a.oScroll.iBarWidth=m.__browser.barWidth}function jb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==
|
10 |
+
e;)a.hasOwnProperty(d)&&(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ga(a,b){var c=m.defaults.column,d=a.aoColumns.length,c=h.extend({},m.models.oColumn,c,{nTh:b?b:H.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},m.models.oSearch,c[d]);la(a,d,h(b).data())}function la(a,b,c){var b=a.aoColumns[b],d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=
|
11 |
+
e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(hb(c),J(m.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var g=b.mData,j=R(g),i=b.mRender?R(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};
|
12 |
+
b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return S(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=
|
13 |
+
d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function Z(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ha(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;(""!==b.sY||""!==b.sX)&&ma(a);s(a,null,"column-sizing",[a])}function $(a,b){var c=na(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function aa(a,b){var c=na(a,"bVisible"),c=h.inArray(b,
|
14 |
+
c);return-1!==c?c:null}function ba(a){var b=0;h.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==h(d.nTh).css("display")&&b++});return b}function na(a,b){var c=[];h.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ia(a){var b=a.aoColumns,c=a.aoData,d=m.ext.type.detect,e,f,g,j,i,h,l,q,r;e=0;for(f=b.length;e<f;e++)if(l=b[e],r=[],!l.sType&&l._sManualType)l.sType=l._sManualType;else if(!l.sType){g=0;for(j=d.length;g<j;g++){i=0;for(h=c.length;i<h;i++){r[i]===k&&(r[i]=B(a,i,e,"type"));
|
15 |
+
q=d[g](r[i],a);if(!q&&g!==d.length-1)break;if("html"===q)break}if(q){l.sType=q;break}}l.sType||(l.sType="string")}}function kb(a,b,c,d){var e,f,g,j,i,n,l=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){n=b[e];var q=n.targets!==k?n.targets:n.aTargets;h.isArray(q)||(q=[q]);f=0;for(g=q.length;f<g;f++)if("number"===typeof q[f]&&0<=q[f]){for(;l.length<=q[f];)Ga(a);d(q[f],n)}else if("number"===typeof q[f]&&0>q[f])d(l.length+q[f],n);else if("string"===typeof q[f]){j=0;for(i=l.length;j<i;j++)("_all"==q[f]||h(l[j].nTh).hasClass(q[f]))&&
|
16 |
+
d(j,n)}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function N(a,b,c,d){var e=a.aoData.length,f=h.extend(!0,{},m.models.oRow,{src:c?"dom":"data",idx:e});f._aData=b;a.aoData.push(f);for(var g=a.aoColumns,j=0,i=g.length;j<i;j++)g[j].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ja(a,e,c,d);return e}function oa(a,b){var c;b instanceof h||(b=h(b));return b.map(function(b,e){c=Ka(a,e);return N(a,c.data,e,c.cells)})}function B(a,b,c,d){var e=a.iDraw,
|
17 |
+
f=a.aoColumns[c],g=a.aoData[b]._aData,j=f.sDefaultContent,i=f.fnGetData(g,d,{settings:a,row:b,col:c});if(i===k)return a.iDrawError!=e&&null===j&&(K(a,0,"Requested unknown parameter "+("function"==typeof f.mData?"{function}":"'"+f.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),j;if((i===g||null===i)&&null!==j&&d!==k)i=j;else if("function"===typeof i)return i.call(g);return null===i&&"display"==d?"":i}function lb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}
|
18 |
+
function La(a){return h.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function R(a){if(h.isPlainObject(a)){var b={};h.each(a,function(a,c){c&&(b[a]=R(c))});return function(a,c,f,g){var j=b[c]||b._;return j!==k?j(a,c,f,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,g){return a(b,c,f,g)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,f){var g,j;if(""!==f){j=La(f);
|
19 |
+
for(var i=0,n=j.length;i<n;i++){f=j[i].match(ca);g=j[i].match(V);if(f){j[i]=j[i].replace(ca,"");""!==j[i]&&(a=a[j[i]]);g=[];j.splice(0,i+1);j=j.join(".");if(h.isArray(a)){i=0;for(n=a.length;i<n;i++)g.push(c(a[i],b,j))}a=f[0].substring(1,f[0].length-1);a=""===a?g:g.join(a);break}else if(g){j[i]=j[i].replace(V,"");a=a[j[i]]();continue}if(null===a||a[j[i]]===k)return k;a=a[j[i]]}}return a};return function(b,e){return c(b,e,a)}}return function(b){return b[a]}}function S(a){if(h.isPlainObject(a))return S(a._);
|
20 |
+
if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var b=function(a,d,e){var e=La(e),f;f=e[e.length-1];for(var g,j,i=0,n=e.length-1;i<n;i++){g=e[i].match(ca);j=e[i].match(V);if(g){e[i]=e[i].replace(ca,"");a[e[i]]=[];f=e.slice();f.splice(0,i+1);g=f.join(".");if(h.isArray(d)){j=0;for(n=d.length;j<n;j++)f={},b(f,d[j],g),a[e[i]].push(f)}else a[e[i]]=d;return}j&&(e[i]=e[i].replace(V,
|
21 |
+
""),a=a[e[i]](d));if(null===a[e[i]]||a[e[i]]===k)a[e[i]]={};a=a[e[i]]}if(f.match(V))a[f.replace(V,"")](d);else a[f.replace(ca,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Ma(a){return D(a.aoData,"_aData")}function pa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function qa(a,b,c){for(var d=-1,e=0,f=a.length;e<f;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===k&&a.splice(d,1)}function da(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);
|
22 |
+
c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ka(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c<f;c++)g(j[c],c)}}e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==k)g[d].sType=null;else{c=0;for(f=g.length;c<f;c++)g[c].sType=null;Na(a,e)}}function Ka(a,b,c,d){var e=[],f=b.firstChild,g,j,i=0,n,l=a.aoColumns,q=a._rowReadObject,d=d!==k?d:q?{}:[],r=function(a,b){if("string"===typeof a){var c=a.indexOf("@");
|
23 |
+
-1!==c&&(c=a.substring(c+1),S(a)(d,b.getAttribute(c)))}},m=function(a){if(c===k||c===i)j=l[i],n=h.trim(a.innerHTML),j&&j._bAttrSrc?(S(j.mData._)(d,n),r(j.mData.sort,a),r(j.mData.type,a),r(j.mData.filter,a)):q?(j._setter||(j._setter=S(j.mData)),j._setter(d,n)):d[i]=n;i++};if(f)for(;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)m(f),e.push(f);f=f.nextSibling}else{e=b.anCells;f=0;for(g=e.length;f<g;f++)m(e[f])}if(b=b.firstChild?b:b.nTr)(b=b.getAttribute("id"))&&S(a.rowId)(d,b);return{data:d,cells:e}}
|
24 |
+
function Ja(a,b,c,d){var e=a.aoData[b],f=e._aData,g=[],j,i,n,l,q;if(null===e.nTr){j=c||H.createElement("tr");e.nTr=j;e.anCells=g;j._DT_RowIndex=b;Na(a,e);l=0;for(q=a.aoColumns.length;l<q;l++){n=a.aoColumns[l];i=c?d[l]:H.createElement(n.sCellType);i._DT_CellIndex={row:b,column:l};g.push(i);if((!c||n.mRender||n.mData!==l)&&(!h.isPlainObject(n.mData)||n.mData._!==l+".display"))i.innerHTML=B(a,b,l,"display");n.sClass&&(i.className+=" "+n.sClass);n.bVisible&&!c?j.appendChild(i):!n.bVisible&&c&&i.parentNode.removeChild(i);
|
25 |
+
n.fnCreatedCell&&n.fnCreatedCell.call(a.oInstance,i,B(a,b,l),f,b,l)}s(a,"aoRowCreatedCallback",null,[j,f,b])}e.nTr.setAttribute("role","row")}function Na(a,b){var c=b.nTr,d=b._aData;if(c){var e=a.rowIdFn(d);e&&(c.id=e);d.DT_RowClass&&(e=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?sa(b.__rowc.concat(e)):e,h(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&h(c).attr(d.DT_RowAttr);d.DT_RowData&&h(c).data(d.DT_RowData)}}function mb(a){var b,c,d,e,f,g=a.nTHead,j=a.nTFoot,i=0===
|
26 |
+
h("th, td",g).length,n=a.oClasses,l=a.aoColumns;i&&(e=h("<tr/>").appendTo(g));b=0;for(c=l.length;b<c;b++)f=l[b],d=h(f.nTh).addClass(f.sClass),i&&d.appendTo(e),a.oFeatures.bSort&&(d.addClass(f.sSortingClass),!1!==f.bSortable&&(d.attr("tabindex",a.iTabIndex).attr("aria-controls",a.sTableId),Oa(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Pa(a,"header")(a,d,f,n);i&&ea(a.aoHeader,g);h(g).find(">tr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(n.sHeaderTH);h(j).find(">tr>th, >tr>td").addClass(n.sFooterTH);
|
27 |
+
if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b<c;b++)f=l[b],f.nTf=a[b].cell,f.sClass&&h(f.nTf).addClass(f.sClass)}}function fa(a,b,c){var d,e,f,g=[],j=[],i=a.aoColumns.length,n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=i-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(n=i=1,j[d][f]===k){a.appendChild(g[d][f].cell);
|
28 |
+
for(j[d][f]=1;g[d+i]!==k&&g[d][f].cell==g[d+i][f].cell;)j[d+i][f]=1,i++;for(;g[d][f+n]!==k&&g[d][f].cell==g[d][f+n].cell;){for(c=0;c<i;c++)j[d+c][f+n]=1;n++}h(g[d][f].cell).attr("rowspan",i).attr("colspan",n)}}}}function O(a){var b=s(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))C(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,g=a.iInitDisplayStart,j="ssp"==y(a),i=a.aiDisplay;a.bDrawing=!0;g!==k&&-1!==g&&(a._iDisplayStart=j?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=
|
29 |
+
-1);var g=a._iDisplayStart,n=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(j){if(!a.bDestroying&&!nb(a))return}else a.iDraw++;if(0!==i.length){f=j?a.aoData.length:n;for(j=j?0:g;j<f;j++){var l=i[j],q=a.aoData[l];null===q.nTr&&Ja(a,l);l=q.nTr;if(0!==e){var r=d[c%e];q._sRowStripe!=r&&(h(l).removeClass(q._sRowStripe).addClass(r),q._sRowStripe=r)}s(a,"aoRowCallback",null,[l,q._aData,c,j]);b.push(l);c++}}else c=f.sZeroRecords,1==a.iDraw&&"ajax"==y(a)?c=f.sLoadingRecords:
|
30 |
+
f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),b[0]=h("<tr/>",{"class":e?d[0]:""}).append(h("<td />",{valign:"top",colSpan:ba(a),"class":a.oClasses.sRowEmpty}).html(c))[0];s(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ma(a),g,n,i]);s(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ma(a),g,n,i]);d=h(a.nTBody);d.children().detach();d.append(h(b));s(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;
|
31 |
+
c.bSort&&ob(a);d?ga(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;O(a);a._drawHold=!1}function pb(a){var b=a.oClasses,c=h(a.nTable),c=h("<div/>").insertBefore(c),d=a.oFeatures,e=h("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,n,l,q,k=0;k<f.length;k++){g=null;j=f[k];if("<"==j){i=h("<div/>")[0];
|
32 |
+
n=f[k+1];if("'"==n||'"'==n){l="";for(q=2;f[k+q]!=n;)l+=f[k+q],q++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(n=l.split("."),i.id=n[0].substr(1,n[0].length-1),i.className=n[1]):"#"==l.charAt(0)?i.id=l.substr(1,l.length-1):i.className=l;k+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=qb(a);else if("f"==j&&d.bFilter)g=rb(a);else if("r"==j&&d.bProcessing)g=sb(a);else if("t"==j)g=tb(a);else if("i"==j&&d.bInfo)g=ub(a);else if("p"==
|
33 |
+
j&&d.bPaginate)g=vb(a);else if(0!==m.ext.feature.length){i=m.ext.feature;q=0;for(n=i.length;q<n;q++)if(j==i[q].cFeature){g=i[q].fnInit(a);break}}g&&(i=a.aanFeatures,i[j]||(i[j]=[]),i[j].push(g),e.append(g))}c.replaceWith(e);a.nHolding=null}function ea(a,b){var c=h(b).children("tr"),d,e,f,g,j,i,n,l,q,k;a.splice(0,a.length);f=0;for(i=c.length;f<i;f++)a.push([]);f=0;for(i=c.length;f<i;f++){d=c[f];for(e=d.firstChild;e;){if("TD"==e.nodeName.toUpperCase()||"TH"==e.nodeName.toUpperCase()){l=1*e.getAttribute("colspan");
|
34 |
+
q=1*e.getAttribute("rowspan");l=!l||0===l||1===l?1:l;q=!q||0===q||1===q?1:q;g=0;for(j=a[f];j[g];)g++;n=g;k=1===l?!0:!1;for(j=0;j<l;j++)for(g=0;g<q;g++)a[f+g][n+j]={cell:e,unique:k},a[f+g].nTr=d}e=e.nextSibling}}}function ta(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],ea(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function ua(a,b,c){s(a,"aoServerParams","serverParams",[b]);if(b&&h.isArray(b)){var d={},
|
35 |
+
e=/(.*?)\[\]$/;h.each(b,function(a,b){var c=b.name.match(e);c?(c=c[0],d[c]||(d[c]=[]),d[c].push(b.value)):d[b.name]=b.value});b=d}var f,g=a.ajax,j=a.oInstance,i=function(b){s(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(h.isPlainObject(g)&&g.data){f=g.data;var n=h.isFunction(f)?f(b,a):f,b=h.isFunction(f)&&n?n:h.extend(!0,b,n);delete g.data}n={data:b,success:function(b){var c=b.error||b.sError;c&&K(a,0,c);a.json=b;i(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c){var d=s(a,null,"xhr",
|
36 |
+
[a,null,a.jqXHR]);-1===h.inArray(!0,d)&&("parsererror"==c?K(a,0,"Invalid JSON response",1):4===b.readyState&&K(a,0,"Ajax error",7));C(a,!1)}};a.oAjaxData=b;s(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(j,a.sAjaxSource,h.map(b,function(a,b){return{name:b,value:a}}),i,a):a.sAjaxSource||"string"===typeof g?a.jqXHR=h.ajax(h.extend(n,{url:g||a.sAjaxSource})):h.isFunction(g)?a.jqXHR=g.call(j,b,i,a):(a.jqXHR=h.ajax(h.extend(n,g)),g.data=f)}function nb(a){return a.bAjaxDataGet?(a.iDraw++,C(a,
|
37 |
+
!0),ua(a,wb(a),function(b){xb(a,b)}),!1):!0}function wb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,g,j=[],i,n,l,k=W(a);g=a._iDisplayStart;i=!1!==d.bPaginate?a._iDisplayLength:-1;var r=function(a,b){j.push({name:a,value:b})};r("sEcho",a.iDraw);r("iColumns",c);r("sColumns",D(b,"sName").join(","));r("iDisplayStart",g);r("iDisplayLength",i);var ra={draw:a.iDraw,columns:[],order:[],start:g,length:i,search:{value:e.sSearch,regex:e.bRegex}};for(g=0;g<c;g++)n=b[g],
|
38 |
+
l=f[g],i="function"==typeof n.mData?"function":n.mData,ra.columns.push({data:i,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:l.sSearch,regex:l.bRegex}}),r("mDataProp_"+g,i),d.bFilter&&(r("sSearch_"+g,l.sSearch),r("bRegex_"+g,l.bRegex),r("bSearchable_"+g,n.bSearchable)),d.bSort&&r("bSortable_"+g,n.bSortable);d.bFilter&&(r("sSearch",e.sSearch),r("bRegex",e.bRegex));d.bSort&&(h.each(k,function(a,b){ra.order.push({column:b.col,dir:b.dir});r("iSortCol_"+a,b.col);r("sSortDir_"+
|
39 |
+
a,b.dir)}),r("iSortingCols",k.length));b=m.ext.legacy.ajax;return null===b?a.sAjaxSource?j:ra:b?j:ra}function xb(a,b){var c=va(a,b),d=b.sEcho!==k?b.sEcho:b.draw,e=b.iTotalRecords!==k?b.iTotalRecords:b.recordsTotal,f=b.iTotalDisplayRecords!==k?b.iTotalDisplayRecords:b.recordsFiltered;if(d){if(1*d<a.iDraw)return;a.iDraw=1*d}pa(a);a._iRecordsTotal=parseInt(e,10);a._iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;O(a);a._bInitComplete||
|
40 |
+
wa(a,b);a.bAjaxDataGet=!0;C(a,!1)}function va(a,b){var c=h.isPlainObject(a.ajax)&&a.ajax.dataSrc!==k?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===c?b.aaData||b[c]:""!==c?R(c)(b):b}function rb(a){var b=a.oClasses,c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,f=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_",g):j+g,b=h("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("<label/>").append(j)),f=function(){var b=!this.value?
|
41 |
+
"":this.value;b!=e.sSearch&&(ga(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,O(a))},g=null!==a.searchDelay?a.searchDelay:"ssp"===y(a)?400:0,i=h("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",g?Qa(f,g):f).on("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);h(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{i[0]!==H.activeElement&&i.val(e.sSearch)}catch(d){}});
|
42 |
+
return b[0]}function ga(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};Ia(a);if("ssp"!=y(a)){yb(a,b.sSearch,c,b.bEscapeRegex!==k?!b.bEscapeRegex:b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<e.length;b++)zb(a,e[b].sSearch,b,e[b].bEscapeRegex!==k?!e[b].bEscapeRegex:e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);Ab(a)}else f(b);a.bFiltered=!0;s(a,null,"search",[a])}function Ab(a){for(var b=
|
43 |
+
m.ext.search,c=a.aiDisplay,d,e,f=0,g=b.length;f<g;f++){for(var j=[],i=0,n=c.length;i<n;i++)e=c[i],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,i)&&j.push(e);c.length=0;h.merge(c,j)}}function zb(a,b,c,d,e,f){if(""!==b){for(var g=[],j=a.aiDisplay,d=Ra(b,d,e,f),e=0;e<j.length;e++)b=a.aoData[j[e]]._aFilterData[c],d.test(b)&&g.push(j[e]);a.aiDisplay=g}}function yb(a,b,c,d,e,f){var d=Ra(b,d,e,f),f=a.oPreviousSearch.sSearch,g=a.aiDisplayMaster,j,e=[];0!==m.ext.search.length&&(c=!0);j=Bb(a);if(0>=b.length)a.aiDisplay=
|
44 |
+
g.slice();else{if(j||c||f.length>b.length||0!==b.indexOf(f)||a.bSorted)a.aiDisplay=g.slice();b=a.aiDisplay;for(c=0;c<b.length;c++)d.test(a.aoData[b[c]]._sFilterRow)&&e.push(b[c]);a.aiDisplay=e}}function Ra(a,b,c,d){a=b?a:Sa(a);c&&(a="^(?=.*?"+h.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0))var b=a.match(/^"(.*)"$/),a=b?b[1]:a;return a.replace('"',"")}).join(")(?=.*?")+").*$");return RegExp(a,d?"i":"")}function Bb(a){var b=a.aoColumns,c,d,e,f,g,j,i,h,l=m.ext.type.search;c=!1;
|
45 |
+
d=0;for(f=a.aoData.length;d<f;d++)if(h=a.aoData[d],!h._aFilterData){j=[];e=0;for(g=b.length;e<g;e++)c=b[e],c.bSearchable?(i=B(a,d,e,"filter"),l[c.sType]&&(i=l[c.sType](i)),null===i&&(i=""),"string"!==typeof i&&i.toString&&(i=i.toString())):i="",i.indexOf&&-1!==i.indexOf("&")&&(xa.innerHTML=i,i=$b?xa.textContent:xa.innerText),i.replace&&(i=i.replace(/[\r\n]/g,"")),j.push(i);h._aFilterData=j;h._sFilterRow=j.join(" ");c=!0}return c}function Cb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,
|
46 |
+
caseInsensitive:a.bCaseInsensitive}}function Db(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function ub(a){var b=a.sTableId,c=a.aanFeatures.i,d=h("<div/>",{"class":a.oClasses.sInfo,id:!c?b+"_info":null});c||(a.aoDrawCallback.push({fn:Eb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),h(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Eb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+
|
47 |
+
1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),j=g?c.sInfo:c.sInfoEmpty;g!==f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=Fb(a,j);c=c.fnInfoCallback;null!==c&&(j=c.call(a.oInstance,a,d,e,f,g,j));h(b).html(j)}}function Fb(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,
|
48 |
+
f)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(f/e)))}function ha(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var g=a.bDeferLoading;if(a.bInitialised){pb(a);mb(a);fa(a,a.aoHeader);fa(a,a.aoFooter);C(a,!0);c.bAutoWidth&&Ha(a);b=0;for(c=e.length;b<c;b++)f=e[b],f.sWidth&&(f.nTh.style.width=v(f.sWidth));s(a,null,"preInit",[a]);T(a);e=y(a);if("ssp"!=e||g)"ajax"==e?ua(a,[],function(c){var f=va(a,c);for(b=0;b<f.length;b++)N(a,f[b]);a.iInitDisplayStart=
|
49 |
+
d;T(a);C(a,!1);wa(a,c)},a):(C(a,!1),wa(a))}else setTimeout(function(){ha(a)},200)}function wa(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Z(a);s(a,null,"plugin-init",[a,b]);s(a,"aoInitComplete","init",[a,b])}function Ta(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Ua(a);s(a,null,"length",[a,c])}function qb(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=h.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=h("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),g=0,j=f.length;g<j;g++)e[0][g]=
|
50 |
+
new Option(d[g],f[g]);var i=h("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).on("change.DT",function(){Ta(a,h(this).val());O(a)});h(a.nTable).on("length.dt.DT",function(b,c,d){a===c&&h("select",i).val(d)});return i[0]}function vb(a){var b=a.sPaginationType,c=m.ext.pager[b],d="function"===typeof c,e=function(a){O(a)},b=h("<div/>").addClass(a.oClasses.sPaging+
|
51 |
+
b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===i,b=l?0:Math.ceil(b/i),i=l?1:Math.ceil(h/i),h=c(b,i),k,l=0;for(k=f.p.length;l<k;l++)Pa(a,"pageButton")(a,f.p[l],l,h,b,i)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Va(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,f=a.fnRecordsDisplay();0===f||-1===e?d=0:"number"===typeof b?(d=b*e,d>f&&
|
52 |
+
(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<f&&(d+=e):"last"==b?d=Math.floor((f-1)/e)*e:K(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(s(a,null,"page",[a]),c&&O(a));return b}function sb(a){return h("<div/>",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");
|
53 |
+
s(a,null,"processing",[a,b])}function tb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),n=h(b[0].cloneNode(!1)),l=b.children("tfoot");l.length||(l=null);i=h("<div/>",{"class":f.sScrollWrapper}).append(h("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:v(d):"100%"}).append(h("<div/>",
|
54 |
+
{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:v(d)}).append(b));l&&i.append(h("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:v(d):"100%"}).append(h("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",
|
55 |
+
0).append("bottom"===j?g:null).append(b.children("tfoot")))));var b=i.children(),k=b[0],f=b[1],r=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(r.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=r;a.aoDrawCallback.push({fn:ma,sName:"scrolling"});return i[0]}function ma(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth,f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,n=j.children("table"),
|
56 |
+
j=a.nScrollBody,l=h(j),q=j.style,r=h(a.nScrollFoot).children("div"),m=r.children("table"),p=h(a.nTHead),o=h(a.nTable),u=o[0],s=u.style,t=a.nTFoot?h(a.nTFoot):null,x=a.oBrowser,U=x.bScrollOversize,ac=D(a.aoColumns,"nTh"),P,L,Q,w,Wa=[],y=[],z=[],A=[],B,C=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};L=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!==L&&a.scrollBarVis!==k)a.scrollBarVis=L,Z(a);else{a.scrollBarVis=L;o.children("thead, tfoot").remove();
|
57 |
+
t&&(Q=t.clone().prependTo(o),P=t.find("tr"),Q=Q.find("tr"));w=p.clone().prependTo(o);p=p.find("tr");L=w.find("tr");w.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(ta(a,w),function(b,c){B=$(a,b);c.style.width=a.aoColumns[B].sWidth});t&&I(function(a){a.style.width=""},Q);f=o.outerWidth();if(""===c){s.width="100%";if(U&&(o.find("tbody").height()>j.offsetHeight||"scroll"==l.css("overflow-y")))s.width=v(o.outerWidth()-b);f=o.outerWidth()}else""!==d&&(s.width=
|
58 |
+
v(d),f=o.outerWidth());I(C,L);I(function(a){z.push(a.innerHTML);Wa.push(v(h(a).css("width")))},L);I(function(a,b){if(h.inArray(a,ac)!==-1)a.style.width=Wa[b]},p);h(L).height(0);t&&(I(C,Q),I(function(a){A.push(a.innerHTML);y.push(v(h(a).css("width")))},Q),I(function(a,b){a.style.width=y[b]},P),h(Q).height(0));I(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+z[b]+"</div>";a.style.width=Wa[b]},L);t&&I(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+
|
59 |
+
A[b]+"</div>";a.style.width=y[b]},Q);if(o.outerWidth()<f){P=j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(U&&(j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")))s.width=v(P-b);(""===c||""!==d)&&K(a,1,"Possible column misalignment",6)}else P="100%";q.width=v(P);g.width=v(P);t&&(a.nScrollFoot.style.width=v(P));!e&&U&&(q.height=v(u.offsetHeight+b));c=o.outerWidth();n[0].style.width=v(c);i.width=v(c);d=o.height()>j.clientHeight||"scroll"==l.css("overflow-y");e="padding"+
|
60 |
+
(x.bScrollbarLeft?"Left":"Right");i[e]=d?b+"px":"0px";t&&(m[0].style.width=v(c),r[0].style.width=v(c),r[0].style[e]=d?b+"px":"0px");o.children("colgroup").insertBefore(o.children("thead"));l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function I(a,b,c){for(var d=0,e=0,f=b.length,g,j;e<f;){g=b[e].firstChild;for(j=c?c[e].firstChild:null;g;)1===g.nodeType&&(c?a(g,j,d):a(g,d),d++),g=g.nextSibling,j=c?j.nextSibling:null;e++}}function Ha(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,
|
61 |
+
e=d.sY,f=d.sX,g=d.sXInner,j=c.length,i=na(a,"bVisible"),n=h("th",a.nTHead),l=b.getAttribute("width"),k=b.parentNode,r=!1,m,p,o=a.oBrowser,d=o.bScrollOversize;(m=b.style.width)&&-1!==m.indexOf("%")&&(l=m);for(m=0;m<i.length;m++)p=c[i[m]],null!==p.sWidth&&(p.sWidth=Gb(p.sWidthOrig,k),r=!0);if(d||!r&&!f&&!e&&j==ba(a)&&j==n.length)for(m=0;m<j;m++)i=$(a,m),null!==i&&(c[i].sWidth=v(n.eq(m).width()));else{j=h(b).clone().css("visibility","hidden").removeAttr("id");j.find("tbody tr").remove();var u=h("<tr/>").appendTo(j.find("tbody"));
|
62 |
+
j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");n=ta(a,j.find("thead")[0]);for(m=0;m<i.length;m++)p=c[i[m]],n[m].style.width=null!==p.sWidthOrig&&""!==p.sWidthOrig?v(p.sWidthOrig):"",p.sWidthOrig&&f&&h(n[m]).append(h("<div/>").css({width:p.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(m=0;m<i.length;m++)r=i[m],p=c[r],h(Hb(a,r)).clone(!1).append(p.sContentPadding).appendTo(u);h("[name]",
|
63 |
+
j).removeAttr("name");p=h("<div/>").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()<k.clientWidth&&l&&j.width(k.clientWidth)):e?j.width(k.clientWidth):l&&j.width(l);for(m=e=0;m<i.length;m++)k=h(n[m]),g=k.outerWidth()-k.width(),k=o.bBounding?Math.ceil(n[m].getBoundingClientRect().width):k.outerWidth(),e+=k,c[i[m]].sWidth=v(k-g);b.style.width=v(e);p.remove()}l&&(b.style.width=
|
64 |
+
v(l));if((l||f)&&!a._reszEvt)b=function(){h(E).on("resize.DT-"+a.sInstance,Qa(function(){Z(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0}function Gb(a,b){if(!a)return 0;var c=h("<div/>").css("width",v(a)).appendTo(b||H.body),d=c[0].offsetWidth;c.remove();return d}function Hb(a,b){var c=Ib(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("<td/>").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Ib(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;f<g;f++)c=B(a,f,b,"display")+"",c=c.replace(bc,
|
65 |
+
""),c=c.replace(/ /g," "),c.length>d&&(d=c.length,e=f);return e}function v(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function W(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var n=[];f=function(a){a.length&&!h.isArray(a[0])?n.push(a):h.merge(n,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;a<n.length;a++){i=n[a][0];f=e[i].aDataSort;b=0;for(c=f.length;b<c;b++)g=f[b],j=e[g].sType||
|
66 |
+
"string",n[a]._idx===k&&(n[a]._idx=h.inArray(n[a][1],e[g].asSorting)),d.push({src:i,col:g,dir:n[a][1],index:n[a]._idx,type:j,formatter:m.ext.type.order[j+"-pre"]})}return d}function ob(a){var b,c,d=[],e=m.ext.type.order,f=a.aoData,g=0,j,i=a.aiDisplayMaster,h;Ia(a);h=W(a);b=0;for(c=h.length;b<c;b++)j=h[b],j.formatter&&g++,Jb(a,j.col);if("ssp"!=y(a)&&0!==h.length){b=0;for(c=i.length;b<c;b++)d[i[b]]=b;g===h.length?i.sort(function(a,b){var c,e,g,j,i=h.length,k=f[a]._aSortData,m=f[b]._aSortData;for(g=
|
67 |
+
0;g<i;g++)if(j=h[g],c=k[j.col],e=m[j.col],c=c<e?-1:c>e?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return c<e?-1:c>e?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,m=f[a]._aSortData,p=f[b]._aSortData;for(j=0;j<k;j++)if(i=h[j],c=m[i.col],g=p[i.col],i=e[i.type+"-"+i.dir]||e["string-"+i.dir],c=i(c,g),0!==c)return c;c=d[a];g=d[b];return c<g?-1:c>g?1:0})}a.bSorted=!0}function Kb(a){for(var b,c,d=a.aoColumns,e=W(a),a=a.oLanguage.oAria,f=0,g=d.length;f<g;f++){c=d[f];var j=c.asSorting;b=c.sTitle.replace(/<.*?>/g,
|
68 |
+
"");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0<e.length&&e[0].col==f?(i.setAttribute("aria-sort","asc"==e[0].dir?"ascending":"descending"),c=j[e[0].index+1]||j[0]):c=j[0],b+="asc"===c?a.sSortAscending:a.sSortDescending);i.setAttribute("aria-label",b)}}function Xa(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===k&&(c=h.inArray(a[1],f));return c+1<f.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=h.inArray(b,
|
69 |
+
D(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=f[b],e[c]._idx=b)):(e.push([b,f[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=f[b],e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);T(a);"function"==typeof d&&d(a)}function Oa(a,b,c,d){var e=a.aoColumns[c];Ya(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(C(a,!0),setTimeout(function(){Xa(a,c,b.shiftKey,d);"ssp"!==y(a)&&C(a,!1)},0)):Xa(a,c,b.shiftKey,d))})}
|
70 |
+
function ya(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=W(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)g=b[e].src,h(D(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3));e=0;for(f=d.length;e<f;e++)g=d[e].src,h(D(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Jb(a,b){var c=a.aoColumns[b],d=m.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,aa(a,b)));for(var f,g=m.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j<i;j++)if(c=a.aoData[j],
|
71 |
+
c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)f=d?e[j]:B(a,j,b,"sort"),c._aSortData[b]=g?g(f):f}function za(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Cb(a.oPreviousSearch),columns:h.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Cb(a.aoPreSearchCols[d])}})};s(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,
|
72 |
+
b)}}function Lb(a,b,c){var d,e,f=a.aoColumns,b=function(b){if(b&&b.time){var i=s(a,"aoStateLoadParams","stateLoadParams",[a,g]);if(-1===h.inArray(!1,i)&&(i=a.iStateDuration,!(0<i&&b.time<+new Date-1E3*i)&&!(b.columns&&f.length!==b.columns.length))){a.oLoadedState=h.extend(!0,{},g);b.start!==k&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==k&&(a._iDisplayLength=b.length);b.order!==k&&(a.aaSorting=[],h.each(b.order,function(b,c){a.aaSorting.push(c[0]>=f.length?[0,c[1]]:c)}));b.search!==
|
73 |
+
k&&h.extend(a.oPreviousSearch,Db(b.search));if(b.columns){d=0;for(e=b.columns.length;d<e;d++)i=b.columns[d],i.visible!==k&&(f[d].bVisible=i.visible),i.search!==k&&h.extend(a.aoPreSearchCols[d],Db(i.search))}s(a,"aoStateLoaded","stateLoaded",[a,g])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==k&&b(g)}else c()}function Aa(a){var b=m.settings,a=h.inArray(a,D(b,"nTable"));return-1!==a?b[a]:null}function K(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+
|
74 |
+
" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)E.console&&console.log&&console.log(c);else if(b=m.ext,b=b.sErrMode||b.errMode,a&&s(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function F(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Mb(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],
|
75 |
+
h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==e&&h.isArray(d)?d.slice():d);return a}function Ya(a,b,c){h(a).on("click.DT",b,function(b){a.blur();c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function s(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+
|
76 |
+
".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Ua(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Pa(a,b){var c=a.renderer,d=m.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ia(a,b){var c=[],c=Nb.numbers_length,d=Math.floor(c/2);b<=c?c=X(0,b):a<=d?(c=X(0,
|
77 |
+
c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=X(b-(c-2),b):(c=X(a-d+2,a+d-1),c.push("ellipsis"),c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function fb(a){h.each({num:function(b){return Ba(b,a)},"num-fmt":function(b){return Ba(b,a,Za)},"html-num":function(b){return Ba(b,a,Ca)},"html-num-fmt":function(b){return Ba(b,a,Ca,Za)}},function(b,c){x.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(x.type.search[b+a]=x.type.search.html)})}function Ob(a){return function(){var b=
|
78 |
+
[Aa(this[m.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return m.ext.internal[a].apply(this,b)}}var m=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new u(Aa(this[x.iApiIndex])):new u(this)};this.fnAddData=function(a,b){var c=this.api(!0),d=h.isArray(a)&&(h.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=
|
79 |
+
function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&ma(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};
|
80 |
+
this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();
|
81 |
+
return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Aa(this[x.iApiIndex])};
|
82 |
+
this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust();(d===k||d)&&h.draw();return 0};this.fnVersionCheck=x.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=x.internal;for(var e in m.ext.internal)e&&(this[e]=Ob(e));this.each(function(){var e={},g=1<d?Mb(e,a,!0):
|
83 |
+
a,j=0,i,e=this.getAttribute("id"),n=!1,l=m.defaults,q=h(this);if("table"!=this.nodeName.toLowerCase())K(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{gb(l);hb(l.column);J(l,l,!0);J(l.column,l.column,!0);J(l,h.extend(g,q.data()));var r=m.settings,j=0;for(i=r.length;j<i;j++){var p=r[j];if(p.nTable==this||p.nTHead.parentNode==this||p.nTFoot&&p.nTFoot.parentNode==this){var u=g.bRetrieve!==k?g.bRetrieve:l.bRetrieve;if(c||u)return p.oInstance;if(g.bDestroy!==k?g.bDestroy:l.bDestroy){p.oInstance.fnDestroy();
|
84 |
+
break}else{K(p,0,"Cannot reinitialise DataTable",3);return}}if(p.sTableId==this.id){r.splice(j,1);break}}if(null===e||""===e)this.id=e="DataTables_Table_"+m.ext._unique++;var o=h.extend(!0,{},m.models.oSettings,{sDestroyWidth:q[0].style.width,sInstance:e,sTableId:e});o.nTable=this;o.oApi=b.internal;o.oInit=g;r.push(o);o.oInstance=1===b.length?b:q.dataTable();gb(g);g.oLanguage&&Fa(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=h.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);
|
85 |
+
g=Mb(h.extend(!0,{},l),g);F(o.oFeatures,g,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));F(o,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],
|
86 |
+
["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"],["bJQueryUI","bJUI"]]);F(o.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);F(o.oLanguage,g,"fnInfoCallback");z(o,"aoDrawCallback",g.fnDrawCallback,"user");z(o,"aoServerParams",g.fnServerParams,"user");z(o,"aoStateSaveParams",g.fnStateSaveParams,"user");z(o,"aoStateLoadParams",g.fnStateLoadParams,"user");z(o,"aoStateLoaded",g.fnStateLoaded,
|
87 |
+
"user");z(o,"aoRowCallback",g.fnRowCallback,"user");z(o,"aoRowCreatedCallback",g.fnCreatedRow,"user");z(o,"aoHeaderCallback",g.fnHeaderCallback,"user");z(o,"aoFooterCallback",g.fnFooterCallback,"user");z(o,"aoInitComplete",g.fnInitComplete,"user");z(o,"aoPreDrawCallback",g.fnPreDrawCallback,"user");o.rowIdFn=R(g.rowId);ib(o);var t=o.oClasses;g.bJQueryUI?(h.extend(t,m.ext.oJUIClasses,g.oClasses),g.sDom===l.sDom&&"lfrtip"===l.sDom&&(o.sDom='<"H"lfr>t<"F"ip>'),o.renderer)?h.isPlainObject(o.renderer)&&
|
88 |
+
!o.renderer.header&&(o.renderer.header="jqueryui"):o.renderer="jqueryui":h.extend(t,m.ext.classes,g.oClasses);q.addClass(t.sTable);o.iInitDisplayStart===k&&(o.iInitDisplayStart=g.iDisplayStart,o._iDisplayStart=g.iDisplayStart);null!==g.iDeferLoading&&(o.bDeferLoading=!0,e=h.isArray(g.iDeferLoading),o._iRecordsDisplay=e?g.iDeferLoading[0]:g.iDeferLoading,o._iRecordsTotal=e?g.iDeferLoading[1]:g.iDeferLoading);var v=o.oLanguage;h.extend(!0,v,g.oLanguage);v.sUrl&&(h.ajax({dataType:"json",url:v.sUrl,success:function(a){Fa(a);
|
89 |
+
J(l.oLanguage,a);h.extend(true,v,a);ha(o)},error:function(){ha(o)}}),n=!0);null===g.asStripeClasses&&(o.asStripeClasses=[t.sStripeOdd,t.sStripeEven]);var e=o.asStripeClasses,x=q.children("tbody").find("tr").eq(0);-1!==h.inArray(!0,h.map(e,function(a){return x.hasClass(a)}))&&(h("tbody tr",this).removeClass(e.join(" ")),o.asDestroyStripes=e.slice());e=[];r=this.getElementsByTagName("thead");0!==r.length&&(ea(o.aoHeader,r[0]),e=ta(o));if(null===g.aoColumns){r=[];j=0;for(i=e.length;j<i;j++)r.push(null)}else r=
|
90 |
+
g.aoColumns;j=0;for(i=r.length;j<i;j++)Ga(o,e?e[j]:null);kb(o,g.aoColumnDefs,r,function(a,b){la(o,a,b)});if(x.length){var w=function(a,b){return a.getAttribute("data-"+b)!==null?b:null};h(x[0]).children("th, td").each(function(a,b){var c=o.aoColumns[a];if(c.mData===a){var d=w(b,"sort")||w(b,"order"),e=w(b,"filter")||w(b,"search");if(d!==null||e!==null){c.mData={_:a+".display",sort:d!==null?a+".@data-"+d:k,type:d!==null?a+".@data-"+d:k,filter:e!==null?a+".@data-"+e:k};la(o,a)}}})}var U=o.oFeatures,
|
91 |
+
e=function(){if(g.aaSorting===k){var a=o.aaSorting;j=0;for(i=a.length;j<i;j++)a[j][1]=o.aoColumns[j].asSorting[0]}ya(o);U.bSort&&z(o,"aoDrawCallback",function(){if(o.bSorted){var a=W(o),b={};h.each(a,function(a,c){b[c.src]=c.dir});s(o,null,"order",[o,a,b]);Kb(o)}});z(o,"aoDrawCallback",function(){(o.bSorted||y(o)==="ssp"||U.bDeferRender)&&ya(o)},"sc");var a=q.children("caption").each(function(){this._captionSide=h(this).css("caption-side")}),b=q.children("thead");b.length===0&&(b=h("<thead/>").appendTo(q));
|
92 |
+
o.nTHead=b[0];b=q.children("tbody");b.length===0&&(b=h("<tbody/>").appendTo(q));o.nTBody=b[0];b=q.children("tfoot");if(b.length===0&&a.length>0&&(o.oScroll.sX!==""||o.oScroll.sY!==""))b=h("<tfoot/>").appendTo(q);if(b.length===0||b.children().length===0)q.addClass(t.sNoFooter);else if(b.length>0){o.nTFoot=b[0];ea(o.aoFooter,o.nTFoot)}if(g.aaData)for(j=0;j<g.aaData.length;j++)N(o,g.aaData[j]);else(o.bDeferLoading||y(o)=="dom")&&oa(o,h(o.nTBody).children("tr"));o.aiDisplay=o.aiDisplayMaster.slice();
|
93 |
+
o.bInitialised=true;n===false&&ha(o)};g.bStateSave?(U.bStateSave=!0,z(o,"aoDrawCallback",za,"state_save"),Lb(o,g,e)):e()}});b=null;return this},x,u,p,t,$a={},Pb=/[\r\n]/g,Ca=/<.*?>/g,cc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,dc=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Za=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Qb=function(a){var b=parseInt(a,10);return!isNaN(b)&&
|
94 |
+
isFinite(a)?b:null},Rb=function(a,b){$a[b]||($a[b]=RegExp(Sa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace($a[b],"."):a},ab=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Rb(a,b));c&&d&&(a=a.replace(Za,""));return!isNaN(parseFloat(a))&&isFinite(a)},Sb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:ab(a.replace(Ca,""),b,c)?!0:null},D=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;e<f;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<
|
95 |
+
f;e++)a[e]&&d.push(a[e][b]);return d},ja=function(a,b,c,d){var e=[],f=0,g=b.length;if(d!==k)for(;f<g;f++)a[b[f]][c]&&e.push(a[b[f]][c][d]);else for(;f<g;f++)e.push(a[b[f]][c]);return e},X=function(a,b){var c=[],d;b===k?(b=0,d=a):(d=b,b=a);for(var e=b;e<d;e++)c.push(e);return c},Tb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},sa=function(a){var b=[],c,d,e=a.length,f,g=0;d=0;a:for(;d<e;d++){c=a[d];for(f=0;f<g;f++)if(b[f]===c)continue a;b.push(c);g++}return b};m.util=
|
96 |
+
{throttle:function(a,b){var c=b!==k?b:200,d,e;return function(){var b=this,g=+new Date,h=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=k;a.apply(b,h)},c)):(d=g,a.apply(b,h))}},escapeRegex:function(a){return a.replace(dc,"\\$1")}};var A=function(a,b,c){a[b]!==k&&(a[c]=a[b])},ca=/\[.*?\]$/,V=/\(\)$/,Sa=m.util.escapeRegex,xa=h("<div>")[0],$b=xa.textContent!==k,bc=/<.*?>/g,Qa=m.util.throttle,Ub=[],w=Array.prototype,ec=function(a){var b,c,d=m.settings,e=h.map(d,function(a){return a.nTable});
|
97 |
+
if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=h.inArray(a,e),-1!==b?[d[b]]:null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return-1!==b?d[b]:null}).toArray()};u=function(a,b){if(!(this instanceof u))return new u(a,b);var c=[],d=function(a){(a=ec(a))&&(c=c.concat(a))};if(h.isArray(a))for(var e=0,f=a.length;e<f;e++)d(a[e]);
|
98 |
+
else d(a);this.context=sa(c);b&&h.merge(this,b);this.selector={rows:null,cols:null,opts:null};u.extend(this,this,Ub)};m.Api=u;h.extend(u.prototype,{any:function(){return 0!==this.count()},concat:w.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new u(b[a],this[a]):null},filter:function(a){var b=[];if(w.filter)b=w.filter.call(this,a,this);
|
99 |
+
else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new u(this.context,b)},flatten:function(){var a=[];return new u(this.context,a.concat.apply(a,this.toArray()))},join:w.join,indexOf:w.indexOf||function(a,b){for(var c=b||0,d=this.length;c<d;c++)if(this[c]===a)return c;return-1},iterator:function(a,b,c,d){var e=[],f,g,h,i,n,l=this.context,m,p,t=this.selector;"string"===typeof a&&(d=c,c=b,b=a,a=!1);g=0;for(h=l.length;g<h;g++){var s=new u(l[g]);if("table"===b)f=
|
100 |
+
c.call(s,l[g],g),f!==k&&e.push(f);else if("columns"===b||"rows"===b)f=c.call(s,l[g],this[g],g),f!==k&&e.push(f);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){p=this[g];"column-rows"===b&&(m=Da(l[g],t.opts));i=0;for(n=p.length;i<n;i++)f=p[i],f="cell"===b?c.call(s,l[g],f.row,f.column,g,i):c.call(s,l[g],f,g,i,m),f!==k&&e.push(f)}}return e.length||d?(a=new u(l,a?e.concat.apply([],e):e),b=a.selector,b.rows=t.rows,b.cols=t.cols,b.opts=t.opts,a):this},lastIndexOf:w.lastIndexOf||function(a,
|
101 |
+
b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(w.map)b=w.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new u(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:w.pop,push:w.push,reduce:w.reduce||function(a,b){return jb(this,a,b,0,this.length,1)},reduceRight:w.reduceRight||function(a,b){return jb(this,a,b,this.length-1,-1,-1)},reverse:w.reverse,selector:null,shift:w.shift,
|
102 |
+
sort:w.sort,splice:w.splice,toArray:function(){return w.slice.call(this)},to$:function(){return h(this)},toJQuery:function(){return h(this)},unique:function(){return new u(this.context,sa(this))},unshift:w.unshift});u.extend=function(a,b,c){if(c.length&&b&&(b instanceof u||b.__dt_wrapper)){var d,e,f,g=function(a,b,c){return function(){var d=b.apply(a,arguments);u.extend(d,d,c.methodExt);return d}};d=0;for(e=c.length;d<e;d++)f=c[d],b[f.name]="function"===typeof f.val?g(a,f.val,f):h.isPlainObject(f.val)?
|
103 |
+
{}:f.val,b[f.name].__dt_wrapper=!0,u.extend(a,b[f.name],f.propExt)}};u.register=p=function(a,b){if(h.isArray(a))for(var c=0,d=a.length;c<d;c++)u.register(a[c],b);else for(var e=a.split("."),f=Ub,g,j,c=0,d=e.length;c<d;c++){g=(j=-1!==e[c].indexOf("()"))?e[c].replace("()",""):e[c];var i;a:{i=0;for(var n=f.length;i<n;i++)if(f[i].name===g){i=f[i];break a}i=null}i||(i={name:g,val:{},methodExt:[],propExt:[]},f.push(i));c===d-1?i.val=b:f=j?i.methodExt:i.propExt}};u.registerPlural=t=function(a,b,c){u.register(a,
|
104 |
+
c);u.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof u?a.length?h.isArray(a[0])?new u(a.context,a[0]):a[0]:k:a})};p("tables()",function(a){var b;if(a){b=u;var c=this.context;if("number"===typeof a)a=[c[a]];else var d=h.map(c,function(a){return a.nTable}),a=h(d).filter(a).map(function(){var a=h.inArray(this,d);return c[a]}).toArray();b=new b(a)}else b=this;return b});p("table()",function(a){var a=this.tables(a),b=a.context;return b.length?new u(b[0]):a});t("tables().nodes()",
|
105 |
+
"table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});t("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},1)});t("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});t("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});t("tables().containers()","table().container()",function(){return this.iterator("table",
|
106 |
+
function(a){return a.nTableWrapper},1)});p("draw()",function(a){return this.iterator("table",function(b){"page"===a?O(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),T(b,!1===a))})});p("page()",function(a){return a===k?this.page.info().page:this.iterator("table",function(b){Va(b,a)})});p("page.info()",function(){if(0===this.context.length)return k;var a=this.context[0],b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),
|
107 |
+
pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:"ssp"===y(a)}});p("page.len()",function(a){return a===k?0!==this.context.length?this.context[0]._iDisplayLength:k:this.iterator("table",function(b){Ta(b,a)})});var Vb=function(a,b,c){if(c){var d=new u(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==y(a))T(a,b);else{C(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ua(a,[],function(c){pa(a);for(var c=va(a,c),d=0,e=c.length;d<
|
108 |
+
e;d++)N(a,c[d]);T(a,b);C(a,!1)})}};p("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});p("ajax.params()",function(){var a=this.context;if(0<a.length)return a[0].oAjaxData});p("ajax.reload()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});p("ajax.url()",function(a){var b=this.context;if(a===k){if(0===b.length)return k;b=b[0];return b.ajax?h.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){h.isPlainObject(b.ajax)?
|
109 |
+
b.ajax.url=a:b.ajax=a})});p("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});var bb=function(a,b,c,d,e){var f=[],g,j,i,n,l,m;i=typeof b;if(!b||"string"===i||"function"===i||b.length===k)b=[b];i=0;for(n=b.length;i<n;i++){j=b[i]&&b[i].split&&!b[i].match(/[\[\(:]/)?b[i].split(","):[b[i]];l=0;for(m=j.length;l<m;l++)(g=c("string"===typeof j[l]?h.trim(j[l]):j[l]))&&g.length&&(f=f.concat(g))}a=x.selector[a];if(a.length){i=0;for(n=a.length;i<n;i++)f=a[i](d,e,f)}return sa(f)},
|
110 |
+
cb=function(a){a||(a={});a.filter&&a.search===k&&(a.search=a.filter);return h.extend({search:"none",order:"current",page:"all"},a)},db=function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Da=function(a,b){var c,d,e,f=[],g=a.aiDisplay;c=a.aiDisplayMaster;var j=b.search;d=b.order;e=b.page;if("ssp"==y(a))return"removed"===j?[]:X(0,c.length);if("current"==e){c=a._iDisplayStart;for(d=a.fnDisplayEnd();c<d;c++)f.push(g[c])}else if("current"==
|
111 |
+
d||"applied"==d)f="none"==j?c.slice():"applied"==j?g.slice():h.map(c,function(a){return-1===h.inArray(a,g)?a:null});else if("index"==d||"original"==d){c=0;for(d=a.aoData.length;c<d;c++)"none"==j?f.push(c):(e=h.inArray(c,g),(-1===e&&"removed"==j||0<=e&&"applied"==j)&&f.push(c))}return f};p("rows()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=cb(b),c=this.iterator("table",function(c){var e=b,f;return bb("row",a,function(a){var b=Qb(a);if(b!==null&&!e)return[b];f||(f=Da(c,e));if(b!==
|
112 |
+
null&&h.inArray(b,f)!==-1)return[b];if(a===null||a===k||a==="")return f;if(typeof a==="function")return h.map(f,function(b){var e=c.aoData[b];return a(b,e._aData,e.nTr)?b:null});b=Tb(ja(c.aoData,f,"nTr"));if(a.nodeName){if(a._DT_RowIndex!==k)return[a._DT_RowIndex];if(a._DT_CellIndex)return[a._DT_CellIndex.row];b=h(a).closest("*[data-dt-row]");return b.length?[b.data("dt-row")]:[]}if(typeof a==="string"&&a.charAt(0)==="#"){var i=c.aIds[a.replace(/^#/,"")];if(i!==k)return[i.idx]}return h(b).filter(a).map(function(){return this._DT_RowIndex}).toArray()},
|
113 |
+
c,e)},1);c.selector.rows=a;c.selector.opts=b;return c});p("rows().nodes()",function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||k},1)});p("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ja(a.aoData,b,"_aData")},1)});t("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){var d=b.aoData[c];return"search"===a?d._aFilterData:d._aSortData},1)});t("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",
|
114 |
+
function(b,c){da(b,c,a)})});t("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});t("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var h=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+h)}return new u(c,b)});t("rows().remove()","row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,h,i,n,l;e.splice(c,1);
|
115 |
+
g=0;for(h=e.length;g<h;g++)if(i=e[g],l=i.anCells,null!==i.nTr&&(i.nTr._DT_RowIndex=g),null!==l){i=0;for(n=l.length;i<n;i++)l[i]._DT_CellIndex.row=g}qa(b.aiDisplayMaster,c);qa(b.aiDisplay,c);qa(a[d],c,!1);Ua(b);c=b.rowIdFn(f._aData);c!==k&&delete b.aIds[c]});this.iterator("table",function(a){for(var c=0,d=a.aoData.length;c<d;c++)a.aoData[c].idx=c});return this});p("rows.add()",function(a){var b=this.iterator("table",function(b){var c,f,g,h=[];f=0;for(g=a.length;f<g;f++)c=a[f],c.nodeName&&"TR"===c.nodeName.toUpperCase()?
|
116 |
+
h.push(oa(b,c)[0]):h.push(N(b,c));return h},1),c=this.rows(-1);c.pop();h.merge(c,b);return c});p("row()",function(a,b){return db(this.rows(a,b))});p("row().data()",function(a){var b=this.context;if(a===k)return b.length&&this.length?b[0].aoData[this[0]]._aData:k;b[0].aoData[this[0]]._aData=a;da(b[0],this[0],"data");return this});p("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});p("row.add()",function(a){a instanceof h&&a.length&&(a=a[0]);
|
117 |
+
var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?oa(b,a)[0]:N(b,a)});return this.row(b[0])});var eb=function(a,b){var c=a.context;if(c.length&&(c=c[0].aoData[b!==k?b:a[0]])&&c._details)c._details.remove(),c._detailsShow=k,c._details=k},Wb=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];if(d._details){(d._detailsShow=b)?d._details.insertAfter(d.nTr):d._details.detach();var e=c[0],f=new u(e),g=e.aoData;f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");
|
118 |
+
0<D(g,"_details").length&&(f.on("draw.dt.DT_details",function(a,b){e===b&&f.rows({page:"current"}).eq(0).each(function(a){a=g[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),f.on("column-visibility.dt.DT_details",function(a,b){if(e===b)for(var c,d=ba(b),f=0,h=g.length;f<h;f++)c=g[f],c._details&&c._details.children("td[colspan]").attr("colspan",d)}),f.on("destroy.dt.DT_details",function(a,b){if(e===b)for(var c=0,d=g.length;c<d;c++)g[c]._details&&eb(f,c)}))}}};p("row().child()",function(a,b){var c=
|
119 |
+
this.context;if(a===k)return c.length&&this.length?c[0].aoData[this[0]]._details:k;if(!0===a)this.child.show();else if(!1===a)eb(this);else if(c.length&&this.length){var d=c[0],c=c[0].aoData[this[0]],e=[],f=function(a,b){if(h.isArray(a)||a instanceof h)for(var c=0,k=a.length;c<k;c++)f(a[c],b);else a.nodeName&&"tr"===a.nodeName.toLowerCase()?e.push(a):(c=h("<tr><td/></tr>").addClass(b),h("td",c).addClass(b).html(a)[0].colSpan=ba(d),e.push(c[0]))};f(a,b);c._details&&c._details.detach();c._details=h(e);
|
120 |
+
c._detailsShow&&c._details.insertAfter(c.nTr)}return this});p(["row().child.show()","row().child().show()"],function(){Wb(this,!0);return this});p(["row().child.hide()","row().child().hide()"],function(){Wb(this,!1);return this});p(["row().child.remove()","row().child().remove()"],function(){eb(this);return this});p("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var fc=/^([^:]+):(name|visIdx|visible)$/,Xb=function(a,b,
|
121 |
+
c,d,e){for(var c=[],d=0,f=e.length;d<f;d++)c.push(B(a,e[d],b));return c};p("columns()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=cb(b),c=this.iterator("table",function(c){var e=a,f=b,g=c.aoColumns,j=D(g,"sName"),i=D(g,"nTh");return bb("column",e,function(a){var b=Qb(a);if(a==="")return X(g.length);if(b!==null)return[b>=0?b:g.length+b];if(typeof a==="function"){var e=Da(c,f);return h.map(g,function(b,f){return a(f,Xb(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(fc):
|
122 |
+
"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var m=h.map(g,function(a,b){return a.bVisible?b:null});return[m[m.length+b]]}return[$(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)},
|
123 |
+
1);c.selector.cols=a;c.selector.opts=b;return c});t("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});t("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});t("columns().data()","column().data()",function(){return this.iterator("column-rows",Xb,1)});t("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},
|
124 |
+
1)});t("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ja(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});t("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ja(a.aoData,e,"anCells",b)},1)});t("columns().visible()","column().visible()",function(a,b){var c=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var f=b.aoColumns,g=f[c],j=b.aoData,
|
125 |
+
i,n,l;if(a!==k&&g.bVisible!==a){if(a){var m=h.inArray(!0,D(f,"bVisible"),c+1);i=0;for(n=j.length;i<n;i++)l=j[i].nTr,f=j[i].anCells,l&&l.insertBefore(f[c],f[m]||null)}else h(D(b.aoData,"anCells",c)).detach();g.bVisible=a;fa(b,b.aoHeader);fa(b,b.aoFooter);za(b)}});a!==k&&(this.iterator("column",function(c,e){s(c,null,"column-visibility",[c,e,a,b])}),(b===k||b)&&this.columns.adjust());return c});t("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===
|
126 |
+
a?aa(b,c):c},1)});p("columns.adjust()",function(){return this.iterator("table",function(a){Z(a)},1)});p("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return $(c,b);if("fromData"===a||"toVisible"===a)return aa(c,b)}});p("column()",function(a,b){return db(this.columns(a,b))});p("cells()",function(a,b,c){h.isPlainObject(a)&&(a.row===k?(c=a,a=null):(c=b,b=null));h.isPlainObject(b)&&(c=b,b=null);if(null===b||b===k)return this.iterator("table",
|
127 |
+
function(b){var d=a,e=cb(c),f=b.aoData,g=Da(b,e),i=Tb(ja(f,g,"anCells")),j=h([].concat.apply([],i)),l,n=b.aoColumns.length,m,p,t,u,s,v;return bb("cell",d,function(a){var c=typeof a==="function";if(a===null||a===k||c){m=[];p=0;for(t=g.length;p<t;p++){l=g[p];for(u=0;u<n;u++){s={row:l,column:u};if(c){v=f[l];a(s,B(b,l,u),v.anCells?v.anCells[u]:null)&&m.push(s)}else m.push(s)}}return m}if(h.isPlainObject(a))return[a];c=j.filter(a).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();
|
128 |
+
if(c.length||!a.nodeName)return c;v=h(a).closest("*[data-dt-row]");return v.length?[{row:v.data("dt-row"),column:v.data("dt-column")}]:[]},b,e)});var d=this.columns(b,c),e=this.rows(a,c),f,g,j,i,n,l=this.iterator("table",function(a,b){f=[];g=0;for(j=e[b].length;g<j;g++){i=0;for(n=d[b].length;i<n;i++)f.push({row:e[b][g],column:d[b][i]})}return f},1);h.extend(l.selector,{cols:b,rows:a,opts:c});return l});t("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=
|
129 |
+
a.aoData[b])&&a.anCells?a.anCells[c]:k},1)});p("cells().data()",function(){return this.iterator("cell",function(a,b,c){return B(a,b,c)},1)});t("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});t("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return B(b,c,d,a)},1)});t("cells().indexes()","cell().index()",function(){return this.iterator("cell",
|
130 |
+
function(a,b,c){return{row:b,column:c,columnVisible:aa(a,c)}},1)});t("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){da(b,c,a,d)})});p("cell()",function(a,b,c){return db(this.cells(a,b,c))});p("cell().data()",function(a){var b=this.context,c=this[0];if(a===k)return b.length&&c.length?B(b[0],c[0].row,c[0].column):k;lb(b[0],c[0].row,c[0].column,a);da(b[0],c[0].row,"data",c[0].column);return this});p("order()",function(a,b){var c=this.context;if(a===
|
131 |
+
k)return 0!==c.length?c[0].aaSorting:k;"number"===typeof a?a=[[a,b]]:a.length&&!h.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});p("order.listener()",function(a,b,c){return this.iterator("table",function(d){Oa(d,a,b,c)})});p("order.fixed()",function(a){if(!a){var b=this.context,b=b.length?b[0].aaSortingFixed:k;return h.isArray(b)?{pre:b}:b}return this.iterator("table",function(b){b.aaSortingFixed=h.extend(!0,{},a)})});p(["columns().order()",
|
132 |
+
"column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];h.each(b[d],function(b,c){e.push([c,a])});c.aaSorting=e})});p("search()",function(a,b,c,d){var e=this.context;return a===k?0!==e.length?e[0].oPreviousSearch.sSearch:k:this.iterator("table",function(e){e.oFeatures.bFilter&&ga(e,h.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});t("columns().search()","column().search()",function(a,
|
133 |
+
b,c,d){return this.iterator("column",function(e,f){var g=e.aoPreSearchCols;if(a===k)return g[f].sSearch;e.oFeatures.bFilter&&(h.extend(g[f],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),ga(e,e.oPreviousSearch,1))})});p("state()",function(){return this.context.length?this.context[0].oSavedState:null});p("state.clear()",function(){return this.iterator("table",function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});p("state.loaded()",function(){return this.context.length?
|
134 |
+
this.context[0].oLoadedState:null});p("state.save()",function(){return this.iterator("table",function(a){za(a)})});m.versionCheck=m.fnVersionCheck=function(a){for(var b=m.version.split("."),a=a.split("."),c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};m.isDataTable=m.fnIsDataTable=function(a){var b=h(a).get(0),c=!1;if(a instanceof m.Api)return!0;h.each(m.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?
|
135 |
+
h("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||g===b)c=!0});return c};m.tables=m.fnTables=function(a){var b=!1;h.isPlainObject(a)&&(b=a.api,a=a.visible);var c=h.map(m.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new u(c):c};m.camelToHungarian=J;p("$()",function(a,b){var c=this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){p(b+"()",function(){var a=Array.prototype.slice.call(arguments);
|
136 |
+
a[0]=h.map(a[0].split(/\s/),function(a){return!a.match(/\.dt\b/)?a+".dt":a}).join(" ");var d=h(this.tables().nodes());d[b].apply(d,a);return this})});p("clear()",function(){return this.iterator("table",function(a){pa(a)})});p("settings()",function(){return new u(this.context,this.context)});p("init()",function(){var a=this.context;return a.length?a[0].oInit:null});p("data()",function(){return this.iterator("table",function(a){return D(a.aoData,"_aData")}).flatten()});p("destroy()",function(a){a=a||
|
137 |
+
!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),l=h.map(b.aoData,function(a){return a.nTr}),p;b.bDestroying=!0;s(b,"aoDestroyCallback","destroy",[b]);a||(new u(b)).columns().visible(!0);k.off(".DT").find(":not(tbody *)").off(".DT");h(E).off(".DT-"+b.sInstance);e!=g.parentNode&&(i.children("thead").detach(),i.append(g));j&&e!=j.parentNode&&(i.children("tfoot").detach(),i.append(j));
|
138 |
+
b.aaSorting=[];b.aaSortingFixed=[];ya(b);h(l).removeClass(b.asStripeClasses.join(" "));h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);b.bJUI&&(h("th span."+d.sSortIcon+", td span."+d.sSortIcon,g).detach(),h("th, td",g).each(function(){var a=h("div."+d.sSortJUIWrapper,this);h(this).append(a.contents());a.detach()}));f.children().detach();f.append(l);g=a?"remove":"detach";i[g]();k[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),i.css("width",
|
139 |
+
b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%p])}));c=h.inArray(b,m.settings);-1!==c&&m.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){p(b+"s().every()",function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,m){a.call(e[b](g,"cell"===b?h:d,"cell"===b?d:k),g,h,i,m)})})});p("i18n()",function(a,b,c){var d=this.context[0],a=R(a)(d.oLanguage);a===k&&(a=b);c!==
|
140 |
+
k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]:a._);return a.replace("%d",c)});m.version="1.10.13";m.settings=[];m.models={};m.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};m.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};m.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,
|
141 |
+
mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};m.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,
|
142 |
+
bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?
|
143 |
+
sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",
|
144 |
+
sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},
|
145 |
+
oSearch:h.extend({},m.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};Y(m.defaults);m.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,
|
146 |
+
sType:null,sWidth:null};Y(m.defaults.column);m.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],
|
147 |
+
aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,
|
148 |
+
searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],
|
149 |
+
fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,
|
150 |
+
aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};m.ext=x={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:m.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:m.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,
|
151 |
+
oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager});h.extend(m.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",
|
152 |
+
sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",
|
153 |
+
sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Ea="",Ea="",G=Ea+"ui-state-default",ka=Ea+"css_right ui-icon ui-icon-",Yb=Ea+"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";h.extend(m.ext.oJUIClasses,m.ext.classes,{sPageButton:"fg-button ui-button "+G,sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:G+" sorting_asc",
|
154 |
+
sSortDesc:G+" sorting_desc",sSortable:G+" sorting",sSortableAsc:G+" sorting_asc_disabled",sSortableDesc:G+" sorting_desc_disabled",sSortableNone:G+" sorting_disabled",sSortJUIAsc:ka+"triangle-1-n",sSortJUIDesc:ka+"triangle-1-s",sSortJUI:ka+"carat-2-n-s",sSortJUIAscAllowed:ka+"carat-1-n",sSortJUIDescAllowed:ka+"carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead "+G,sScrollFoot:"dataTables_scrollFoot "+G,sHeaderTH:G,sFooterTH:G,sJUIHeader:Yb+
|
155 |
+
" ui-corner-tl ui-corner-tr",sJUIFooter:Yb+" ui-corner-bl ui-corner-br"});var Nb=m.ext.pager;h.extend(Nb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,m.ext.renderer,
|
156 |
+
{pageButton:{_:function(a,b,c,d,e,f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},m,l,p=0,r=function(b,d){var k,t,u,s,v=function(b){Va(a,b.data.action,true)};k=0;for(t=d.length;k<t;k++){s=d[k];if(h.isArray(s)){u=h("<"+(s.DT_el||"div")+"/>").appendTo(b);r(u,s)}else{m=null;l="";switch(s){case "ellipsis":b.append('<span class="ellipsis">…</span>');break;case "first":m=j.sFirst;l=s+(e>0?"":" "+g.sPageButtonDisabled);break;case "previous":m=j.sPrevious;l=s+(e>0?"":" "+
|
157 |
+
g.sPageButtonDisabled);break;case "next":m=j.sNext;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;case "last":m=j.sLast;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;default:m=s+1;l=e===s?g.sPageButtonActive:""}if(m!==null){u=h("<a>",{"class":g.sPageButton+" "+l,"aria-controls":a.sTableId,"aria-label":i[s],"data-dt-idx":p,tabindex:a.iTabIndex,id:c===0&&typeof s==="string"?a.sTableId+"_"+s:null}).html(m).appendTo(b);Ya(u,{action:s},v);p++}}}},t;try{t=h(b).find(H.activeElement).data("dt-idx")}catch(u){}r(h(b).empty(),
|
158 |
+
d);t!==k&&h(b).find("[data-dt-idx="+t+"]").focus()}}});h.extend(m.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return ab(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&!cc.test(a))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||M(a)?"date":null},function(a,b){var c=b.oLanguage.sDecimal;return ab(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Sb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Sb(a,c,!0)?"html-num-fmt"+
|
159 |
+
c:null},function(a){return M(a)||"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);h.extend(m.ext.type.search,{html:function(a){return M(a)?a:"string"===typeof a?a.replace(Pb," ").replace(Ca,""):""},string:function(a){return M(a)?a:"string"===typeof a?a.replace(Pb," "):a}});var Ba=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Rb(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};h.extend(x.type.order,{"date-pre":function(a){return Date.parse(a)||-Infinity},
|
160 |
+
"html-pre":function(a){return M(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,b){return a<b?1:a>b?-1:0}});fb("");h.extend(!0,m.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]==
|
161 |
+
"asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+
|
162 |
+
d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]=="asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var Zb=function(a){return"string"===typeof a?a.replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):a};m.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return Zb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):
|
163 |
+
"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+f+(e||"")}}},text:function(){return{display:Zb}}};h.extend(m.ext.internal,{_fnExternApiFunc:Ob,_fnBuildAjax:ua,_fnAjaxUpdate:nb,_fnAjaxParameters:wb,_fnAjaxUpdateDraw:xb,_fnAjaxDataSrc:va,_fnAddColumn:Ga,_fnColumnOptions:la,_fnAdjustColumnSizing:Z,_fnVisibleToColumnIndex:$,_fnColumnIndexToVisible:aa,_fnVisbleColumns:ba,_fnGetColumns:na,_fnColumnTypes:Ia,_fnApplyColumnDefs:kb,_fnHungarianMap:Y,_fnCamelToHungarian:J,_fnLanguageCompat:Fa,
|
164 |
+
_fnBrowserDetect:ib,_fnAddData:N,_fnAddTr:oa,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:lb,_fnSplitObjNotation:La,_fnGetObjectDataFn:R,_fnSetObjectDataFn:S,_fnGetDataMaster:Ma,_fnClearTable:pa,_fnDeleteIndex:qa,_fnInvalidate:da,_fnGetRowElements:Ka,_fnCreateTr:Ja,_fnBuildHead:mb,_fnDrawHead:fa,_fnDraw:O,_fnReDraw:T,_fnAddOptionsHtml:pb,_fnDetectHeader:ea,
|
165 |
+
_fnGetUniqueThs:ta,_fnFeatureHtmlFilter:rb,_fnFilterComplete:ga,_fnFilterCustom:Ab,_fnFilterColumn:zb,_fnFilter:yb,_fnFilterCreateSearch:Ra,_fnEscapeRegex:Sa,_fnFilterData:Bb,_fnFeatureHtmlInfo:ub,_fnUpdateInfo:Eb,_fnInfoMacros:Fb,_fnInitialise:ha,_fnInitComplete:wa,_fnLengthChange:Ta,_fnFeatureHtmlLength:qb,_fnFeatureHtmlPaginate:vb,_fnPageChange:Va,_fnFeatureHtmlProcessing:sb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:tb,_fnScrollDraw:ma,_fnApplyToChildren:I,_fnCalculateColumnWidths:Ha,_fnThrottle:Qa,
|
166 |
+
_fnConvertToWidth:Gb,_fnGetWidestNode:Hb,_fnGetMaxLenString:Ib,_fnStringToCss:v,_fnSortFlatten:W,_fnSort:ob,_fnSortAria:Kb,_fnSortListener:Xa,_fnSortAttachListener:Oa,_fnSortingClasses:ya,_fnSortData:Jb,_fnSaveState:za,_fnLoadState:Lb,_fnSettingsFromNode:Aa,_fnLog:K,_fnMap:F,_fnBindAction:Ya,_fnCallbackReg:z,_fnCallbackFire:s,_fnLengthOverflow:Ua,_fnRenderer:Pa,_fnDataSource:y,_fnRowAttributes:Na,_fnCalculateEnd:function(){}});h.fn.dataTable=m;m.$=h;h.fn.dataTableSettings=m.settings;h.fn.dataTableExt=
|
167 |
+
m.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()};h.each(m,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable});
|
admin/js/materialize.clockpicker.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(){function t(t){return document.createElementNS(r,t)}function i(t){return(t<10?"0":"")+t}function e(t){var i=++v+"";return t?t+i:i}function s(s,n){function r(t,i){var e=h.offset(),s=/^touch/.test(t.type),o=e.left+f,c=e.top+f,r=(s?t.originalEvent.touches[0]:t).pageX-o,l=(s?t.originalEvent.touches[0]:t).pageY-c,u=Math.sqrt(r*r+l*l),m=!1;if(!i||!(u<b-w||u>b+w)){t.preventDefault();var v=setTimeout(function(){V.popover.addClass("clockpicker-moving")},200);p&&h.append(V.canvas),V.setHand(r,l,!i,!0),a.off(d).on(d,function(t){t.preventDefault();var i=/^touch/.test(t.type),e=(i?t.originalEvent.touches[0]:t).pageX-o,s=(i?t.originalEvent.touches[0]:t).pageY-c;(m||e!==r||s!==l)&&(m=!0,V.setHand(e,s,!1,!0))}),a.off(k).on(k,function(t){a.off(k),t.preventDefault();var e=/^touch/.test(t.type),s=(e?t.originalEvent.changedTouches[0]:t).pageX-o,p=(e?t.originalEvent.changedTouches[0]:t).pageY-c;(i||m)&&s===r&&p===l&&V.setHand(s,p),"hours"===V.currentView?V.toggleView("minutes",A/2):n.autoclose&&(V.minutesView.addClass("clockpicker-dial-out"),setTimeout(function(){V.done()},A/2)),h.prepend(z),clearTimeout(v),V.popover.removeClass("clockpicker-moving"),a.off(d)})}}var l=c(M),h=l.find(".clockpicker-plate"),m=l.find(".picker__holder"),v=l.find(".clockpicker-hours"),P=l.find(".clockpicker-minutes"),C=l.find(".clockpicker-am-pm-block"),x="INPUT"===s.prop("tagName"),T=x?s:s.find("input"),_=c("label[for="+T.attr("id")+"]"),V=this;if(this.id=e("cp"),this.element=s,this.holder=m,this.options=n,this.isAppended=!1,this.isShown=!1,this.currentView="hours",this.isInput=x,this.input=T,this.label=_,this.popover=l,this.plate=h,this.hoursView=v,this.minutesView=P,this.amPmBlock=C,this.spanHours=l.find(".clockpicker-span-hours"),this.spanMinutes=l.find(".clockpicker-span-minutes"),this.spanAmPm=l.find(".clockpicker-span-am-pm"),this.footer=l.find(".picker__footer"),this.amOrPm="PM",n.twelvehour){var H=['<div class="clockpicker-am-pm-block">','<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-am-button">',"AM","</button>",'<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-pm-button">',"PM","</button>","</div>"].join("");c(H);n.ampmclickable?(this.spanAmPm.empty(),c('<div id="click-am">AM</div>').on("click",function(){V.spanAmPm.children("#click-am").addClass("text-primary"),V.spanAmPm.children("#click-pm").removeClass("text-primary"),V.amOrPm="AM"}).appendTo(this.spanAmPm),c('<div id="click-pm">PM</div>').on("click",function(){V.spanAmPm.children("#click-pm").addClass("text-primary"),V.spanAmPm.children("#click-am").removeClass("text-primary"),V.amOrPm="PM"}).appendTo(this.spanAmPm)):(c('<button type="button" class="btn-floating btn-flat clockpicker-button am-button" tabindex="1">AM</button>').on("click",function(){V.amOrPm="AM",V.amPmBlock.children(".pm-button").removeClass("active"),V.amPmBlock.children(".am-button").addClass("active"),V.spanAmPm.empty().append("AM")}).appendTo(this.amPmBlock),c('<button type="button" class="btn-floating btn-flat clockpicker-button pm-button" tabindex="2">PM</button>').on("click",function(){V.amOrPm="PM",V.amPmBlock.children(".am-button").removeClass("active"),V.amPmBlock.children(".pm-button").addClass("active"),V.spanAmPm.empty().append("PM")}).appendTo(this.amPmBlock))}T.attr("type","text"),n.darktheme&&l.addClass("darktheme"),c('<button type="button" class="btn-flat clockpicker-button" tabindex="'+(n.twelvehour?"3":"1")+'">'+n.donetext+"</button>").click(c.proxy(this.done,this)).appendTo(this.footer),this.spanHours.click(c.proxy(this.toggleView,this,"hours")),this.spanMinutes.click(c.proxy(this.toggleView,this,"minutes")),T.on("focus.clockpicker click.clockpicker",c.proxy(this.show,this));var S,B,D,E,I=c('<div class="clockpicker-tick"></div>');if(n.twelvehour)for(S=1;S<13;S+=1)B=I.clone(),D=S/6*Math.PI,E=b,B.css("font-size","140%"),B.css({left:f+Math.sin(D)*E-w,top:f-Math.cos(D)*E-w}),B.html(0===S?"00":S),v.append(B),B.on(u,r);else for(S=0;S<24;S+=1){B=I.clone(),D=S/6*Math.PI;var O=S>0&&S<13;E=O?g:b,B.css({left:f+Math.sin(D)*E-w,top:f-Math.cos(D)*E-w}),O&&B.css("font-size","120%"),B.html(0===S?"00":S),v.append(B),B.on(u,r)}for(S=0;S<60;S+=5)B=I.clone(),D=S/30*Math.PI,B.css({left:f+Math.sin(D)*b-w,top:f-Math.cos(D)*b-w}),B.css("font-size","140%"),B.html(i(S)),P.append(B),B.on(u,r);if(h.on(u,function(t){0===c(t.target).closest(".clockpicker-tick").length&&r(t,!0)}),p){var z=l.find(".clockpicker-canvas"),U=t("svg");U.setAttribute("class","clockpicker-svg"),U.setAttribute("width",y),U.setAttribute("height",y);var j=t("g");j.setAttribute("transform","translate("+f+","+f+")");var L=t("circle");L.setAttribute("class","clockpicker-canvas-bearing"),L.setAttribute("cx",0),L.setAttribute("cy",0),L.setAttribute("r",2);var N=t("line");N.setAttribute("x1",0),N.setAttribute("y1",0);var X=t("circle");X.setAttribute("class","clockpicker-canvas-bg"),X.setAttribute("r",w);var Y=t("circle");Y.setAttribute("class","clockpicker-canvas-fg"),Y.setAttribute("r",5),j.appendChild(N),j.appendChild(X),j.appendChild(Y),j.appendChild(L),U.appendChild(j),z.append(U),this.hand=N,this.bg=X,this.fg=Y,this.bearing=L,this.g=j,this.canvas=z}o(this.options.init)}function o(t){t&&"function"==typeof t&&t()}var c=window.jQuery,n=c(window),a=c(document),r="http://www.w3.org/2000/svg",p="SVGAngle"in window&&function(){var t,i=document.createElement("div");return i.innerHTML="<svg/>",t=(i.firstChild&&i.firstChild.namespaceURI)==r,i.innerHTML="",t}(),l=function(){var t=document.createElement("div").style;return"transition"in t||"WebkitTransition"in t||"MozTransition"in t||"msTransition"in t||"OTransition"in t}(),h="ontouchstart"in window,u="mousedown"+(h?" touchstart":""),d="mousemove.clockpicker"+(h?" touchmove.clockpicker":""),k="mouseup.clockpicker"+(h?" touchend.clockpicker":""),m=navigator.vibrate?"vibrate":navigator.webkitVibrate?"webkitVibrate":null,v=0,f=135,b=110,g=80,w=20,y=2*f,A=l?350:1,M=['<div class="clockpicker picker">','<div class="picker__holder">','<div class="picker__frame">','<div class="picker__wrap">','<div class="picker__box">','<div class="picker__date-display">','<div class="clockpicker-display">','<div class="clockpicker-display-column">','<span class="clockpicker-span-hours text-primary"></span>',":",'<span class="clockpicker-span-minutes"></span>',"</div>",'<div class="clockpicker-display-column clockpicker-display-am-pm">','<div class="clockpicker-span-am-pm"></div>',"</div>","</div>","</div>",'<div class="picker__calendar-container">','<div class="clockpicker-plate">','<div class="clockpicker-canvas"></div>','<div class="clockpicker-dial clockpicker-hours"></div>','<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',"</div>",'<div class="clockpicker-am-pm-block">',"</div>","</div>",'<div class="picker__footer">',"</div>","</div>","</div>","</div>","</div>","</div>"].join("");s.DEFAULTS={"default":"",fromnow:0,donetext:"Done",autoclose:!1,ampmclickable:!1,darktheme:!1,twelvehour:!0,vibrate:!0},s.prototype.toggle=function(){this[this.isShown?"hide":"show"]()},s.prototype.locate=function(){var t=this.element,i=this.popover;t.offset(),t.outerWidth(),t.outerHeight(),this.options.align;i.show()},s.prototype.show=function(t){if(this.setAMorPM=function(t){var i=t,e="pm"==t?"am":"pm";this.options.twelvehour&&(this.amOrPm=i.toUpperCase(),this.options.ampmclickable?(this.spanAmPm.children("#click-"+i).addClass("text-primary"),this.spanAmPm.children("#click-"+e).removeClass("text-primary")):(this.amPmBlock.children("."+e+"-button").removeClass("active"),this.amPmBlock.children("."+i+"-button").addClass("active"),this.spanAmPm.empty().append(this.amOrPm)))},!this.isShown){o(this.options.beforeShow),c(":input").each(function(){c(this).attr("tabindex",-1)});var e=this;this.input.blur(),this.popover.addClass("picker--opened"),this.input.addClass("picker__input picker__input--active"),c(document.body).css("overflow","hidden"),this.isAppended||(this.options.hasOwnProperty("container")?this.popover.appendTo(this.options.container):this.popover.insertAfter(this.input),this.setAMorPM("pm"),n.on("resize.clockpicker"+this.id,function(){e.isShown&&e.locate()}),this.isAppended=!0);var s=((this.input.prop("value")||this.options["default"]||"")+"").split(":");if(this.options.twelvehour&&"undefined"!=typeof s[1]&&(s[1].includes("AM")?this.setAMorPM("am"):this.setAMorPM("pm"),s[1]=s[1].replace("AM","").replace("PM","")),"now"===s[0]){var r=new Date(+new Date+this.options.fromnow);r.getHours()>=12?this.setAMorPM("pm"):this.setAMorPM("am"),s=[r.getHours(),r.getMinutes()]}this.hours=+s[0]||0,this.minutes=+s[1]||0,this.spanHours.html(i(this.hours)),this.spanMinutes.html(i(this.minutes)),this.toggleView("hours"),this.locate(),this.isShown=!0,a.on("click.clockpicker."+this.id+" focusin.clockpicker."+this.id,function(t){var i=c(t.target);0===i.closest(e.popover.find(".picker__wrap")).length&&0===i.closest(e.input).length&&e.hide()}),a.on("keyup.clockpicker."+this.id,function(t){27===t.keyCode&&e.hide()}),o(this.options.afterShow)}},s.prototype.hide=function(){o(this.options.beforeHide),this.input.removeClass("picker__input picker__input--active"),this.popover.removeClass("picker--opened"),c(document.body).css("overflow","visible"),this.isShown=!1,c(":input").each(function(t){c(this).attr("tabindex",t+1)}),a.off("click.clockpicker."+this.id+" focusin.clockpicker."+this.id),a.off("keyup.clockpicker."+this.id),this.popover.hide(),o(this.options.afterHide)},s.prototype.toggleView=function(t,i){var e=!1;"minutes"===t&&"visible"===c(this.hoursView).css("visibility")&&(o(this.options.beforeHourSelect),e=!0);var s="hours"===t,n=s?this.hoursView:this.minutesView,a=s?this.minutesView:this.hoursView;this.currentView=t,this.spanHours.toggleClass("text-primary",s),this.spanMinutes.toggleClass("text-primary",!s),a.addClass("clockpicker-dial-out"),n.css("visibility","visible").removeClass("clockpicker-dial-out"),this.resetClock(i),clearTimeout(this.toggleViewTimer),this.toggleViewTimer=setTimeout(function(){a.css("visibility","hidden")},A),e&&o(this.options.afterHourSelect)},s.prototype.resetClock=function(t){var i=this.currentView,e=this[i],s="hours"===i,o=Math.PI/(s?6:30),c=e*o,n=s&&e>0&&e<13?g:b,a=Math.sin(c)*n,r=-Math.cos(c)*n,l=this;p&&t?(l.canvas.addClass("clockpicker-canvas-out"),setTimeout(function(){l.canvas.removeClass("clockpicker-canvas-out"),l.setHand(a,r)},t)):this.setHand(a,r)},s.prototype.setHand=function(t,e,s,o){var n,a=Math.atan2(t,-e),r="hours"===this.currentView,l=Math.PI/(r||s?6:30),h=Math.sqrt(t*t+e*e),u=this.options,d=r&&h<(b+g)/2,k=d?g:b;if(u.twelvehour&&(k=b),a<0&&(a=2*Math.PI+a),n=Math.round(a/l),a=n*l,u.twelvehour?r?0===n&&(n=12):(s&&(n*=5),60===n&&(n=0)):r?(12===n&&(n=0),n=d?0===n?12:n:0===n?0:n+12):(s&&(n*=5),60===n&&(n=0)),r?this.fg.setAttribute("class","clockpicker-canvas-fg"):n%5==0?this.fg.setAttribute("class","clockpicker-canvas-fg"):this.fg.setAttribute("class","clockpicker-canvas-fg active"),this[this.currentView]!==n&&m&&this.options.vibrate&&(this.vibrateTimer||(navigator[m](10),this.vibrateTimer=setTimeout(c.proxy(function(){this.vibrateTimer=null},this),100))),this[this.currentView]=n,this[r?"spanHours":"spanMinutes"].html(i(n)),!p)return void this[r?"hoursView":"minutesView"].find(".clockpicker-tick").each(function(){var t=c(this);t.toggleClass("active",n===+t.html())});o||!r&&n%5?(this.g.insertBefore(this.hand,this.bearing),this.g.insertBefore(this.bg,this.fg),this.bg.setAttribute("class","clockpicker-canvas-bg clockpicker-canvas-bg-trans")):(this.g.insertBefore(this.hand,this.bg),this.g.insertBefore(this.fg,this.bg),this.bg.setAttribute("class","clockpicker-canvas-bg"));var v=Math.sin(a)*(k-w),f=-Math.cos(a)*(k-w),y=Math.sin(a)*k,A=-Math.cos(a)*k;this.hand.setAttribute("x2",v),this.hand.setAttribute("y2",f),this.bg.setAttribute("cx",y),this.bg.setAttribute("cy",A),this.fg.setAttribute("cx",y),this.fg.setAttribute("cy",A)},s.prototype.done=function(){o(this.options.beforeDone),this.hide(),this.label.addClass("active");var t=this.input.prop("value"),e=i(this.hours)+":"+i(this.minutes);this.options.twelvehour&&(e+=this.amOrPm),this.input.prop("value",e),e!==t&&(this.input.triggerHandler("change"),this.isInput||this.element.trigger("change")),this.options.autoclose&&this.input.trigger("blur"),o(this.options.afterDone)},s.prototype.remove=function(){this.element.removeData("clockpicker"),this.input.off("focus.clockpicker click.clockpicker"),this.isShown&&this.hide(),this.isAppended&&(n.off("resize.clockpicker"+this.id),this.popover.remove())},c.fn.pickatime=function(t){var i=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=c(this),o=e.data("clockpicker");if(o)"function"==typeof o[t]&&o[t].apply(o,i);else{var n=c.extend({},s.DEFAULTS,e.data(),"object"==typeof t&&t);e.data("clockpicker",new s(e,n))}})}}();
|
admin/js/materialize.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Materialize v0.97.8 (http://materializecss.com)
|
3 |
+
* Copyright 2014-2015 Materialize
|
4 |
+
* MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
|
5 |
+
*/
|
6 |
+
if("undefined"==typeof jQuery){var jQuery;jQuery="function"==typeof require?$=require("jquery"):$}jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,b,c,d,e){return jQuery.easing[jQuery.easing.def](a,b,c,d,e)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*(2*Math.PI)/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(2==(b/=e/2))return c+d;if(g||(g=e*(.3*1.5)),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return 1>b?-.5*(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c:h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g)*.5+d+c},easeInBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*(b/=e)*b*((f+1)*b-f)+c},easeOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*((b=b/e-1)*b*((f+1)*b+f)+1)+c},easeInOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),(b/=e/2)<1?d/2*(b*b*(((f*=1.525)+1)*b-f))+c:d/2*((b-=2)*b*(((f*=1.525)+1)*b+f)+2)+c},easeInBounce:function(a,b,c,d,e){return d-jQuery.easing.easeOutBounce(a,e-b,0,d,e)+c},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*(7.5625*b*b)+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(a,b,c,d,e){return e/2>b?.5*jQuery.easing.easeInBounce(a,2*b,0,d,e)+c:.5*jQuery.easing.easeOutBounce(a,2*b-e,0,d,e)+.5*d+c}}),jQuery.extend(jQuery.easing,{easeInOutMaterial:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:d/4*((b-=2)*b*b+2)+c}}),jQuery.Velocity?console.log("Velocity is already loaded. You may be needlessly importing Velocity again; note that Materialize includes Velocity."):(!function(a){function b(a){var b=a.length,d=c.type(a);return"function"===d||c.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===d||0===b||"number"==typeof b&&b>0&&b-1 in a}if(!a.jQuery){var c=function(a,b){return new c.fn.init(a,b)};c.isWindow=function(a){return null!=a&&a==a.window},c.type=function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?e[g.call(a)]||"object":typeof a},c.isArray=Array.isArray||function(a){return"array"===c.type(a)},c.isPlainObject=function(a){var b;if(!a||"object"!==c.type(a)||a.nodeType||c.isWindow(a))return!1;try{if(a.constructor&&!f.call(a,"constructor")&&!f.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(d){return!1}for(b in a);return void 0===b||f.call(a,b)},c.each=function(a,c,d){var e,f=0,g=a.length,h=b(a);if(d){if(h)for(;g>f&&(e=c.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=c.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=c.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=c.call(a[f],f,a[f]),e===!1)break;return a},c.data=function(a,b,e){if(void 0===e){var f=a[c.expando],g=f&&d[f];if(void 0===b)return g;if(g&&b in g)return g[b]}else if(void 0!==b){var f=a[c.expando]||(a[c.expando]=++c.uuid);return d[f]=d[f]||{},d[f][b]=e,e}},c.removeData=function(a,b){var e=a[c.expando],f=e&&d[e];f&&c.each(b,function(a,b){delete f[b]})},c.extend=function(){var a,b,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[i]||{},i++),"object"!=typeof h&&"function"!==c.type(h)&&(h={}),i===j&&(h=this,i--);j>i;i++)if(null!=(f=arguments[i]))for(e in f)a=h[e],d=f[e],h!==d&&(k&&d&&(c.isPlainObject(d)||(b=c.isArray(d)))?(b?(b=!1,g=a&&c.isArray(a)?a:[]):g=a&&c.isPlainObject(a)?a:{},h[e]=c.extend(k,g,d)):void 0!==d&&(h[e]=d));return h},c.queue=function(a,d,e){function f(a,c){var d=c||[];return null!=a&&(b(Object(a))?!function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;)a[e++]=b[d++];if(c!==c)for(;void 0!==b[d];)a[e++]=b[d++];return a.length=e,a}(d,"string"==typeof a?[a]:a):[].push.call(d,a)),d}if(a){d=(d||"fx")+"queue";var g=c.data(a,d);return e?(!g||c.isArray(e)?g=c.data(a,d,f(e)):g.push(e),g):g||[]}},c.dequeue=function(a,b){c.each(a.nodeType?[a]:a,function(a,d){b=b||"fx";var e=c.queue(d,b),f=e.shift();"inprogress"===f&&(f=e.shift()),f&&("fx"===b&&e.unshift("inprogress"),f.call(d,function(){c.dequeue(d,b)}))})},c.fn=c.prototype={init:function(a){if(a.nodeType)return this[0]=a,this;throw new Error("Not a DOM node.")},offset:function(){var b=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:b.top+(a.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:b.left+(a.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function a(){for(var a=this.offsetParent||document;a&&"html"===!a.nodeType.toLowerCase&&"static"===a.style.position;)a=a.offsetParent;return a||document}var b=this[0],a=a.apply(b),d=this.offset(),e=/^(?:body|html)$/i.test(a.nodeName)?{top:0,left:0}:c(a).offset();return d.top-=parseFloat(b.style.marginTop)||0,d.left-=parseFloat(b.style.marginLeft)||0,a.style&&(e.top+=parseFloat(a.style.borderTopWidth)||0,e.left+=parseFloat(a.style.borderLeftWidth)||0),{top:d.top-e.top,left:d.left-e.left}}};var d={};c.expando="velocity"+(new Date).getTime(),c.uuid=0;for(var e={},f=e.hasOwnProperty,g=e.toString,h="Boolean Number String Function Array Date RegExp Object Error".split(" "),i=0;i<h.length;i++)e["[object "+h[i]+"]"]=h[i].toLowerCase();c.fn.init.prototype=c.fn,a.Velocity={Utilities:c}}}(window),function(a){"object"==typeof module&&"object"==typeof module.exports?module.exports=a():"function"==typeof define&&define.amd?define(a):a()}(function(){return function(a,b,c,d){function e(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.push(e)}return d}function f(a){return p.isWrapped(a)?a=[].slice.call(a):p.isNode(a)&&(a=[a]),a}function g(a){var b=m.data(a,"velocity");return null===b?d:b}function h(a){return function(b){return Math.round(b*a)*(1/a)}}function i(a,c,d,e){function f(a,b){return 1-3*b+3*a}function g(a,b){return 3*b-6*a}function h(a){return 3*a}function i(a,b,c){return((f(b,c)*a+g(b,c))*a+h(b))*a}function j(a,b,c){return 3*f(b,c)*a*a+2*g(b,c)*a+h(b)}function k(b,c){for(var e=0;p>e;++e){var f=j(c,a,d);if(0===f)return c;var g=i(c,a,d)-b;c-=g/f}return c}function l(){for(var b=0;t>b;++b)x[b]=i(b*u,a,d)}function m(b,c,e){var f,g,h=0;do g=c+(e-c)/2,f=i(g,a,d)-b,f>0?e=g:c=g;while(Math.abs(f)>r&&++h<s);return g}function n(b){for(var c=0,e=1,f=t-1;e!=f&&x[e]<=b;++e)c+=u;--e;var g=(b-x[e])/(x[e+1]-x[e]),h=c+g*u,i=j(h,a,d);return i>=q?k(b,h):0==i?h:m(b,c,c+u)}function o(){y=!0,(a!=c||d!=e)&&l()}var p=4,q=.001,r=1e-7,s=10,t=11,u=1/(t-1),v="Float32Array"in b;if(4!==arguments.length)return!1;for(var w=0;4>w;++w)if("number"!=typeof arguments[w]||isNaN(arguments[w])||!isFinite(arguments[w]))return!1;a=Math.min(a,1),d=Math.min(d,1),a=Math.max(a,0),d=Math.max(d,0);var x=v?new Float32Array(t):new Array(t),y=!1,z=function(b){return y||o(),a===c&&d===e?b:0===b?0:1===b?1:i(n(b),c,e)};z.getControlPoints=function(){return[{x:a,y:c},{x:d,y:e}]};var A="generateBezier("+[a,c,d,e]+")";return z.toString=function(){return A},z}function j(a,b){var c=a;return p.isString(a)?t.Easings[a]||(c=!1):c=p.isArray(a)&&1===a.length?h.apply(null,a):p.isArray(a)&&2===a.length?u.apply(null,a.concat([b])):p.isArray(a)&&4===a.length?i.apply(null,a):!1,c===!1&&(c=t.Easings[t.defaults.easing]?t.defaults.easing:s),c}function k(a){if(a){var b=(new Date).getTime(),c=t.State.calls.length;c>1e4&&(t.State.calls=e(t.State.calls));for(var f=0;c>f;f++)if(t.State.calls[f]){var h=t.State.calls[f],i=h[0],j=h[2],n=h[3],o=!!n,q=null;n||(n=t.State.calls[f][3]=b-16);for(var r=Math.min((b-n)/j.duration,1),s=0,u=i.length;u>s;s++){var w=i[s],y=w.element;if(g(y)){var z=!1;if(j.display!==d&&null!==j.display&&"none"!==j.display){if("flex"===j.display){var A=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];m.each(A,function(a,b){v.setPropertyValue(y,"display",b)})}v.setPropertyValue(y,"display",j.display)}j.visibility!==d&&"hidden"!==j.visibility&&v.setPropertyValue(y,"visibility",j.visibility);for(var B in w)if("element"!==B){var C,D=w[B],E=p.isString(D.easing)?t.Easings[D.easing]:D.easing;if(1===r)C=D.endValue;else{var F=D.endValue-D.startValue;if(C=D.startValue+F*E(r,j,F),!o&&C===D.currentValue)continue}if(D.currentValue=C,"tween"===B)q=C;else{if(v.Hooks.registered[B]){var G=v.Hooks.getRoot(B),H=g(y).rootPropertyValueCache[G];H&&(D.rootPropertyValue=H)}var I=v.setPropertyValue(y,B,D.currentValue+(0===parseFloat(C)?"":D.unitType),D.rootPropertyValue,D.scrollData);v.Hooks.registered[B]&&(g(y).rootPropertyValueCache[G]=v.Normalizations.registered[G]?v.Normalizations.registered[G]("extract",null,I[1]):I[1]),"transform"===I[0]&&(z=!0)}}j.mobileHA&&g(y).transformCache.translate3d===d&&(g(y).transformCache.translate3d="(0px, 0px, 0px)",z=!0),z&&v.flushTransformCache(y)}}j.display!==d&&"none"!==j.display&&(t.State.calls[f][2].display=!1),j.visibility!==d&&"hidden"!==j.visibility&&(t.State.calls[f][2].visibility=!1),j.progress&&j.progress.call(h[1],h[1],r,Math.max(0,n+j.duration-b),n,q),1===r&&l(f)}}t.State.isTicking&&x(k)}function l(a,b){if(!t.State.calls[a])return!1;for(var c=t.State.calls[a][0],e=t.State.calls[a][1],f=t.State.calls[a][2],h=t.State.calls[a][4],i=!1,j=0,k=c.length;k>j;j++){var l=c[j].element;if(b||f.loop||("none"===f.display&&v.setPropertyValue(l,"display",f.display),"hidden"===f.visibility&&v.setPropertyValue(l,"visibility",f.visibility)),f.loop!==!0&&(m.queue(l)[1]===d||!/\.velocityQueueEntryFlag/i.test(m.queue(l)[1]))&&g(l)){g(l).isAnimating=!1,g(l).rootPropertyValueCache={};var n=!1;m.each(v.Lists.transforms3D,function(a,b){var c=/^scale/.test(b)?1:0,e=g(l).transformCache[b];g(l).transformCache[b]!==d&&new RegExp("^\\("+c+"[^.]").test(e)&&(n=!0,delete g(l).transformCache[b])}),f.mobileHA&&(n=!0,delete g(l).transformCache.translate3d),n&&v.flushTransformCache(l),v.Values.removeClass(l,"velocity-animating")}if(!b&&f.complete&&!f.loop&&j===k-1)try{f.complete.call(e,e)}catch(o){setTimeout(function(){throw o},1)}h&&f.loop!==!0&&h(e),g(l)&&f.loop===!0&&!b&&(m.each(g(l).tweensContainer,function(a,b){/^rotate/.test(a)&&360===parseFloat(b.endValue)&&(b.endValue=0,b.startValue=360),/^backgroundPosition/.test(a)&&100===parseFloat(b.endValue)&&"%"===b.unitType&&(b.endValue=0,b.startValue=100)}),t(l,"reverse",{loop:!0,delay:f.delay})),f.queue!==!1&&m.dequeue(l,f.queue)}t.State.calls[a]=!1;for(var p=0,q=t.State.calls.length;q>p;p++)if(t.State.calls[p]!==!1){i=!0;break}i===!1&&(t.State.isTicking=!1,delete t.State.calls,t.State.calls=[])}var m,n=function(){if(c.documentMode)return c.documentMode;for(var a=7;a>4;a--){var b=c.createElement("div");if(b.innerHTML="<!--[if IE "+a+"]><span></span><![endif]-->",b.getElementsByTagName("span").length)return b=null,a}return d}(),o=function(){var a=0;return b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||function(b){var c,d=(new Date).getTime();return c=Math.max(0,16-(d-a)),a=d+c,setTimeout(function(){b(d+c)},c)}}(),p={isString:function(a){return"string"==typeof a},isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},isFunction:function(a){return"[object Function]"===Object.prototype.toString.call(a)},isNode:function(a){return a&&a.nodeType},isNodeList:function(a){return"object"==typeof a&&/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(a))&&a.length!==d&&(0===a.length||"object"==typeof a[0]&&a[0].nodeType>0)},isWrapped:function(a){return a&&(a.jquery||b.Zepto&&b.Zepto.zepto.isZ(a))},isSVG:function(a){return b.SVGElement&&a instanceof b.SVGElement},isEmptyObject:function(a){for(var b in a)return!1;return!0}},q=!1;if(a.fn&&a.fn.jquery?(m=a,q=!0):m=b.Velocity.Utilities,8>=n&&!q)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=n)return void(jQuery.fn.velocity=jQuery.fn.animate);var r=400,s="swing",t={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:b.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:c.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:m,Redirects:{},Easings:{},Promise:b.Promise,defaults:{queue:"",duration:r,easing:s,begin:d,complete:d,progress:d,display:d,visibility:d,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(a){m.data(a,"velocity",{isSVG:p.isSVG(a),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};b.pageYOffset!==d?(t.State.scrollAnchor=b,t.State.scrollPropertyLeft="pageXOffset",t.State.scrollPropertyTop="pageYOffset"):(t.State.scrollAnchor=c.documentElement||c.body.parentNode||c.body,t.State.scrollPropertyLeft="scrollLeft",t.State.scrollPropertyTop="scrollTop");var u=function(){function a(a){return-a.tension*a.x-a.friction*a.v}function b(b,c,d){var e={x:b.x+d.dx*c,v:b.v+d.dv*c,tension:b.tension,friction:b.friction};return{dx:e.v,dv:a(e)}}function c(c,d){var e={dx:c.v,dv:a(c)},f=b(c,.5*d,e),g=b(c,.5*d,f),h=b(c,d,g),i=1/6*(e.dx+2*(f.dx+g.dx)+h.dx),j=1/6*(e.dv+2*(f.dv+g.dv)+h.dv);return c.x=c.x+i*d,c.v=c.v+j*d,c}return function d(a,b,e){var f,g,h,i={x:-1,v:0,tension:null,friction:null},j=[0],k=0,l=1e-4,m=.016;for(a=parseFloat(a)||500,b=parseFloat(b)||20,e=e||null,i.tension=a,i.friction=b,f=null!==e,f?(k=d(a,b),g=k/e*m):g=m;h=c(h||i,g),j.push(1+h.x),k+=16,Math.abs(h.x)>l&&Math.abs(h.v)>l;);return f?function(a){return j[a*(j.length-1)|0]}:k}}();t.Easings={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},spring:function(a){return 1-Math.cos(4.5*a*Math.PI)*Math.exp(6*-a)}},m.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(a,b){t.Easings[b[0]]=i.apply(null,b[1])});var v=t.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var a=0;a<v.Lists.colors.length;a++){var b="color"===v.Lists.colors[a]?"0 0 0 1":"255 255 255 1";v.Hooks.templates[v.Lists.colors[a]]=["Red Green Blue Alpha",b]}var c,d,e;if(n)for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");var f=d[1].match(v.RegEx.valueSplit);"Color"===e[0]&&(e.push(e.shift()),f.push(f.shift()),v.Hooks.templates[c]=[e.join(" "),f.join(" ")])}for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");for(var a in e){var g=c+e[a],h=a;v.Hooks.registered[g]=[c,h]}}},getRoot:function(a){var b=v.Hooks.registered[a];return b?b[0]:a},cleanRootPropertyValue:function(a,b){return v.RegEx.valueUnwrap.test(b)&&(b=b.match(v.RegEx.valueUnwrap)[1]),v.Values.isCSSNullValue(b)&&(b=v.Hooks.templates[a][1]),b},extractValue:function(a,b){var c=v.Hooks.registered[a];if(c){var d=c[0],e=c[1];return b=v.Hooks.cleanRootPropertyValue(d,b),b.toString().match(v.RegEx.valueSplit)[e]}return b},injectValue:function(a,b,c){var d=v.Hooks.registered[a];if(d){var e,f,g=d[0],h=d[1];return c=v.Hooks.cleanRootPropertyValue(g,c),e=c.toString().match(v.RegEx.valueSplit),e[h]=b,f=e.join(" ")}return c}},Normalizations:{registered:{clip:function(a,b,c){switch(a){case"name":return"clip";case"extract":var d;return v.RegEx.wrappedValueAlreadyExtracted.test(c)?d=c:(d=c.toString().match(v.RegEx.valueUnwrap),d=d?d[1].replace(/,(\s+)?/g," "):c),d;case"inject":return"rect("+c+")"}},blur:function(a,b,c){switch(a){case"name":return t.State.isFirefox?"filter":"-webkit-filter";case"extract":var d=parseFloat(c);if(!d&&0!==d){var e=c.toString().match(/blur\(([0-9]+[A-z]+)\)/i);d=e?e[1]:0}return d;case"inject":return parseFloat(c)?"blur("+c+")":"none"}},opacity:function(a,b,c){if(8>=n)switch(a){case"name":return"filter";case"extract":var d=c.toString().match(/alpha\(opacity=(.*)\)/i);return c=d?d[1]/100:1;case"inject":return b.style.zoom=1,parseFloat(c)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(c),10)+")"}else switch(a){case"name":return"opacity";case"extract":return c;case"inject":return c}}},register:function(){9>=n||t.State.isGingerbread||(v.Lists.transformsBase=v.Lists.transformsBase.concat(v.Lists.transforms3D));for(var a=0;a<v.Lists.transformsBase.length;a++)!function(){var b=v.Lists.transformsBase[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return"transform";case"extract":return g(c)===d||g(c).transformCache[b]===d?/^scale/i.test(b)?1:0:g(c).transformCache[b].replace(/[()]/g,"");case"inject":var f=!1;switch(b.substr(0,b.length-1)){case"translate":f=!/(%|px|em|rem|vw|vh|\d)$/i.test(e);break;case"scal":case"scale":t.State.isAndroid&&g(c).transformCache[b]===d&&1>e&&(e=1),f=!/(\d)$/i.test(e);break;case"skew":f=!/(deg|\d)$/i.test(e);break;case"rotate":f=!/(deg|\d)$/i.test(e)}return f||(g(c).transformCache[b]="("+e+")"),g(c).transformCache[b]}}}();for(var a=0;a<v.Lists.colors.length;a++)!function(){var b=v.Lists.colors[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return b;case"extract":var f;if(v.RegEx.wrappedValueAlreadyExtracted.test(e))f=e;else{var g,h={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(e)?g=h[e]!==d?h[e]:h.black:v.RegEx.isHex.test(e)?g="rgb("+v.Values.hexToRgb(e).join(" ")+")":/^rgba?\(/i.test(e)||(g=h.black),f=(g||e).toString().match(v.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g," ")}return 8>=n||3!==f.split(" ").length||(f+=" 1"),f;case"inject":return 8>=n?4===e.split(" ").length&&(e=e.split(/\s+/).slice(0,3).join(" ")):3===e.split(" ").length&&(e+=" 1"),(8>=n?"rgb":"rgba")+"("+e.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(a){return a.replace(/-(\w)/g,function(a,b){return b.toUpperCase()})},SVGAttribute:function(a){var b="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(n||t.State.isAndroid&&!t.State.isChrome)&&(b+="|transform"),new RegExp("^("+b+")$","i").test(a)},prefixCheck:function(a){if(t.State.prefixMatches[a])return[t.State.prefixMatches[a],!0];for(var b=["","Webkit","Moz","ms","O"],c=0,d=b.length;d>c;c++){var e;if(e=0===c?a:b[c]+a.replace(/^\w/,function(a){return a.toUpperCase()}),p.isString(t.State.prefixElement.style[e]))return t.State.prefixMatches[a]=e,[e,!0]}return[a,!1]}},Values:{hexToRgb:function(a){var b,c=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,d=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;return a=a.replace(c,function(a,b,c,d){return b+b+c+c+d+d}),b=d.exec(a),b?[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]:[0,0,0]},isCSSNullValue:function(a){return 0==a||/^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(a)},getUnitType:function(a){return/^(rotate|skew)/i.test(a)?"deg":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(a)?"":"px"},getDisplayType:function(a){var b=a&&a.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(b)?"inline":/^(li)$/i.test(b)?"list-item":/^(tr)$/i.test(b)?"table-row":/^(table)$/i.test(b)?"table":/^(tbody)$/i.test(b)?"table-row-group":"block"},addClass:function(a,b){a.classList?a.classList.add(b):a.className+=(a.className.length?" ":"")+b},removeClass:function(a,b){a.classList?a.classList.remove(b):a.className=a.className.toString().replace(new RegExp("(^|\\s)"+b.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(a,c,e,f){function h(a,c){function e(){j&&v.setPropertyValue(a,"display","none")}var i=0;if(8>=n)i=m.css(a,c);else{var j=!1;if(/^(width|height)$/.test(c)&&0===v.getPropertyValue(a,"display")&&(j=!0,v.setPropertyValue(a,"display",v.Values.getDisplayType(a))),!f){if("height"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var k=a.offsetHeight-(parseFloat(v.getPropertyValue(a,"borderTopWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderBottomWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingTop"))||0)-(parseFloat(v.getPropertyValue(a,"paddingBottom"))||0);return e(),k}if("width"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var l=a.offsetWidth-(parseFloat(v.getPropertyValue(a,"borderLeftWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderRightWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingLeft"))||0)-(parseFloat(v.getPropertyValue(a,"paddingRight"))||0);return e(),l}}var o;o=g(a)===d?b.getComputedStyle(a,null):g(a).computedStyle?g(a).computedStyle:g(a).computedStyle=b.getComputedStyle(a,null),"borderColor"===c&&(c="borderTopColor"),i=9===n&&"filter"===c?o.getPropertyValue(c):o[c],(""===i||null===i)&&(i=a.style[c]),e()}if("auto"===i&&/^(top|right|bottom|left)$/i.test(c)){var p=h(a,"position");("fixed"===p||"absolute"===p&&/top|left/i.test(c))&&(i=m(a).position()[c]+"px")}return i}var i;if(v.Hooks.registered[c]){var j=c,k=v.Hooks.getRoot(j);e===d&&(e=v.getPropertyValue(a,v.Names.prefixCheck(k)[0])),v.Normalizations.registered[k]&&(e=v.Normalizations.registered[k]("extract",a,e)),i=v.Hooks.extractValue(j,e)}else if(v.Normalizations.registered[c]){var l,o;l=v.Normalizations.registered[c]("name",a),"transform"!==l&&(o=h(a,v.Names.prefixCheck(l)[0]),v.Values.isCSSNullValue(o)&&v.Hooks.templates[c]&&(o=v.Hooks.templates[c][1])),i=v.Normalizations.registered[c]("extract",a,o)}if(!/^[\d-]/.test(i))if(g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c))if(/^(height|width)$/i.test(c))try{i=a.getBBox()[c]}catch(p){i=0}else i=a.getAttribute(c);else i=h(a,v.Names.prefixCheck(c)[0]);return v.Values.isCSSNullValue(i)&&(i=0),t.debug>=2&&console.log("Get "+c+": "+i),i},setPropertyValue:function(a,c,d,e,f){var h=c;if("scroll"===c)f.container?f.container["scroll"+f.direction]=d:"Left"===f.direction?b.scrollTo(d,f.alternateValue):b.scrollTo(f.alternateValue,d);else if(v.Normalizations.registered[c]&&"transform"===v.Normalizations.registered[c]("name",a))v.Normalizations.registered[c]("inject",a,d),h="transform",d=g(a).transformCache[c];else{if(v.Hooks.registered[c]){var i=c,j=v.Hooks.getRoot(c);e=e||v.getPropertyValue(a,j),d=v.Hooks.injectValue(i,d,e),c=j}if(v.Normalizations.registered[c]&&(d=v.Normalizations.registered[c]("inject",a,d),c=v.Normalizations.registered[c]("name",a)),h=v.Names.prefixCheck(c)[0],8>=n)try{a.style[h]=d}catch(k){t.debug&&console.log("Browser does not support ["+d+"] for ["+h+"]")}else g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c)?a.setAttribute(c,d):a.style[h]=d;t.debug>=2&&console.log("Set "+c+" ("+h+"): "+d)}return[h,d]},flushTransformCache:function(a){function b(b){return parseFloat(v.getPropertyValue(a,b))}var c="";if((n||t.State.isAndroid&&!t.State.isChrome)&&g(a).isSVG){var d={translate:[b("translateX"),b("translateY")],skewX:[b("skewX")],skewY:[b("skewY")],scale:1!==b("scale")?[b("scale"),b("scale")]:[b("scaleX"),b("scaleY")],rotate:[b("rotateZ"),0,0]};m.each(g(a).transformCache,function(a){/^translate/i.test(a)?a="translate":/^scale/i.test(a)?a="scale":/^rotate/i.test(a)&&(a="rotate"),d[a]&&(c+=a+"("+d[a].join(" ")+") ",delete d[a])})}else{var e,f;m.each(g(a).transformCache,function(b){return e=g(a).transformCache[b],"transformPerspective"===b?(f=e,!0):(9===n&&"rotateZ"===b&&(b="rotate"),void(c+=b+e+" "))}),f&&(c="perspective"+f+" "+c)}v.setPropertyValue(a,"transform",c)}};v.Hooks.register(),v.Normalizations.register(),t.hook=function(a,b,c){var e=d;return a=f(a),m.each(a,function(a,f){if(g(f)===d&&t.init(f),c===d)e===d&&(e=t.CSS.getPropertyValue(f,b));else{var h=t.CSS.setPropertyValue(f,b,c);"transform"===h[0]&&t.CSS.flushTransformCache(f),e=h}}),e};var w=function(){function a(){return h?B.promise||null:i}function e(){function a(a){function l(a,b){var c=d,e=d,g=d;return p.isArray(a)?(c=a[0],!p.isArray(a[1])&&/^[\d-]/.test(a[1])||p.isFunction(a[1])||v.RegEx.isHex.test(a[1])?g=a[1]:(p.isString(a[1])&&!v.RegEx.isHex.test(a[1])||p.isArray(a[1]))&&(e=b?a[1]:j(a[1],h.duration),a[2]!==d&&(g=a[2]))):c=a,b||(e=e||h.easing),p.isFunction(c)&&(c=c.call(f,y,x)),p.isFunction(g)&&(g=g.call(f,y,x)),[c||0,e,g]}function n(a,b){var c,d;return d=(b||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(a){return c=a,""}),c||(c=v.Values.getUnitType(a)),[d,c]}function r(){var a={myParent:f.parentNode||c.body,position:v.getPropertyValue(f,"position"),fontSize:v.getPropertyValue(f,"fontSize")},d=a.position===I.lastPosition&&a.myParent===I.lastParent,e=a.fontSize===I.lastFontSize;I.lastParent=a.myParent,I.lastPosition=a.position,I.lastFontSize=a.fontSize;var h=100,i={};if(e&&d)i.emToPx=I.lastEmToPx,i.percentToPxWidth=I.lastPercentToPxWidth,i.percentToPxHeight=I.lastPercentToPxHeight;else{var j=g(f).isSVG?c.createElementNS("http://www.w3.org/2000/svg","rect"):c.createElement("div");t.init(j),a.myParent.appendChild(j),m.each(["overflow","overflowX","overflowY"],function(a,b){t.CSS.setPropertyValue(j,b,"hidden")}),t.CSS.setPropertyValue(j,"position",a.position),t.CSS.setPropertyValue(j,"fontSize",a.fontSize),t.CSS.setPropertyValue(j,"boxSizing","content-box"),m.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(a,b){t.CSS.setPropertyValue(j,b,h+"%")}),t.CSS.setPropertyValue(j,"paddingLeft",h+"em"),i.percentToPxWidth=I.lastPercentToPxWidth=(parseFloat(v.getPropertyValue(j,"width",null,!0))||1)/h,i.percentToPxHeight=I.lastPercentToPxHeight=(parseFloat(v.getPropertyValue(j,"height",null,!0))||1)/h,i.emToPx=I.lastEmToPx=(parseFloat(v.getPropertyValue(j,"paddingLeft"))||1)/h,a.myParent.removeChild(j)}return null===I.remToPx&&(I.remToPx=parseFloat(v.getPropertyValue(c.body,"fontSize"))||16),null===I.vwToPx&&(I.vwToPx=parseFloat(b.innerWidth)/100,I.vhToPx=parseFloat(b.innerHeight)/100),i.remToPx=I.remToPx,i.vwToPx=I.vwToPx,i.vhToPx=I.vhToPx,t.debug>=1&&console.log("Unit ratios: "+JSON.stringify(i),f),i}if(h.begin&&0===y)try{h.begin.call(o,o)}catch(u){setTimeout(function(){throw u},1)}if("scroll"===C){var w,z,A,D=/^x$/i.test(h.axis)?"Left":"Top",E=parseFloat(h.offset)||0;h.container?p.isWrapped(h.container)||p.isNode(h.container)?(h.container=h.container[0]||h.container,w=h.container["scroll"+D],A=w+m(f).position()[D.toLowerCase()]+E):h.container=null:(w=t.State.scrollAnchor[t.State["scrollProperty"+D]],z=t.State.scrollAnchor[t.State["scrollProperty"+("Left"===D?"Top":"Left")]],A=m(f).offset()[D.toLowerCase()]+E),i={scroll:{rootPropertyValue:!1,startValue:w,currentValue:w,endValue:A,unitType:"",easing:h.easing,scrollData:{container:h.container,direction:D,alternateValue:z}},element:f},t.debug&&console.log("tweensContainer (scroll): ",i.scroll,f)}else if("reverse"===C){if(!g(f).tweensContainer)return void m.dequeue(f,h.queue);"none"===g(f).opts.display&&(g(f).opts.display="auto"),"hidden"===g(f).opts.visibility&&(g(f).opts.visibility="visible"),g(f).opts.loop=!1,g(f).opts.begin=null,g(f).opts.complete=null,s.easing||delete h.easing,s.duration||delete h.duration,h=m.extend({},g(f).opts,h);var F=m.extend(!0,{},g(f).tweensContainer);for(var G in F)if("element"!==G){var H=F[G].startValue;F[G].startValue=F[G].currentValue=F[G].endValue,F[G].endValue=H,p.isEmptyObject(s)||(F[G].easing=h.easing),t.debug&&console.log("reverse tweensContainer ("+G+"): "+JSON.stringify(F[G]),f)}i=F}else if("start"===C){var F;g(f).tweensContainer&&g(f).isAnimating===!0&&(F=g(f).tweensContainer),m.each(q,function(a,b){if(RegExp("^"+v.Lists.colors.join("$|^")+"$").test(a)){var c=l(b,!0),e=c[0],f=c[1],g=c[2];if(v.RegEx.isHex.test(e)){for(var h=["Red","Green","Blue"],i=v.Values.hexToRgb(e),j=g?v.Values.hexToRgb(g):d,k=0;k<h.length;k++){var m=[i[k]];f&&m.push(f),j!==d&&m.push(j[k]),q[a+h[k]]=m}delete q[a]}}});for(var K in q){var L=l(q[K]),M=L[0],N=L[1],O=L[2];K=v.Names.camelCase(K);var P=v.Hooks.getRoot(K),Q=!1;if(g(f).isSVG||"tween"===P||v.Names.prefixCheck(P)[1]!==!1||v.Normalizations.registered[P]!==d){(h.display!==d&&null!==h.display&&"none"!==h.display||h.visibility!==d&&"hidden"!==h.visibility)&&/opacity|filter/.test(K)&&!O&&0!==M&&(O=0),h._cacheValues&&F&&F[K]?(O===d&&(O=F[K].endValue+F[K].unitType),Q=g(f).rootPropertyValueCache[P]):v.Hooks.registered[K]?O===d?(Q=v.getPropertyValue(f,P),O=v.getPropertyValue(f,K,Q)):Q=v.Hooks.templates[P][1]:O===d&&(O=v.getPropertyValue(f,K));var R,S,T,U=!1;if(R=n(K,O),O=R[0],T=R[1],R=n(K,M),M=R[0].replace(/^([+-\/*])=/,function(a,b){return U=b,""}),S=R[1],O=parseFloat(O)||0,M=parseFloat(M)||0,"%"===S&&(/^(fontSize|lineHeight)$/.test(K)?(M/=100,S="em"):/^scale/.test(K)?(M/=100,S=""):/(Red|Green|Blue)$/i.test(K)&&(M=M/100*255,S="")),/[\/*]/.test(U))S=T;else if(T!==S&&0!==O)if(0===M)S=T;else{e=e||r();var V=/margin|padding|left|right|width|text|word|letter/i.test(K)||/X$/.test(K)||"x"===K?"x":"y";
|
7 |
+
switch(T){case"%":O*="x"===V?e.percentToPxWidth:e.percentToPxHeight;break;case"px":break;default:O*=e[T+"ToPx"]}switch(S){case"%":O*=1/("x"===V?e.percentToPxWidth:e.percentToPxHeight);break;case"px":break;default:O*=1/e[S+"ToPx"]}}switch(U){case"+":M=O+M;break;case"-":M=O-M;break;case"*":M=O*M;break;case"/":M=O/M}i[K]={rootPropertyValue:Q,startValue:O,currentValue:O,endValue:M,unitType:S,easing:N},t.debug&&console.log("tweensContainer ("+K+"): "+JSON.stringify(i[K]),f)}else t.debug&&console.log("Skipping ["+P+"] due to a lack of browser support.")}i.element=f}i.element&&(v.Values.addClass(f,"velocity-animating"),J.push(i),""===h.queue&&(g(f).tweensContainer=i,g(f).opts=h),g(f).isAnimating=!0,y===x-1?(t.State.calls.push([J,o,h,null,B.resolver]),t.State.isTicking===!1&&(t.State.isTicking=!0,k())):y++)}var e,f=this,h=m.extend({},t.defaults,s),i={};switch(g(f)===d&&t.init(f),parseFloat(h.delay)&&h.queue!==!1&&m.queue(f,h.queue,function(a){t.velocityQueueEntryFlag=!0,g(f).delayTimer={setTimeout:setTimeout(a,parseFloat(h.delay)),next:a}}),h.duration.toString().toLowerCase()){case"fast":h.duration=200;break;case"normal":h.duration=r;break;case"slow":h.duration=600;break;default:h.duration=parseFloat(h.duration)||1}t.mock!==!1&&(t.mock===!0?h.duration=h.delay=1:(h.duration*=parseFloat(t.mock)||1,h.delay*=parseFloat(t.mock)||1)),h.easing=j(h.easing,h.duration),h.begin&&!p.isFunction(h.begin)&&(h.begin=null),h.progress&&!p.isFunction(h.progress)&&(h.progress=null),h.complete&&!p.isFunction(h.complete)&&(h.complete=null),h.display!==d&&null!==h.display&&(h.display=h.display.toString().toLowerCase(),"auto"===h.display&&(h.display=t.CSS.Values.getDisplayType(f))),h.visibility!==d&&null!==h.visibility&&(h.visibility=h.visibility.toString().toLowerCase()),h.mobileHA=h.mobileHA&&t.State.isMobile&&!t.State.isGingerbread,h.queue===!1?h.delay?setTimeout(a,h.delay):a():m.queue(f,h.queue,function(b,c){return c===!0?(B.promise&&B.resolver(o),!0):(t.velocityQueueEntryFlag=!0,void a(b))}),""!==h.queue&&"fx"!==h.queue||"inprogress"===m.queue(f)[0]||m.dequeue(f)}var h,i,n,o,q,s,u=arguments[0]&&(arguments[0].p||m.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||p.isString(arguments[0].properties));if(p.isWrapped(this)?(h=!1,n=0,o=this,i=this):(h=!0,n=1,o=u?arguments[0].elements||arguments[0].e:arguments[0]),o=f(o)){u?(q=arguments[0].properties||arguments[0].p,s=arguments[0].options||arguments[0].o):(q=arguments[n],s=arguments[n+1]);var x=o.length,y=0;if(!/^(stop|finish)$/i.test(q)&&!m.isPlainObject(s)){var z=n+1;s={};for(var A=z;A<arguments.length;A++)p.isArray(arguments[A])||!/^(fast|normal|slow)$/i.test(arguments[A])&&!/^\d/.test(arguments[A])?p.isString(arguments[A])||p.isArray(arguments[A])?s.easing=arguments[A]:p.isFunction(arguments[A])&&(s.complete=arguments[A]):s.duration=arguments[A]}var B={promise:null,resolver:null,rejecter:null};h&&t.Promise&&(B.promise=new t.Promise(function(a,b){B.resolver=a,B.rejecter=b}));var C;switch(q){case"scroll":C="scroll";break;case"reverse":C="reverse";break;case"finish":case"stop":m.each(o,function(a,b){g(b)&&g(b).delayTimer&&(clearTimeout(g(b).delayTimer.setTimeout),g(b).delayTimer.next&&g(b).delayTimer.next(),delete g(b).delayTimer)});var D=[];return m.each(t.State.calls,function(a,b){b&&m.each(b[1],function(c,e){var f=s===d?"":s;return f===!0||b[2].queue===f||s===d&&b[2].queue===!1?void m.each(o,function(c,d){d===e&&((s===!0||p.isString(s))&&(m.each(m.queue(d,p.isString(s)?s:""),function(a,b){p.isFunction(b)&&b(null,!0)}),m.queue(d,p.isString(s)?s:"",[])),"stop"===q?(g(d)&&g(d).tweensContainer&&f!==!1&&m.each(g(d).tweensContainer,function(a,b){b.endValue=b.currentValue}),D.push(a)):"finish"===q&&(b[2].duration=1))}):!0})}),"stop"===q&&(m.each(D,function(a,b){l(b,!0)}),B.promise&&B.resolver(o)),a();default:if(!m.isPlainObject(q)||p.isEmptyObject(q)){if(p.isString(q)&&t.Redirects[q]){var E=m.extend({},s),F=E.duration,G=E.delay||0;return E.backwards===!0&&(o=m.extend(!0,[],o).reverse()),m.each(o,function(a,b){parseFloat(E.stagger)?E.delay=G+parseFloat(E.stagger)*a:p.isFunction(E.stagger)&&(E.delay=G+E.stagger.call(b,a,x)),E.drag&&(E.duration=parseFloat(F)||(/^(callout|transition)/.test(q)?1e3:r),E.duration=Math.max(E.duration*(E.backwards?1-a/x:(a+1)/x),.75*E.duration,200)),t.Redirects[q].call(b,b,E||{},a,x,o,B.promise?B:d)}),a()}var H="Velocity: First argument ("+q+") was not a property map, a known action, or a registered redirect. Aborting.";return B.promise?B.rejecter(new Error(H)):console.log(H),a()}C="start"}var I={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},J=[];m.each(o,function(a,b){p.isNode(b)&&e.call(b)});var K,E=m.extend({},t.defaults,s);if(E.loop=parseInt(E.loop),K=2*E.loop-1,E.loop)for(var L=0;K>L;L++){var M={delay:E.delay,progress:E.progress};L===K-1&&(M.display=E.display,M.visibility=E.visibility,M.complete=E.complete),w(o,"reverse",M)}return a()}};t=m.extend(w,t),t.animate=w;var x=b.requestAnimationFrame||o;return t.State.isMobile||c.hidden===d||c.addEventListener("visibilitychange",function(){c.hidden?(x=function(a){return setTimeout(function(){a(!0)},16)},k()):x=b.requestAnimationFrame||o}),a.Velocity=t,a!==b&&(a.fn.velocity=w,a.fn.velocity.defaults=t.defaults),m.each(["Down","Up"],function(a,b){t.Redirects["slide"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j=i.begin,k=i.complete,l={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},n={};i.display===d&&(i.display="Down"===b?"inline"===t.CSS.Values.getDisplayType(a)?"inline-block":"block":"none"),i.begin=function(){j&&j.call(g,g);for(var c in l){n[c]=a.style[c];var d=t.CSS.getPropertyValue(a,c);l[c]="Down"===b?[d,0]:[0,d]}n.overflow=a.style.overflow,a.style.overflow="hidden"},i.complete=function(){for(var b in n)a.style[b]=n[b];k&&k.call(g,g),h&&h.resolver(g)},t(a,l,i)}}),m.each(["In","Out"],function(a,b){t.Redirects["fade"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j={opacity:"In"===b?1:0},k=i.complete;i.complete=e!==f-1?i.begin=null:function(){k&&k.call(g,g),h&&h.resolver(g)},i.display===d&&(i.display="In"===b?"auto":"none"),t(this,j,i)}}),t}(window.jQuery||window.Zepto||window,window,document)})),!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(k(a,c),b)}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function i(a,b){return h(a,b,!0)}function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&h(d,c)}function k(a,b){return function(){return a.apply(b,arguments)}}function l(a,b){return typeof a==ka?a.apply(b?b[0]||d:d,b):a}function m(a,b){return a===d?b:a}function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function q(a,b){return a.indexOf(b)>-1}function r(a){return a.trim().split(/\s+/g)}function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function t(a){return Array.prototype.slice.call(a,0)}function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];s(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ia.length;){if(c=ia[g],e=c?c+f:b,e in a)return e;g++}return d}function w(){return oa++}function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){l(a.options.enable,[a])&&c.handler(b)},this.init()}function z(a){var b,c=a.options.inputClass;return new(b=c?c:ra?N:sa?Q:qa?S:M)(a,A)}function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&ya&&0===d-e,g=b&(Aa|Ba)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,B(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=E(b)),e>1&&!c.firstMultiple?c.firstMultiple=E(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=F(d);b.timeStamp=na(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=J(h,i),b.distance=I(h,i),C(c,b),b.offsetDirection=H(b.deltaX,b.deltaY),b.scale=g?L(g.pointers,d):1,b.rotation=g?K(g.pointers,d):0,D(c,b);var j=a.element;p(b.srcEvent.target,j)&&(j=b.srcEvent.target),b.target=j}function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===ya||f.eventType===Aa)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ba&&(i>xa||h.velocity===d)){var j=h.deltaX-b.deltaX,k=h.deltaY-b.deltaY,l=G(i,j,k);e=l.x,f=l.y,c=ma(l.x)>ma(l.y)?l.x:l.y,g=H(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:la(a.pointers[c].clientX),clientY:la(a.pointers[c].clientY)},c++;return{timeStamp:na(),pointers:b,center:F(b),deltaX:a.deltaX,deltaY:a.deltaY}}function F(a){var b=a.length;if(1===b)return{x:la(a[0].clientX),y:la(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:la(c/b),y:la(d/b)}}function G(a,b,c){return{x:b/a||0,y:c/a||0}}function H(a,b){return a===b?Ca:ma(a)>=ma(b)?a>0?Da:Ea:b>0?Fa:Ga}function I(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function J(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function K(a,b){return J(b[1],b[0],La)-J(a[1],a[0],La)}function L(a,b){return I(b[0],b[1],La)/I(a[0],a[1],La)}function M(){this.evEl=Na,this.evWin=Oa,this.allow=!0,this.pressed=!1,y.apply(this,arguments)}function N(){this.evEl=Ra,this.evWin=Sa,y.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function O(){this.evTarget=Ua,this.evWin=Va,this.started=!1,y.apply(this,arguments)}function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Aa|Ba)&&(c=u(c.concat(d),"identifier",!0)),[c,d]}function Q(){this.evTarget=Xa,this.targetIds={},y.apply(this,arguments)}function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(ya|za)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=t(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return p(a.target,i)}),b===ya)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Aa|Ba)&&delete d[g[e].identifier],e++;return h.length?[u(f.concat(h),"identifier",!0),h]:void 0}function S(){y.apply(this,arguments);var a=k(this.handler,this);this.touch=new Q(this.manager,a),this.mouse=new M(this.manager,a)}function T(a,b){this.manager=a,this.set(b)}function U(a){if(q(a,bb))return bb;var b=q(a,cb),c=q(a,db);return b&&c?cb+" "+db:b||c?b?cb:db:q(a,ab)?ab:_a}function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.defaults),this.options.enable=m(this.options.enable,!0),this.state=eb,this.simultaneous={},this.requireFail=[]}function W(a){return a&jb?"cancel":a&hb?"end":a&gb?"move":a&fb?"start":""}function X(a){return a==Ga?"down":a==Fa?"up":a==Da?"left":a==Ea?"right":""}function Y(a,b){var c=b.manager;return c?c.get(a):a}function Z(){V.apply(this,arguments)}function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}function _(){Z.apply(this,arguments)}function aa(){V.apply(this,arguments),this._timer=null,this._input=null}function ba(){Z.apply(this,arguments)}function ca(){Z.apply(this,arguments)}function da(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function ea(a,b){return b=b||{},b.recognizers=m(b.recognizers,ea.defaults.preset),new fa(a,b)}function fa(a,b){b=b||{},this.options=i(b,ea.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=z(this),this.touchAction=new T(this,this.options.touchAction),ga(this,!0),g(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function ga(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.style[v(c.style,d)]=b?a:""})}function ha(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var ia=["","webkit","moz","MS","ms","o"],ja=b.createElement("div"),ka="function",la=Math.round,ma=Math.abs,na=Date.now,oa=1,pa=/mobile|tablet|ip(ad|hone|od)|android/i,qa="ontouchstart"in a,ra=v(a,"PointerEvent")!==d,sa=qa&&pa.test(navigator.userAgent),ta="touch",ua="pen",va="mouse",wa="kinect",xa=25,ya=1,za=2,Aa=4,Ba=8,Ca=1,Da=2,Ea=4,Fa=8,Ga=16,Ha=Da|Ea,Ia=Fa|Ga,Ja=Ha|Ia,Ka=["x","y"],La=["clientX","clientY"];y.prototype={handler:function(){},init:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(x(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&o(this.element,this.evEl,this.domHandler),this.evTarget&&o(this.target,this.evTarget,this.domHandler),this.evWin&&o(x(this.element),this.evWin,this.domHandler)}};var Ma={mousedown:ya,mousemove:za,mouseup:Aa},Na="mousedown",Oa="mousemove mouseup";j(M,y,{handler:function(a){var b=Ma[a.type];b&ya&&0===a.button&&(this.pressed=!0),b&za&&1!==a.which&&(b=Aa),this.pressed&&this.allow&&(b&Aa&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:va,srcEvent:a}))}});var Pa={pointerdown:ya,pointermove:za,pointerup:Aa,pointercancel:Ba,pointerout:Ba},Qa={2:ta,3:ua,4:va,5:wa},Ra="pointerdown",Sa="pointermove pointerup pointercancel";a.MSPointerEvent&&(Ra="MSPointerDown",Sa="MSPointerMove MSPointerUp MSPointerCancel"),j(N,y,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Pa[d],f=Qa[a.pointerType]||a.pointerType,g=f==ta,h=s(b,a.pointerId,"pointerId");e&ya&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Aa|Ba)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Ta={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Ua="touchstart",Va="touchstart touchmove touchend touchcancel";j(O,y,{handler:function(a){var b=Ta[a.type];if(b===ya&&(this.started=!0),this.started){var c=P.call(this,a,b);b&(Aa|Ba)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}});var Wa={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Xa="touchstart touchmove touchend touchcancel";j(Q,y,{handler:function(a){var b=Wa[a.type],c=R.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}),j(S,y,{handler:function(a,b,c){var d=c.pointerType==ta,e=c.pointerType==va;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Aa|Ba)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Ya=v(ja.style,"touchAction"),Za=Ya!==d,$a="compute",_a="auto",ab="manipulation",bb="none",cb="pan-x",db="pan-y";T.prototype={set:function(a){a==$a&&(a=this.compute()),Za&&(this.manager.element.style[Ya]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){l(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),U(a.join(" "))},preventDefaults:function(a){if(!Za){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=q(d,bb),f=q(d,db),g=q(d,cb);return e||f&&c&Ha||g&&c&Ia?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var eb=1,fb=2,gb=4,hb=8,ib=hb,jb=16,kb=32;V.prototype={defaults:{},set:function(a){return h(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=Y(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=Y(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=Y(a,this),-1===s(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=Y(a,this);var b=s(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}var c=this,d=this.state;hb>d&&b(!0),b(),d>=hb&&b(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=kb)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(kb|eb)))return!1;a++}return!0},recognize:function(a){var b=h({},a);return l(this.options.enable,[this,b])?(this.state&(ib|jb|kb)&&(this.state=eb),this.state=this.process(b),void(this.state&(fb|gb|hb|jb)&&this.tryEmit(b))):(this.reset(),void(this.state=kb))},process:function(){},getTouchAction:function(){},reset:function(){}},j(Z,V,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(fb|gb),e=this.attrTest(a);return d&&(c&Ba||!e)?b|jb:d||e?c&Aa?b|hb:b&fb?b|gb:fb:kb}}),j($,Z,{defaults:{event:"pan",threshold:10,pointers:1,direction:Ja},getTouchAction:function(){var a=this.options.direction,b=[];return a&Ha&&b.push(db),a&Ia&&b.push(cb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Ha?(e=0===f?Ca:0>f?Da:Ea,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ca:0>g?Fa:Ga,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return Z.prototype.attrTest.call(this,a)&&(this.state&fb||!(this.state&fb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),j(_,Z,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&fb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),j(aa,V,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[_a]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Aa|Ba)&&!f)this.reset();else if(a.eventType&ya)this.reset(),this._timer=e(function(){this.state=ib,this.tryEmit()},b.time,this);else if(a.eventType&Aa)return ib;return kb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===ib&&(a&&a.eventType&Aa?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=na(),this.manager.emit(this.options.event,this._input)))}}),j(ba,Z,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&fb)}}),j(ca,Z,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:Ha|Ia,pointers:1},getTouchAction:function(){return $.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Ha|Ia)?b=a.velocity:c&Ha?b=a.velocityX:c&Ia&&(b=a.velocityY),this._super.attrTest.call(this,a)&&c&a.direction&&a.distance>this.options.threshold&&ma(b)>this.options.velocity&&a.eventType&Aa},emit:function(a){var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),j(da,V,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[ab]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&ya&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Aa)return this.failTimeout();var g=this.pTime?a.timeStamp-this.pTime<b.interval:!0,h=!this.pCenter||I(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=ib,this.tryEmit()},b.interval,this),fb):ib}return kb},failTimeout:function(){return this._timer=e(function(){this.state=kb},this.options.interval,this),kb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==ib&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),ea.VERSION="2.0.4",ea.defaults={domEvents:!1,touchAction:$a,enable:!0,inputTarget:null,inputClass:null,preset:[[ba,{enable:!1}],[_,{enable:!1},["rotate"]],[ca,{direction:Ha}],[$,{direction:Ha},["swipe"]],[da],[da,{event:"doubletap",taps:2},["tap"]],[aa]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var lb=1,mb=2;fa.prototype={set:function(a){return h(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?mb:lb},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&ib)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===mb||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(fb|gb|hb)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof V)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(s(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return g(r(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return g(r(a),function(a){b?c[a].splice(s(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&ha(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&ga(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(ea,{INPUT_START:ya,INPUT_MOVE:za,INPUT_END:Aa,INPUT_CANCEL:Ba,STATE_POSSIBLE:eb,STATE_BEGAN:fb,STATE_CHANGED:gb,STATE_ENDED:hb,STATE_RECOGNIZED:ib,STATE_CANCELLED:jb,STATE_FAILED:kb,DIRECTION_NONE:Ca,DIRECTION_LEFT:Da,DIRECTION_RIGHT:Ea,DIRECTION_UP:Fa,DIRECTION_DOWN:Ga,DIRECTION_HORIZONTAL:Ha,DIRECTION_VERTICAL:Ia,DIRECTION_ALL:Ja,Manager:fa,Input:y,TouchAction:T,TouchInput:Q,MouseInput:M,PointerEventInput:N,TouchMouseInput:S,SingleTouchInput:O,Recognizer:V,AttrRecognizer:Z,Tap:da,Pan:$,Swipe:ca,Pinch:_,Rotate:ba,Press:aa,on:n,off:o,each:g,merge:i,extend:h,inherit:j,bindFn:k,prefixed:v}),typeof define==ka&&define.amd?define(function(){return ea}):"undefined"!=typeof module&&module.exports?module.exports=ea:a[c]=ea}(window,document,"Hammer"),function(a){"function"==typeof define&&define.amd?define(["jquery","hammerjs"],a):"object"==typeof exports?a(require("jquery"),require("hammerjs")):a(jQuery,Hammer)}(function(a,b){function c(c,d){var e=a(c);e.data("hammer")||e.data("hammer",new b(e[0],d))}a.fn.hammer=function(a){return this.each(function(){c(this,a)})},b.Manager.prototype.emit=function(b){return function(c,d){b.call(this,c,d),a(this.element).trigger({type:c,gesture:d})}}(b.Manager.prototype.emit)}),function(a){a.Package?Materialize={}:a.Materialize={}}(window),function(a){for(var b=0,c=["webkit","moz"],d=a.requestAnimationFrame,e=a.cancelAnimationFrame,f=c.length;--f>=0&&!d;)d=a[c[f]+"RequestAnimationFrame"],e=a[c[f]+"CancelRequestAnimationFrame"];d&&e||(d=function(a){var c=+Date.now(),d=Math.max(b+16,c);return setTimeout(function(){a(b=d)},d-c)},e=clearTimeout),a.requestAnimationFrame=d,a.cancelAnimationFrame=e}(window),Materialize.guid=function(){function a(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}}(),Materialize.escapeHash=function(a){return a.replace(/(:|\.|\[|\]|,|=)/g,"\\$1")},Materialize.elementOrParentIsFixed=function(a){var b=$(a),c=b.add(b.parents()),d=!1;return c.each(function(){return"fixed"===$(this).css("position")?(d=!0,!1):void 0}),d};var Vel;Vel=jQuery?jQuery.Velocity:$?$.Velocity:Velocity,function(a){a.fn.collapsible=function(b){var c={accordion:void 0,onOpen:void 0,onClose:void 0};return b=a.extend(c,b),this.each(function(){function c(b){j=i.find("> li > .collapsible-header"),b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}),j.not(b).removeClass("active").parent().removeClass("active"),j.not(b).parent().children(".collapsible-body").stop(!0,!1).each(function(){a(this).is(":visible")&&a(this).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height",""),f(a(this).siblings(".collapsible-header"))}})})}function d(b){b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}})}function e(a){b.accordion||"accordion"===k||void 0===k?c(a):d(a),f(a)}function f(a){a.hasClass("active")?"function"==typeof b.onOpen&&b.onOpen.call(this,a.parent()):"function"==typeof b.onClose&&b.onClose.call(this,a.parent())}function g(a){var b=h(a);return b.length>0}function h(a){return a.closest("li > .collapsible-header")}var i=a(this),j=a(this).find("> li > .collapsible-header"),k=i.data("collapsible");i.off("click.collapse","> li > .collapsible-header"),j.off("click.collapse"),i.on("click.collapse","> li > .collapsible-header",function(b){var c=a(b.target);g(c)&&(c=h(c)),c.toggleClass("active"),e(c)}),b.accordion||"accordion"===k||void 0===k?e(j.filter(".active").first()):j.filter(".active").each(function(){e(a(this))})})},a(document).ready(function(){a(".collapsible").collapsible()})}(jQuery),function(a){a.fn.scrollTo=function(b){return a(this).scrollTop(a(this).scrollTop()-a(this).offset().top+a(b).offset().top),this},a.fn.dropdown=function(b){var c={inDuration:300,outDuration:225,constrain_width:!0,hover:!1,gutter:0,belowOrigin:!1,alignment:"left",stopPropagation:!1};return"open"===b?(this.each(function(){a(this).trigger("open")}),!1):"close"===b?(this.each(function(){a(this).trigger("close")}),!1):void this.each(function(){function d(){void 0!==g.data("induration")&&(h.inDuration=g.data("induration")),void 0!==g.data("outduration")&&(h.outDuration=g.data("outduration")),void 0!==g.data("constrainwidth")&&(h.constrain_width=g.data("constrainwidth")),void 0!==g.data("hover")&&(h.hover=g.data("hover")),void 0!==g.data("gutter")&&(h.gutter=g.data("gutter")),void 0!==g.data("beloworigin")&&(h.belowOrigin=g.data("beloworigin")),void 0!==g.data("alignment")&&(h.alignment=g.data("alignment")),void 0!==g.data("stoppropagation")&&(h.stopPropagation=g.data("stoppropagation"))}function e(b){"focus"===b&&(i=!0),d(),j.addClass("active"),g.addClass("active"),h.constrain_width===!0?j.css("width",g.outerWidth()):j.css("white-space","nowrap");var c=window.innerHeight,e=g.innerHeight(),f=g.offset().left,k=g.offset().top-a(window).scrollTop(),l=h.alignment,m=0,n=0,o=0;h.belowOrigin===!0&&(o=e);var p=0,q=0,r=g.parent();if(r.is("body")||(r[0].scrollHeight>r[0].clientHeight&&(p=r[0].scrollTop),r[0].scrollWidth>r[0].clientWidth&&(q=r[0].scrollLeft)),f+j.innerWidth()>a(window).width()?l="right":f-j.innerWidth()+g.innerWidth()<0&&(l="left"),k+j.innerHeight()>c)if(k+e-j.innerHeight()<0){var s=c-k-o;j.css("max-height",s)}else o||(o+=e),o-=j.innerHeight();if("left"===l)m=h.gutter,n=g.position().left+m;else if("right"===l){var t=g.position().left+g.outerWidth()-j.outerWidth();m=-h.gutter,n=t+m}j.css({position:"absolute",top:g.position().top+o+p,left:n+q}),j.stop(!0,!0).css("opacity",0).slideDown({queue:!1,duration:h.inDuration,easing:"easeOutCubic",complete:function(){a(this).css("height","")}}).animate({opacity:1},{queue:!1,duration:h.inDuration,easing:"easeOutSine"})}function f(){i=!1,j.fadeOut(h.outDuration),j.removeClass("active"),g.removeClass("active"),setTimeout(function(){j.css("max-height","")},h.outDuration)}var g=a(this),h=a.extend({},c,b),i=!1,j=a("#"+g.attr("data-activates"));if(d(),g.after(j),h.hover){var k=!1;g.unbind("click."+g.attr("id")),g.on("mouseenter",function(a){k===!1&&(e(),k=!0)}),g.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-content").is(j)||(j.stop(!0,!0),f(),k=!1)}),j.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-button").is(g)||(j.stop(!0,!0),f(),k=!1)})}else g.unbind("click."+g.attr("id")),g.bind("click."+g.attr("id"),function(b){i||(g[0]!=b.currentTarget||g.hasClass("active")||0!==a(b.target).closest(".dropdown-content").length?g.hasClass("active")&&(f(),a(document).unbind("click."+j.attr("id")+" touchstart."+j.attr("id"))):(b.preventDefault(),h.stopPropagation&&b.stopPropagation(),e("click")),j.hasClass("active")&&a(document).bind("click."+j.attr("id")+" touchstart."+j.attr("id"),function(b){j.is(b.target)||g.is(b.target)||g.find(b.target).length||(f(),a(document).unbind("click."+j.attr("id")+" touchstart."+j.attr("id")))}))});g.on("open",function(a,b){e(b)}),g.on("close",f)})},a(document).ready(function(){a(".dropdown-button").dropdown()})}(jQuery),function(a){var b=0,c=0,d=function(){return c++,"materialize-modal-overlay-"+c},e={init:function(c){var e={opacity:.5,in_duration:350,out_duration:250,ready:void 0,complete:void 0,dismissible:!0,starting_top:"4%",ending_top:"10%"};return c=a.extend(e,c),this.each(function(){var e=a(this),f=a(this).attr("id")||"#"+a(this).data("target"),g=function(){var d=e.data("overlay-id"),f=a("#"+d);e.removeClass("open"),a("body").css({overflow:"",width:""}),e.find(".modal-close").off("click.close"),a(document).off("keyup.modal"+d),f.velocity({opacity:0},{duration:c.out_duration,queue:!1,ease:"easeOutQuart"});var g={
|
8 |
+
duration:c.out_duration,queue:!1,ease:"easeOutCubic",complete:function(){a(this).css({display:"none"}),"function"==typeof c.complete&&c.complete.call(this,e),f.remove(),b--}};e.hasClass("bottom-sheet")?e.velocity({bottom:"-100%",opacity:0},g):e.velocity({top:c.starting_top,opacity:0,scaleX:.7},g)},h=function(f){var h=a("body"),i=h.innerWidth();if(h.css("overflow","hidden"),h.width(i),!e.hasClass("open")){var j=d(),k=a('<div class="modal-overlay"></div>');lStack=++b,k.attr("id",j).css("z-index",1e3+2*lStack),e.data("overlay-id",j).css("z-index",1e3+2*lStack+1),e.addClass("open"),a("body").append(k),c.dismissible&&(k.click(function(){g()}),a(document).on("keyup.modal"+j,function(a){27===a.keyCode&&g()})),e.find(".modal-close").on("click.close",function(a){g()}),k.css({display:"block",opacity:0}),e.css({display:"block",opacity:0}),k.velocity({opacity:c.opacity},{duration:c.in_duration,queue:!1,ease:"easeOutCubic"}),e.data("associated-overlay",k[0]);var l={duration:c.in_duration,queue:!1,ease:"easeOutCubic",complete:function(){"function"==typeof c.ready&&c.ready.call(this,e,f)}};e.hasClass("bottom-sheet")?e.velocity({bottom:"0",opacity:1},l):(a.Velocity.hook(e,"scaleX",.7),e.css({top:c.starting_top}),e.velocity({top:c.ending_top,opacity:1,scaleX:"1"},l))}};a(document).off("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]'),a(this).off("openModal"),a(this).off("closeModal"),a(document).on("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]',function(b){c.starting_top=(a(this).offset().top-a(window).scrollTop())/1.15,h(a(this)),b.preventDefault()}),a(this).on("openModal",function(){a(this).attr("href")||"#"+a(this).data("target");h()}),a(this).on("closeModal",function(){g()})})},open:function(){a(this).trigger("openModal")},close:function(){a(this).trigger("closeModal")}};a.fn.modal=function(b){return e[b]?e[b].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof b&&b?void a.error("Method "+b+" does not exist on jQuery.modal"):e.init.apply(this,arguments)}}(jQuery),function(a){a.fn.materialbox=function(){return this.each(function(){function b(){f=!1;var b=i.parent(".material-placeholder"),d=(window.innerWidth,window.innerHeight,i.data("width")),g=i.data("height");i.velocity("stop",!0),a("#materialbox-overlay").velocity("stop",!0),a(".materialbox-caption").velocity("stop",!0),a("#materialbox-overlay").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){e=!1,a(this).remove()}}),i.velocity({width:d,height:g,left:0,top:0},{duration:h,queue:!1,easing:"easeOutQuad"}),a(".materialbox-caption").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){b.css({height:"",width:"",position:"",top:"",left:""}),i.css({height:"",top:"",left:"",width:"","max-width":"",position:"","z-index":""}),i.removeClass("active"),f=!0,a(this).remove(),c&&c.css("overflow","")}})}if(!a(this).hasClass("initialized")){a(this).addClass("initialized");var c,d,e=!1,f=!0,g=275,h=200,i=a(this),j=a("<div></div>").addClass("material-placeholder");i.wrap(j),i.on("click",function(){var h=i.parent(".material-placeholder"),j=window.innerWidth,k=window.innerHeight,l=i.width(),m=i.height();if(f===!1)return b(),!1;if(e&&f===!0)return b(),!1;f=!1,i.addClass("active"),e=!0,h.css({width:h[0].getBoundingClientRect().width,height:h[0].getBoundingClientRect().height,position:"relative",top:0,left:0}),c=void 0,d=h[0].parentNode;for(;null!==d&&!a(d).is(document);){var n=a(d);"visible"!==n.css("overflow")&&(n.css("overflow","visible"),c=void 0===c?n:c.add(n)),d=d.parentNode}i.css({position:"absolute","z-index":1e3}).data("width",l).data("height",m);var o=a('<div id="materialbox-overlay"></div>').css({opacity:0}).click(function(){f===!0&&b()});if(i.before(o),o.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"}),""!==i.data("caption")){var p=a('<div class="materialbox-caption"></div>');p.text(i.data("caption")),a("body").append(p),p.css({display:"inline"}),p.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"})}var q=0,r=l/j,s=m/k,t=0,u=0;r>s?(q=m/l,t=.9*j,u=.9*j*q):(q=l/m,t=.9*k*q,u=.9*k),i.hasClass("responsive-img")?i.velocity({"max-width":t,width:l},{duration:0,queue:!1,complete:function(){i.css({left:0,top:0}).velocity({height:u,width:t,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-t/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-u/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}}):i.css("left",0).css("top",0).velocity({height:u,width:t,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-t/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-u/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}),a(window).scroll(function(){e&&b()}),a(document).keyup(function(a){27===a.keyCode&&f===!0&&e&&b()})}})},a(document).ready(function(){a(".materialboxed").materialbox()})}(jQuery),function(a){a.fn.parallax=function(){var b=a(window).width();return this.each(function(c){function d(c){var d;d=601>b?e.height()>0?e.height():e.children("img").height():e.height()>0?e.height():500;var f=e.children("img").first(),g=f.height(),h=g-d,i=e.offset().top+d,j=e.offset().top,k=a(window).scrollTop(),l=window.innerHeight,m=k+l,n=(m-j)/(d+l),o=Math.round(h*n);c&&f.css("display","block"),i>k&&k+l>j&&f.css("transform","translate3D(-50%,"+o+"px, 0)")}var e=a(this);e.addClass("parallax"),e.children("img").one("load",function(){d(!0)}).each(function(){this.complete&&a(this).trigger("load")}),a(window).scroll(function(){b=a(window).width(),d(!1)}),a(window).resize(function(){b=a(window).width(),d(!1)})})}}(jQuery),function(a){var b={init:function(b){var c={onShow:null};return b=a.extend(c,b),this.each(function(){var c,d,e=a(this),f=(a(window).width(),e.find("li.tab a")),g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,i=0,j=function(a){return g-a.position().left-a.outerWidth()-e.scrollLeft()},k=function(a){return a.position().left+e.scrollLeft()};c=a(f.filter('[href="'+location.hash+'"]')),0===c.length&&(c=a(this).find("li.tab a.active").first()),0===c.length&&(c=a(this).find("li.tab a").first()),c.addClass("active"),i=f.index(c),0>i&&(i=0),void 0!==c[0]&&(d=a(c[0].hash)),e.append('<div class="indicator"></div>');var l=e.find(".indicator");e.is(":visible")&&setTimeout(function(){l.css({right:j(c)}),l.css({left:k(c)})},0),a(window).resize(function(){g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,0>i&&(i=0),0!==h&&0!==g&&(l.css({right:j(c)}),l.css({left:k(c)}))}),f.not(c).each(function(){a(Materialize.escapeHash(this.hash)).hide()}),e.on("click","a",function(m){if(a(this).parent().hasClass("disabled"))return void m.preventDefault();if(!a(this).attr("target")){g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,c.removeClass("active"),void 0!==d&&d.hide(),c=a(this),d=a(Materialize.escapeHash(this.hash)),f=e.find("li.tab a");c.position();c.addClass("active");var n=i;i=f.index(a(this)),0>i&&(i=0),void 0!==d&&(d.show(),"function"==typeof b.onShow&&b.onShow.call(this,d)),i-n>=0?(l.velocity({right:j(c)},{duration:300,queue:!1,easing:"easeOutQuad"}),l.velocity({left:k(c)},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})):(l.velocity({left:k(c)},{duration:300,queue:!1,easing:"easeOutQuad"}),l.velocity({right:j(c)},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})),m.preventDefault()}})})},select_tab:function(a){this.find('a[href="#'+a+'"]').trigger("click")}};a.fn.tabs=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tabs"):b.init.apply(this,arguments)},a(document).ready(function(){a("ul.tabs").tabs()})}(jQuery),function(a){a.fn.tooltip=function(c){var d=5,e={delay:350,tooltip:"",position:"bottom",html:!1};return"remove"===c?(this.each(function(){a("#"+a(this).attr("data-tooltip-id")).remove(),a(this).off("mouseenter.tooltip mouseleave.tooltip")}),!1):(c=a.extend(e,c),this.each(function(){var e=Materialize.guid(),f=a(this);f.attr("data-tooltip-id")&&a("#"+f.attr("data-tooltip-id")).remove(),f.attr("data-tooltip-id",e);var g,h,i,j,k,l,m=function(){g=f.attr("data-html")?"true"===f.attr("data-html"):c.html,h=f.attr("data-delay"),h=void 0===h||""===h?c.delay:h,i=f.attr("data-position"),i=void 0===i||""===i?c.position:i,j=f.attr("data-tooltip"),j=void 0===j||""===j?c.tooltip:j};m();var n=function(){var b=a('<div class="material-tooltip"></div>');return j=g?a("<span></span>").html(j):a("<span></span>").text(j),b.append(j).appendTo(a("body")).attr("id",e),l=a('<div class="backdrop"></div>'),l.appendTo(b),b};k=n(),f.off("mouseenter.tooltip mouseleave.tooltip");var o,p=!1;f.on({"mouseenter.tooltip":function(a){var c=function(){m(),p=!0,k.velocity("stop"),l.velocity("stop"),k.css({display:"block",left:"0px",top:"0px"});var a,c,e,g=f.outerWidth(),h=f.outerHeight(),j=k.outerHeight(),n=k.outerWidth(),o="0px",q="0px",r=8,s=8;"top"===i?(a=f.offset().top-j-d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="-10px",l.css({bottom:0,left:0,borderRadius:"14px 14px 0 0",transformOrigin:"50% 100%",marginTop:j,marginLeft:n/2-l.width()/2})):"left"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left-n-d,e=b(c,a,n,j),q="-10px",l.css({top:"-7px",right:0,width:"14px",height:"14px",borderRadius:"14px 0 0 14px",transformOrigin:"95% 50%",marginTop:j/2,marginLeft:n})):"right"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left+g+d,e=b(c,a,n,j),q="+10px",l.css({top:"-7px",left:0,width:"14px",height:"14px",borderRadius:"0 14px 14px 0",transformOrigin:"5% 50%",marginTop:j/2,marginLeft:"0px"})):(a=f.offset().top+f.outerHeight()+d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="+10px",l.css({top:0,left:0,marginLeft:n/2-l.width()/2})),k.css({top:e.y,left:e.x}),r=Math.SQRT2*n/parseInt(l.css("width")),s=Math.SQRT2*j/parseInt(l.css("height")),k.velocity({marginTop:o,marginLeft:q},{duration:350,queue:!1}).velocity({opacity:1},{duration:300,delay:50,queue:!1}),l.css({display:"block"}).velocity({opacity:1},{duration:55,delay:0,queue:!1}).velocity({scaleX:r,scaleY:s},{duration:300,delay:0,queue:!1,easing:"easeInOutQuad"})};o=setTimeout(c,h)},"mouseleave.tooltip":function(){p=!1,clearTimeout(o),setTimeout(function(){p!==!0&&(k.velocity({opacity:0,marginTop:0,marginLeft:0},{duration:225,queue:!1}),l.velocity({opacity:0,scaleX:1,scaleY:1},{duration:225,queue:!1,complete:function(){l.css("display","none"),k.css("display","none"),p=!1}}))},225)}})}))};var b=function(b,c,d,e){var f=b,g=c;return 0>f?f=4:f+d>window.innerWidth&&(f-=f+d-window.innerWidth),0>g?g=4:g+e>window.innerHeight+a(window).scrollTop&&(g-=g+e-window.innerHeight),{x:f,y:g}};a(document).ready(function(){a(".tooltipped").tooltip()})}(jQuery),function(a){"use strict";function b(a){return null!==a&&a===a.window}function c(a){return b(a)?a:9===a.nodeType&&a.defaultView}function d(a){var b,d,e={top:0,left:0},f=a&&a.ownerDocument;return b=f.documentElement,"undefined"!=typeof a.getBoundingClientRect&&(e=a.getBoundingClientRect()),d=c(f),{top:e.top+d.pageYOffset-b.clientTop,left:e.left+d.pageXOffset-b.clientLeft}}function e(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b+=c+":"+a[c]+";");return b}function f(a){if(k.allowEvent(a)===!1)return null;for(var b=null,c=a.target||a.srcElement;null!==c.parentElement;){if(!(c instanceof SVGElement||-1===c.className.indexOf("waves-effect"))){b=c;break}if(c.classList.contains("waves-effect")){b=c;break}c=c.parentElement}return b}function g(b){var c=f(b);null!==c&&(j.show(b,c),"ontouchstart"in a&&(c.addEventListener("touchend",j.hide,!1),c.addEventListener("touchcancel",j.hide,!1)),c.addEventListener("mouseup",j.hide,!1),c.addEventListener("mouseleave",j.hide,!1))}var h=h||{},i=document.querySelectorAll.bind(document),j={duration:750,show:function(a,b){if(2===a.button)return!1;var c=b||this,f=document.createElement("div");f.className="waves-ripple",c.appendChild(f);var g=d(c),h=a.pageY-g.top,i=a.pageX-g.left,k="scale("+c.clientWidth/100*10+")";"touches"in a&&(h=a.touches[0].pageY-g.top,i=a.touches[0].pageX-g.left),f.setAttribute("data-hold",Date.now()),f.setAttribute("data-scale",k),f.setAttribute("data-x",i),f.setAttribute("data-y",h);var l={top:h+"px",left:i+"px"};f.className=f.className+" waves-notransition",f.setAttribute("style",e(l)),f.className=f.className.replace("waves-notransition",""),l["-webkit-transform"]=k,l["-moz-transform"]=k,l["-ms-transform"]=k,l["-o-transform"]=k,l.transform=k,l.opacity="1",l["-webkit-transition-duration"]=j.duration+"ms",l["-moz-transition-duration"]=j.duration+"ms",l["-o-transition-duration"]=j.duration+"ms",l["transition-duration"]=j.duration+"ms",l["-webkit-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-moz-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-o-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f.setAttribute("style",e(l))},hide:function(a){k.touchup(a);var b=this,c=(1.4*b.clientWidth,null),d=b.getElementsByClassName("waves-ripple");if(!(d.length>0))return!1;c=d[d.length-1];var f=c.getAttribute("data-x"),g=c.getAttribute("data-y"),h=c.getAttribute("data-scale"),i=Date.now()-Number(c.getAttribute("data-hold")),l=350-i;0>l&&(l=0),setTimeout(function(){var a={top:g+"px",left:f+"px",opacity:"0","-webkit-transition-duration":j.duration+"ms","-moz-transition-duration":j.duration+"ms","-o-transition-duration":j.duration+"ms","transition-duration":j.duration+"ms","-webkit-transform":h,"-moz-transform":h,"-ms-transform":h,"-o-transform":h,transform:h};c.setAttribute("style",e(a)),setTimeout(function(){try{b.removeChild(c)}catch(a){return!1}},j.duration)},l)},wrapInput:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("input"===c.tagName.toLowerCase()){var d=c.parentNode;if("i"===d.tagName.toLowerCase()&&-1!==d.className.indexOf("waves-effect"))continue;var e=document.createElement("i");e.className=c.className+" waves-input-wrapper";var f=c.getAttribute("style");f||(f=""),e.setAttribute("style",f),c.className="waves-button-input",c.removeAttribute("style"),d.replaceChild(e,c),e.appendChild(c)}}}},k={touches:0,allowEvent:function(a){var b=!0;return"touchstart"===a.type?k.touches+=1:"touchend"===a.type||"touchcancel"===a.type?setTimeout(function(){k.touches>0&&(k.touches-=1)},500):"mousedown"===a.type&&k.touches>0&&(b=!1),b},touchup:function(a){k.allowEvent(a)}};h.displayEffect=function(b){b=b||{},"duration"in b&&(j.duration=b.duration),j.wrapInput(i(".waves-effect")),"ontouchstart"in a&&document.body.addEventListener("touchstart",g,!1),document.body.addEventListener("mousedown",g,!1)},h.attach=function(b){"input"===b.tagName.toLowerCase()&&(j.wrapInput([b]),b=b.parentElement),"ontouchstart"in a&&b.addEventListener("touchstart",g,!1),b.addEventListener("mousedown",g,!1)},a.Waves=h,document.addEventListener("DOMContentLoaded",function(){h.displayEffect()},!1)}(window),Materialize.toast=function(a,b,c,d){function e(a){var b=document.createElement("div");if(b.classList.add("toast"),c)for(var e=c.split(" "),f=0,g=e.length;g>f;f++)b.classList.add(e[f]);("object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName)?b.appendChild(a):a instanceof jQuery?b.appendChild(a[0]):b.innerHTML=a;var h=new Hammer(b,{prevent_default:!1});return h.on("pan",function(a){var c=a.deltaX,d=80;b.classList.contains("panning")||b.classList.add("panning");var e=1-Math.abs(c/d);0>e&&(e=0),Vel(b,{left:c,opacity:e},{duration:50,queue:!1,easing:"easeOutQuad"})}),h.on("panend",function(a){var c=a.deltaX,e=80;Math.abs(c)>e?Vel(b,{marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),b.parentNode.removeChild(b)}}):(b.classList.remove("panning"),Vel(b,{left:0,opacity:1},{duration:300,easing:"easeOutExpo",queue:!1}))}),b}c=c||"";var f=document.getElementById("toast-container");null===f&&(f=document.createElement("div"),f.id="toast-container",document.body.appendChild(f));var g=e(a);a&&f.appendChild(g),g.style.top="35px",g.style.opacity=0,Vel(g,{top:"0px",opacity:1},{duration:300,easing:"easeOutCubic",queue:!1});var h,i=b;null!=i&&(h=setInterval(function(){null===g.parentNode&&window.clearInterval(h),g.classList.contains("panning")||(i-=20),0>=i&&(Vel(g,{opacity:0,marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),this[0].parentNode.removeChild(this[0])}}),window.clearInterval(h))},20))},function(a){var b={init:function(b){var c={menuWidth:300,edge:"left",closeOnClick:!1,draggable:!0};b=a.extend(c,b),a(this).each(function(){var c=a(this),d=a("#"+c.attr("data-activates"));300!=b.menuWidth&&d.css("width",b.menuWidth);var e;b.draggable?(e=a('<div class="drag-target"></div>').attr("data-sidenav",c.attr("data-activates")),a("body").append(e)):e=a(),"left"==b.edge?(d.css("transform","translateX(-100%)"),e.css({left:0})):(d.addClass("right-aligned").css("transform","translateX(100%)"),e.css({right:0})),d.hasClass("fixed")&&window.innerWidth>992&&d.css("transform","translateX(0)"),d.hasClass("fixed")&&a(window).resize(function(){window.innerWidth>992?0!==a("#sidenav-overlay").length&&h?f(!0):d.css("transform","translateX(0%)"):h===!1&&("left"===b.edge?d.css("transform","translateX(-100%)"):d.css("transform","translateX(100%)"))}),b.closeOnClick===!0&&d.on("click.itemclick","a:not(.collapsible-header)",function(){f()});var f=function(c){g=!1,h=!1,a("body").css({overflow:"",width:""}),a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),"left"===b.edge?(e.css({width:"",right:"",left:"0"}),d.velocity({translateX:"-100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(d.removeAttr("style"),d.css("width",b.menuWidth))}})):(e.css({width:"",right:"0",left:""}),d.velocity({translateX:"100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(d.removeAttr("style"),d.css("width",b.menuWidth))}}))},g=!1,h=!1;b.draggable&&(e.on("click",function(){h&&f()}),e.hammer({prevent_default:!1}).bind("pan",function(c){if("touch"==c.gesture.pointerType){var e=(c.gesture.direction,c.gesture.center.x),g=(c.gesture.center.y,c.gesture.velocityX,a("body")),i=a("#sidenav-overlay"),j=g.innerWidth();if(g.css("overflow","hidden"),g.width(j),0===i.length&&(i=a('<div id="sidenav-overlay"></div>'),i.css("opacity",0).click(function(){f()}),a("body").append(i)),"left"===b.edge&&(e>b.menuWidth?e=b.menuWidth:0>e&&(e=0)),"left"===b.edge)e<b.menuWidth/2?h=!1:e>=b.menuWidth/2&&(h=!0),d.css("transform","translateX("+(e-b.menuWidth)+"px)");else{e<window.innerWidth-b.menuWidth/2?h=!0:e>=window.innerWidth-b.menuWidth/2&&(h=!1);var k=e-b.menuWidth/2;0>k&&(k=0),d.css("transform","translateX("+k+"px)")}var l;"left"===b.edge?(l=e/b.menuWidth,i.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"})):(l=Math.abs((e-window.innerWidth)/b.menuWidth),i.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(c){if("touch"==c.gesture.pointerType){var f=a('<div id="sidenav-overlay"></div>'),i=c.gesture.velocityX,j=c.gesture.center.x,k=j-b.menuWidth,l=j-b.menuWidth/2;k>0&&(k=0),0>l&&(l=0),g=!1,"left"===b.edge?h&&.3>=i||-.5>i?(0!==k&&d.velocity({translateX:[0,k]},{duration:300,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),e.css({width:"50%",right:0,left:""}),h=!0):(!h||i>.3)&&(a("body").css({overflow:"",width:""}),d.velocity({translateX:[-1*b.menuWidth-10,k]},{duration:200,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),e.css({width:"10px",right:"",left:0})):h&&i>=-.3||i>.5?(0!==l&&d.velocity({translateX:[0,l]},{duration:300,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),e.css({width:"50%",right:"",left:0}),h=!0):(!h||-.3>i)&&(a("body").css({overflow:"",width:""}),d.velocity({translateX:[b.menuWidth+10,l]},{duration:200,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),e.css({width:"10px",right:0,left:""}))}})),c.click(function(){if(h===!0)h=!1,g=!1,f();else{var c=a("body"),i=a('<div id="sidenav-overlay"></div>'),j=c.innerWidth();c.css("overflow","hidden"),c.width(j),a("body").append(e),"left"===b.edge?(e.css({width:"50%",right:0,left:""}),d.velocity({translateX:[0,-1*b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})):(e.css({width:"50%",right:"",left:0}),d.velocity({translateX:[0,b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})),i.css("opacity",0).click(function(){h=!1,g=!1,f(),i.velocity({opacity:0},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}})}),a("body").append(i),i.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){h=!0,g=!1}})}return!1})})},destroy:function(){var b=a("#sidenav-overlay"),c=a('.drag-target[data-sidenav="'+a(this).attr("data-activates")+'"]');b.trigger("click"),c.remove(),a(this).off("click"),b.remove()},show:function(){this.trigger("click")},hide:function(){a("#sidenav-overlay").trigger("click")}};a.fn.sideNav=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.sideNav"):b.init.apply(this,arguments)}}(jQuery),function(a){function b(b,c,d,e){var f=a();return a.each(g,function(a,g){if(g.height()>0){var h=g.offset().top,i=g.offset().left,j=i+g.width(),k=h+g.height(),l=!(i>c||e>j||h>d||b>k);l&&f.push(g)}}),f}function c(c){++j;var d=f.scrollTop(),e=f.scrollLeft(),g=e+f.width(),i=d+f.height(),l=b(d+k.top+c||200,g+k.right,i+k.bottom,e+k.left);a.each(l,function(a,b){var c=b.data("scrollSpy:ticks");"number"!=typeof c&&b.triggerHandler("scrollSpy:enter"),b.data("scrollSpy:ticks",j)}),a.each(h,function(a,b){var c=b.data("scrollSpy:ticks");"number"==typeof c&&c!==j&&(b.triggerHandler("scrollSpy:exit"),b.data("scrollSpy:ticks",null))}),h=l}function d(){f.trigger("scrollSpy:winSize")}function e(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:l(),g=null,f=a.apply(d,e),d=e=null};return function(){var j=l();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),d=e=null):g||c.trailing===!1||(g=setTimeout(i,k)),f}}var f=a(window),g=[],h=[],i=!1,j=0,k={top:0,right:0,bottom:0,left:0},l=Date.now||function(){return(new Date).getTime()};a.scrollSpy=function(b,d){var h={throttle:100,scrollOffset:200};d=a.extend(h,d);var j=[];b=a(b),b.each(function(b,c){g.push(a(c)),a(c).data("scrollSpy:id",b),a('a[href="#'+a(c).attr("id")+'"]').click(function(b){b.preventDefault();var c=a(Materialize.escapeHash(this.hash)).offset().top+1;a("html, body").animate({scrollTop:c-d.scrollOffset},{duration:400,queue:!1,easing:"easeOutCubic"})})}),k.top=d.offsetTop||0,k.right=d.offsetRight||0,k.bottom=d.offsetBottom||0,k.left=d.offsetLeft||0;var l=e(function(){c(d.scrollOffset)},d.throttle||100),m=function(){a(document).ready(l)};return i||(f.on("scroll",m),f.on("resize",m),i=!0),setTimeout(m,0),b.on("scrollSpy:enter",function(){j=a.grep(j,function(a){return 0!=a.height()});var b=a(this);j[0]?(a('a[href="#'+j[0].attr("id")+'"]').removeClass("active"),b.data("scrollSpy:id")<j[0].data("scrollSpy:id")?j.unshift(a(this)):j.push(a(this))):j.push(a(this)),a('a[href="#'+j[0].attr("id")+'"]').addClass("active")}),b.on("scrollSpy:exit",function(){if(j=a.grep(j,function(a){return 0!=a.height()}),j[0]){a('a[href="#'+j[0].attr("id")+'"]').removeClass("active");var b=a(this);j=a.grep(j,function(a){return a.attr("id")!=b.attr("id")}),j[0]&&a('a[href="#'+j[0].attr("id")+'"]').addClass("active")}}),b},a.winSizeSpy=function(b){return a.winSizeSpy=function(){return f},b=b||{throttle:100},f.on("resize",e(d,b.throttle||100))},a.fn.scrollSpy=function(b){return a.scrollSpy(a(this),b)}}(jQuery),function(a){a(document).ready(function(){function b(b){var c=b.css("font-family"),d=b.css("font-size"),f=b.css("line-height");d&&e.css("font-size",d),c&&e.css("font-family",c),f&&e.css("line-height",f),"off"===b.attr("wrap")&&e.css("overflow-wrap","normal").css("white-space","pre"),e.text(b.val()+"\n");var g=e.html().replace(/\n/g,"<br>");e.html(g),b.is(":visible")?e.css("width",b.width()):e.css("width",a(window).width()/2),b.css("height",e.height())}Materialize.updateTextFields=function(){var b="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(b).each(function(b,c){a(c).val().length>0||c.autofocus||void 0!==a(this).attr("placeholder")||a(c)[0].validity.badInput===!0?a(this).siblings("label").addClass("active"):a(this).siblings("label").removeClass("active")})};var c="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(document).on("change",c,function(){(0!==a(this).val().length||void 0!==a(this).attr("placeholder"))&&a(this).siblings("label").addClass("active"),validate_field(a(this))}),a(document).ready(function(){Materialize.updateTextFields()}),a(document).on("reset",function(b){var d=a(b.target);d.is("form")&&(d.find(c).removeClass("valid").removeClass("invalid"),d.find(c).each(function(){""===a(this).attr("value")&&a(this).siblings("label").removeClass("active")}),d.find("select.initialized").each(function(){var a=d.find("option[selected]").text();d.siblings("input.select-dropdown").val(a)}))}),a(document).on("focus",c,function(){a(this).siblings("label, .prefix").addClass("active")}),a(document).on("blur",c,function(){var b=a(this),c=".prefix";0===b.val().length&&b[0].validity.badInput!==!0&&void 0===b.attr("placeholder")&&(c+=", label"),b.siblings(c).removeClass("active"),validate_field(b)}),window.validate_field=function(a){var b=void 0!==a.attr("length"),c=parseInt(a.attr("length")),d=a.val().length;0===a.val().length&&a[0].validity.badInput===!1?a.hasClass("validate")&&(a.removeClass("valid"),a.removeClass("invalid")):a.hasClass("validate")&&(a.is(":valid")&&b&&c>=d||a.is(":valid")&&!b?(a.removeClass("invalid"),a.addClass("valid")):(a.removeClass("valid"),a.addClass("invalid")))};var d="input[type=radio], input[type=checkbox]";a(document).on("keyup.radio",d,function(b){if(9===b.which){a(this).addClass("tabbed");var c=a(this);return void c.one("blur",function(b){a(this).removeClass("tabbed")})}});var e=a(".hiddendiv").first();e.length||(e=a('<div class="hiddendiv common"></div>'),a("body").append(e));var f=".materialize-textarea";a(f).each(function(){var c=a(this);c.val().length&&b(c)}),a("body").on("keyup keydown autoresize",f,function(){b(a(this))}),a(document).on("change",'.file-field input[type="file"]',function(){for(var b=a(this).closest(".file-field"),c=b.find("input.file-path"),d=a(this)[0].files,e=[],f=0;f<d.length;f++)e.push(d[f].name);c.val(e.join(", ")),c.trigger("change")});var g,h="input[type=range]",i=!1;a(h).each(function(){var b=a('<span class="thumb"><span class="value"></span></span>');a(this).after(b)});var j=".range-field";a(document).on("change",h,function(b){var c=a(this).siblings(".thumb");c.find(".value").html(a(this).val())}),a(document).on("input mousedown touchstart",h,function(b){var c=a(this).siblings(".thumb"),d=a(this).outerWidth();c.length<=0&&(c=a('<span class="thumb"><span class="value"></span></span>'),a(this).after(c)),c.find(".value").html(a(this).val()),i=!0,a(this).addClass("active"),c.hasClass("active")||c.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"}),"input"!==b.type&&(g=void 0===b.pageX||null===b.pageX?b.originalEvent.touches[0].pageX-a(this).offset().left:b.pageX-a(this).offset().left,0>g?g=0:g>d&&(g=d),c.addClass("active").css("left",g)),c.find(".value").html(a(this).val())}),a(document).on("mouseup touchend",j,function(){i=!1,a(this).removeClass("active")}),a(document).on("mousemove touchmove",j,function(b){var c,d=a(this).children(".thumb");if(i){d.hasClass("active")||d.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"}),c=void 0===b.pageX||null===b.pageX?b.originalEvent.touches[0].pageX-a(this).offset().left:b.pageX-a(this).offset().left;var e=a(this).outerWidth();0>c?c=0:c>e&&(c=e),d.addClass("active").css("left",c),d.find(".value").html(d.siblings(h).val())}}),a(document).on("mouseout touchleave",j,function(){if(!i){var b=a(this).children(".thumb");b.hasClass("active")&&b.velocity({height:"0",width:"0",top:"10px",marginLeft:"-6px"},{duration:100}),b.removeClass("active")}}),a.fn.autocomplete=function(b){var c={data:{}};return b=a.extend(c,b),this.each(function(){var c=a(this),d=b.data,e=c.closest(".input-field");if(!a.isEmptyObject(d)){var f=a('<ul class="autocomplete-content dropdown-content"></ul>');e.length?e.append(f):c.after(f);var g=function(a,b){var c=b.find("img"),d=b.text().toLowerCase().indexOf(""+a.toLowerCase()),e=d+a.length-1,f=b.text().slice(0,d),g=b.text().slice(d,e+1),h=b.text().slice(e+1);b.html("<span>"+f+"<span class='highlight'>"+g+"</span>"+h+"</span>"),c.length&&b.prepend(c)};c.on("keyup",function(b){if(13===b.which)return void f.find("li").first().click();var e=c.val().toLowerCase();if(f.empty(),""!==e)for(var h in d)if(d.hasOwnProperty(h)&&-1!==h.toLowerCase().indexOf(e)&&h.toLowerCase()!==e){var i=a("<li></li>");d[h]?i.append('<img src="'+d[h]+'" class="right circle"><span>'+h+"</span>"):i.append("<span>"+h+"</span>"),f.append(i),g(e,i)}}),f.on("click","li",function(){c.val(a(this).text().trim()),c.trigger("change"),f.empty()})}})}}),a.fn.material_select=function(b){function c(a,b,c){var e=a.indexOf(b),f=-1===e;return f?a.push(b):a.splice(e,1),c.siblings("ul.dropdown-content").find("li").eq(b).toggleClass("active"),c.find("option").eq(b).prop("selected",f),d(a,c),f}function d(a,b){for(var c="",d=0,e=a.length;e>d;d++){var f=b.find("option").eq(a[d]).text();c+=0===d?f:", "+f}""===c&&(c=b.find("option:disabled").eq(0).text()),b.siblings("input.select-dropdown").val(c)}a(this).each(function(){var d=a(this);if(!d.hasClass("browser-default")){var e=d.attr("multiple")?!0:!1,f=d.data("select-id");if(f&&(d.parent().find("span.caret").remove(),d.parent().find("input").remove(),d.unwrap(),a("ul#select-options-"+f).remove()),"destroy"===b)return void d.data("select-id",null).removeClass("initialized");var g=Materialize.guid();d.data("select-id",g);var h=a('<div class="select-wrapper"></div>');h.addClass(d.attr("class"));var i=a('<ul id="select-options-'+g+'" class="dropdown-content select-dropdown '+(e?"multiple-select-dropdown":"")+'"></ul>'),j=d.children("option, optgroup"),k=[],l=!1,m=d.find("option:selected").html()||d.find("option:first").html()||"",n=function(b,c,d){var e=c.is(":disabled")?"disabled ":"",f="optgroup-option"===d?"optgroup-option ":"",g=c.data("icon"),h=c.attr("class");if(g){var j="";return h&&(j=' class="'+h+'"'),"multiple"===d?i.append(a('<li class="'+e+'"><img alt="" src="'+g+'"'+j+'><span><input type="checkbox"'+e+"/><label></label>"+c.html()+"</span></li>")):i.append(a('<li class="'+e+f+'"><img alt="" src="'+g+'"'+j+"><span>"+c.html()+"</span></li>")),!0}"multiple"===d?i.append(a('<li class="'+e+'"><span><input type="checkbox"'+e+"/><label></label>"+c.html()+"</span></li>")):i.append(a('<li class="'+e+f+'"><span>'+c.html()+"</span></li>"))};j.length&&j.each(function(){if(a(this).is("option"))e?n(d,a(this),"multiple"):n(d,a(this));else if(a(this).is("optgroup")){var b=a(this).children("option");i.append(a('<li class="optgroup"><span>'+a(this).attr("label")+"</span></li>")),b.each(function(){n(d,a(this),"optgroup-option")})}}),i.find("li:not(.optgroup)").each(function(f){a(this).click(function(g){if(!a(this).hasClass("disabled")&&!a(this).hasClass("optgroup")){
|
9 |
+
var h=!0;e?(a('input[type="checkbox"]',this).prop("checked",function(a,b){return!b}),h=c(k,a(this).index(),d),q.trigger("focus")):(i.find("li").removeClass("active"),a(this).toggleClass("active"),q.val(a(this).text())),r(i,a(this)),d.find("option").eq(f).prop("selected",h),d.trigger("change"),"undefined"!=typeof b&&b()}g.stopPropagation()})}),d.wrap(h);var o=a('<span class="caret">▼</span>');d.is(":disabled")&&o.addClass("disabled");var p=m.replace(/"/g,"""),q=a('<input type="text" class="select-dropdown" readonly="true" '+(d.is(":disabled")?"disabled":"")+' data-activates="select-options-'+g+'" value="'+p+'"/>');d.before(q),q.before(o),q.after(i),d.is(":disabled")||q.dropdown({hover:!1,closeOnClick:!1}),d.attr("tabindex")&&a(q[0]).attr("tabindex",d.attr("tabindex")),d.addClass("initialized"),q.on({focus:function(){if(a("ul.select-dropdown").not(i[0]).is(":visible")&&a("input.select-dropdown").trigger("close"),!i.is(":visible")){a(this).trigger("open",["focus"]);var b=a(this).val(),c=i.find("li").filter(function(){return a(this).text().toLowerCase()===b.toLowerCase()})[0];r(i,c)}},click:function(a){a.stopPropagation()}}),q.on("blur",function(){e||a(this).trigger("close"),i.find("li.selected").removeClass("selected")}),i.hover(function(){l=!0},function(){l=!1}),a(window).on({click:function(){e&&(l||q.trigger("close"))}}),e&&d.find("option:selected:not(:disabled)").each(function(){var b=a(this).index();c(k,b,d),i.find("li").eq(b).find(":checkbox").prop("checked",!0)});var r=function(b,c){if(c){b.find("li.selected").removeClass("selected");var d=a(c);d.addClass("selected"),i.scrollTo(d)}},s=[],t=function(b){if(9==b.which)return void q.trigger("close");if(40==b.which&&!i.is(":visible"))return void q.trigger("open");if(13!=b.which||i.is(":visible")){b.preventDefault();var c=String.fromCharCode(b.which).toLowerCase(),d=[9,13,27,38,40];if(c&&-1===d.indexOf(b.which)){s.push(c);var f=s.join(""),g=i.find("li").filter(function(){return 0===a(this).text().toLowerCase().indexOf(f)})[0];g&&r(i,g)}if(13==b.which){var h=i.find("li.selected:not(.disabled)")[0];h&&(a(h).trigger("click"),e||q.trigger("close"))}40==b.which&&(g=i.find("li.selected").length?i.find("li.selected").next("li:not(.disabled)")[0]:i.find("li:not(.disabled)")[0],r(i,g)),27==b.which&&q.trigger("close"),38==b.which&&(g=i.find("li.selected").prev("li:not(.disabled)")[0],g&&r(i,g)),setTimeout(function(){s=[]},1e3)}};q.on("keydown",t)}})}}(jQuery),function(a){var b={init:function(b){var c={indicators:!0,height:400,transition:500,interval:6e3};return b=a.extend(c,b),this.each(function(){function c(a,b){a.hasClass("center-align")?a.velocity({opacity:0,translateY:-100},{duration:b,queue:!1}):a.hasClass("right-align")?a.velocity({opacity:0,translateX:100},{duration:b,queue:!1}):a.hasClass("left-align")&&a.velocity({opacity:0,translateX:-100},{duration:b,queue:!1})}function d(a){a>=j.length?a=0:0>a&&(a=j.length-1),k=i.find(".active").index(),k!=a&&(e=j.eq(k),$caption=e.find(".caption"),e.removeClass("active"),e.velocity({opacity:0},{duration:b.transition,queue:!1,easing:"easeOutQuad",complete:function(){j.not(".active").velocity({opacity:0,translateX:0,translateY:0},{duration:0,queue:!1})}}),c($caption,b.transition),b.indicators&&f.eq(k).removeClass("active"),j.eq(a).velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,delay:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).addClass("active"),b.indicators&&f.eq(a).addClass("active"))}var e,f,g,h=a(this),i=h.find("ul.slides").first(),j=i.find("> li"),k=i.find(".active").index();-1!=k&&(e=j.eq(k)),h.hasClass("fullscreen")||(b.indicators?h.height(b.height+40):h.height(b.height),i.height(b.height)),j.find(".caption").each(function(){c(a(this),0)}),j.find("img").each(function(){var b="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";a(this).attr("src")!==b&&(a(this).css("background-image","url("+a(this).attr("src")+")"),a(this).attr("src",b))}),b.indicators&&(f=a('<ul class="indicators"></ul>'),j.each(function(c){var e=a('<li class="indicator-item"></li>');e.click(function(){var c=i.parent(),e=c.find(a(this)).index();d(e),clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),f.append(e)}),h.append(f),f=h.find("ul.indicators").find("li.indicator-item")),e?e.show():(j.first().addClass("active").velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),k=0,e=j.eq(k),b.indicators&&f.eq(k).addClass("active")),e.find("img").each(function(){e.find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,queue:!1,easing:"easeOutQuad"})}),g=setInterval(function(){k=i.find(".active").index(),d(k+1)},b.transition+b.interval);var l=!1,m=!1,n=!1;h.hammer({prevent_default:!1}).bind("pan",function(a){if("touch"===a.gesture.pointerType){clearInterval(g);var b=a.gesture.direction,c=a.gesture.deltaX,d=a.gesture.velocityX;$curr_slide=i.find(".active"),$curr_slide.velocity({translateX:c},{duration:50,queue:!1,easing:"easeOutQuad"}),4===b&&(c>h.innerWidth()/2||-.65>d)?n=!0:2===b&&(c<-1*h.innerWidth()/2||d>.65)&&(m=!0);var e;m&&(e=$curr_slide.next(),0===e.length&&(e=j.first()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"})),n&&(e=$curr_slide.prev(),0===e.length&&(e=j.last()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(a){"touch"===a.gesture.pointerType&&($curr_slide=i.find(".active"),l=!1,curr_index=i.find(".active").index(),!n&&!m||j.length<=1?$curr_slide.velocity({translateX:0},{duration:300,queue:!1,easing:"easeOutQuad"}):m?(d(curr_index+1),$curr_slide.velocity({translateX:-1*h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})):n&&(d(curr_index-1),$curr_slide.velocity({translateX:h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})),m=!1,n=!1,clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval))}),h.on("sliderPause",function(){clearInterval(g)}),h.on("sliderStart",function(){clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),h.on("sliderNext",function(){k=i.find(".active").index(),d(k+1)}),h.on("sliderPrev",function(){k=i.find(".active").index(),d(k-1)})})},pause:function(){a(this).trigger("sliderPause")},start:function(){a(this).trigger("sliderStart")},next:function(){a(this).trigger("sliderNext")},prev:function(){a(this).trigger("sliderPrev")}};a.fn.slider=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tooltip"):b.init.apply(this,arguments)}}(jQuery),function(a){a(document).ready(function(){a(document).on("click.card",".card",function(b){a(this).find("> .card-reveal").length&&(a(b.target).is(a(".card-reveal .card-title"))||a(b.target).is(a(".card-reveal .card-title i"))?a(this).find(".card-reveal").velocity({translateY:0},{duration:225,queue:!1,easing:"easeInOutQuad",complete:function(){a(this).css({display:"none"})}}):(a(b.target).is(a(".card .activator"))||a(b.target).is(a(".card .activator i")))&&(a(b.target).closest(".card").css("overflow","hidden"),a(this).find(".card-reveal").css({display:"block"}).velocity("stop",!1).velocity({translateY:"-100%"},{duration:300,queue:!1,easing:"easeInOutQuad"})))})})}(jQuery),function(a){var b=!1,c={data:[],placeholder:"",secondaryPlaceholder:""};a(document).ready(function(){a(document).on("click",".chip .close",function(b){var c=a(this).closest(".chips");c.attr("data-initialized")||a(this).closest(".chip").remove()})}),a.fn.material_chip=function(d){var e=this;if(this.$el=a(this),this.$document=a(document),this.SELS={CHIPS:".chips",CHIP:".chip",INPUT:"input",DELETE:".material-icons",SELECTED_CHIP:".selected"},"data"===d)return this.$el.data("chips");var f=a.extend({},c,d);this.init=function(){var b=0;e.$el.each(function(){var c=a(this),d=Materialize.guid();f.data&&f.data instanceof Array||(f.data=[]),c.data("chips",f.data),c.attr("data-index",b),c.attr("data-initialized",!0),c.hasClass(e.SELS.CHIPS)||c.addClass("chips"),e.chips(c,d),b++})},this.handleEvents=function(){var b=e.SELS;e.$document.off("click.chips-focus",b.CHIPS).on("click.chips-focus",b.CHIPS,function(c){a(c.target).find(b.INPUT).focus()}),e.$document.off("click.chips-select",b.CHIP).on("click.chips-select",b.CHIP,function(c){a(b.CHIP).removeClass("selected"),a(this).toggleClass("selected")}),e.$document.off("keydown.chips").on("keydown.chips",function(c){if(!a(c.target).is("input, textarea")){var d,f=e.$document.find(b.CHIP+b.SELECTED_CHIP),g=f.closest(b.CHIPS),h=f.siblings(b.CHIP).length;if(f.length)if(8===c.which||46===c.which){c.preventDefault(),d=f.index(),e.deleteChip(d,g);var i=null;h>d+1?i=d:(d===h||d+1===h)&&(i=h-1),0>i&&(i=null),null!==i&&e.selectChip(i,g),h||g.find("input").focus()}else if(37===c.which){if(d=f.index()-1,0>d)return;a(b.CHIP).removeClass("selected"),e.selectChip(d,g)}else if(39===c.which){if(d=f.index()+1,a(b.CHIP).removeClass("selected"),d>h)return void g.find("input").focus();e.selectChip(d,g)}}}),e.$document.off("focusin.chips",b.CHIPS+" "+b.INPUT).on("focusin.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.addClass("focus"),d.siblings("label, .prefix").addClass("active"),a(b.CHIP).removeClass("selected")}),e.$document.off("focusout.chips",b.CHIPS+" "+b.INPUT).on("focusout.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.removeClass("focus"),d.data("chips").length||d.siblings("label").removeClass("active"),d.siblings(".prefix").removeClass("active")}),e.$document.off("keydown.chips-add",b.CHIPS+" "+b.INPUT).on("keydown.chips-add",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target),f=d.closest(b.CHIPS),g=f.children(b.CHIP).length;return 13===c.which?(c.preventDefault(),e.addChip({tag:d.val()},f),void d.val("")):8!==c.keyCode&&37!==c.keyCode||""!==d.val()||!g?void 0:(e.selectChip(g-1,f),void d.blur())}),e.$document.off("click.chips-delete",b.CHIPS+" "+b.DELETE).on("click.chips-delete",b.CHIPS+" "+b.DELETE,function(c){var d=a(c.target),f=d.closest(b.CHIPS),g=d.closest(b.CHIP);c.stopPropagation(),e.deleteChip(g.index(),f),f.find("input").focus()})},this.chips=function(a,b){var c="";a.data("chips").forEach(function(a){c+=e.renderChip(a)}),c+='<input id="'+b+'" class="input" placeholder="">',a.html(c),e.setPlaceholder(a);var d=a.next("label");d.length&&(d.attr("for",b),a.data("chips").length&&d.addClass("active"))},this.renderChip=function(a){if(a.tag){var b='<div class="chip">'+a.tag;return a.image&&(b+=' <img src="'+a.image+'"> '),b+='<i class="material-icons close">close</i>',b+="</div>"}},this.setPlaceholder=function(a){a.data("chips").length&&f.placeholder?a.find("input").prop("placeholder",f.placeholder):!a.data("chips").length&&f.secondaryPlaceholder&&a.find("input").prop("placeholder",f.secondaryPlaceholder)},this.isValid=function(a,b){for(var c=a.data("chips"),d=!1,e=0;e<c.length;e++)if(c[e].tag===b.tag)return void(d=!0);return""!==b.tag&&!d},this.addChip=function(b,c){if(e.isValid(c,b)){for(var d=e.renderChip(b),f=[],g=c.data("chips"),h=0;h<g.length;h++)f.push(g[h]);f.push(b),c.data("chips",f),a(d).insertBefore(c.find("input")),c.trigger("chip.add",b),e.setPlaceholder(c)}},this.deleteChip=function(a,b){var c=b.data("chips")[a];b.find(".chip").eq(a).remove();for(var d=[],f=b.data("chips"),g=0;g<f.length;g++)g!==a&&d.push(f[g]);b.data("chips",d),b.trigger("chip.delete",c),e.setPlaceholder(b)},this.selectChip=function(a,b){var c=b.find(".chip").eq(a);c&&!1===c.hasClass("selected")&&(c.addClass("selected"),b.trigger("chip.select",b.data("chips")[a]))},this.getChipsElement=function(a,b){return b.eq(a)},this.init(),b||(this.handleEvents(),b=!0)}}(jQuery),function(a){a.fn.pushpin=function(b){var c={top:0,bottom:1/0,offset:0};return"remove"===b?(this.each(function(){(id=a(this).data("pushpin-id"))&&(a(window).off("scroll."+id),a(this).removeData("pushpin-id").removeClass("pin-top pinned pin-bottom").removeAttr("style"))}),!1):(b=a.extend(c,b),$index=0,this.each(function(){function c(a){a.removeClass("pin-top"),a.removeClass("pinned"),a.removeClass("pin-bottom")}function d(d,e){d.each(function(){b.top<=e&&b.bottom>=e&&!a(this).hasClass("pinned")&&(c(a(this)),a(this).css("top",b.offset),a(this).addClass("pinned")),e<b.top&&!a(this).hasClass("pin-top")&&(c(a(this)),a(this).css("top",0),a(this).addClass("pin-top")),e>b.bottom&&!a(this).hasClass("pin-bottom")&&(c(a(this)),a(this).addClass("pin-bottom"),a(this).css("top",b.bottom-g))})}var e=Materialize.guid(),f=a(this),g=a(this).offset().top;a(this).data("pushpin-id",e),d(f,a(window).scrollTop()),a(window).on("scroll."+e,function(){var c=a(window).scrollTop()+b.offset;d(f,c)})}))}}(jQuery),function(a){a(document).ready(function(){a.fn.reverse=[].reverse,a(document).on("mouseenter.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(c){var d=a(this);b(d)}),a(document).on("mouseleave.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(b){var d=a(this);c(d)}),a(document).on("click.fabClickToggle",".fixed-action-btn.click-to-toggle > a",function(d){var e=a(this),f=e.parent();f.hasClass("active")?c(f):b(f)}),a(document).on("click.fabToolbar",".fixed-action-btn.toolbar > a",function(b){var c=a(this),e=c.parent();d(e)})}),a.fn.extend({openFAB:function(){b(a(this))},closeFAB:function(){c(a(this))},openToolbar:function(){d(a(this))},closeToolbar:function(){e(a(this))}});var b=function(b){var c=b;if(c.hasClass("active")===!1){var d,e,f=c.hasClass("horizontal");f===!0?e=40:d=40,c.addClass("active"),c.find("ul .btn-floating").velocity({scaleY:".4",scaleX:".4",translateY:d+"px",translateX:e+"px"},{duration:0});var g=0;c.find("ul .btn-floating").reverse().each(function(){a(this).velocity({opacity:"1",scaleX:"1",scaleY:"1",translateY:"0",translateX:"0"},{duration:80,delay:g}),g+=40})}},c=function(a){var b,c,d=a,e=d.hasClass("horizontal");e===!0?c=40:b=40,d.removeClass("active");d.find("ul .btn-floating").velocity("stop",!0),d.find("ul .btn-floating").velocity({opacity:"0",scaleX:".4",scaleY:".4",translateY:b+"px",translateX:c+"px"},{duration:80})},d=function(b){if("true"!==b.attr("data-open")){var c,d,f,g=window.innerWidth,h=window.innerHeight,i=b[0].getBoundingClientRect(),j=b.find("> a").first(),k=b.find("> ul").first(),l=a('<div class="fab-backdrop"></div>'),m=j.css("background-color");j.append(l),c=i.left-g/2+i.width/2,d=h-i.bottom,f=g/l.width(),b.attr("data-origin-bottom",i.bottom),b.attr("data-origin-left",i.left),b.attr("data-origin-width",i.width),b.addClass("active"),b.attr("data-open",!0),b.css({"text-align":"center",width:"100%",bottom:0,left:0,transform:"translateX("+c+"px)",transition:"none"}),j.css({transform:"translateY("+-d+"px)",transition:"none"}),l.css({"background-color":m}),setTimeout(function(){b.css({transform:"",transition:"transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s"}),j.css({overflow:"visible",transform:"",transition:"transform .2s"}),setTimeout(function(){b.css({overflow:"hidden","background-color":m}),l.css({transform:"scale("+f+")",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"}),k.find("> li > a").css({opacity:1}),a(window).on("scroll.fabToolbarClose",function(){e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose")}),a(document).on("click.fabToolbarClose",function(c){a(c.target).closest(k).length||(e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose"))})},100)},0)}},e=function(a){if("true"===a.attr("data-open")){var b,c,d,e=window.innerWidth,f=window.innerHeight,g=a.attr("data-origin-width"),h=a.attr("data-origin-bottom"),i=a.attr("data-origin-left"),j=a.find("> .btn-floating").first(),k=a.find("> ul").first(),l=a.find(".fab-backdrop"),m=j.css("background-color");b=i-e/2+g/2,c=f-h,d=e/l.width(),a.removeClass("active"),a.attr("data-open",!1),a.css({"background-color":"transparent",transition:"none"}),j.css({transition:"none"}),l.css({transform:"scale(0)","background-color":m}),k.find("> li > a").css({opacity:""}),setTimeout(function(){l.remove(),a.css({"text-align":"",width:"",bottom:"",left:"",overflow:"","background-color":"",transform:"translate3d("+-b+"px,0,0)"}),j.css({overflow:"",transform:"translate3d(0,"+c+"px,0)"}),setTimeout(function(){a.css({transform:"translate3d(0,0,0)",transition:"transform .2s"}),j.css({transform:"translate3d(0,0,0)",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"})},20)},200)}}}(jQuery),function(a){Materialize.fadeInImage=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}c.css({opacity:0}),a(c).velocity({opacity:1},{duration:650,queue:!1,easing:"easeOutSine"}),a(c).velocity({opacity:1},{duration:1300,queue:!1,easing:"swing",step:function(b,c){c.start=100;var d=b/100,e=150-(100-b)/1.75;100>e&&(e=100),b>=0&&a(this).css({"-webkit-filter":"grayscale("+d+")brightness("+e+"%)",filter:"grayscale("+d+")brightness("+e+"%)"})}})},Materialize.showStaggeredList=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}var d=0;c.find("li").velocity({translateX:"-100px"},{duration:0}),c.find("li").each(function(){a(this).velocity({opacity:"1",translateX:"0"},{duration:800,delay:d,easing:[60,10]}),d+=120})},a(document).ready(function(){var b=!1,c=!1;a(".dismissable").each(function(){a(this).hammer({prevent_default:!1}).bind("pan",function(d){if("touch"===d.gesture.pointerType){var e=a(this),f=d.gesture.direction,g=d.gesture.deltaX,h=d.gesture.velocityX;e.velocity({translateX:g},{duration:50,queue:!1,easing:"easeOutQuad"}),4===f&&(g>e.innerWidth()/2||-.75>h)&&(b=!0),2===f&&(g<-1*e.innerWidth()/2||h>.75)&&(c=!0)}}).bind("panend",function(d){if(Math.abs(d.gesture.deltaX)<a(this).innerWidth()/2&&(c=!1,b=!1),"touch"===d.gesture.pointerType){var e=a(this);if(b||c){var f;f=b?e.innerWidth():-1*e.innerWidth(),e.velocity({translateX:f},{duration:100,queue:!1,easing:"easeOutQuad",complete:function(){e.css("border","none"),e.velocity({height:0,padding:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){e.remove()}})}})}else e.velocity({translateX:0},{duration:100,queue:!1,easing:"easeOutQuad"});b=!1,c=!1}})})})}(jQuery),function(a){Materialize.scrollFire=function(a){var b=!1;window.addEventListener("scroll",function(){b=!0}),setInterval(function(){if(b){b=!1;for(var c=window.pageYOffset+window.innerHeight,d=0;d<a.length;d++){var e=a[d],f=e.selector,g=e.offset,h=e.callback,i=document.querySelector(f);if(null!==i){var j=i.getBoundingClientRect().top+window.pageYOffset;if(c>j+g&&e.done!==!0){if("function"==typeof h)h.call(this,i);else if("string"==typeof h){var k=new Function(h);k(i)}e.done=!0}}}}},100)}}(jQuery),function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(f,g,i,l){function m(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",y.component.nodes(t.open),v.box),v.wrap),v.frame),v.holder)}function n(){w.data(g,y).addClass(v.input).attr("tabindex",-1).val(w.data("value")?y.get("select",u.format):f.value),u.editable||w.on("focus."+t.id+" click."+t.id,function(a){a.preventDefault(),y.$root.eq(0).focus()}).on("keydown."+t.id,q),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"})}function o(){y.$root.on({keydown:q,focusin:function(a){y.$root.removeClass(v.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=y.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),y.$root.eq(0).focus()))}}).on({focus:function(){w.addClass(v.target)},blur:function(){w.removeClass(v.target)}}).on("focus.toOpen",r).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(v.navDisabled)||b.hasClass(v.disabled),e=h();e=e&&(e.type||e.href),(d||e&&!a.contains(y.$root[0],e))&&y.$root.eq(0).focus(),!d&&c.nav?y.set("highlight",y.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?y.set("select",c.pick):c.clear?y.clear().close(!0):c.close&&y.close(!0)}),e(y.$root[0],"hidden",!0)}function p(){var b;u.hiddenName===!0?(b=f.name,f.name=""):(b=["string"==typeof u.hiddenPrefix?u.hiddenPrefix:"","string"==typeof u.hiddenSuffix?u.hiddenSuffix:"_submit"],b=b[0]+f.name+b[1]),y._hidden=a('<input type=hidden name="'+b+'"'+(w.data("value")||f.value?' value="'+y.get("select",u.formatSubmit)+'"':"")+">")[0],w.on("change."+t.id,function(){y._hidden.value=f.value?y.get("select",u.formatSubmit):""}),u.container?a(u.container).append(y._hidden):w.after(y._hidden)}function q(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(y.close(),!1):void((32==b||c||!t.open&&y.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?y.clear().close():y.open()))}function r(a){a.stopPropagation(),"focus"==a.type&&y.$root.addClass(v.focused),y.open()}if(!f)return b;var s=!1,t={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},u=i?a.extend(!0,{},i.defaults,l):l||{},v=a.extend({},b.klasses(),u.klass),w=a(f),x=function(){return this.start()},y=x.prototype={constructor:x,$node:w,start:function(){return t&&t.start?y:(t.methods={},t.start=!0,t.open=!1,t.type=f.type,f.autofocus=f==h(),f.readOnly=!u.editable,f.id=f.id||t.id,"text"!=f.type&&(f.type="text"),y.component=new i(y,u),y.$root=a(b._.node("div",m(),v.picker,'id="'+f.id+'_root" tabindex="0"')),o(),u.formatSubmit&&p(),n(),u.container?a(u.container).append(y.$root):w.after(y.$root),y.on({start:y.component.onStart,render:y.component.onRender,stop:y.component.onStop,open:y.component.onOpen,close:y.component.onClose,set:y.component.onSet}).on({start:u.onStart,render:u.onRender,stop:u.onStop,open:u.onOpen,close:u.onClose,set:u.onSet}),s=c(y.$root.children()[0]),f.autofocus&&y.open(),y.trigger("start").trigger("render"))},render:function(a){return a?y.$root.html(m()):y.$root.find("."+v.box).html(y.component.nodes(t.open)),y.trigger("render")},stop:function(){return t.start?(y.close(),y._hidden&&y._hidden.parentNode.removeChild(y._hidden),y.$root.remove(),w.removeClass(v.input).removeData(g),setTimeout(function(){w.off("."+t.id)},0),f.type=t.type,f.readOnly=!1,y.trigger("stop"),t.methods={},t.start=!1,y):y},open:function(c){return t.open?y:(w.addClass(v.active),e(f,"expanded",!0),setTimeout(function(){y.$root.addClass(v.opened),e(y.$root[0],"hidden",!1)},0),c!==!1&&(t.open=!0,s&&k.css("overflow","hidden").css("padding-right","+="+d()),y.$root.eq(0).focus(),j.on("click."+t.id+" focusin."+t.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&y.close(b===y.$root.children()[0])}).on("keydown."+t.id,function(c){var d=c.keyCode,e=y.component.key[d],f=c.target;27==d?y.close(!0):f!=y.$root[0]||!e&&13!=d?a.contains(y.$root[0],f)&&13==d&&(c.preventDefault(),f.click()):(c.preventDefault(),e?b._.trigger(y.component.key.go,y,[b._.trigger(e)]):y.$root.find("."+v.highlighted).hasClass(v.disabled)||y.set("select",y.component.item.highlight).close())})),y.trigger("open"))},close:function(a){return a&&(y.$root.off("focus.toOpen").eq(0).focus(),setTimeout(function(){y.$root.on("focus.toOpen",r)},0)),w.removeClass(v.active),e(f,"expanded",!1),setTimeout(function(){y.$root.removeClass(v.opened+" "+v.focused),e(y.$root[0],"hidden",!0)},0),t.open?(t.open=!1,s&&k.css("overflow","").css("padding-right","-="+d()),j.off("."+t.id),y.trigger("close")):y},clear:function(a){return y.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in y.component.item&&(void 0===f&&(f=null),y.component.set(e,f,d)),("select"==e||"clear"==e)&&w.val("clear"==e?"":y.get(e,u.format)).trigger("change");y.render()}return d.muted?y:y.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=t[a])return t[a];if("valueSubmit"==a){if(y._hidden)return y._hidden.value;a="value"}if("value"==a)return f.value;if(a in y.component.item){if("string"==typeof c){var d=y.component.get(a);return d?b._.trigger(y.component.formats.toString,y.component,[c,d]):""}return y.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),t.methods[e]=t.methods[e]||[],t.methods[e].push(f)}return y},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)b=c[a],b in t.methods&&delete t.methods[b];return y},trigger:function(a,c){var d=function(a){var d=t.methods[a];d&&d.map(function(a){b._.trigger(a,y,[c])})};return d("_"+a),d(a),y}};return new x}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(k.height()<=i.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}function h(){try{return document.activeElement}catch(a){}}var i=a(window),j=a(document),k=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b}),function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-(1/0)||c==1/0?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?"string"==typeof b?b=c.parse(a,b):f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-(1/0):1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0;
|
10 |
+
});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysLetter).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(d){var e=c.showMonthsShort?c.monthsShort:c.monthsFull;return"short_months"==d&&(e=c.monthsShort),c.selectMonths&&void 0==d?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[e[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):"short_months"==d?null!=i?f.node("div",e[i.month]):f.node("div",e[k.month]):f.node("div",e[k.month],c.klass.month)},r=function(d){var e=k.year,g=c.selectYears===!0?5:~~(c.selectYears/2);if(g){var h=m.year,i=n.year,j=e-g,l=e+g;if(h>j&&(l+=h-j,j=h),l>i){var o=j-h,p=l-i;j-=o>p?p:o,l=i}if(c.selectYears&&void 0==d)return f.node("select",f.group({min:j,max:l,i:1,node:"option",item:function(a){return[a,0,"value="+a+(e==a?" selected":"")]}}),c.klass.selectYear+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return"raw"==d?f.node("div",e):f.node("div",e,c.klass.year)};return createDayLabel=function(){return null!=i?f.node("div",i.date):f.node("div",h.date)},createWeekdayLabel=function(){var a;a=null!=i?i.day:h.day;var b=c.weekdaysFull[a];return b},f.node("div",f.node("div",createWeekdayLabel(),"picker__weekday-display")+f.node("div",q("short_months"),c.klass.month_display)+f.node("div",createDayLabel(),c.klass.day_display)+f.node("div",r("raw"),c.klass.year_display),c.klass.date_display)+f.node("div",f.node("div",(c.selectYears?q()+r():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick,o=f.trigger(b.formats.toString,b,[c.format,a]);return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",label:o,selected:d&&b.$node.val()===o?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0})),c.klass.calendar_container)+f.node("div",f.node("button",c.today,"btn-flat picker__today","type=button data-pick="+h.pick+(a&&!b.disabled(h)?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,"btn-flat picker__clear","type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.close,"btn-flat picker__close","type=button data-close=true "+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysLetter:["S","M","T","W","T","F","S"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",date_display:a+"date-display",day_display:a+"day-display",month_display:a+"month-display",year_display:a+"year-display",calendar_container:a+"calendar-container",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)}),function(a){function b(){var b=+a(this).attr("length"),c=+a(this).val().length,d=b>=c;a(this).parent().find('span[class="character-counter"]').html(c+"/"+b),e(d,a(this))}function c(b){var c=b.parent().find('span[class="character-counter"]');c.length||(c=a("<span/>").addClass("character-counter").css("float","right").css("font-size","12px").css("height",1),b.parent().append(c))}function d(){a(this).parent().find('span[class="character-counter"]').html("")}function e(a,b){var c=b.hasClass("invalid");a&&c?b.removeClass("invalid"):a||c||(b.removeClass("valid"),b.addClass("invalid"))}a.fn.characterCounter=function(){return this.each(function(){var e=a(this),f=e.parent().find('span[class="character-counter"]');if(!f.length){var g=void 0!==e.attr("length");g&&(e.on("input",b),e.on("focus",b),e.on("blur",d),c(e))}})},a(document).ready(function(){a("input, textarea").characterCounter()})}(jQuery),function(a){var b={init:function(b){var c={time_constant:200,dist:-100,shift:0,padding:0,full_width:!1,indicators:!1,no_wrap:!1};return b=a.extend(c,b),this.each(function(){function c(){"undefined"!=typeof window.ontouchstart&&(H[0].addEventListener("touchstart",l),H[0].addEventListener("touchmove",m),H[0].addEventListener("touchend",n)),H[0].addEventListener("mousedown",l),H[0].addEventListener("mousemove",m),H[0].addEventListener("mouseup",n),H[0].addEventListener("mouseleave",n),H[0].addEventListener("click",j)}function d(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientX:a.clientX}function e(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientY:a.clientY}function f(a){return a>=t?a%t:0>a?f(t+a%t):a}function g(a){var c,d,e,g,h,i,j;if(p="number"==typeof a?a:p,q=Math.floor((p+s/2)/s),e=p-q*s,g=0>e?1:-1,h=-g*e*2/s,d=t>>1,b.full_width?j="translateX(0)":(j="translateX("+(H[0].clientWidth-item_width)/2+"px) ",j+="translateY("+(H[0].clientHeight-item_width)/2+"px)"),I){var k=q%t,l=G.find(".indicator-item.active");l.index()!==k&&(l.removeClass("active"),G.find(".indicator-item").eq(k).addClass("active"))}for((!b.no_wrap||q>=0&&t>q)&&(i=o[f(q)],i.style[A]=j+" translateX("+-e/2+"px) translateX("+g*b.shift*h*c+"px) translateZ("+b.dist*h+"px)",i.style.zIndex=0,b.full_width?tweenedOpacity=1:tweenedOpacity=1-.2*h,i.style.opacity=tweenedOpacity,i.style.display="block"),c=1;d>=c;++c)b.full_width?(zTranslation=b.dist,tweenedOpacity=c===d&&0>e?1-h:1):(zTranslation=b.dist*(2*c+h*g),tweenedOpacity=1-.2*(2*c+h*g)),(!b.no_wrap||t>q+c)&&(i=o[f(q+c)],i.style[A]=j+" translateX("+(b.shift+(s*c-e)/2)+"px) translateZ("+zTranslation+"px)",i.style.zIndex=-c,i.style.opacity=tweenedOpacity,i.style.display="block"),b.full_width?(zTranslation=b.dist,tweenedOpacity=c===d&&e>0?1-h:1):(zTranslation=b.dist*(2*c-h*g),tweenedOpacity=1-.2*(2*c-h*g)),(!b.no_wrap||q-c>=0)&&(i=o[f(q-c)],i.style[A]=j+" translateX("+(-b.shift+(-s*c-e)/2)+"px) translateZ("+zTranslation+"px)",i.style.zIndex=-c,i.style.opacity=tweenedOpacity,i.style.display="block");(!b.no_wrap||q>=0&&t>q)&&(i=o[f(q)],i.style[A]=j+" translateX("+-e/2+"px) translateX("+g*b.shift*h+"px) translateZ("+b.dist*h+"px)",i.style.zIndex=0,b.full_width?tweenedOpacity=1:tweenedOpacity=1-.2*h,i.style.opacity=tweenedOpacity,i.style.display="block")}function h(){var a,b,c,d;a=Date.now(),b=a-C,C=a,c=p-B,B=p,d=1e3*c/(1+b),z=.8*d+.2*z}function i(){var a,c;w&&(a=Date.now()-C,c=w*Math.exp(-a/b.time_constant),c>2||-2>c?(g(x-c),requestAnimationFrame(i)):g(x))}function j(c){if(E)return c.preventDefault(),c.stopPropagation(),!1;if(!b.full_width){var d=a(c.target).closest(".carousel-item").index(),e=q%t-d;0!==e&&(c.preventDefault(),c.stopPropagation()),k(d)}}function k(a){var c=q%t-a;b.no_wrap||(0>c?Math.abs(c+t)<Math.abs(c)&&(c+=t):c>0&&Math.abs(c-t)<c&&(c-=t)),0>c?H.trigger("carouselNext",[Math.abs(c)]):c>0&&H.trigger("carouselPrev",[c])}function l(a){r=!0,E=!1,F=!1,u=d(a),v=e(a),z=w=0,B=p,C=Date.now(),clearInterval(D),D=setInterval(h,100)}function m(a){var b,c,f;if(r)if(b=d(a),y=e(a),c=u-b,f=Math.abs(v-y),30>f&&!F)(c>2||-2>c)&&(E=!0,u=b,g(p+c));else{if(E)return a.preventDefault(),a.stopPropagation(),!1;F=!0}return E?(a.preventDefault(),a.stopPropagation(),!1):void 0}function n(a){return r?(r=!1,clearInterval(D),x=p,(z>10||-10>z)&&(w=.9*z,x=p+w),x=Math.round(x/s)*s,b.no_wrap&&(x>=s*(t-1)?x=s*(t-1):0>x&&(x=0)),w=x-p,C=Date.now(),requestAnimationFrame(i),E&&(a.preventDefault(),a.stopPropagation()),!1):void 0}var o,p,q,r,s,t,u,v,w,x,z,A,B,C,D,E,F,G=a('<ul class="indicators"></ul>'),H=a(this),I=H.attr("data-indicators")||b.indicators;if(H.hasClass("initialized"))return a(this).trigger("carouselNext",[1e-6]),!0;if(b.full_width){b.dist=0;var J=H.find(".carousel-item img").first();J.length?imageHeight=J.on("load",function(){H.css("height",a(this).height())}):(imageHeight=H.find(".carousel-item").first().height(),H.css("height",imageHeight)),I&&H.find(".carousel-fixed-item").addClass("with-indicators")}H.addClass("initialized"),r=!1,p=x=0,o=[],item_width=H.find(".carousel-item").first().innerWidth(),s=2*item_width+b.padding,H.find(".carousel-item").each(function(b){if(o.push(a(this)[0]),I){var c=a('<li class="indicator-item"></li>');0===b&&c.addClass("active"),c.click(function(){var b=a(this).index();k(b)}),G.append(c)}}),I&&H.append(G),t=o.length,A="transform",["webkit","Moz","O","ms"].every(function(a){var b=a+"Transform";return"undefined"!=typeof document.body.style[b]?(A=b,!1):!0}),window.onresize=g,c(),g(p),a(this).on("carouselNext",function(a,b){void 0===b&&(b=1),x=p+s*b,p!==x&&(w=x-p,C=Date.now(),requestAnimationFrame(i))}),a(this).on("carouselPrev",function(a,b){void 0===b&&(b=1),x=p-s*b,p!==x&&(w=x-p,C=Date.now(),requestAnimationFrame(i))}),a(this).on("carouselSet",function(a,b){void 0===b&&(b=0),k(b)})})},next:function(b){a(this).trigger("carouselNext",[b])},prev:function(b){a(this).trigger("carouselPrev",[b])},set:function(b){a(this).trigger("carouselSet",[b])}};a.fn.carousel=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.carousel"):b.init.apply(this,arguments)}}(jQuery);
|
admin/js/xcloner-admin.js
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function( $ ) {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
jQuery(document).ready(function(){
|
5 |
+
|
6 |
+
jQuery("span.shorten_string").click(function(){
|
7 |
+
jQuery(this).toggleClass("full");
|
8 |
+
doShortText(jQuery(this));
|
9 |
+
})
|
10 |
+
|
11 |
+
jQuery("span.shorten_string").each(function(){
|
12 |
+
doShortText(jQuery(this));
|
13 |
+
})
|
14 |
+
|
15 |
+
jQuery("#xcloner_regex_exclude").on("focus", function(){
|
16 |
+
jQuery("ul.xcloner_regex_exclude_limit li").fadeIn();
|
17 |
+
})
|
18 |
+
|
19 |
+
jQuery(".regex_pattern").click(function(){
|
20 |
+
jQuery(this).select();
|
21 |
+
})
|
22 |
+
|
23 |
+
jQuery(".btn.system_info_toggle").click(function(){
|
24 |
+
jQuery(".additional_system_info").toggle();
|
25 |
+
})
|
26 |
+
|
27 |
+
jQuery(".nav-tab-wrapper.content li").click(function(e){
|
28 |
+
jQuery(".nav-tab-wrapper li a").removeClass("nav-tab-active");
|
29 |
+
jQuery(this).find('a').addClass("nav-tab-active");
|
30 |
+
jQuery(".nav-tab-wrapper-content .tab-content").removeClass('active');
|
31 |
+
jQuery(".nav-tab-wrapper-content "+jQuery(this).find('a').attr('href')).addClass('active');
|
32 |
+
|
33 |
+
e.preventDefault();
|
34 |
+
|
35 |
+
location.hash = jQuery(this).find('a').attr('href')+"_hash";
|
36 |
+
|
37 |
+
})
|
38 |
+
|
39 |
+
var hash = window.location.hash;
|
40 |
+
if(hash){
|
41 |
+
next_tab(hash.replace("_hash",""));
|
42 |
+
}
|
43 |
+
})
|
44 |
+
|
45 |
+
/**
|
46 |
+
* All of the code for your admin-facing JavaScript source
|
47 |
+
* should reside in this file.
|
48 |
+
*
|
49 |
+
* Note: It has been assumed you will write jQuery code here, so the
|
50 |
+
* $ function reference has been prepared for usage within the scope
|
51 |
+
* of this function.
|
52 |
+
*
|
53 |
+
* This enables you to define handlers, for when the DOM is ready:
|
54 |
+
*
|
55 |
+
* $(function() {
|
56 |
+
*
|
57 |
+
* });
|
58 |
+
*
|
59 |
+
* When the window is loaded:
|
60 |
+
*
|
61 |
+
* $( window ).load(function() {
|
62 |
+
*
|
63 |
+
* });
|
64 |
+
*
|
65 |
+
* ...and/or other possibilities.
|
66 |
+
*
|
67 |
+
* Ideally, it is not considered best practise to attach more than a
|
68 |
+
* single DOM-ready or window-load handler for a particular page.
|
69 |
+
* Although scripts in the WordPress core, Plugins and Themes may be
|
70 |
+
* practising this, we should strive to set a better example in our own work.
|
71 |
+
*/
|
72 |
+
|
73 |
+
})( jQuery );
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
jQuery( document ).ajaxError(function(err, request) {
|
79 |
+
//console.log( err );
|
80 |
+
//console.log( request );
|
81 |
+
//show_ajax_error("dd", "dd12", request)
|
82 |
+
});
|
83 |
+
|
84 |
+
function next_tab(hash){
|
85 |
+
jQuery(".nav-tab-wrapper").find("li a[href='"+hash+"']").trigger('click');
|
86 |
+
location.hash = hash;
|
87 |
+
}
|
88 |
+
|
89 |
+
function doShortText(elem)
|
90 |
+
{
|
91 |
+
if(elem.hasClass("full")){
|
92 |
+
elem.text(elem.attr("data-text"));
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
var text = elem.text()
|
96 |
+
var text_lenght = text.length;
|
97 |
+
var first = text.substr(0, 10);
|
98 |
+
var last = text.substr(text_lenght-20, text_lenght);
|
99 |
+
|
100 |
+
elem.attr("data-text", text).text(first+"..."+last);
|
101 |
+
}
|
102 |
+
|
103 |
+
function show_ajax_error(title, msg, json){
|
104 |
+
|
105 |
+
//var json = jQuery.parseJSON( body )
|
106 |
+
|
107 |
+
if(xcloner_backup !== undefined)
|
108 |
+
xcloner_backup.cancel_backup();
|
109 |
+
|
110 |
+
if(json.responseText)
|
111 |
+
msg = msg+": "+json.responseText;
|
112 |
+
|
113 |
+
jQuery("#error_modal .title").text(title);
|
114 |
+
jQuery("#error_modal .msg").text(msg);
|
115 |
+
|
116 |
+
if(json.status)
|
117 |
+
jQuery("#error_modal .status").text(json.status+" "+json.statusText);
|
118 |
+
|
119 |
+
jQuery("#error_modal .body").text(JSON.stringify(json));
|
120 |
+
var error_modal = jQuery("#error_modal").modal();
|
121 |
+
error_modal.modal('open');
|
122 |
+
}
|
123 |
+
|
124 |
+
var ID = function () {
|
125 |
+
// Math.random should be unique because of its seeding algorithm.
|
126 |
+
// Convert it to base 36 (numbers + letters), and grab the first 9 characters
|
127 |
+
// after the decimal.
|
128 |
+
return '_' + Math.random().toString(36).substr(2, 9);
|
129 |
+
};
|
130 |
+
|
131 |
+
|
132 |
+
|
admin/js/xcloner-backup-class.js
ADDED
@@ -0,0 +1,422 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class Xcloner_Backup{
|
2 |
+
|
3 |
+
constructor()
|
4 |
+
{
|
5 |
+
this.cancel = 0;
|
6 |
+
this.params;
|
7 |
+
this.generate_hash = false;
|
8 |
+
this.last_dumpfile = "";
|
9 |
+
this.last_backup_file = ""
|
10 |
+
this.backup_part = 0
|
11 |
+
this.backup_size_total = 0;
|
12 |
+
this.resume = new Object();
|
13 |
+
}
|
14 |
+
|
15 |
+
get_form_params()
|
16 |
+
{
|
17 |
+
var table_params = []
|
18 |
+
var files_params = []
|
19 |
+
var extra = []
|
20 |
+
|
21 |
+
jQuery.each(jQuery("#jstree_database_container").jstree("get_checked",true),function(){
|
22 |
+
|
23 |
+
var object = new Object();
|
24 |
+
object.id = this.id
|
25 |
+
object.parent = this.parent
|
26 |
+
|
27 |
+
var index = table_params.length;
|
28 |
+
table_params[index] = object
|
29 |
+
});
|
30 |
+
|
31 |
+
jQuery.each(jQuery("#jstree_files_container").jstree("get_checked",true),function(){
|
32 |
+
//console.log(this.id+"-"+this.parent);
|
33 |
+
|
34 |
+
var object = new Object();
|
35 |
+
object.id = this.id
|
36 |
+
object.parent = this.parent
|
37 |
+
|
38 |
+
var index = files_params.length;
|
39 |
+
files_params[index] = object
|
40 |
+
});
|
41 |
+
|
42 |
+
var $return = new Object();
|
43 |
+
$return.table_params = table_params;
|
44 |
+
$return.files_params = files_params;
|
45 |
+
$return.backup_params = jQuery('#generate_backup_form').serializeArray();
|
46 |
+
|
47 |
+
return $return;
|
48 |
+
}
|
49 |
+
|
50 |
+
do_backup_database_callback(elem, action, json )
|
51 |
+
{
|
52 |
+
if(json.extra)
|
53 |
+
this.params.extra = json.extra;
|
54 |
+
|
55 |
+
if(json.extra.stats)
|
56 |
+
{
|
57 |
+
if(json.extra.stats.tables_count !== undefined)
|
58 |
+
jQuery(elem).find(".table-counter").text(parseInt(json.extra.stats.tables_count));
|
59 |
+
|
60 |
+
if(json.extra.stats.database_count !== undefined)
|
61 |
+
jQuery(elem).find(".database-counter").text(parseInt(json.extra.stats.database_count));
|
62 |
+
|
63 |
+
if(json.extra.stats.total_records !== undefined)
|
64 |
+
jQuery(elem).find(".total-records").text(parseInt(json.extra.stats.total_records));
|
65 |
+
}
|
66 |
+
|
67 |
+
if(json.extra.tableName)
|
68 |
+
{
|
69 |
+
jQuery(elem).find(".last-logged-table").text(json.extra.databaseName+"."+json.extra.tableName+" ("+json.extra.processedRecords+" records)");
|
70 |
+
}
|
71 |
+
|
72 |
+
if(json.extra.processedRecords !== undefined && !json.extra.startAtRecord && !json.extra.endDump)
|
73 |
+
{
|
74 |
+
var records = parseInt(jQuery(elem).find(".total-records").attr('data-processed')) + parseInt(json.extra.processedRecords);
|
75 |
+
|
76 |
+
var percent = 100*parseInt(records)/parseInt(jQuery(elem).find(".total-records").text());
|
77 |
+
jQuery(elem).find('.progress .determinate').css('width', percent+'%');
|
78 |
+
|
79 |
+
jQuery(elem).find(".total-records").attr('data-processed', records);
|
80 |
+
jQuery(elem).find(".status-body ul.logged-tables").prepend(jQuery("<li>").text(json.extra.databaseName+"."+json.extra.tableName+" ("+json.extra.processedRecords+" records)"));
|
81 |
+
}
|
82 |
+
|
83 |
+
if(json.extra.dumpfile !== undefined){
|
84 |
+
var db_text = (json.extra.dumpfile+" ("+this.getSize(json.extra.dumpsize, 1024)+" KB)");
|
85 |
+
|
86 |
+
if(!jQuery(this.last_dumpfile).hasClass(json.extra.dumpfile)){
|
87 |
+
this.last_dumpfile = (jQuery("<li>").addClass(json.extra.dumpfile).html(db_text)).prependTo("ul.logged-databases");
|
88 |
+
}
|
89 |
+
else{
|
90 |
+
jQuery(this.last_dumpfile).html(db_text)
|
91 |
+
}
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
+
if(!json.finished /*&& !this.cancel*/){
|
96 |
+
|
97 |
+
this.do_ajax(elem, action);
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
jQuery(elem).find(".last-logged-table").text('done');
|
104 |
+
jQuery(elem).find('.progress .determinate').css('width', '100%');
|
105 |
+
|
106 |
+
this.do_backup_files();
|
107 |
+
|
108 |
+
}
|
109 |
+
|
110 |
+
do_backup_database()
|
111 |
+
{
|
112 |
+
if(!jQuery('#jstree_database_container').length){
|
113 |
+
this.do_backup_files();
|
114 |
+
return;
|
115 |
+
}
|
116 |
+
|
117 |
+
/*if(this.cancel)
|
118 |
+
return false;*/
|
119 |
+
|
120 |
+
var elem = "#generate_backup ul.backup-status li.database-backup";
|
121 |
+
jQuery(elem).show();
|
122 |
+
jQuery(elem+' .status-body').show();
|
123 |
+
|
124 |
+
jQuery(elem).find(".total-records").text(0);
|
125 |
+
jQuery(elem).find(".total-records").attr('data-processed', 0);
|
126 |
+
jQuery(elem).find(".table-counter").text(0);
|
127 |
+
jQuery(elem).find(".database-counter").text(0);
|
128 |
+
jQuery(elem).find(".logged-databases").html("");
|
129 |
+
jQuery(elem).find(".logged-tables").html("");
|
130 |
+
|
131 |
+
this.last_dumpfile = 0;
|
132 |
+
|
133 |
+
jQuery(elem).find('.progress .determinate').css('width', '0%');
|
134 |
+
|
135 |
+
this.do_ajax(elem, 'backup_database', 1);
|
136 |
+
}
|
137 |
+
|
138 |
+
do_scan_filesystem_callback(elem, action, json )
|
139 |
+
{
|
140 |
+
|
141 |
+
if(json.total_files_num)
|
142 |
+
jQuery(".file-system .file-counter").text(parseInt(json.total_files_num) + parseInt(jQuery(".file-system .file-counter").text()));
|
143 |
+
|
144 |
+
if(json.total_files_size) {
|
145 |
+
var size = parseFloat(json.total_files_size) + parseFloat(jQuery(".file-system .file-size-total").text())
|
146 |
+
jQuery(".file-system .file-size-total").text(size.toFixed(2));
|
147 |
+
}
|
148 |
+
|
149 |
+
if(json.last_logged_file)
|
150 |
+
jQuery(".file-system .last-logged-file").text(json.last_logged_file);
|
151 |
+
|
152 |
+
if(!json.finished /*&& !this.cancel*/){
|
153 |
+
|
154 |
+
this.do_ajax(elem, action);
|
155 |
+
return false;
|
156 |
+
}
|
157 |
+
|
158 |
+
//finished
|
159 |
+
jQuery(elem).find('.progress .indeterminate').removeClass('indeterminate').addClass('determinate').css('width', '100%');
|
160 |
+
jQuery(".file-system .last-logged-file").text('done');
|
161 |
+
|
162 |
+
//this.do_backup_database();
|
163 |
+
this.do_backup_database();
|
164 |
+
|
165 |
+
}
|
166 |
+
do_scan_filesystem()
|
167 |
+
{
|
168 |
+
/*if(this.cancel)
|
169 |
+
return false;*/
|
170 |
+
|
171 |
+
var elem = "#generate_backup ul.backup-status li.file-system";
|
172 |
+
jQuery(elem).show();
|
173 |
+
jQuery(elem+' .status-body').show();
|
174 |
+
jQuery(elem).find('.collapsible-header').trigger('click');
|
175 |
+
|
176 |
+
jQuery(".file-system .file-counter").text(0);
|
177 |
+
jQuery(".file-system .last-logged-file").text("");
|
178 |
+
jQuery(".file-system .file-size-total").text(0);
|
179 |
+
jQuery('.file-system .progress div').removeClass('determinate').addClass('indeterminate').css('width', '0%');
|
180 |
+
|
181 |
+
|
182 |
+
this.do_ajax(elem, 'scan_filesystem', 1);
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
do_backup_files_callback(elem, action, json)
|
187 |
+
{
|
188 |
+
/*if(this.cancel)
|
189 |
+
return false;*/
|
190 |
+
|
191 |
+
if(json.extra)
|
192 |
+
this.params.extra = json.extra;
|
193 |
+
|
194 |
+
if(json.extra)
|
195 |
+
{
|
196 |
+
if(json.extra.start_at_line !== undefined)
|
197 |
+
jQuery(elem).find(".file-counter").text(parseInt(json.extra.start_at_line));
|
198 |
+
|
199 |
+
if(json.extra.start_at_line !== undefined){
|
200 |
+
//var prev_backup_size = parseInt(jQuery(elem).find(".file-size-total").attr('data-processed'));
|
201 |
+
jQuery(elem).find(".file-size-total").text( this.getSize(this.backup_size_total+parseInt(json.extra.backup_size)));
|
202 |
+
//var backup_size = parseInt(json.extra.backup_size);
|
203 |
+
}
|
204 |
+
|
205 |
+
}
|
206 |
+
|
207 |
+
if(json.extra.processed_file)
|
208 |
+
{
|
209 |
+
if(json.extra.start_at_byte !== undefined && json.extra.start_at_byte)
|
210 |
+
var processed_size = json.extra.start_at_byte;
|
211 |
+
else
|
212 |
+
var processed_size = json.extra.processed_file_size;
|
213 |
+
|
214 |
+
jQuery(elem).find(".last-logged-file").text(json.extra.processed_file+" ("+this.getSize(processed_size, 1024)+" KB)");
|
215 |
+
}
|
216 |
+
|
217 |
+
if(json.extra.processed_file !== undefined){
|
218 |
+
|
219 |
+
var backup_text = json.extra.backup_archive_name_full+" ("+this.getSize(json.extra.backup_size)+") MB";
|
220 |
+
|
221 |
+
if(this.backup_part != json.extra.backup_part)
|
222 |
+
{
|
223 |
+
this.backup_part = json.extra.backup_part;
|
224 |
+
this.backup_size_total = this.backup_size_total+json.extra.backup_size;
|
225 |
+
}
|
226 |
+
|
227 |
+
if(!jQuery(this.last_backup_file).hasClass(json.extra.backup_archive_name)){
|
228 |
+
this.last_backup_file = (jQuery("<li>").addClass(json.extra.backup_archive_name).html(backup_text)).prependTo(jQuery(elem).find(".status-body .backup-name"));
|
229 |
+
}
|
230 |
+
|
231 |
+
jQuery(this.last_backup_file).html(backup_text)
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
|
236 |
+
if(json.extra.lines_total)
|
237 |
+
{
|
238 |
+
var percent = 100*parseInt(json.extra.start_at_line)/parseInt(json.extra.lines_total);
|
239 |
+
jQuery(elem).find('.progress .determinate').css('width', percent+'%');
|
240 |
+
}
|
241 |
+
|
242 |
+
if(!json.finished /*&& !this.cancel*/){
|
243 |
+
|
244 |
+
this.do_ajax(elem, action);
|
245 |
+
return false;
|
246 |
+
}
|
247 |
+
|
248 |
+
jQuery(elem).find(".last-logged-file").text('done');
|
249 |
+
jQuery(".backup-done .cloud-upload").attr("href", "#"+json.extra.backup_parent);
|
250 |
+
jQuery(".backup-done .download").attr("href", "#"+json.extra.backup_parent);
|
251 |
+
jQuery(".backup-done .list-backup-content").attr("href", "#"+json.extra.backup_parent);
|
252 |
+
|
253 |
+
//this.restart_backup();
|
254 |
+
this.do_backup_done()
|
255 |
+
}
|
256 |
+
|
257 |
+
do_backup_files()
|
258 |
+
{
|
259 |
+
if(this.cancel)
|
260 |
+
return false;
|
261 |
+
|
262 |
+
var elem = "#generate_backup ul.backup-status li.files-backup";
|
263 |
+
jQuery(elem).show();
|
264 |
+
jQuery(elem+' .status-body').show();
|
265 |
+
jQuery(elem).find('.collapsible-header').trigger('click');
|
266 |
+
|
267 |
+
jQuery(elem).find(".file-size-total").text(0);
|
268 |
+
jQuery(elem).find(".file-size-total").attr('data-processed', 0);
|
269 |
+
jQuery(elem).find(".file-counter").text(0);
|
270 |
+
jQuery(elem).find(".last-logged-file").text("");
|
271 |
+
|
272 |
+
jQuery(elem).find('.progress .determinate').css('width', '0%');
|
273 |
+
|
274 |
+
this.do_ajax(elem, 'backup_files', 1);
|
275 |
+
}
|
276 |
+
|
277 |
+
do_backup_done()
|
278 |
+
{
|
279 |
+
var elem = "#generate_backup ul.backup-status li.backup-done";
|
280 |
+
jQuery(elem).show();
|
281 |
+
jQuery(elem+' .status-body').show();
|
282 |
+
jQuery(elem).find('.collapsible-header').trigger('click');
|
283 |
+
|
284 |
+
this.set_cancel(false)
|
285 |
+
jQuery('#generate_backup .action-buttons a').hide();
|
286 |
+
jQuery('#generate_backup .action-buttons .start').css('display', 'inline-block');
|
287 |
+
|
288 |
+
}
|
289 |
+
|
290 |
+
do_save_schedule_callback(elem, action, json)
|
291 |
+
{
|
292 |
+
jQuery("#schedule_backup_success").show();
|
293 |
+
}
|
294 |
+
|
295 |
+
cancel_backup()
|
296 |
+
{
|
297 |
+
this.set_cancel(true)
|
298 |
+
jQuery('#generate_backup .action-buttons a').hide();
|
299 |
+
jQuery('#generate_backup .action-buttons .start').css('display', 'inline-block');
|
300 |
+
jQuery('#generate_backup .action-buttons .restart').css('display', 'inline-block');
|
301 |
+
|
302 |
+
//this.restart_backup();
|
303 |
+
}
|
304 |
+
|
305 |
+
restart_backup()
|
306 |
+
{ this.set_cancel(false);
|
307 |
+
|
308 |
+
jQuery('#generate_backup .action-buttons a').hide();
|
309 |
+
jQuery('#generate_backup .action-buttons .cancel').css('display', 'inline-block');
|
310 |
+
|
311 |
+
if(this.resume.action)
|
312 |
+
{
|
313 |
+
//console.log(this.resume.action)
|
314 |
+
this.do_ajax(this.resume.elem, this.resume.action, this.resume.params);
|
315 |
+
this.resume = new Object();
|
316 |
+
return;
|
317 |
+
}
|
318 |
+
|
319 |
+
this.start_backup()
|
320 |
+
}
|
321 |
+
|
322 |
+
start_backup()
|
323 |
+
{
|
324 |
+
|
325 |
+
this.resume = new Object()
|
326 |
+
this.set_cancel(false);
|
327 |
+
jQuery('#generate_backup .action-buttons a').hide();
|
328 |
+
jQuery('#generate_backup .action-buttons .cancel').css('display', 'inline-block');
|
329 |
+
|
330 |
+
|
331 |
+
this.generate_hash = true;
|
332 |
+
//this.cancel = false;
|
333 |
+
this.backup_size_total = 0;
|
334 |
+
this.last_backup_file = "";
|
335 |
+
this.backup_part = 0;
|
336 |
+
jQuery('#generate_backup ul.backup-name li').remove();
|
337 |
+
|
338 |
+
jQuery('#generate_backup ul.backup-status > li').hide();
|
339 |
+
jQuery('#generate_backup .backup-status').show();
|
340 |
+
|
341 |
+
this.params = this.get_form_params();
|
342 |
+
|
343 |
+
|
344 |
+
|
345 |
+
this.do_scan_filesystem();
|
346 |
+
|
347 |
+
}
|
348 |
+
|
349 |
+
set_cancel(status)
|
350 |
+
{
|
351 |
+
if(status)
|
352 |
+
{
|
353 |
+
//document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
|
354 |
+
//jQuery("#generate_backup .collapsible-header.active .progress > div").add
|
355 |
+
}
|
356 |
+
this.cancel = status
|
357 |
+
}
|
358 |
+
|
359 |
+
get_cancel(status)
|
360 |
+
{
|
361 |
+
return this.cancel
|
362 |
+
}
|
363 |
+
|
364 |
+
init_resume(elem, action, init)
|
365 |
+
{
|
366 |
+
this.resume.elem = elem
|
367 |
+
this.resume.action = action
|
368 |
+
this.resume.init = init
|
369 |
+
}
|
370 |
+
|
371 |
+
do_ajax(elem, action, init = 0)
|
372 |
+
{
|
373 |
+
var hash = '';
|
374 |
+
if(this.params.hash !==undefined)
|
375 |
+
hash = this.params.hash;
|
376 |
+
else if(this.generate_hash)
|
377 |
+
hash = 'generate_hash';
|
378 |
+
|
379 |
+
|
380 |
+
if(this.cancel == true)
|
381 |
+
{
|
382 |
+
this.init_resume(elem, action, init);
|
383 |
+
return;
|
384 |
+
}
|
385 |
+
|
386 |
+
var callback = 'do_'+action+'_callback';
|
387 |
+
var data = JSON.stringify(this.params);
|
388 |
+
var $this = this;
|
389 |
+
|
390 |
+
jQuery.ajax({
|
391 |
+
url: ajaxurl,
|
392 |
+
dataType: 'json',
|
393 |
+
type: 'POST',
|
394 |
+
data: {'action': action, 'data': data, 'init': init, 'hash': hash, 'API_ID': ID()},
|
395 |
+
error: function(err) {
|
396 |
+
show_ajax_error("Communication Error", "", err)
|
397 |
+
$this.init_resume(elem, action, init);
|
398 |
+
//console.log(err);
|
399 |
+
}
|
400 |
+
}).done(function(json) {
|
401 |
+
if(json.hash){
|
402 |
+
$this.params.hash = json.hash;
|
403 |
+
//console.log(json.hash);
|
404 |
+
}
|
405 |
+
if(json.error !== undefined){
|
406 |
+
show_ajax_error("Communication Error", "", json.error_message);
|
407 |
+
$this.init_resume(elem, action, init);
|
408 |
+
return;
|
409 |
+
}
|
410 |
+
|
411 |
+
$this.resume = new Object();
|
412 |
+
|
413 |
+
$this[callback](elem, action, json)
|
414 |
+
|
415 |
+
});
|
416 |
+
}
|
417 |
+
|
418 |
+
getSize(bytes, conv = 1024*1024)
|
419 |
+
{
|
420 |
+
return (bytes/conv).toFixed(2);
|
421 |
+
}
|
422 |
+
}
|
admin/js/xcloner-manage-backups-class.js
ADDED
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
class Xcloner_Manage_Backups{
|
3 |
+
|
4 |
+
constructor()
|
5 |
+
{
|
6 |
+
this.file_counter = 0
|
7 |
+
//this.edit_modal = jQuery('.modal').modal();
|
8 |
+
}
|
9 |
+
|
10 |
+
download_backup_by_name(id)
|
11 |
+
{
|
12 |
+
window.open(ajaxurl+"?action=download_backup_by_name&name="+id);
|
13 |
+
return false;
|
14 |
+
}
|
15 |
+
|
16 |
+
delete_backup_by_name(id, elem, dataTable)
|
17 |
+
{
|
18 |
+
var $this = this
|
19 |
+
|
20 |
+
if(id){
|
21 |
+
jQuery.ajax({
|
22 |
+
url: ajaxurl,
|
23 |
+
method: 'post',
|
24 |
+
data: { action : 'delete_backup_by_name', name: id},
|
25 |
+
success: function(response){
|
26 |
+
if(response.finished)
|
27 |
+
{
|
28 |
+
dataTable
|
29 |
+
.row( jQuery(elem).parents('tr') )
|
30 |
+
.remove()
|
31 |
+
.draw();
|
32 |
+
}
|
33 |
+
else{
|
34 |
+
alert("There was an error deleting the file");
|
35 |
+
}
|
36 |
+
},
|
37 |
+
dataType: 'json'
|
38 |
+
});
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
list_backup_content_callback(backup_file, start = 0, part= 0)
|
43 |
+
{
|
44 |
+
var $this = this;
|
45 |
+
|
46 |
+
if(backup_file)
|
47 |
+
{
|
48 |
+
jQuery.ajax({
|
49 |
+
url: ajaxurl,
|
50 |
+
method: 'post',
|
51 |
+
data: { action : 'list_backup_files', file: backup_file, start: start, part: part},
|
52 |
+
success: function(response){
|
53 |
+
|
54 |
+
if(response.error)
|
55 |
+
{
|
56 |
+
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(response.message)
|
57 |
+
jQuery("#backup_cotent_modal .progress > div").addClass("determinate").removeClass(".indeterminate").css('width', "100%")
|
58 |
+
return;
|
59 |
+
}
|
60 |
+
|
61 |
+
var files_text = [];
|
62 |
+
|
63 |
+
for(var i in response.files)
|
64 |
+
{
|
65 |
+
|
66 |
+
if(response.total_size !== undefined)
|
67 |
+
{
|
68 |
+
var percent = parseInt(response.start*100)/parseInt(response.total_size)
|
69 |
+
//jQuery("#backup_cotent_modal .progress .determinate").css('width', percent + "%")
|
70 |
+
}
|
71 |
+
|
72 |
+
$this.file_counter++
|
73 |
+
|
74 |
+
files_text[i] = "<li>"+($this.file_counter +". <span title='"+response.files[i].mtime+"'>"+response.files[i].path+"</span> ("+response.files[i].size+" bytes)")+"</li>";
|
75 |
+
}
|
76 |
+
|
77 |
+
jQuery("#backup_cotent_modal .modal-content .files-list").prepend(files_text.reverse().join("\n"));
|
78 |
+
|
79 |
+
if(!response.finished && jQuery('#backup_cotent_modal').is(':visible'))
|
80 |
+
$this.list_backup_content_callback(backup_file, response.start, response.part)
|
81 |
+
else
|
82 |
+
jQuery("#backup_cotent_modal .progress > div").addClass('determinate').removeClass(".indeterminate").css('width', "100%")
|
83 |
+
|
84 |
+
},
|
85 |
+
error: function(xhr, textStatus, error){
|
86 |
+
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(textStatus+error)
|
87 |
+
},
|
88 |
+
dataType: 'json'
|
89 |
+
});
|
90 |
+
}
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
list_backup_content(backup_file)
|
96 |
+
{
|
97 |
+
this.file_counter = 0
|
98 |
+
jQuery("#backup_cotent_modal .modal-content .files-list").text("").removeClass("error");
|
99 |
+
jQuery("#backup_cotent_modal .modal-content .backup-name").text(backup_file);
|
100 |
+
jQuery("#backup_cotent_modal").modal('open');
|
101 |
+
jQuery("#backup_cotent_modal .progress > div").removeClass('determinate').addClass("indeterminate");
|
102 |
+
|
103 |
+
this.list_backup_content_callback(backup_file)
|
104 |
+
}
|
105 |
+
|
106 |
+
cloud_upload(backup_file)
|
107 |
+
{
|
108 |
+
jQuery('#remote_storage_modal').find(".backup_name").text(backup_file)
|
109 |
+
jQuery('#remote_storage_modal').find("input.backup_name").val(backup_file)
|
110 |
+
Materialize.updateTextFields();
|
111 |
+
jQuery('select').material_select();
|
112 |
+
jQuery("#remote_storage_modal").modal('open')
|
113 |
+
jQuery("#remote_storage_modal .status").hide();
|
114 |
+
|
115 |
+
jQuery(".remote-storage-form").off("submit").on("submit",function(){
|
116 |
+
jQuery("#remote_storage_modal .status").show();
|
117 |
+
jQuery("#remote_storage_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
|
118 |
+
jQuery("#remote_storage_modal .status-text").removeClass("error").text("");
|
119 |
+
|
120 |
+
var storage_type = jQuery("#remote_storage_modal select").val();
|
121 |
+
|
122 |
+
if(backup_file)
|
123 |
+
{
|
124 |
+
jQuery.ajax({
|
125 |
+
url: ajaxurl,
|
126 |
+
method: 'post',
|
127 |
+
data: { action : 'upload_backup_to_remote', file: backup_file, storage_type: storage_type},
|
128 |
+
success: function(response){
|
129 |
+
if(response.error)
|
130 |
+
{
|
131 |
+
jQuery("#remote_storage_modal .status-text").addClass("error").text(response.message)
|
132 |
+
}else{
|
133 |
+
jQuery("#remote_storage_modal .status-text").removeClass("error").text("done")
|
134 |
+
}
|
135 |
+
|
136 |
+
jQuery("#remote_storage_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
|
137 |
+
},
|
138 |
+
error: function(xhr, textStatus, error){
|
139 |
+
jQuery("#remote_storage_modal .status-text").addClass("error").text(textStatus+error)
|
140 |
+
},
|
141 |
+
dataType: 'json'
|
142 |
+
});
|
143 |
+
}
|
144 |
+
|
145 |
+
return false;
|
146 |
+
})
|
147 |
+
}
|
148 |
+
|
149 |
+
//end class
|
150 |
+
}
|
151 |
+
|
152 |
+
jQuery(document).ready(function(){
|
153 |
+
|
154 |
+
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
155 |
+
|
156 |
+
jQuery("a.expand-multipart").on("click", function(){
|
157 |
+
jQuery(this).parent().find("ul.multipart").toggle();
|
158 |
+
jQuery(this).parent().find("a.expand-multipart.remove").toggle();
|
159 |
+
jQuery(this).parent().find("a.expand-multipart.add").toggle();
|
160 |
+
})
|
161 |
+
var dataTable = jQuery('#manage_backups').DataTable( {
|
162 |
+
'responsive': true,
|
163 |
+
'bFilter': true,
|
164 |
+
"order": [[ 2, "desc" ]],
|
165 |
+
buttons: [
|
166 |
+
'selectAll',
|
167 |
+
'selectNone'
|
168 |
+
],
|
169 |
+
"language": {
|
170 |
+
"emptyTable": "No backups available",
|
171 |
+
buttons: {
|
172 |
+
selectAll: "Select all items",
|
173 |
+
selectNone: "Select none"
|
174 |
+
}
|
175 |
+
},
|
176 |
+
columnDefs: [
|
177 |
+
{ targets: 'no-sort', orderable: false }
|
178 |
+
],
|
179 |
+
"columns": [
|
180 |
+
{ "width": "1%" },
|
181 |
+
{ "width": "25%" },
|
182 |
+
{ "width": "5%" },
|
183 |
+
{ "width": "5%" },
|
184 |
+
{ "width": "5%" },
|
185 |
+
],
|
186 |
+
"oLanguage": {
|
187 |
+
"sSearch": "",
|
188 |
+
"sSearchPlaceholder" : 'Search Backups',
|
189 |
+
} ,
|
190 |
+
"fnDrawCallback": function( oSettings ) {
|
191 |
+
|
192 |
+
jQuery(this).off("click", ".delete").on("click", ".delete", function(e){
|
193 |
+
|
194 |
+
var hash = jQuery(this).attr('href');
|
195 |
+
var id = hash.substr(1)
|
196 |
+
if(show_delete_alert && confirm('Are you sure you want to delete it?'))
|
197 |
+
var data = xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
198 |
+
else
|
199 |
+
var data = xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
200 |
+
e.preventDefault();
|
201 |
+
})
|
202 |
+
|
203 |
+
jQuery(this).off("click", ".download").on("click", ".download", function(e){
|
204 |
+
var hash = jQuery(this).attr('href');
|
205 |
+
var id = hash.substr(1)
|
206 |
+
var data = xcloner_manage_backups.download_backup_by_name(id);
|
207 |
+
e.preventDefault();
|
208 |
+
})
|
209 |
+
|
210 |
+
jQuery(this).off("click", ".cloud-upload").on("click", ".cloud-upload", function(e){
|
211 |
+
var hash = jQuery(this).attr('href');
|
212 |
+
var id = hash.substr(1)
|
213 |
+
var data = xcloner_manage_backups.cloud_upload(id);
|
214 |
+
e.preventDefault();
|
215 |
+
})
|
216 |
+
|
217 |
+
jQuery(this).off("click", ".list-backup-content").on("click", ".list-backup-content", function(e){
|
218 |
+
var hash = jQuery(this).attr('href');
|
219 |
+
var id = hash.substr(1)
|
220 |
+
var data = xcloner_manage_backups.list_backup_content(id);
|
221 |
+
e.preventDefault();
|
222 |
+
})
|
223 |
+
}
|
224 |
+
});
|
225 |
+
|
226 |
+
jQuery('#select_all').click(function () {
|
227 |
+
jQuery('input:checkbox').prop('checked', this.checked);
|
228 |
+
});
|
229 |
+
|
230 |
+
jQuery(".delete-all").click(function(){
|
231 |
+
if(confirm('Are you sure you want to delete selected items?'))
|
232 |
+
{
|
233 |
+
show_delete_alert = 0;
|
234 |
+
jQuery('input:checkbox').each(function(){
|
235 |
+
if(jQuery(this).is(":checked"))
|
236 |
+
{
|
237 |
+
jQuery(this).parent().parent().parent().find(".delete").trigger('click');
|
238 |
+
}
|
239 |
+
})
|
240 |
+
show_delete_alert = 1;
|
241 |
+
}
|
242 |
+
})
|
243 |
+
|
244 |
+
/*jQuery("#save_schedule").on("submit", function(){
|
245 |
+
|
246 |
+
xcloner_scheduler.save_schedule(jQuery(this), dataTable)
|
247 |
+
|
248 |
+
return false;
|
249 |
+
})*/
|
250 |
+
|
251 |
+
jQuery("#remote_storage_modal").modal();
|
252 |
+
|
253 |
+
|
254 |
+
var show_delete_alert=1;
|
255 |
+
|
256 |
+
|
257 |
+
});
|
admin/js/xcloner-remote-storage-class.js
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class Xcloner_Remote_Storage
|
2 |
+
{
|
3 |
+
|
4 |
+
constructor()
|
5 |
+
{
|
6 |
+
|
7 |
+
}
|
8 |
+
|
9 |
+
toggle_status(elem)
|
10 |
+
{
|
11 |
+
var field = jQuery(elem).attr("name")
|
12 |
+
var value = 0
|
13 |
+
if(jQuery(elem).is(":checked"))
|
14 |
+
value = 1;
|
15 |
+
|
16 |
+
if(field){
|
17 |
+
jQuery.ajax({
|
18 |
+
url: ajaxurl,
|
19 |
+
method: 'post',
|
20 |
+
data: { action : 'remote_storage_save_status', id: field, value: value},
|
21 |
+
success: function(response){
|
22 |
+
if(!response.finished)
|
23 |
+
alert('Error changing status')
|
24 |
+
},
|
25 |
+
dataType: 'json'
|
26 |
+
|
27 |
+
})
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
31 |
+
}
|
admin/js/xcloner-restore-class.js
ADDED
@@ -0,0 +1,827 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class Xcloner_Restore{
|
2 |
+
|
3 |
+
constructor(hash)
|
4 |
+
{
|
5 |
+
this.steps = ['restore-script-upload-step','backup-upload-step','restore-remote-backup-step','restore-remote-database-step','restore-finish-step']
|
6 |
+
this.ajaxurl = ajaxurl;
|
7 |
+
this.cancel = false;
|
8 |
+
this.upload_file_event = new Event('upload_file_event');
|
9 |
+
this.resume = new Object();
|
10 |
+
this.hash = hash;
|
11 |
+
|
12 |
+
document.addEventListener("backup_upload_finish", function (e) {
|
13 |
+
|
14 |
+
jQuery(".xcloner-restore .backup-upload-step .toggler").removeClass("cancel");
|
15 |
+
|
16 |
+
}, false);
|
17 |
+
|
18 |
+
document.addEventListener("remote_restore_backup_finish", function (e) {
|
19 |
+
|
20 |
+
jQuery(".xcloner-restore .restore-remote-backup-step .toggler").removeClass("cancel");
|
21 |
+
|
22 |
+
}, false);
|
23 |
+
|
24 |
+
document.addEventListener("remote_restore_mysql_backup_finish", function (e) {
|
25 |
+
|
26 |
+
jQuery(".xcloner-restore .restore-remote-database-step .toggler").removeClass("cancel");
|
27 |
+
|
28 |
+
}, false);
|
29 |
+
|
30 |
+
document.addEventListener("restore_script_invalid", function (e) {
|
31 |
+
|
32 |
+
jQuery(".xcloner-restore #restore_script_url").addClass("invalid").removeClass('valid');
|
33 |
+
jQuery(".xcloner-restore #validate_url .material-icons").text("error");
|
34 |
+
|
35 |
+
}, false);
|
36 |
+
|
37 |
+
document.addEventListener("restore_script_valid", function (e) {
|
38 |
+
|
39 |
+
jQuery(".xcloner-restore #validate_url .material-icons").text("check_circle");
|
40 |
+
jQuery(".xcloner-restore #restore_script_url").removeClass("invalid").addClass('valid');
|
41 |
+
|
42 |
+
}, false);
|
43 |
+
|
44 |
+
document.addEventListener("xcloner_populate_remote_backup_files_list", function (e) {
|
45 |
+
|
46 |
+
var files = e.detail.files
|
47 |
+
|
48 |
+
jQuery('.xcloner-restore #remote_backup_file').find('option').not(':first').remove();
|
49 |
+
|
50 |
+
|
51 |
+
for( var key in files)
|
52 |
+
{
|
53 |
+
if(files[key].selected)
|
54 |
+
var selected = "selected";
|
55 |
+
else
|
56 |
+
var selected = "not-selected";
|
57 |
+
|
58 |
+
jQuery('.xcloner-restore #remote_backup_file').append("<option value='"+files[key].path+"' "+selected+">"+files[key].path+"("+e.detail.$this.getSize(files[key].size)+" MB)"+"</option>").addClass("file");
|
59 |
+
}
|
60 |
+
|
61 |
+
}, false);
|
62 |
+
|
63 |
+
document.addEventListener("xcloner_populate_remote_mysqldump_files_list", function (e) {
|
64 |
+
|
65 |
+
var files = e.detail.files
|
66 |
+
|
67 |
+
jQuery('.xcloner-restore #remote_database_file').find('option').not(':first').remove();
|
68 |
+
|
69 |
+
for( var key in files)
|
70 |
+
{
|
71 |
+
if(files[key].selected)
|
72 |
+
var selected = "selected";
|
73 |
+
else
|
74 |
+
var selected = "not-selected";
|
75 |
+
|
76 |
+
var option = jQuery('.xcloner-restore #remote_database_file').append("<option value='"+files[key].path+"' "+selected+">"+files[key].path+"("+e.detail.$this.getSize(files[key].size)+" MB) "+files[key].timestamp+"</option>").addClass("file");
|
77 |
+
}
|
78 |
+
|
79 |
+
}, false);
|
80 |
+
|
81 |
+
document.addEventListener("xcloner_restore_next_step", function (e) {
|
82 |
+
|
83 |
+
if(e.detail.$this !== undefined)
|
84 |
+
{
|
85 |
+
var $this = e.detail.$this
|
86 |
+
jQuery(".xcloner-restore li."+$this.steps[$this.set_current_step]).addClass('active').show().find(".collapsible-header").trigger('click');
|
87 |
+
}
|
88 |
+
|
89 |
+
}, false);
|
90 |
+
|
91 |
+
document.addEventListener("xcloner_restore_update_progress", function (e) {
|
92 |
+
|
93 |
+
if(e.detail.percent !== undefined)
|
94 |
+
{
|
95 |
+
jQuery(".xcloner-restore .steps.active .progress").show();
|
96 |
+
|
97 |
+
if(e.detail.class == "indeterminate")
|
98 |
+
jQuery(".xcloner-restore .steps.active .progress > div").addClass(e.detail.class).removeClass('determinate')
|
99 |
+
if(e.detail.class == "determinate")
|
100 |
+
jQuery(".xcloner-restore .steps.active .progress > div").addClass(e.detail.class).removeClass('indeterminate')
|
101 |
+
|
102 |
+
if(e.detail.percent == 100)
|
103 |
+
jQuery(".xcloner-restore .steps.active .progress > div").removeClass('indeterminate').addClass('determinate').css("width", e.detail.percent+"%")
|
104 |
+
else
|
105 |
+
jQuery(".xcloner-restore .steps.active .progress .determinate").css("width", e.detail.percent+"%")
|
106 |
+
}
|
107 |
+
|
108 |
+
}, false);
|
109 |
+
|
110 |
+
|
111 |
+
document.addEventListener("xcloner_restore_display_status_text", function (e) {
|
112 |
+
|
113 |
+
if(e.detail.status === undefined)
|
114 |
+
e.detail.status = "updated";
|
115 |
+
|
116 |
+
if(e.detail.message !== undefined)
|
117 |
+
{
|
118 |
+
jQuery(".xcloner-restore .steps.active .status").html("<div class='"+e.detail.status+"'>"+e.detail.message+"</div>");
|
119 |
+
}
|
120 |
+
|
121 |
+
}, false);
|
122 |
+
|
123 |
+
document.addEventListener("xcloner_populate_remote_restore_path", function (e) {
|
124 |
+
|
125 |
+
if(e.detail.dir !== undefined)
|
126 |
+
{
|
127 |
+
if(!jQuery(".xcloner-restore #remote_restore_path").val())
|
128 |
+
jQuery(".xcloner-restore #remote_restore_path").val(e.detail.dir);
|
129 |
+
}
|
130 |
+
|
131 |
+
if(e.detail.restore_script_url !== undefined)
|
132 |
+
{
|
133 |
+
if(!jQuery(".xcloner-restore #remote_restore_url").val())
|
134 |
+
jQuery(".xcloner-restore #remote_restore_url").val(e.detail.restore_script_url);
|
135 |
+
|
136 |
+
if(!jQuery(".xcloner-restore #remote_restore_site_url").val())
|
137 |
+
jQuery(".xcloner-restore #remote_restore_site_url").val(e.detail.restore_script_url);
|
138 |
+
}
|
139 |
+
|
140 |
+
}, false);
|
141 |
+
|
142 |
+
document.addEventListener("remote_restore_update_files_list", function (e) {
|
143 |
+
|
144 |
+
if(e.detail.files !== undefined && e.detail.files.length)
|
145 |
+
{
|
146 |
+
var files_text = [];
|
147 |
+
for(var i=0; i<e.detail.files.length;i++)
|
148 |
+
{
|
149 |
+
files_text[i] = "<li>"+(e.detail.files[i])+"</li>";
|
150 |
+
}
|
151 |
+
jQuery('.xcloner-restore .restore-remote-backup-step .files-list').prepend(files_text.reverse().join("\n"));
|
152 |
+
}else{
|
153 |
+
jQuery('.xcloner-restore .restore-remote-backup-step .files-list').html("");
|
154 |
+
}
|
155 |
+
|
156 |
+
}, false);
|
157 |
+
|
158 |
+
document.addEventListener("xcloner_restore_display_query_box", function (e) {
|
159 |
+
|
160 |
+
if(e.detail.query)
|
161 |
+
{
|
162 |
+
jQuery(".xcloner-restore .query-box").show();
|
163 |
+
jQuery(".xcloner-restore .query-list").val(e.detail.query)
|
164 |
+
}else{
|
165 |
+
jQuery(".xcloner-restore .query-box").hide();
|
166 |
+
jQuery(".xcloner-restore .query-list").val("")
|
167 |
+
}
|
168 |
+
|
169 |
+
|
170 |
+
}, false);
|
171 |
+
|
172 |
+
document.addEventListener("xcloner_restore_finish", function (e) {
|
173 |
+
|
174 |
+
jQuery(".xcloner-restore #xcloner_restore_finish").show();
|
175 |
+
|
176 |
+
}, false);
|
177 |
+
|
178 |
+
|
179 |
+
}
|
180 |
+
|
181 |
+
get_remote_backup_files_callback(response, status, params = new Object())
|
182 |
+
{
|
183 |
+
if(status)
|
184 |
+
{
|
185 |
+
var files = response.statusText.files;
|
186 |
+
document.dispatchEvent(new CustomEvent("xcloner_populate_remote_backup_files_list", {detail: {files: files, $this: this }}));
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
get_remote_backup_files()
|
191 |
+
{
|
192 |
+
this.ajaxurl = this.restore_script_url;
|
193 |
+
this.set_cancel(false);
|
194 |
+
|
195 |
+
var params = new Object()
|
196 |
+
params.local_backup_file = jQuery(".xcloner-restore .backup-upload-step #backup_file").val();
|
197 |
+
|
198 |
+
this.do_ajax('get_remote_backup_files_callback', 'list_backup_archives', params)
|
199 |
+
|
200 |
+
this.get_remote_restore_path_default()
|
201 |
+
}
|
202 |
+
|
203 |
+
get_remote_mysqldump_files_callback(response, status, params = new Object())
|
204 |
+
{
|
205 |
+
|
206 |
+
if(status)
|
207 |
+
{
|
208 |
+
var files = response.statusText.files;
|
209 |
+
document.dispatchEvent(new CustomEvent("xcloner_populate_remote_mysqldump_files_list", {detail: {files: files, $this: this }}));
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
get_remote_mysqldump_files()
|
214 |
+
{
|
215 |
+
this.ajaxurl = this.restore_script_url;
|
216 |
+
this.set_cancel(false);
|
217 |
+
|
218 |
+
|
219 |
+
if(this.resume.callback == "get_remote_mysqldump_files_callback")
|
220 |
+
{
|
221 |
+
console.log("do resume");
|
222 |
+
this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
|
223 |
+
this.resume = new Object();
|
224 |
+
return;
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
var params = new Object()
|
229 |
+
params.backup_file = this.get_backup_file()
|
230 |
+
params.remote_path = this.get_remote_path()
|
231 |
+
|
232 |
+
//console.log(params)
|
233 |
+
|
234 |
+
this.do_ajax('get_remote_mysqldump_files_callback', 'list_mysqldump_backups', params)
|
235 |
+
|
236 |
+
}
|
237 |
+
|
238 |
+
get_backup_file()
|
239 |
+
{
|
240 |
+
return jQuery(".xcloner-restore #remote_backup_file").val()
|
241 |
+
}
|
242 |
+
|
243 |
+
get_remote_path()
|
244 |
+
{
|
245 |
+
return jQuery(".xcloner-restore #remote_restore_path").val()
|
246 |
+
}
|
247 |
+
|
248 |
+
get_remote_restore_path_default_callback(response, status, params = new Object())
|
249 |
+
{
|
250 |
+
if(status)
|
251 |
+
{
|
252 |
+
document.dispatchEvent(new CustomEvent("xcloner_populate_remote_restore_path", {detail: {dir: response.statusText.dir, restore_script_url: response.statusText.restore_script_url, $this: this }}))
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
get_remote_restore_path_default()
|
257 |
+
{
|
258 |
+
this.ajaxurl = this.restore_script_url;
|
259 |
+
this.set_cancel(false);
|
260 |
+
|
261 |
+
var params = new Object()
|
262 |
+
|
263 |
+
params.restore_script_url = this.restore_script_url;
|
264 |
+
|
265 |
+
this.do_ajax('get_remote_restore_path_default_callback', 'get_current_directory', params)
|
266 |
+
}
|
267 |
+
|
268 |
+
remote_restore_backup_file_callback(response, status, params = new Object())
|
269 |
+
{
|
270 |
+
|
271 |
+
if(!status)
|
272 |
+
{
|
273 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText }}));
|
274 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
275 |
+
document.dispatchEvent(new CustomEvent("remote_restore_backup_finish"));
|
276 |
+
return;
|
277 |
+
}
|
278 |
+
|
279 |
+
var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
|
280 |
+
|
281 |
+
if(response.statusText.extracted_files)
|
282 |
+
{
|
283 |
+
//console.log(response.statusText.extracted_files);
|
284 |
+
document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: response.statusText.extracted_files}}));
|
285 |
+
}
|
286 |
+
|
287 |
+
if(!response.statusText.finished)
|
288 |
+
{
|
289 |
+
params.start = response.statusText.start
|
290 |
+
params.part = response.statusText.part
|
291 |
+
params.processed = response.statusText.processed
|
292 |
+
|
293 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: 'Processing <strong>'+response.statusText.backup_file+'</strong>- wrote '+this.getSize(processed, 1024)+" KB to disk"}}));
|
294 |
+
|
295 |
+
this.do_ajax('remote_restore_backup_file_callback', 'restore_backup_to_path', params)
|
296 |
+
return
|
297 |
+
}
|
298 |
+
|
299 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
300 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done restoring <strong>"+ response.statusText.backup_file +"</strong>."}}));
|
301 |
+
document.dispatchEvent(new CustomEvent("remote_restore_backup_finish"));
|
302 |
+
this.cancel = false;
|
303 |
+
}
|
304 |
+
|
305 |
+
remote_restore_backup_file(backup_file, remote_path)
|
306 |
+
{
|
307 |
+
this.ajaxurl = this.restore_script_url;
|
308 |
+
this.set_cancel(false);
|
309 |
+
|
310 |
+
var params = new Object()
|
311 |
+
params.backup_file = backup_file
|
312 |
+
params.remote_path = remote_path
|
313 |
+
|
314 |
+
if(this.resume.callback == "remote_restore_backup_file_callback")
|
315 |
+
{
|
316 |
+
console.log("do resume");
|
317 |
+
this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
|
318 |
+
this.resume = new Object();
|
319 |
+
return;
|
320 |
+
}
|
321 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'indeterminate' }}));
|
322 |
+
document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: ""}}));
|
323 |
+
|
324 |
+
this.do_ajax('remote_restore_backup_file_callback', 'restore_backup_to_path', params)
|
325 |
+
}
|
326 |
+
|
327 |
+
remote_restore_mysql_backup_file_callback(response, status, params = new Object())
|
328 |
+
{
|
329 |
+
//var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
|
330 |
+
|
331 |
+
if(!status)
|
332 |
+
{
|
333 |
+
this.start = response.statusText.start;
|
334 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: response.statusText.query }}));
|
335 |
+
|
336 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText.message }}));
|
337 |
+
//document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
338 |
+
document.dispatchEvent(new CustomEvent("remote_restore_mysql_backup_finish"));
|
339 |
+
return;
|
340 |
+
}
|
341 |
+
|
342 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: "" }}));
|
343 |
+
params.query = "";
|
344 |
+
|
345 |
+
var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
|
346 |
+
|
347 |
+
if(response.statusText.extracted_files)
|
348 |
+
{
|
349 |
+
//console.log(response.statusText.extracted_files);
|
350 |
+
//document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: response.statusText.extracted_files}}));
|
351 |
+
}
|
352 |
+
|
353 |
+
if(!response.statusText.finished)
|
354 |
+
{
|
355 |
+
params.start = response.statusText.start
|
356 |
+
params.processed = response.statusText.processed
|
357 |
+
|
358 |
+
var percent = 0;
|
359 |
+
|
360 |
+
if(response.statusText.backup_size)
|
361 |
+
percent = (100*parseInt(response.statusText.start))/parseInt(response.statusText.backup_size);
|
362 |
+
|
363 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: 'Processing <strong>'+response.statusText.backup_file+'</strong>- wrote '+this.getSize(response.statusText.start, 1024)+" KB of data"}}));
|
364 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: percent }}));
|
365 |
+
|
366 |
+
this.do_ajax('remote_restore_mysql_backup_file_callback', 'restore_mysql_backup', params)
|
367 |
+
return
|
368 |
+
}
|
369 |
+
|
370 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
371 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done restoring <strong>"+ response.statusText.backup_file +"</strong>."}}));
|
372 |
+
document.dispatchEvent(new CustomEvent("remote_restore_mysql_backup_finish"));
|
373 |
+
this.cancel = false;
|
374 |
+
|
375 |
+
}
|
376 |
+
|
377 |
+
remote_restore_mysql_backup_file(mysqldump_file)
|
378 |
+
{
|
379 |
+
this.ajaxurl = this.restore_script_url;
|
380 |
+
this.set_cancel(false);
|
381 |
+
|
382 |
+
var params = new Object()
|
383 |
+
|
384 |
+
params.remote_mysql_host = jQuery(".xcloner-restore #remote_mysql_host").val();
|
385 |
+
params.remote_mysql_db = jQuery(".xcloner-restore #remote_mysql_db").val();
|
386 |
+
params.remote_mysql_user = jQuery(".xcloner-restore #remote_mysql_user").val();
|
387 |
+
params.remote_mysql_pass = jQuery(".xcloner-restore #remote_mysql_pass").val();
|
388 |
+
params.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
|
389 |
+
|
390 |
+
params.wp_home_url = jQuery(".xcloner-restore #wp_home_url").val();
|
391 |
+
params.remote_restore_url = jQuery(".xcloner-restore #remote_restore_url").val();
|
392 |
+
|
393 |
+
if(jQuery(".xcloner-restore #wp_site_url").length)
|
394 |
+
{
|
395 |
+
params.wp_site_url = jQuery(".xcloner-restore #wp_site_url").val();
|
396 |
+
params.restore_site_url = jQuery(".xcloner-restore #remote_restore_site_url").val();
|
397 |
+
}
|
398 |
+
|
399 |
+
//console.log(params)
|
400 |
+
|
401 |
+
params.mysqldump_file = mysqldump_file
|
402 |
+
params.query = ""
|
403 |
+
params.start = 0
|
404 |
+
|
405 |
+
if(jQuery(".xcloner-restore .query-box .query-list").val())
|
406 |
+
{
|
407 |
+
params.query = jQuery(".xcloner-restore .query-box .query-list").val();
|
408 |
+
params.start = this.start
|
409 |
+
}
|
410 |
+
|
411 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: "" }}));
|
412 |
+
|
413 |
+
if(this.resume.callback == "remote_restore_mysql_backup_file_callback")
|
414 |
+
{
|
415 |
+
console.log("do resume mysql backup restore");
|
416 |
+
this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
|
417 |
+
this.resume = new Object();
|
418 |
+
return;
|
419 |
+
}
|
420 |
+
|
421 |
+
this.do_ajax('remote_restore_mysql_backup_file_callback', 'restore_mysql_backup', params)
|
422 |
+
}
|
423 |
+
|
424 |
+
restore_finish_callback(response, status, params = new Object())
|
425 |
+
{
|
426 |
+
if(status)
|
427 |
+
{
|
428 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: response.statusText, $this: this }}))
|
429 |
+
}else{
|
430 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: "error", message: response.statusText, $this: this }}))
|
431 |
+
return false;
|
432 |
+
}
|
433 |
+
|
434 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_finish", {detail: {message: response.statusText, $this: this }}))
|
435 |
+
}
|
436 |
+
|
437 |
+
restore_finish()
|
438 |
+
{
|
439 |
+
this.ajaxurl = this.restore_script_url;
|
440 |
+
this.set_cancel(false);
|
441 |
+
|
442 |
+
var params = new Object()
|
443 |
+
|
444 |
+
params.remote_mysql_host = jQuery(".xcloner-restore #remote_mysql_host").val();
|
445 |
+
params.remote_mysql_db = jQuery(".xcloner-restore #remote_mysql_db").val();
|
446 |
+
params.remote_mysql_user = jQuery(".xcloner-restore #remote_mysql_user").val();
|
447 |
+
params.remote_mysql_pass = jQuery(".xcloner-restore #remote_mysql_pass").val();
|
448 |
+
params.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
|
449 |
+
params.remote_restore_url = jQuery(".xcloner-restore #remote_restore_url").val();
|
450 |
+
|
451 |
+
params.delete_backup_temporary_folder = 0;
|
452 |
+
params.delete_restore_script = 0;
|
453 |
+
params.update_remote_site_url = 0;
|
454 |
+
|
455 |
+
if(jQuery(".xcloner-restore #delete_backup_temporary_folder").is(":checked"))
|
456 |
+
params.delete_backup_temporary_folder = 1;
|
457 |
+
if(jQuery(".xcloner-restore #delete_restore_script").is(":checked"))
|
458 |
+
params.delete_restore_script = 1;
|
459 |
+
if(jQuery(".xcloner-restore #update_remote_site_url").is(":checked"))
|
460 |
+
params.update_remote_site_url = 1;
|
461 |
+
|
462 |
+
this.do_ajax('restore_finish_callback', 'restore_finish', params)
|
463 |
+
|
464 |
+
}
|
465 |
+
|
466 |
+
upload_backup_file(file)
|
467 |
+
{
|
468 |
+
this.ajaxurl = ajaxurl;
|
469 |
+
var params = new Object()
|
470 |
+
this.set_cancel(false);
|
471 |
+
|
472 |
+
if(this.resume.callback == "upload_backup_file_callback")
|
473 |
+
{
|
474 |
+
this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
|
475 |
+
this.resume = new Object();
|
476 |
+
return;
|
477 |
+
}
|
478 |
+
|
479 |
+
params.file = file;
|
480 |
+
params.start = 0;
|
481 |
+
params.target_url = this.restore_script_url
|
482 |
+
|
483 |
+
document.dispatchEvent(new CustomEvent("backup_upload_start"));
|
484 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Uploading backup 0%" }}));
|
485 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
|
486 |
+
|
487 |
+
this.do_ajax('upload_backup_file_callback', 'restore_upload_backup', params)
|
488 |
+
}
|
489 |
+
|
490 |
+
|
491 |
+
upload_backup_file_callback(response, status, params = new Object())
|
492 |
+
{
|
493 |
+
if(!status)
|
494 |
+
{
|
495 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText }}));
|
496 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
497 |
+
return;
|
498 |
+
}
|
499 |
+
|
500 |
+
if(response && (response.start !== false || response.part<response.total_parts))
|
501 |
+
{
|
502 |
+
var percent = 0;
|
503 |
+
if(response.total_size)
|
504 |
+
{
|
505 |
+
if(!response.start)
|
506 |
+
response.start = 0;
|
507 |
+
var size = parseInt(response.start)+parseInt(response.uploaded_size)
|
508 |
+
percent = (100*parseInt(size))/parseInt(response.total_size)
|
509 |
+
}
|
510 |
+
|
511 |
+
var part_text = "";
|
512 |
+
if(response.part > 0)
|
513 |
+
part_text = "part "+response.part+" - ";
|
514 |
+
|
515 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: percent }}));
|
516 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Uploading backup "+part_text+parseFloat(percent).toFixed(2)+"%" }}));
|
517 |
+
|
518 |
+
params.start = response.start;
|
519 |
+
params.part = response.part;
|
520 |
+
params.uploaded_size = response.uploaded_size;
|
521 |
+
this.do_ajax('upload_backup_file_callback', 'restore_upload_backup', params)
|
522 |
+
}
|
523 |
+
else
|
524 |
+
{
|
525 |
+
this.cancel = false
|
526 |
+
document.dispatchEvent(new CustomEvent("backup_upload_finish"));
|
527 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
528 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done." }}));
|
529 |
+
}
|
530 |
+
}
|
531 |
+
|
532 |
+
verify_restore_url(response, status, params = new Object())
|
533 |
+
{
|
534 |
+
this.ajaxurl = this.restore_script_url;
|
535 |
+
|
536 |
+
jQuery(".xcloner-restore #xcloner_restore_finish").hide();
|
537 |
+
|
538 |
+
if(!response)
|
539 |
+
{
|
540 |
+
this.cancel = false;
|
541 |
+
this.set_current_step = 0
|
542 |
+
this.do_ajax("verify_restore_url");
|
543 |
+
}else{
|
544 |
+
|
545 |
+
if(!status)
|
546 |
+
{
|
547 |
+
document.dispatchEvent(new CustomEvent("restore_script_invalid"));
|
548 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status:'error', message: response.status+" "+response.statusText }}));
|
549 |
+
//document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
|
550 |
+
|
551 |
+
}else{
|
552 |
+
|
553 |
+
document.dispatchEvent(new CustomEvent("restore_script_valid"));
|
554 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Validation ok." }}));
|
555 |
+
|
556 |
+
this.next_step();
|
557 |
+
}
|
558 |
+
}
|
559 |
+
}
|
560 |
+
|
561 |
+
next_step()
|
562 |
+
{
|
563 |
+
this.set_current_step = jQuery(".xcloner-restore li.active").attr("data-step");
|
564 |
+
|
565 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_next_step", {detail: {$this: this}}));
|
566 |
+
|
567 |
+
}
|
568 |
+
|
569 |
+
init_resume()
|
570 |
+
{
|
571 |
+
this.resume = new Object()
|
572 |
+
if(jQuery(".xcloner-restore .steps.active .progress").is(":visible"))
|
573 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
|
574 |
+
if(jQuery(".xcloner-restore .steps.active .status").html())
|
575 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: ""}}));
|
576 |
+
document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: ""}}));
|
577 |
+
}
|
578 |
+
|
579 |
+
do_ajax(callback, action="", params= new Object())
|
580 |
+
{
|
581 |
+
params.action = action
|
582 |
+
params.hash = this.hash
|
583 |
+
params.API_ID = ID()
|
584 |
+
|
585 |
+
if(this.cancel == true)
|
586 |
+
{
|
587 |
+
this.resume.callback = callback
|
588 |
+
this.resume.action = action
|
589 |
+
this.resume.params = params
|
590 |
+
|
591 |
+
//this.request.abort();
|
592 |
+
|
593 |
+
return;
|
594 |
+
}
|
595 |
+
|
596 |
+
if(!this.restore_script_url)
|
597 |
+
return false;
|
598 |
+
|
599 |
+
var $this = this;
|
600 |
+
|
601 |
+
jQuery(".xcloner-restore .steps.active").addClass("active_status");
|
602 |
+
|
603 |
+
this.request = jQuery.ajax({
|
604 |
+
url: this.ajaxurl,
|
605 |
+
dataType: 'json',
|
606 |
+
type: 'POST',
|
607 |
+
data: params,
|
608 |
+
error: function(xhr, status, error) {
|
609 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: xhr.status+" "+xhr.statusText}}));
|
610 |
+
$this[callback](xhr, false);
|
611 |
+
}
|
612 |
+
}).done(function(json) {
|
613 |
+
|
614 |
+
if(json.status != 200){
|
615 |
+
if(json.error)
|
616 |
+
{
|
617 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: json.message}}));
|
618 |
+
}
|
619 |
+
else
|
620 |
+
{
|
621 |
+
$this[callback](json, false, params);
|
622 |
+
}
|
623 |
+
|
624 |
+
return;
|
625 |
+
}
|
626 |
+
$this[callback](json, true, params);
|
627 |
+
});
|
628 |
+
}
|
629 |
+
|
630 |
+
|
631 |
+
set_restore_script_url(url)
|
632 |
+
{
|
633 |
+
this.restore_script_url = url;
|
634 |
+
}
|
635 |
+
|
636 |
+
set_current_step(id)
|
637 |
+
{
|
638 |
+
this.set_current_step = id;
|
639 |
+
}
|
640 |
+
|
641 |
+
set_cancel(status)
|
642 |
+
{
|
643 |
+
if(status)
|
644 |
+
{
|
645 |
+
//document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {append : true, message: "Cancelled" }}));
|
646 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
|
647 |
+
|
648 |
+
}
|
649 |
+
|
650 |
+
this.cancel = status
|
651 |
+
}
|
652 |
+
|
653 |
+
get_cancel(status)
|
654 |
+
{
|
655 |
+
return this.cancel
|
656 |
+
}
|
657 |
+
|
658 |
+
getSize(bytes, conv = 1024*1024)
|
659 |
+
{
|
660 |
+
return (bytes/conv).toFixed(2);
|
661 |
+
}
|
662 |
+
|
663 |
+
|
664 |
+
}
|
665 |
+
|
666 |
+
var xcloner_auth_key = "";
|
667 |
+
|
668 |
+
jQuery(document).ready(function(){
|
669 |
+
|
670 |
+
var xcloner_restore = new Xcloner_Restore(xcloner_auth_key);
|
671 |
+
|
672 |
+
xcloner_restore.set_current_step(0);
|
673 |
+
|
674 |
+
jQuery('select').material_select();
|
675 |
+
|
676 |
+
jQuery(".xcloner-restore .upload-backup.cancel").on("click", function(){
|
677 |
+
//jQuery(".xcloner-restore #upload_backup").show();
|
678 |
+
//jQuery(this).hide();
|
679 |
+
xcloner_restore.set_cancel(true);
|
680 |
+
})
|
681 |
+
|
682 |
+
jQuery(".xcloner-restore .upload-backup").on("click",function(){
|
683 |
+
|
684 |
+
if(jQuery(this).hasClass('cancel'))
|
685 |
+
xcloner_restore.set_cancel(true);
|
686 |
+
else
|
687 |
+
xcloner_restore.set_cancel(false);
|
688 |
+
|
689 |
+
var backup_file = jQuery(".xcloner-restore #backup_file").val();
|
690 |
+
|
691 |
+
if(backup_file)
|
692 |
+
{
|
693 |
+
jQuery(this).parent().toggleClass("cancel")
|
694 |
+
|
695 |
+
if(!xcloner_restore.get_cancel())
|
696 |
+
xcloner_restore.upload_backup_file(backup_file);
|
697 |
+
}else{
|
698 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a backup file from the list above" }}));
|
699 |
+
|
700 |
+
}
|
701 |
+
})
|
702 |
+
|
703 |
+
jQuery(".xcloner-restore #validate_url").on("click", function(){
|
704 |
+
|
705 |
+
xcloner_restore.set_restore_script_url(jQuery(".xcloner-restore #restore_script_url").val());
|
706 |
+
xcloner_restore.verify_restore_url();
|
707 |
+
|
708 |
+
})
|
709 |
+
|
710 |
+
jQuery(".xcloner-restore #skip_upload_backup").on("click", function(){
|
711 |
+
|
712 |
+
xcloner_restore.set_cancel(true);
|
713 |
+
xcloner_restore.next_step();
|
714 |
+
|
715 |
+
})
|
716 |
+
|
717 |
+
jQuery(".xcloner-restore #skip_restore_remote_database_step").on("click", function(){
|
718 |
+
|
719 |
+
xcloner_restore.set_cancel(true);
|
720 |
+
xcloner_restore.next_step();
|
721 |
+
|
722 |
+
})
|
723 |
+
|
724 |
+
jQuery(".xcloner-restore li.steps").on("click", function(){
|
725 |
+
xcloner_restore.set_current_step = (jQuery(this).attr("data-step")-1)
|
726 |
+
})
|
727 |
+
|
728 |
+
jQuery(".xcloner-restore #skip_remote_backup_step").on("click", function(){
|
729 |
+
xcloner_restore.set_cancel(true);
|
730 |
+
xcloner_restore.next_step();
|
731 |
+
})
|
732 |
+
|
733 |
+
jQuery(".xcloner-restore .restore-remote-backup-step .collapsible-header").click(function(){
|
734 |
+
xcloner_restore.get_remote_backup_files();
|
735 |
+
})
|
736 |
+
|
737 |
+
jQuery(".xcloner-restore .restore-remote-database-step .collapsible-header").click(function(){
|
738 |
+
xcloner_restore.get_remote_mysqldump_files();
|
739 |
+
})
|
740 |
+
|
741 |
+
jQuery(".xcloner-restore #remote_backup_file").on("change", function(){
|
742 |
+
xcloner_restore.init_resume()
|
743 |
+
})
|
744 |
+
|
745 |
+
jQuery(".xcloner-restore #backup_file").on("change", function(){
|
746 |
+
xcloner_restore.init_resume()
|
747 |
+
})
|
748 |
+
|
749 |
+
jQuery(".xcloner-restore #restore_finish").click(function(){
|
750 |
+
xcloner_restore.restore_finish();
|
751 |
+
})
|
752 |
+
|
753 |
+
jQuery(".xcloner-restore #refresh_remote_backup_file").on("click", function(e){
|
754 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
|
755 |
+
xcloner_restore.resume = new Object();
|
756 |
+
xcloner_restore.get_remote_backup_files();
|
757 |
+
e.stopPropagation();
|
758 |
+
})
|
759 |
+
|
760 |
+
jQuery(".xcloner-restore #refresh_database_file").on("click", function(e){
|
761 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
|
762 |
+
xcloner_restore.resume = new Object();
|
763 |
+
xcloner_restore.get_remote_mysqldump_files();
|
764 |
+
e.stopPropagation();
|
765 |
+
})
|
766 |
+
|
767 |
+
jQuery(".xcloner-restore #toggle_file_restore_display").on("click", function(){
|
768 |
+
jQuery(".xcloner-restore .restore-remote-backup-step .files-list").toggle();
|
769 |
+
})
|
770 |
+
|
771 |
+
jQuery(".xcloner-restore .restore_remote_mysqldump").on("click", function(e){
|
772 |
+
if(jQuery(this).hasClass('cancel'))
|
773 |
+
xcloner_restore.set_cancel(true);
|
774 |
+
else
|
775 |
+
xcloner_restore.set_cancel(false);
|
776 |
+
|
777 |
+
this.remote_database_file = jQuery(".xcloner-restore #remote_database_file").val();
|
778 |
+
|
779 |
+
if(!this.remote_database_file)
|
780 |
+
{
|
781 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a mysqld backup file from the list" }}));
|
782 |
+
return;
|
783 |
+
}
|
784 |
+
|
785 |
+
jQuery(this).parent().toggleClass("cancel")
|
786 |
+
|
787 |
+
if(!xcloner_restore.get_cancel())
|
788 |
+
{
|
789 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
|
790 |
+
xcloner_restore.remote_restore_mysql_backup_file(this.remote_database_file);
|
791 |
+
}
|
792 |
+
|
793 |
+
})
|
794 |
+
|
795 |
+
jQuery(".xcloner-restore .restore-remote-backup-step .restore_remote_backup").click(function(){
|
796 |
+
if(jQuery(this).hasClass('cancel'))
|
797 |
+
xcloner_restore.set_cancel(true);
|
798 |
+
else
|
799 |
+
xcloner_restore.set_cancel(false);
|
800 |
+
|
801 |
+
this.backup_file = jQuery(".xcloner-restore #remote_backup_file").val();
|
802 |
+
|
803 |
+
if(!this.backup_file)
|
804 |
+
{
|
805 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a backup file from the list above" }}));
|
806 |
+
return;
|
807 |
+
}
|
808 |
+
|
809 |
+
this.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
|
810 |
+
|
811 |
+
if(!this.remote_path)
|
812 |
+
{
|
813 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please enter the remote restore path" }}));
|
814 |
+
return;
|
815 |
+
}
|
816 |
+
|
817 |
+
jQuery(this).parent().toggleClass("cancel")
|
818 |
+
|
819 |
+
if(!xcloner_restore.get_cancel())
|
820 |
+
{
|
821 |
+
document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'indeterminate' }}));
|
822 |
+
xcloner_restore.remote_restore_backup_file(this.backup_file, this.remote_path);
|
823 |
+
}
|
824 |
+
|
825 |
+
})
|
826 |
+
|
827 |
+
})
|
admin/js/xcloner-scheduler-class.js
ADDED
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function(){
|
2 |
+
|
3 |
+
class Xcloner_Scheduler{
|
4 |
+
|
5 |
+
constructor()
|
6 |
+
{
|
7 |
+
this.edit_modal = jQuery('.modal').modal();
|
8 |
+
}
|
9 |
+
|
10 |
+
get_form_params()
|
11 |
+
{
|
12 |
+
|
13 |
+
}
|
14 |
+
|
15 |
+
get_schedule_by_id(id)
|
16 |
+
{
|
17 |
+
var $this = this
|
18 |
+
|
19 |
+
if(id){
|
20 |
+
jQuery.ajax({
|
21 |
+
url: ajaxurl,
|
22 |
+
data: { action : 'get_schedule_by_id', id: id},
|
23 |
+
success: function(response){
|
24 |
+
if(response.id == id)
|
25 |
+
$this.create_modal(response)
|
26 |
+
},
|
27 |
+
dataType: 'json'
|
28 |
+
});
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
delete_schedule_by_id(id, elem, dataTable)
|
33 |
+
{
|
34 |
+
var $this = this
|
35 |
+
|
36 |
+
if(id){
|
37 |
+
jQuery.ajax({
|
38 |
+
url: ajaxurl,
|
39 |
+
data: { action : 'delete_schedule_by_id', id: id},
|
40 |
+
success: function(response){
|
41 |
+
//window.location = "";
|
42 |
+
//alert("Schedule deleted");
|
43 |
+
dataTable
|
44 |
+
.row( jQuery(elem).parents('tr') )
|
45 |
+
.remove()
|
46 |
+
.draw();
|
47 |
+
},
|
48 |
+
dataType: 'json'
|
49 |
+
});
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
create_modal(response)
|
54 |
+
{
|
55 |
+
this.edit_modal.find("#schedule_id").text(response.id)
|
56 |
+
|
57 |
+
if(response.status == 1)
|
58 |
+
this.edit_modal.find("#status").attr("checked", "checked");
|
59 |
+
else
|
60 |
+
this.edit_modal.find("#status").removeAttr("checked");
|
61 |
+
|
62 |
+
this.edit_modal.find("#schedule_id").text(response.id)
|
63 |
+
this.edit_modal.find("#schedule_id_hidden").val(response.id)
|
64 |
+
this.edit_modal.find("#schedule_name").val(response.name)
|
65 |
+
this.edit_modal.find("#backup_name").val(response.backup_params.backup_name)
|
66 |
+
this.edit_modal.find("#email_notification").val(response.backup_params.email_notification)
|
67 |
+
this.edit_modal.find('#schedule_frequency>option[value="' + response.recurrence + '"]').prop('selected', true);
|
68 |
+
this.edit_modal.find('#schedule_storage>option[value="' + response.remote_storage + '"]').prop('selected', true);
|
69 |
+
//var date = new Date(response.start_at);
|
70 |
+
this.edit_modal.find("#schedule_start_date").val(response.start_at)
|
71 |
+
|
72 |
+
var tables = jQuery.parseJSON(response.table_params)
|
73 |
+
|
74 |
+
var tables_list = "";
|
75 |
+
|
76 |
+
for(var db in tables)
|
77 |
+
{
|
78 |
+
for(var i in tables[db])
|
79 |
+
tables_list += db+"."+tables[db][i]+"\n";
|
80 |
+
}
|
81 |
+
|
82 |
+
this.edit_modal.find("#table_params").val(tables_list)
|
83 |
+
|
84 |
+
var files = jQuery.parseJSON(response.excluded_files)
|
85 |
+
var exclude_files_list = "";
|
86 |
+
for(var i in files)
|
87 |
+
{
|
88 |
+
exclude_files_list += files[i]+"\n";
|
89 |
+
|
90 |
+
}
|
91 |
+
|
92 |
+
this.edit_modal.find("#excluded_files").val(exclude_files_list)
|
93 |
+
|
94 |
+
jQuery('select').material_select();
|
95 |
+
|
96 |
+
Materialize.updateTextFields();
|
97 |
+
|
98 |
+
this.edit_modal.modal('open');
|
99 |
+
}
|
100 |
+
|
101 |
+
save_schedule(form, dataTable)
|
102 |
+
{
|
103 |
+
/*if(!this.IsJsonString(jQuery("#table_params").val()) )
|
104 |
+
{
|
105 |
+
//alert("Database field is not a valid json data!");
|
106 |
+
//return false;
|
107 |
+
}
|
108 |
+
|
109 |
+
if(!this.IsJsonString(jQuery("#excluded_files").val()) )
|
110 |
+
{
|
111 |
+
alert("Exclude files field is not a valid json data!");
|
112 |
+
return false;
|
113 |
+
}*/
|
114 |
+
|
115 |
+
var data = jQuery(form).serialize();
|
116 |
+
var $this = this
|
117 |
+
|
118 |
+
jQuery.ajax({
|
119 |
+
url: ajaxurl,
|
120 |
+
dataType: 'json',
|
121 |
+
type: 'POST',
|
122 |
+
data: data,
|
123 |
+
error: function(err) {
|
124 |
+
//show_ajax_error("Communication Error", "", err)
|
125 |
+
//console.log(err);
|
126 |
+
alert("Error saving schedule!");
|
127 |
+
}
|
128 |
+
}).done(function(json) {
|
129 |
+
|
130 |
+
if(json.error !== undefined){
|
131 |
+
alert("Error saving schedule!"+json.error);
|
132 |
+
return;
|
133 |
+
}
|
134 |
+
|
135 |
+
$this.edit_modal.modal('close');
|
136 |
+
//location.reload();
|
137 |
+
dataTable.ajax.reload();
|
138 |
+
|
139 |
+
});
|
140 |
+
|
141 |
+
}
|
142 |
+
|
143 |
+
IsJsonString(str) {
|
144 |
+
try {
|
145 |
+
JSON.parse(str);
|
146 |
+
} catch (e) {
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
return true;
|
150 |
+
}
|
151 |
+
|
152 |
+
//end class
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
var xcloner_scheduler = new Xcloner_Scheduler();
|
157 |
+
|
158 |
+
jQuery("select[required]").css({display: "block", height: 0, padding: 0, width: 0, position: 'absolute'});
|
159 |
+
|
160 |
+
dataTable = jQuery('#scheduled_backups').DataTable( {
|
161 |
+
'responsive': true,
|
162 |
+
'bFilter': false,
|
163 |
+
"order": [[ 3, "desc" ]],
|
164 |
+
buttons: [
|
165 |
+
'selectAll',
|
166 |
+
'selectNone'
|
167 |
+
],
|
168 |
+
"language": {
|
169 |
+
"emptyTable": "No schedules available"
|
170 |
+
},
|
171 |
+
columnDefs: [
|
172 |
+
{ targets: 'no-sort', orderable: false },
|
173 |
+
{ className: "hide-on-med-and-down", "targets": [ 3, 5 ] }
|
174 |
+
],
|
175 |
+
language: {
|
176 |
+
buttons: {
|
177 |
+
selectAll: "Select all items",
|
178 |
+
selectNone: "Select none"
|
179 |
+
}
|
180 |
+
},
|
181 |
+
"ajax": ajaxurl+"?action=get_scheduler_list",
|
182 |
+
"fnDrawCallback": function( oSettings ) {
|
183 |
+
//jQuery("#scheduled_backups").find(".edit").each(function(){
|
184 |
+
jQuery(this).off("click", ".edit").on("click", ".edit",function(){
|
185 |
+
var hash = jQuery(this).attr('href');
|
186 |
+
var id = hash.substr(1)
|
187 |
+
var data = xcloner_scheduler.get_schedule_by_id(id);
|
188 |
+
})
|
189 |
+
//})
|
190 |
+
|
191 |
+
//jQuery("#scheduled_backups").find(".delete").each(function(){
|
192 |
+
jQuery(this).off("click", ".delete").on("click", ".delete", function(){
|
193 |
+
var hash = jQuery(this).attr('href');
|
194 |
+
var id = hash.substr(1)
|
195 |
+
if(confirm('Are you sure you want to delete it?'))
|
196 |
+
var data = xcloner_scheduler.delete_schedule_by_id(id, (this), dataTable);
|
197 |
+
})
|
198 |
+
//})
|
199 |
+
|
200 |
+
jQuery("span.shorten_string").each(function(){
|
201 |
+
doShortText(jQuery(this));
|
202 |
+
})
|
203 |
+
jQuery("span.shorten_string").click(function(){
|
204 |
+
jQuery(this).toggleClass("full");
|
205 |
+
doShortText(jQuery(this));
|
206 |
+
})
|
207 |
+
|
208 |
+
}
|
209 |
+
});
|
210 |
+
|
211 |
+
jQuery("#save_schedule").on("submit", function(){
|
212 |
+
|
213 |
+
xcloner_scheduler.save_schedule(jQuery(this), dataTable)
|
214 |
+
|
215 |
+
return false;
|
216 |
+
})
|
217 |
+
|
218 |
+
jQuery('.timepicker').pickatime({
|
219 |
+
default: 'now',
|
220 |
+
min: [7,30],
|
221 |
+
twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
|
222 |
+
donetext: 'OK',
|
223 |
+
autoclose: false,
|
224 |
+
vibrate: true // vibrate the device when dragging clock hand
|
225 |
+
});
|
226 |
+
|
227 |
+
var date_picker = jQuery('.datepicker').pickadate({
|
228 |
+
format: 'd mmmm yyyy',
|
229 |
+
selectMonths: true, // Creates a dropdown to control month
|
230 |
+
selectYears: 15, // Creates a dropdown of 15 years to control year
|
231 |
+
min: +0.1,
|
232 |
+
onSet: function() {
|
233 |
+
//this.close();
|
234 |
+
}
|
235 |
+
});
|
236 |
+
|
237 |
+
});
|
admin/partials/xcloner_console_page.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$xcloner_settings = new Xcloner_Settings();
|
4 |
+
$logger = new Xcloner_Logger();
|
5 |
+
|
6 |
+
|
7 |
+
$xcloner_scheduler = new Xcloner_Scheduler();
|
8 |
+
//$xcloner_scheduler->xcloner_scheduler_callback(90);
|
9 |
+
|
10 |
+
//$logger_content = $logger->getLastDebugLines();
|
11 |
+
|
12 |
+
$xcloner_file_transfer = new Xcloner_File_Transfer();
|
13 |
+
|
14 |
+
$xcloner_file_transfer->set_target("http://thinkovi.com/xcloner/xcloner_restore.php");
|
15 |
+
//$xcloner_file_transfer->set_target("http://localhost/xcloner/xcloner_restore.php");
|
16 |
+
|
17 |
+
$start = 0 ;
|
18 |
+
while( $start = $xcloner_file_transfer->transfer_file("backup_localhost-2017-02-07_13-29-sql-ac9b0.tgz", $start))
|
19 |
+
{
|
20 |
+
//echo $start."--";
|
21 |
+
}
|
22 |
+
|
23 |
+
echo "done";
|
24 |
+
?>
|
25 |
+
<div class="col s12 ">
|
26 |
+
<div>
|
27 |
+
<h5 class="left-align">
|
28 |
+
<?php echo __('XCloner Debugger Dashboard', 'xcloner-backup-and-restore') ?>
|
29 |
+
</h5>
|
30 |
+
|
31 |
+
<?php if($xcloner_settings->get_xcloner_option('xcloner_enable_log')) :?>
|
32 |
+
<ul class="collapsible xcloner-debugger" data-collapsible="accordion">
|
33 |
+
<li class="active">
|
34 |
+
<div class="collapsible-header active"><i class="material-icons">bug_report</i>XCloner Debugger</div>
|
35 |
+
<div class="collapsible-body">
|
36 |
+
<div class="console" id="xcloner-console"><?php if(isset($logger_content)) echo implode("<br />\n", $logger_content); ?></div>
|
37 |
+
</div>
|
38 |
+
</li>
|
39 |
+
</ul>
|
40 |
+
<script>
|
41 |
+
jQuery(document).ready(function(){
|
42 |
+
var objDiv = document.getElementById("xcloner-console");
|
43 |
+
objDiv.scrollTop = objDiv.scrollHeight;
|
44 |
+
/*setInterval(function(){
|
45 |
+
getXclonerLog();
|
46 |
+
}, 2000);*/
|
47 |
+
})
|
48 |
+
</script>
|
49 |
+
<?php endif;?>
|
50 |
+
</div>
|
51 |
+
</div>
|
admin/partials/xcloner_generate_backups_page.php
ADDED
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$xcloner_settings = new Xcloner_Settings();
|
3 |
+
$xcloner_remote_storage = new Xcloner_Remote_Storage();
|
4 |
+
$available_storages = $xcloner_remote_storage->get_available_storages();
|
5 |
+
$tab = 1;
|
6 |
+
?>
|
7 |
+
|
8 |
+
<script>var xcloner_backup = new Xcloner_Backup();</script>
|
9 |
+
|
10 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
11 |
+
|
12 |
+
<ul class="nav-tab-wrapper content row">
|
13 |
+
<li><a href="#backup_options" class="nav-tab col s12 m3 l2 nav-tab-active"><?php echo $tab.". ".__('Backup Options','xcloner-backup-and-restore')?></a></li>
|
14 |
+
<?php if($xcloner_settings->get_enable_mysql_backup()):?>
|
15 |
+
<li><a href="#database_options" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Database Options','xcloner-backup-and-restore')?></a></li>
|
16 |
+
<?php endif?>
|
17 |
+
<li><a href="#files_options" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Files Options','xcloner-backup-and-restore')?></a></li>
|
18 |
+
<li><a href="#generate_backup" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Generate Backup','xcloner-backup-and-restore')?></a></li>
|
19 |
+
<li><a href="#schedule_backup" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Schedule Backup','xcloner-backup-and-restore')?></a></li>
|
20 |
+
</ul>
|
21 |
+
|
22 |
+
<form action="" method="POST" id="generate_backup_form">
|
23 |
+
<div class="nav-tab-wrapper-content">
|
24 |
+
<!-- Backup Options Content Tab-->
|
25 |
+
<div id="backup_options" class="tab-content active">
|
26 |
+
<div class="row">
|
27 |
+
<div class="input-field inline col s12 m10 l6">
|
28 |
+
<i class="material-icons prefix">input</i>
|
29 |
+
<input name="backup_name" id="backup_name" type="text" value=<?php echo $xcloner_settings->get_default_backup_name() ?> >
|
30 |
+
<label for="backup_name"><?php echo __('Backup Name','xcloner-backup-and-restore')?></label>
|
31 |
+
</div>
|
32 |
+
<div class="hide-on-small-only m2">
|
33 |
+
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('The default backup name, supported tags [time], [hostname], [domain]','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<div class="row">
|
38 |
+
<div class="input-field inline col s12 m10 l6">
|
39 |
+
<i class="material-icons prefix">input</i>
|
40 |
+
<input name="email_notification" id="email_notification" type="text" value="<?php echo get_option('admin_email');?>" >
|
41 |
+
<label for="email_notification"><?php echo __('Send Email Notification To','xcloner-backup-and-restore')?></label>
|
42 |
+
</div>
|
43 |
+
<div class="hide-on-small-only m2">
|
44 |
+
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('If left blank, no notification will be sent','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
45 |
+
</div>
|
46 |
+
</div>
|
47 |
+
|
48 |
+
<div class="row">
|
49 |
+
<div class="input-field col s12 m10 l6">
|
50 |
+
<i class="material-icons prefix">input</i>
|
51 |
+
<textarea name="backup_comments" id="backup_comments" class="materialize-textarea"></textarea>
|
52 |
+
<label for="backup_comments"><?php echo __('Backup Comments','xcloner-backup-and-restore')?></label>
|
53 |
+
</div>
|
54 |
+
<div class="hide-on-small-only m2">
|
55 |
+
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('Some default backup comments that will be stored inside the backup archive','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
|
59 |
+
<div class="row">
|
60 |
+
<div class="input-field col s12 m10 l6 right-align">
|
61 |
+
<a class="waves-effect waves-light btn" onclick="next_tab('#database_options');"><i class="material-icons right">skip_next</i>Next</a>
|
62 |
+
</div>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
<?php if($xcloner_settings->get_enable_mysql_backup()):?>
|
67 |
+
<div id="database_options" class="tab-content">
|
68 |
+
<h2><?php echo __('Select database data to include in the backup', 'xcloner-backup-and-restore')?>:
|
69 |
+
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('Enable the \'Backup only WP tables\' setting if you don\'t want to show all other databases and tables not related to this Wordpress install','xcloner-backup-and-restore');?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
70 |
+
</h2>
|
71 |
+
|
72 |
+
<!-- database/tables tree -->
|
73 |
+
<div class="row">
|
74 |
+
<div class="col s12 l6">
|
75 |
+
<div id="jstree_database_container"></div>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
|
79 |
+
<div class="row">
|
80 |
+
<div class="input-field col s12 m10 l6 right-align">
|
81 |
+
<a class="waves-effect waves-light btn" onclick="next_tab('#files_options');"><i class="material-icons right">skip_next</i>Next</a>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
|
85 |
+
</div>
|
86 |
+
<?php endif ?>
|
87 |
+
|
88 |
+
<div id="files_options" class="tab-content">
|
89 |
+
<h2><?php echo __('Select from below the files/folders you want to exclude from your Backup Archive','xcloner-backup-and-restore')?>:
|
90 |
+
<a class="btn-floating tooltipped btn-small" data-position="bottom" data-delay="50" data-html="true" data-tooltip="<?php echo __('You can navigate below through all your site structure(Backup Start Location) to exclude any file/folder you need by clicking the checkbox near it. <br />If the checkobx is disabled, then it matches a Regex Exclude File option and it can\'t be unchecked','xcloner-backup-and-restore');?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
91 |
+
</h2>
|
92 |
+
|
93 |
+
<!-- Files System Container -->
|
94 |
+
<div class="row">
|
95 |
+
<div class="col s12 l6">
|
96 |
+
<div id="jstree_files_container"></div>
|
97 |
+
</div>
|
98 |
+
</div>
|
99 |
+
|
100 |
+
<div class="row">
|
101 |
+
<div class="input-field col s12 m10 l6 right-align">
|
102 |
+
<a class="waves-effect waves-light btn" onclick="next_tab('#generate_backup');"><i class="material-icons right">skip_next</i>Next</a>
|
103 |
+
</div>
|
104 |
+
</div>
|
105 |
+
|
106 |
+
</div>
|
107 |
+
<div id="generate_backup" class="tab-content">
|
108 |
+
<div class="row ">
|
109 |
+
<div class="col s12 l10 center action-buttons">
|
110 |
+
<a class="waves-effect waves-light btn-large teal darken-1 start" onclick="xcloner_backup.start_backup()">Start Backup<i class="material-icons left">forward</i></a>
|
111 |
+
<a class="waves-effect waves-light btn-large teal darken-1 restart" onclick="xcloner_backup.restart_backup()">Restart Backup<i class="material-icons left">cached</i></a>
|
112 |
+
<a class="waves-effect waves-light btn-large red darken-1 cancel" onclick="xcloner_backup.cancel_backup()">Cancel Backup<i class="material-icons left">cancel</i></a>
|
113 |
+
</div>
|
114 |
+
<div class="col l10 s12">
|
115 |
+
<ul class="backup-status collapsible" data-collapsible="accordion">
|
116 |
+
<li class="file-system">
|
117 |
+
<div class="collapsible-header">
|
118 |
+
<i class="material-icons">folder</i><?php echo __('Scanning The File System...','xcloner-backup-and-restore')?>
|
119 |
+
|
120 |
+
<p class="right"><?php echo sprintf(__('Found %s files (%s)', 'xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span class="file-size-total">0</span>MB')?></p>
|
121 |
+
|
122 |
+
<div>
|
123 |
+
<p class="right"><span class="last-logged-file"></span></p>
|
124 |
+
</div>
|
125 |
+
|
126 |
+
<div class="progress">
|
127 |
+
<div class="indeterminate"></div>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
<div class="collapsible-body status-body"></div>
|
131 |
+
</li>
|
132 |
+
<?php if($xcloner_settings->get_enable_mysql_backup()):?>
|
133 |
+
<li class="database-backup">
|
134 |
+
<div class="collapsible-header">
|
135 |
+
<i class="material-icons">storage</i><?php echo __('Generating the Mysql Backup...','xcloner-backup-and-restore')?>
|
136 |
+
|
137 |
+
<p class="right"><?php echo sprintf(__('Found %s tables in %s databases (%s)', 'xcloner-backup-and-restore'), '<span class="table-counter">0</span>', '<span class="database-counter">0</span>', '<span data-processed="0" class="total-records">0</span> records','xcloner-backup-and-restore')?></p>
|
138 |
+
|
139 |
+
<div>
|
140 |
+
<p class="right"><span class="last-logged-table"></span></p>
|
141 |
+
</div>
|
142 |
+
|
143 |
+
<div class="progress">
|
144 |
+
<div class="determinate" style="width:0%"></div>
|
145 |
+
</div>
|
146 |
+
</div>
|
147 |
+
<div class="collapsible-body status-body">
|
148 |
+
<div class="row">
|
149 |
+
<div class="col l7 s12">
|
150 |
+
<ul class="logged-tables"></ul>
|
151 |
+
</div>
|
152 |
+
<div class="col l5 s12">
|
153 |
+
<ul class="logged-databases right"></ul>
|
154 |
+
</div>
|
155 |
+
</div>
|
156 |
+
</div>
|
157 |
+
</li>
|
158 |
+
<?php endif?>
|
159 |
+
<li class="files-backup">
|
160 |
+
<div class="collapsible-header">
|
161 |
+
<i class="material-icons">archive</i><?php echo __('Adding Files to Archive...','xcloner-backup-and-restore')?>
|
162 |
+
|
163 |
+
<p class="right"><?php echo sprintf(__('Adding %s files (%s)','xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span data-processed="0" class="file-size-total">0</span>MB')?></p>
|
164 |
+
|
165 |
+
<div>
|
166 |
+
<p class="right"><span class="last-logged-file"></span></p>
|
167 |
+
</div>
|
168 |
+
|
169 |
+
<div class="progress">
|
170 |
+
<div class="determinate" style="width:0%"></div>
|
171 |
+
</div>
|
172 |
+
</div>
|
173 |
+
<div class="collapsible-body status-body">
|
174 |
+
<div class="row">
|
175 |
+
<div class="col l3 s12">
|
176 |
+
<h2><?php echo __("Backup Parts",'xcloner-backup-and-restore')?>: </h2>
|
177 |
+
</div>
|
178 |
+
<div class="col l9 s12">
|
179 |
+
<ul class="backup-name"></ul>
|
180 |
+
</div>
|
181 |
+
</div>
|
182 |
+
</div>
|
183 |
+
</li>
|
184 |
+
<li class="backup-done">
|
185 |
+
<div class="collapsible-header">
|
186 |
+
<i class="material-icons">done</i><?php echo __('Backup Done','xcloner-backup-and-restore')?>
|
187 |
+
|
188 |
+
<p class="right">
|
189 |
+
<?php if(sizeof($available_storages)):?>
|
190 |
+
<a href="#" class="cloud-upload" title="<?php echo __("Send Backup To Remote Storage",'xcloner-backup-and-restore')?>"><i class="material-icons">cloud_upload</i></a>
|
191 |
+
<?php endif?>
|
192 |
+
<a href="#" class="download" title="<?php echo __("Download Backup",'xcloner-backup-and-restore')?>"><i class="material-icons">file_download</i></a>
|
193 |
+
<a href="#" class="list-backup-content" title="<?php echo __("List Backup Content",'xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
|
194 |
+
</p>
|
195 |
+
|
196 |
+
<div class="progress">
|
197 |
+
<div class="determinate" style="width:100%"></div>
|
198 |
+
</div>
|
199 |
+
|
200 |
+
</div>
|
201 |
+
<div class="collapsible-body center-align">
|
202 |
+
<div class="row">
|
203 |
+
<h5><?php echo __("Thank you for using XCloner.",'xcloner-backup-and-restore')?></h5>
|
204 |
+
<h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'),'<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore/reviews/" target="_blank">Wordpress XCloner Reviews Section</a>') ?></h6>
|
205 |
+
<a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow @thinkovi</a>
|
206 |
+
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
207 |
+
</div>
|
208 |
+
</div>
|
209 |
+
</li>
|
210 |
+
</ul>
|
211 |
+
</div>
|
212 |
+
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
|
216 |
+
<div id="schedule_backup" class="tab-content">
|
217 |
+
|
218 |
+
<div class="row">
|
219 |
+
<div id="schedule_backup_success" class="col s12 l6 updated settings-error notice is-dismissible">
|
220 |
+
<p><strong><?php echo __('Schedule Saved', 'xcloner-backup-and-restore')?></strong></p>
|
221 |
+
<button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php echo __('(Dismiss this notice.','xcloner-backup-and-restore')?></span></button>
|
222 |
+
</div>
|
223 |
+
</div>
|
224 |
+
|
225 |
+
<!--<div class="row server-time">
|
226 |
+
<div class="col s12 m10 l6 teal lighten-1">
|
227 |
+
<h2><?php echo __('Current Server Time', 'xcloner-backup-and-restore')?>: <span class="right"><?php echo date("Y/m/d H:i")?></span></h2>
|
228 |
+
</div>
|
229 |
+
</div>
|
230 |
+
-->
|
231 |
+
<div class="row">
|
232 |
+
<div class="input-field inline col s12 m10 l6">
|
233 |
+
<input type="text" id="schedule_name" class="" name="schedule_name" required>
|
234 |
+
<label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
|
235 |
+
</div>
|
236 |
+
</div>
|
237 |
+
|
238 |
+
<div class="row">
|
239 |
+
<div class="input-field inline col s12 m6 l4">
|
240 |
+
<input type="datetime-local" id="datepicker" class="datepicker" name="schedule_start_date" >
|
241 |
+
<label for="datepicker"><?php echo __('Schedule Backup To Start On:','xcloner-backup-and-restore')?></label>
|
242 |
+
</div>
|
243 |
+
<div class="input-field inline col s12 m4 l2">
|
244 |
+
<input id="timepicker_ampm_dark" class="timepicker" type="time" name="schedule_start_time">
|
245 |
+
<label for="timepicker_ampm_dark"><?php echo __('At:','xcloner-backup-and-restore')?></label>
|
246 |
+
</div>
|
247 |
+
</div>
|
248 |
+
|
249 |
+
<div class="row">
|
250 |
+
<div class="input-field col s12 m10 l6">
|
251 |
+
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
252 |
+
<option value="" disabled selected><?php echo __('please select', 'xcloner-backup-and-restore') ?></option>
|
253 |
+
<option value="single"><?php echo __("Don't Repeat",'xcloner-backup-and-restore')?></option>
|
254 |
+
<option value="hourly"><?php echo __("Hourly",'xcloner-backup-and-restore')?></option>
|
255 |
+
<option value="daily"><?php echo __("Daily",'xcloner-backup-and-restore')?></option>
|
256 |
+
<option value="weekly"><?php echo __("Weekly",'xcloner-backup-and-restore')?></option>
|
257 |
+
<option value="monthly"><?php echo __("Monthly",'xcloner-backup-and-restore')?></option>
|
258 |
+
</select>
|
259 |
+
<label><?php echo __('Please Select Frequency to run', 'xcloner-backup-and-restore') ?></label>
|
260 |
+
</div>
|
261 |
+
</div>
|
262 |
+
|
263 |
+
<?php if(sizeof($available_storages)):?>
|
264 |
+
<div class="row">
|
265 |
+
<div class="input-field col s12 m10 l6">
|
266 |
+
<select name="schedule_storage" id="schedule_storage" class="validate">
|
267 |
+
<option value="" selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
|
268 |
+
<?php foreach($available_storages as $storage=>$text):?>
|
269 |
+
<option value="<?php echo $storage?>"><?php echo $text?></option>
|
270 |
+
<?php endforeach?>
|
271 |
+
</select>
|
272 |
+
<label><?php echo __('Send To Remote Storage', 'xcloner-backup-and-restore') ?></label>
|
273 |
+
</div>
|
274 |
+
</div>
|
275 |
+
<?php endif?>
|
276 |
+
<div class="row">
|
277 |
+
<div class="col s12 m10 l6">
|
278 |
+
<button class="right btn waves-effect waves-light submit_schedule" type="submit" name="action"><?php echo __("Submit" ,'xcloner-backup-and-restore')?>
|
279 |
+
<i class="material-icons right">send</i>
|
280 |
+
</button>
|
281 |
+
</div>
|
282 |
+
</div>
|
283 |
+
</div>
|
284 |
+
</div>
|
285 |
+
</form>
|
286 |
+
|
287 |
+
<!-- Error Modal Structure -->
|
288 |
+
<div id="error_modal" class="modal">
|
289 |
+
<a title="Online Help" href="https://wordpress.org/support/plugin/xcloner-backup-and-restore" target="_blank"><i class="material-icons medium right">help</i></a>
|
290 |
+
<div class="modal-content">
|
291 |
+
<h4 class="title_line"><span class="title"></span></h4>
|
292 |
+
<!--<h5 class="title_line"><?php echo __('Message')?>: <span class="msg.old"></span></h5>-->
|
293 |
+
<h5><?php echo __('Response Code', 'xcloner-backup-and-restore')?>: <span class="status"></span></h5>
|
294 |
+
<textarea class="body" rows="5"></textarea>
|
295 |
+
</div>
|
296 |
+
<div class="modal-footer">
|
297 |
+
<a class=" modal-action modal-close waves-effect waves-green btn-flat red darken-2"><?php echo __('Close','xcloner-backup-and-restore')?></a>
|
298 |
+
</div>
|
299 |
+
</div>
|
300 |
+
|
301 |
+
<!-- List Backup Content Modal-->
|
302 |
+
|
303 |
+
<div id="backup_cotent_modal" class="modal">
|
304 |
+
<div class="modal-content">
|
305 |
+
<h4><?php echo sprintf(__("Listing Backup Content ",'xcloner-backup-and-restore'), "")?></h4>
|
306 |
+
<h5 class="backup-name"></h5>
|
307 |
+
|
308 |
+
<div class="progress">
|
309 |
+
<div class="indeterminate"></div>
|
310 |
+
</div>
|
311 |
+
<ul class="files-list"></ul>
|
312 |
+
</div>
|
313 |
+
</div>
|
314 |
+
|
315 |
+
<!-- Remote Storage Modal Structure -->
|
316 |
+
<div id="remote_storage_modal" class="modal">
|
317 |
+
<form method="POST" class="remote-storage-form">
|
318 |
+
<input type="hidden" name="file" class="backup_name">
|
319 |
+
<div class="modal-content">
|
320 |
+
<h4><?php echo __("Remote Storage Transfer",'xcloner-backup-and-restore')?></h4>
|
321 |
+
<p>
|
322 |
+
<?php if(sizeof($available_storages)):?>
|
323 |
+
<div class="row">
|
324 |
+
<div class="col s12 label">
|
325 |
+
<label><?php echo __(sprintf('Send %s to remote storage', "<span class='backup_name'></span>"), 'xcloner-backup-and-restore') ?></label>
|
326 |
+
</div>
|
327 |
+
<div class="input-field col s8 m10">
|
328 |
+
<select name="transfer_storage" id="transfer_storage" class="validate" required >
|
329 |
+
<option value="" selected><?php echo __('please select...', 'xcloner-backup-and-restore') ?></option>
|
330 |
+
<?php foreach($available_storages as $storage=>$text):?>
|
331 |
+
<option value="<?php echo $storage?>"><?php echo $text?></option>
|
332 |
+
<?php endforeach?>
|
333 |
+
</select>
|
334 |
+
|
335 |
+
</div>
|
336 |
+
<div class="s4 m2 right">
|
337 |
+
<button type="submit" class="upload-submit btn-floating btn-large waves-effect waves-light teal"><i class="material-icons">file_upload</i></submit>
|
338 |
+
</div>
|
339 |
+
</div>
|
340 |
+
<div class="row status">
|
341 |
+
<?php echo __("Uploading backup to the selected remote storage...",'xcloner-backup-and-restore')?> <span class="status-text"></span>
|
342 |
+
<div class="progress">
|
343 |
+
<div class="indeterminate"></div>
|
344 |
+
</div>
|
345 |
+
</div>
|
346 |
+
<?php endif?>
|
347 |
+
</p>
|
348 |
+
</div>
|
349 |
+
</form>
|
350 |
+
</div>
|
351 |
+
|
352 |
+
<script>
|
353 |
+
jQuery(function () {
|
354 |
+
|
355 |
+
jQuery('select').material_select();
|
356 |
+
jQuery("select[required]").css({display: "block", height: 0, padding: 0, width: 0, position: 'absolute'});
|
357 |
+
jQuery(".backup-done .cloud-upload").on("click", function(e){
|
358 |
+
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
359 |
+
var hash = jQuery(this).attr('href');
|
360 |
+
var id = hash.substr(1)
|
361 |
+
|
362 |
+
e.preventDefault();
|
363 |
+
xcloner_manage_backups.cloud_upload(id)
|
364 |
+
})
|
365 |
+
|
366 |
+
jQuery("#generate_backup_form").on("submit", function(){
|
367 |
+
|
368 |
+
xcloner_backup.params = xcloner_backup.get_form_params();
|
369 |
+
var data = JSON.stringify(xcloner_backup.params);
|
370 |
+
|
371 |
+
xcloner_backup.set_cancel(false);
|
372 |
+
|
373 |
+
xcloner_backup.do_ajax(data, "save_schedule")
|
374 |
+
return false;
|
375 |
+
})
|
376 |
+
|
377 |
+
jQuery(".backup-done .download").on("click", function(e){
|
378 |
+
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
379 |
+
var hash = jQuery(this).attr('href');
|
380 |
+
var id = hash.substr(1)
|
381 |
+
|
382 |
+
e.preventDefault();
|
383 |
+
xcloner_manage_backups.download_backup_by_name(id)
|
384 |
+
})
|
385 |
+
|
386 |
+
jQuery(".backup-done .list-backup-content").on("click", function(e){
|
387 |
+
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
388 |
+
var hash = jQuery(this).attr('href');
|
389 |
+
var id = hash.substr(1)
|
390 |
+
|
391 |
+
e.preventDefault();
|
392 |
+
xcloner_manage_backups.list_backup_content(id)
|
393 |
+
})
|
394 |
+
|
395 |
+
jQuery('.timepicker').pickatime({
|
396 |
+
default: 'now',
|
397 |
+
min: [7,30],
|
398 |
+
twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
|
399 |
+
donetext: 'OK',
|
400 |
+
autoclose: false,
|
401 |
+
vibrate: true // vibrate the device when dragging clock hand
|
402 |
+
});
|
403 |
+
|
404 |
+
var date_picker = jQuery('.datepicker').pickadate({
|
405 |
+
format: 'd mmmm yyyy',
|
406 |
+
selectMonths: true, // Creates a dropdown to control month
|
407 |
+
selectYears: 15, // Creates a dropdown of 15 years to control year
|
408 |
+
min: +0.1,
|
409 |
+
onSet: function() {
|
410 |
+
//this.close();
|
411 |
+
}
|
412 |
+
});
|
413 |
+
|
414 |
+
<?php if($xcloner_settings->get_enable_mysql_backup()):?>
|
415 |
+
jQuery('#jstree_database_container').jstree({
|
416 |
+
'core' : {
|
417 |
+
'check_callback' : true,
|
418 |
+
'data' : {
|
419 |
+
'method': 'POST',
|
420 |
+
'dataType': 'json',
|
421 |
+
'url' : ajaxurl,
|
422 |
+
'data' : function (node) {
|
423 |
+
var data = {
|
424 |
+
'action': 'get_database_tables_action',
|
425 |
+
'id' : node.id
|
426 |
+
}
|
427 |
+
return data;
|
428 |
+
}
|
429 |
+
},
|
430 |
+
|
431 |
+
'error' : function (err) {
|
432 |
+
//alert("We have encountered a communication error with the server, please review the javascript console.");
|
433 |
+
var json = jQuery.parseJSON( err.data )
|
434 |
+
show_ajax_error("Error Loading Database Structure ", err.reason, json.xhr);
|
435 |
+
},
|
436 |
+
|
437 |
+
'strings' : { 'Loading ...' : 'Loading the database structure...' },
|
438 |
+
'themes' : {
|
439 |
+
"variant" : "default"
|
440 |
+
},
|
441 |
+
},
|
442 |
+
'checkbox': {
|
443 |
+
three_state: true
|
444 |
+
},
|
445 |
+
'plugins' : [
|
446 |
+
"checkbox",
|
447 |
+
"massload",
|
448 |
+
"search",
|
449 |
+
//"sort",
|
450 |
+
//"state",
|
451 |
+
"types",
|
452 |
+
"unique",
|
453 |
+
"wholerow"
|
454 |
+
]
|
455 |
+
});
|
456 |
+
<?php endif ?>
|
457 |
+
|
458 |
+
jQuery('#jstree_files_container').jstree({
|
459 |
+
'core' : {
|
460 |
+
'check_callback' : true,
|
461 |
+
'data' : {
|
462 |
+
'method': 'POST',
|
463 |
+
'dataType': 'json',
|
464 |
+
'url' : ajaxurl,
|
465 |
+
'data' : function (node) {
|
466 |
+
var data = {
|
467 |
+
'action': 'get_file_system_action',
|
468 |
+
'id' : node.id
|
469 |
+
}
|
470 |
+
return data;
|
471 |
+
}
|
472 |
+
},
|
473 |
+
|
474 |
+
'error' : function (err) {
|
475 |
+
//alert("We have encountered a communication error with the server, please review the javascript console.");
|
476 |
+
var json = jQuery.parseJSON( err.data )
|
477 |
+
show_ajax_error("Error Loading Files Structure ", err.reason, json.xhr);
|
478 |
+
},
|
479 |
+
|
480 |
+
'strings' : { 'Loading ...' : 'Loading the database structure...' },
|
481 |
+
'themes' : {
|
482 |
+
"variant" : "default"
|
483 |
+
},
|
484 |
+
},
|
485 |
+
'checkbox': {
|
486 |
+
three_state: true
|
487 |
+
},
|
488 |
+
'plugins' : [
|
489 |
+
"checkbox",
|
490 |
+
"massload",
|
491 |
+
"search",
|
492 |
+
//"sort",
|
493 |
+
//"state",
|
494 |
+
"types",
|
495 |
+
"unique",
|
496 |
+
"wholerow"
|
497 |
+
]
|
498 |
+
});
|
499 |
+
});
|
500 |
+
|
501 |
+
|
502 |
+
</script>
|
admin/partials/xcloner_init_page.php
ADDED
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Provide a admin area view for the plugin
|
5 |
+
*
|
6 |
+
* This file is used to markup the admin-facing aspects of the plugin.
|
7 |
+
*
|
8 |
+
* @link http://www.thinkovi.com
|
9 |
+
* @since 1.0.0
|
10 |
+
*
|
11 |
+
* @package Xcloner
|
12 |
+
* @subpackage Xcloner/admin/partials
|
13 |
+
*/
|
14 |
+
|
15 |
+
$requirements = new XCloner_Requirements();
|
16 |
+
$xcloner_settings = new Xcloner_Settings();
|
17 |
+
$xcloner_file_system = new Xcloner_File_System();
|
18 |
+
$logger = new Xcloner_Logger();
|
19 |
+
$xcloner_scheduler = new Xcloner_Scheduler();
|
20 |
+
|
21 |
+
$logger_content = $logger->getLastDebugLines();
|
22 |
+
|
23 |
+
$date_format = get_option( 'date_format' );
|
24 |
+
$time_format = get_option( 'time_format' );
|
25 |
+
|
26 |
+
if($requirements->check_backup_ready_status())
|
27 |
+
{
|
28 |
+
$latest_backup = $xcloner_file_system->get_latest_backup();
|
29 |
+
$xcloner_file_system->backup_storage_cleanup();
|
30 |
+
}
|
31 |
+
?>
|
32 |
+
|
33 |
+
<div class="row">
|
34 |
+
<div class="col s12">
|
35 |
+
<h5 class="left-align">
|
36 |
+
<?php echo __('Backup Dashboard', 'xcloner-backup-and-restore') ?>
|
37 |
+
</h5>
|
38 |
+
</div>
|
39 |
+
</div>
|
40 |
+
|
41 |
+
<?php if(isset($latest_backup['timestamp']) and $latest_backup['timestamp'] < strtotime("-1 day")): ?>
|
42 |
+
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
43 |
+
<p><strong>
|
44 |
+
<?php echo __('Your latest backup is older than 24 hours, please create a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
|
45 |
+
</strong>
|
46 |
+
</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
|
47 |
+
</div>
|
48 |
+
<?php endif?>
|
49 |
+
|
50 |
+
<?php if(!isset($latest_backup['timestamp']) ): ?>
|
51 |
+
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
52 |
+
<p><strong>
|
53 |
+
<?php echo __('You have no backup that I could find, please generate a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
|
54 |
+
</strong>
|
55 |
+
</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
|
56 |
+
</div>
|
57 |
+
<?php endif?>
|
58 |
+
|
59 |
+
<?php if(!$requirements->check_backup_ready_status()):?>
|
60 |
+
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
61 |
+
<p><strong>
|
62 |
+
<?php echo __('Backup system not ready, please check and fix the issues marked in red', 'xcloner-backup-and-restore') ?>
|
63 |
+
</strong>
|
64 |
+
</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
|
65 |
+
</div>
|
66 |
+
|
67 |
+
<?php endif ?>
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
<!-- This file should primarily consist of HTML with a little bit of PHP. -->
|
72 |
+
<div class="row dashboard">
|
73 |
+
<div class="col s12 m12 l7">
|
74 |
+
|
75 |
+
<div class="row">
|
76 |
+
|
77 |
+
<ul class="collapsible xcloner-debugger" data-collapsible="accordion">
|
78 |
+
|
79 |
+
<li class="active">
|
80 |
+
<div class="collapsible-header active"><i class="material-icons">info</i>Backup Status</div>
|
81 |
+
<div class="collapsible-body">
|
82 |
+
<div class="" id="backup-status">
|
83 |
+
<div class="row">
|
84 |
+
<h5><?php echo __("Latest Backup", 'xcloner-backup-and-restore')?></h5>
|
85 |
+
<blockquote>
|
86 |
+
<?php if($latest_backup):?>
|
87 |
+
<div class="item">
|
88 |
+
<div class="title"><?php echo __("Backup Name", 'xcloner-backup-and-restore')?>:</div>
|
89 |
+
<?php echo $latest_backup['basename']?>
|
90 |
+
</div>
|
91 |
+
<div class="item">
|
92 |
+
<div class="title">
|
93 |
+
<?php echo __("Backup Size", 'xcloner-backup-and-restore')?>:
|
94 |
+
</div>
|
95 |
+
<?php echo size_format($latest_backup['size'])?>
|
96 |
+
</div>
|
97 |
+
<div class="item">
|
98 |
+
<div class="title"><?php echo __("Backup Date", 'xcloner-backup-and-restore')?>:</div>
|
99 |
+
<?php
|
100 |
+
echo date($date_format." ".$time_format, $latest_backup['timestamp'])
|
101 |
+
?>
|
102 |
+
</div>
|
103 |
+
<?php else:?>
|
104 |
+
<div class="item">
|
105 |
+
<div class="title"><?php echo __("No Backup Yet", 'xcloner-backup-and-restore')?></div>
|
106 |
+
</div>
|
107 |
+
<?php endif?>
|
108 |
+
</blockquote>
|
109 |
+
<div>
|
110 |
+
<h5><?php echo __("Backup Storage Usage", 'xcloner-backup-and-restore')?></h5>
|
111 |
+
<blockquote>
|
112 |
+
<div class="item">
|
113 |
+
<div class="title"><?php echo __("Total Size", 'xcloner-backup-and-restore')?>:</div>
|
114 |
+
<?php echo size_format($xcloner_file_system->get_storage_usage());?>
|
115 |
+
</div>
|
116 |
+
</blockquote>
|
117 |
+
<h5><?php echo __("Next Scheduled Backup", 'xcloner-backup-and-restore')?></h5>
|
118 |
+
<blockquote>
|
119 |
+
<div class="item">
|
120 |
+
<?php
|
121 |
+
$list = ($xcloner_scheduler->get_next_run_schedule());
|
122 |
+
|
123 |
+
if(is_array($list))
|
124 |
+
{
|
125 |
+
$xcloner_file_system->sort_by($list, "next_run_time","desc");
|
126 |
+
}
|
127 |
+
|
128 |
+
if(isset($list[0]))
|
129 |
+
$latest_schedule = $list[0];
|
130 |
+
?>
|
131 |
+
<?php if(isset($latest_schedule->name)):?>
|
132 |
+
<div class="title"><?php echo __("Schedule Name", 'xcloner-backup-and-restore')?>:</div>
|
133 |
+
<?php echo $latest_schedule->name;?>
|
134 |
+
<?php endif;?>
|
135 |
+
</div>
|
136 |
+
<div class="item">
|
137 |
+
<div class="title"><?php echo __("Next Call", 'xcloner-backup-and-restore')?>:</div>
|
138 |
+
<?php if(isset($latest_schedule->next_run_time))
|
139 |
+
echo date($date_format." ".$time_format, $latest_schedule->next_run_time);
|
140 |
+
else
|
141 |
+
echo __("Unscheduled",'xcloner-backup-and-restore');
|
142 |
+
?>
|
143 |
+
</div>
|
144 |
+
</blockquote>
|
145 |
+
</div>
|
146 |
+
</div>
|
147 |
+
</li>
|
148 |
+
|
149 |
+
<?php if($xcloner_settings->get_xcloner_option('xcloner_enable_log')) :?>
|
150 |
+
<li class="active">
|
151 |
+
<div class="collapsible-header active">
|
152 |
+
<i class="material-icons">bug_report</i><?php echo __('XCloner Debugger', 'xcloner-backup-and-restore')?>
|
153 |
+
<span class="right"><?php echo basename($logger->get_main_logger_url())?></span>
|
154 |
+
</div>
|
155 |
+
<div class="collapsible-body">
|
156 |
+
<div class="console" id="xcloner-console"><?php if($logger_content) echo implode("<br />\n", array_reverse($logger_content)); ?></div>
|
157 |
+
</div>
|
158 |
+
</li>
|
159 |
+
<script>
|
160 |
+
jQuery(document).ready(function(){
|
161 |
+
var objDiv = document.getElementById("xcloner-console");
|
162 |
+
objDiv.scrollTop = objDiv.scrollHeight;
|
163 |
+
/*setInterval(function(){
|
164 |
+
getXclonerLog();
|
165 |
+
}, 2000);*/
|
166 |
+
})
|
167 |
+
</script>
|
168 |
+
<?php endif;?>
|
169 |
+
|
170 |
+
</ul>
|
171 |
+
|
172 |
+
</div>
|
173 |
+
|
174 |
+
|
175 |
+
</div>
|
176 |
+
<div class="col s12 m12 l5">
|
177 |
+
|
178 |
+
<div class="card blue-grey darken-1 z-depth-4 backup-ready">
|
179 |
+
<div class="card-content white-text">
|
180 |
+
<span class="card-title"><?php echo __("System Check",'xcloner-backup-and-restore')?></span>
|
181 |
+
<ul>
|
182 |
+
<li class="card-panel <?php echo ($requirements->check_xcloner_start_path(1)?"teal":"red")?> lighten-2" >
|
183 |
+
<?php echo __('Backup Start Location','xcloner-backup-and-restore')?>: <span class="shorten_string "><?php echo $requirements->check_xcloner_start_path();?></span>
|
184 |
+
</li>
|
185 |
+
<li class="card-panel <?php echo ($requirements->check_xcloner_store_path(1)?"teal":"red")?> lighten-2" >
|
186 |
+
<?php echo __('Backup Storage Location','xcloner-backup-and-restore')?>: <span class="shorten_string"><?php echo $requirements->check_xcloner_store_path();?></span>
|
187 |
+
</li>
|
188 |
+
<li class="card-panel <?php echo ($requirements->check_xcloner_tmp_path(1)?"teal":"red")?> lighten-2" >
|
189 |
+
<?php echo __('Temporary Location','xcloner-backup-and-restore')?>: <span class="shorten_string"><?php echo $requirements->check_xcloner_tmp_path();?></span>
|
190 |
+
</li>
|
191 |
+
|
192 |
+
<li class="card-panel <?php echo ($requirements->check_min_php_version(1)?"teal":"red")?> lighten-2" >
|
193 |
+
<?php echo __('PHP Version Check','xcloner-backup-and-restore')?>: <?php echo $requirements->check_min_php_version();?>
|
194 |
+
( >= <?php echo $requirements->get_constant('min_php_version')?>)
|
195 |
+
</li>
|
196 |
+
<li class="card-panel <?php echo ($requirements->check_safe_mode(1)?"teal":"orange")?> lighten-2" >
|
197 |
+
<?php echo __('PHP Safe Mode','xcloner-backup-and-restore')?>: <?php echo $requirements->check_safe_mode();?>
|
198 |
+
( <?php echo $requirements->get_constant('safe_mode')?>)
|
199 |
+
</li>
|
200 |
+
<li class="card-panel <?php echo ($requirements->check_backup_ready_status()?"teal":"red")?> lighten-2">
|
201 |
+
<?php echo ($requirements->check_backup_ready_status()?__('BACKUP READY','xcloner-backup-and-restore'):__('Backup not ready, please check above requirements','xcloner-backup-and-restore'))?>
|
202 |
+
<i class="material-icons right tiny"><?php echo ($requirements->check_backup_ready_status()?'thumb_up':'thumb_down')?></i>
|
203 |
+
</li>
|
204 |
+
</ul>
|
205 |
+
<ul class="additional_system_info">
|
206 |
+
<li class="card-panel grey darken-1" >
|
207 |
+
<?php echo __('PHP max_execution_time','xcloner-backup-and-restore')?>: <?php echo $requirements->get_max_execution_time();?>
|
208 |
+
</li>
|
209 |
+
<li class="card-panel grey darken-1" >
|
210 |
+
<?php echo __('PHP memory_limit','xcloner-backup-and-restore')?>: <?php echo $requirements->get_memory_limit();?>
|
211 |
+
</li>
|
212 |
+
<li class="card-panel grey darken-1" >
|
213 |
+
<?php echo __('PHP open_basedir','xcloner-backup-and-restore')?>: <?php echo $requirements->get_open_basedir();?>
|
214 |
+
</li>
|
215 |
+
<?php
|
216 |
+
$data = array();
|
217 |
+
if($requirements->check_backup_ready_status())
|
218 |
+
$data = $xcloner_file_system->estimate_read_write_time();
|
219 |
+
?>
|
220 |
+
<li class="card-panel grey darken-1" >
|
221 |
+
<?php echo __('Reading Time 1MB Block','xcloner-backup-and-restore')?>: <?php echo (isset($data['reading_time'])?$data['reading_time']:__("unknown"));?>
|
222 |
+
</li>
|
223 |
+
<li class="card-panel grey darken-1" >
|
224 |
+
<?php echo __('Writing Time 1MB Block','xcloner-backup-and-restore')?>: <?php echo (isset($data['writing_time'])?$data['writing_time']:__("unknown"));?>
|
225 |
+
</li>
|
226 |
+
<li class="card-panel grey darken-1" >
|
227 |
+
<?php echo __('Free Disk Space','xcloner-backup-and-restore')?>: <?php echo $requirements->get_free_disk_space();;?>
|
228 |
+
</li>
|
229 |
+
</ul>
|
230 |
+
</div>
|
231 |
+
<div class="card-action">
|
232 |
+
<a class="waves-effect waves-light btn system_info_toggle blue darken-1"><i class="material-icons left">list</i><?php echo __('Toggle Additional System Info','xcloner-backup-and-restore')?></a>
|
233 |
+
</div>
|
234 |
+
</div>
|
235 |
+
|
236 |
+
</div>
|
237 |
+
</div>
|
admin/partials/xcloner_manage_backups_page.php
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$xcloner_file_system = new Xcloner_File_System();
|
4 |
+
|
5 |
+
$backup_list = $xcloner_file_system->get_backup_archives_list();
|
6 |
+
|
7 |
+
$xcloner_remote_storage = new Xcloner_Remote_Storage();
|
8 |
+
$available_storages = $xcloner_remote_storage->get_available_storages();
|
9 |
+
?>
|
10 |
+
|
11 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
12 |
+
|
13 |
+
<table id="manage_backups">
|
14 |
+
<thead>
|
15 |
+
<tr class="grey lighten-2">
|
16 |
+
<th class="no-sort">
|
17 |
+
<p>
|
18 |
+
<input name="select_all" class="" id="select_all" value="1" type="checkbox">
|
19 |
+
<label for="select_all"> </label>
|
20 |
+
</p>
|
21 |
+
</th>
|
22 |
+
<th data-field="id"><?php echo __("Backup Name",'xcloner-backup-and-restore')?></th>
|
23 |
+
<th data-field="name"><?php echo __("Created Time",'xcloner-backup-and-restore')?></th>
|
24 |
+
<th data-field="name"><?php echo __("Size",'xcloner-backup-and-restore')?></th>
|
25 |
+
<th class="no-sort" data-field="price"><?php echo __("Action",'xcloner-backup-and-restore')?></th>
|
26 |
+
|
27 |
+
</tr>
|
28 |
+
</thead>
|
29 |
+
|
30 |
+
<tbody>
|
31 |
+
|
32 |
+
|
33 |
+
<?php
|
34 |
+
$i = 0;
|
35 |
+
foreach($backup_list as $file_info):?>
|
36 |
+
<?php if(!isset($file_info['parent'])):?>
|
37 |
+
|
38 |
+
<tr>
|
39 |
+
<td class="checkbox">
|
40 |
+
<p>
|
41 |
+
<input name="backup[]" value="<?php echo $file_info['path']?>" type="checkbox" id="checkbox_<?php echo ++$i?>">
|
42 |
+
<label for="checkbox_<?php echo $i?>"> </label>
|
43 |
+
</p>
|
44 |
+
</td>
|
45 |
+
<td>
|
46 |
+
<?php echo $file_info['path']?>
|
47 |
+
<?php
|
48 |
+
if(isset($file_info['childs']) and is_array($file_info['childs'])):
|
49 |
+
?>
|
50 |
+
<a href="#" title="expand" class="expand-multipart add"><i class="material-icons">add</i></a>
|
51 |
+
<a href="#" title="collapse" class="expand-multipart remove"><i class="material-icons">remove</i></a>
|
52 |
+
<ul class="multipart">
|
53 |
+
<?php foreach($file_info['childs'] as $child):?>
|
54 |
+
<?php #$download_file .= "|".$child[0];?>
|
55 |
+
<li>
|
56 |
+
<?php echo $child[0]?> (<?php echo size_format($child[2])?>)
|
57 |
+
<a href="#<?php echo $child[0];?>" class="download" title="Download Backup"><i class="material-icons">file_download</i></a>
|
58 |
+
<a href="#<?php echo $child[0]?>" class="list-backup-content" title="<?php echo __('List Backup Content','xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
|
59 |
+
</li>
|
60 |
+
<?php endforeach;?>
|
61 |
+
</ul>
|
62 |
+
<?php endif;?>
|
63 |
+
</td>
|
64 |
+
<td><?php echo date("d M, Y H:i", $file_info['timestamp'])?></td>
|
65 |
+
<td><?php echo size_format($file_info['size'])?></td>
|
66 |
+
<td>
|
67 |
+
<a href="#<?php echo $file_info['path'];?>" class="download" title="<?php echo __('Download Backup','xcloner-backup-and-restore')?>"><i class="material-icons">file_download</i></a>
|
68 |
+
<?php if(sizeof($available_storages)):?>
|
69 |
+
<a href="#<?php echo $file_info['path']?>" class="cloud-upload" title="<?php echo __('Send Backup To Remote Storage','xcloner-backup-and-restore')?>"><i class="material-icons">cloud_upload</i></a>
|
70 |
+
<?php endif?>
|
71 |
+
<a href="#<?php echo $file_info['path']?>" class="list-backup-content" title="<?php echo __('List Backup Content','xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
|
72 |
+
<a href="#<?php echo $file_info['path']?>" class="delete" title="<?php echo __('Delete Backup','xcloner-backup-and-restore')?>"><i class="material-icons">delete</i></a>
|
73 |
+
</td>
|
74 |
+
|
75 |
+
</tr>
|
76 |
+
|
77 |
+
<?php endif?>
|
78 |
+
<?php endforeach?>
|
79 |
+
|
80 |
+
</tbody>
|
81 |
+
</table>
|
82 |
+
|
83 |
+
<a class="waves-effect waves-light btn delete-all"><i class="material-icons left">delete</i><?php echo __("Delete",'xcloner-backup-and-restore')?></a>
|
84 |
+
|
85 |
+
<!-- List Backup Content Modal-->
|
86 |
+
|
87 |
+
<div id="backup_cotent_modal" class="modal">
|
88 |
+
<div class="modal-content">
|
89 |
+
<h4><?php echo sprintf(__("Listing Backup Content ",'xcloner-backup-and-restore'), "")?></h4>
|
90 |
+
<h5 class="backup-name"></h5>
|
91 |
+
|
92 |
+
<div class="progress">
|
93 |
+
<div class="indeterminate"></div>
|
94 |
+
</div>
|
95 |
+
<ul class="files-list"></ul>
|
96 |
+
</div>
|
97 |
+
</div>
|
98 |
+
|
99 |
+
<!-- Remote Storage Modal Structure -->
|
100 |
+
<div id="remote_storage_modal" class="modal">
|
101 |
+
<form method="POST" class="remote-storage-form">
|
102 |
+
<input type="hidden" name="file" class="backup_name">
|
103 |
+
<div class="modal-content">
|
104 |
+
<h4><?php echo __("Remote Storage Transfer",'xcloner-backup-and-restore')?></h4>
|
105 |
+
<p>
|
106 |
+
<?php if(sizeof($available_storages)):?>
|
107 |
+
<div class="row">
|
108 |
+
<div class="col s12 label">
|
109 |
+
<label><?php echo sprintf(__('Send %s to remote storage','xcloner-backup-and-restore'), "<span class='backup_name'></span>") ?></label>
|
110 |
+
</div>
|
111 |
+
<div class="input-field col s8 m10">
|
112 |
+
<select name="transfer_storage" id="transfer_storage" class="validate" required >
|
113 |
+
<option value="" selected><?php echo __('please select...', 'xcloner-backup-and-restore') ?></option>
|
114 |
+
<?php foreach($available_storages as $storage=>$text):?>
|
115 |
+
<option value="<?php echo $storage?>"><?php echo $text?></option>
|
116 |
+
<?php endforeach?>
|
117 |
+
</select>
|
118 |
+
|
119 |
+
</div>
|
120 |
+
<div class="s4 m2 right">
|
121 |
+
<button type="submit" class="upload-submit btn-floating btn-large waves-effect waves-light teal"><i class="material-icons">file_upload</i></submit>
|
122 |
+
</div>
|
123 |
+
</div>
|
124 |
+
<div class="row status">
|
125 |
+
<?php echo __("Uploading backup to the selected remote storage...",'xcloner-backup-and-restore')?> <span class="status-text"></span>
|
126 |
+
<div class="progress">
|
127 |
+
<div class="indeterminate"></div>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
<?php endif?>
|
131 |
+
</p>
|
132 |
+
</div>
|
133 |
+
</form>
|
134 |
+
</div>
|
135 |
+
|
admin/partials/xcloner_remote_storage_page.php
ADDED
@@ -0,0 +1,593 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
2 |
+
|
3 |
+
<form class="remote-storage-form" method="POST">
|
4 |
+
|
5 |
+
<input type="hidden" id="connection_check" name="connection_check" value="">
|
6 |
+
|
7 |
+
<div class="row remote-storage">
|
8 |
+
<div class="col s12 m12 l10">
|
9 |
+
<ul class="collapsible popout" data-collapsible="accordion">
|
10 |
+
<!-- FTP STORAGE-->
|
11 |
+
<li id="ftp">
|
12 |
+
<div class="collapsible-header">
|
13 |
+
<i class="material-icons">computer</i><?php echo __("Ftp Storage",'xcloner-backup-and-restore')?>
|
14 |
+
<div class="right">
|
15 |
+
<div class="switch">
|
16 |
+
<label>
|
17 |
+
Off
|
18 |
+
<input type="checkbox" name="xcloner_ftp_enable" class="status" value="1" <?php if(get_option("xcloner_ftp_enable")) echo "checked"?> \>
|
19 |
+
<span class="lever"></span>
|
20 |
+
On
|
21 |
+
</label>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
</div>
|
25 |
+
<div class="collapsible-body">
|
26 |
+
<div class="row">
|
27 |
+
<div class="col s12 m3 label">
|
28 |
+
<label for="ftp_host"><?php echo __("Ftp Hostname",'xcloner-backup-and-restore')?></label>
|
29 |
+
</div>
|
30 |
+
<div class="col s12 m6">
|
31 |
+
<input placeholder="<?php echo __("Ftp Hostname",'xcloner-backup-and-restore')?>" id="ftp_host" type="text" name="xcloner_ftp_hostname" class="validate" value="<?php echo get_option("xcloner_ftp_hostname")?>">
|
32 |
+
</div>
|
33 |
+
<div class=" col s12 m2">
|
34 |
+
<input placeholder="<?php echo __("Ftp Port",'xcloner-backup-and-restore')?>" id="ftp_port" type="text" name="xcloner_ftp_port" class="validate" value="<?php echo get_option("xcloner_ftp_port", 21)?>">
|
35 |
+
</div>
|
36 |
+
</div>
|
37 |
+
|
38 |
+
<div class="row">
|
39 |
+
<div class="col s12 m3 label">
|
40 |
+
<label for="ftp_username"><?php echo __("Ftp Username",'xcloner-backup-and-restore')?></label>
|
41 |
+
</div>
|
42 |
+
<div class=" col s12 m6">
|
43 |
+
<input placeholder="<?php echo __("Ftp Username",'xcloner-backup-and-restore')?>" id="ftp_username" type="text" name="xcloner_ftp_username" class="validate" value="<?php echo get_option("xcloner_ftp_username")?>" autocomplete="off" >
|
44 |
+
</div>
|
45 |
+
</div>
|
46 |
+
|
47 |
+
|
48 |
+
<div class="row">
|
49 |
+
<div class="col s12 m3 label">
|
50 |
+
<label for="ftp_password"><?php echo __("Ftp Password",'xcloner-backup-and-restore')?></label>
|
51 |
+
</div>
|
52 |
+
<div class=" col s12 m6">
|
53 |
+
<input placeholder="<?php echo __("Ftp Password",'xcloner-backup-and-restore')?>" id="ftp_password" type="password" name="xcloner_ftp_password" class="validate" value="<?php echo get_option("xcloner_ftp_password")?>" autocomplete="off" >
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
|
57 |
+
<div class="row">
|
58 |
+
<div class="col s12 m3 label">
|
59 |
+
<label for="ftp_root"><?php echo __("Ftp Storage Folder",'xcloner-backup-and-restore')?></label>
|
60 |
+
</div>
|
61 |
+
<div class=" col s12 m6">
|
62 |
+
<input placeholder="<?php echo __("Ftp Storage Folder",'xcloner-backup-and-restore')?>" id="ftp_root" type="text" name="xcloner_ftp_path" class="validate" value="<?php echo get_option("xcloner_ftp_path")?>">
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
<div class="row">
|
67 |
+
<div class="col s12 m3 label">
|
68 |
+
<label for="ftp_root"><?php echo __("Ftp Transfer Mode",'xcloner-backup-and-restore')?></label>
|
69 |
+
</div>
|
70 |
+
<div class=" col s12 m6 input-field inline">
|
71 |
+
<input name="xcloner_ftp_transfer_mode" type="radio" id="passive" value="1" <?php if(get_option("xcloner_ftp_transfer_mode", 1)) echo "checked"?> />
|
72 |
+
<label for="passive"><?php echo __("Passive",'xcloner-backup-and-restore')?></label>
|
73 |
+
|
74 |
+
<input name="xcloner_ftp_transfer_mode" type="radio" id="active" value="0" <?php if(!get_option("xcloner_ftp_transfer_mode", 1)) echo "checked"?> />
|
75 |
+
<label for="active"><?php echo __("Active",'xcloner-backup-and-restore')?></label>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
|
79 |
+
<div class="row">
|
80 |
+
<div class="col s12 m3 label">
|
81 |
+
<label for="ftp_ssl_mode"><?php echo __("Ftp Secure Connection",'xcloner-backup-and-restore')?></label>
|
82 |
+
</div>
|
83 |
+
<div class=" col s12 m6 input-field inline">
|
84 |
+
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_inactive" value="0" <?php if(!get_option("xcloner_ftp_ssl_mode")) echo "checked"?> />
|
85 |
+
<label for="ftp_ssl_mode_inactive"><?php echo __("Disable",'xcloner-backup-and-restore')?></label>
|
86 |
+
|
87 |
+
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_active" value="1" <?php if(get_option("xcloner_ftp_ssl_mode")) echo "checked"?> />
|
88 |
+
<label for="ftp_ssl_mode_active"><?php echo __("Enable",'xcloner-backup-and-restore')?></label>
|
89 |
+
</div>
|
90 |
+
</div>
|
91 |
+
|
92 |
+
<div class="row">
|
93 |
+
<div class="col s12 m3 label">
|
94 |
+
<label for="ftp_timeout"><?php echo __("Ftp Timeout",'xcloner-backup-and-restore')?></label>
|
95 |
+
</div>
|
96 |
+
<div class=" col s12 m2">
|
97 |
+
<input placeholder="<?php echo __("Ftp Timeout",'xcloner-backup-and-restore')?>" id="ftp_timeout" type="text" name="xcloner_ftp_timeout" class="validate" value="<?php echo get_option("xcloner_ftp_timeout", 30)?>">
|
98 |
+
</div>
|
99 |
+
</div>
|
100 |
+
|
101 |
+
<div class="row">
|
102 |
+
<div class="col s12 m3 label">
|
103 |
+
<label for="ftp_cleanup_days"><?php echo __("Ftp Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
104 |
+
</div>
|
105 |
+
<div class=" col s12 m6">
|
106 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="ftp_cleanup_days" type="text" name="xcloner_ftp_cleanup_days" class="validate" value="<?php echo get_option("xcloner_ftp_cleanup_days")?>">
|
107 |
+
</div>
|
108 |
+
</div>
|
109 |
+
|
110 |
+
<div class="row">
|
111 |
+
<div class="col s6 m4">
|
112 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="ftp"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
113 |
+
<i class="material-icons right">save</i>
|
114 |
+
</button>
|
115 |
+
</div>
|
116 |
+
<div class="col s6 m4">
|
117 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="ftp" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
118 |
+
<i class="material-icons right">import_export</i>
|
119 |
+
</button>
|
120 |
+
</div>
|
121 |
+
</div>
|
122 |
+
|
123 |
+
</div>
|
124 |
+
</li>
|
125 |
+
<!-- SFTP STORAGE-->
|
126 |
+
<li id="sftp">
|
127 |
+
<div class="collapsible-header">
|
128 |
+
<i class="material-icons">computer</i><?php echo __("SFTP Storage",'xcloner-backup-and-restore')?>
|
129 |
+
<div class="right">
|
130 |
+
<div class="switch">
|
131 |
+
<label>
|
132 |
+
Off
|
133 |
+
<input type="checkbox" name="xcloner_sftp_enable" class="status" value="1" <?php if(get_option("xcloner_sftp_enable")) echo "checked"?> \>
|
134 |
+
<span class="lever"></span>
|
135 |
+
On
|
136 |
+
</label>
|
137 |
+
</div>
|
138 |
+
</div>
|
139 |
+
</div>
|
140 |
+
<div class="collapsible-body">
|
141 |
+
<div class="row">
|
142 |
+
<div class="col s12 m3 label">
|
143 |
+
<label for="sftp_host"><?php echo __("SFTP Hostname",'xcloner-backup-and-restore')?></label>
|
144 |
+
</div>
|
145 |
+
<div class="col s12 m6">
|
146 |
+
<input placeholder="<?php echo __("SFTP Hostname",'xcloner-backup-and-restore')?>" id="sftp_host" type="text" name="xcloner_sftp_hostname" class="validate" value="<?php echo get_option("xcloner_sftp_hostname")?>">
|
147 |
+
</div>
|
148 |
+
<div class=" col s12 m2">
|
149 |
+
<input placeholder="<?php echo __("SFTP Port",'xcloner-backup-and-restore')?>" id="sftp_port" type="text" name="xcloner_sftp_port" class="validate" value="<?php echo get_option("xcloner_sftp_port", 22)?>">
|
150 |
+
</div>
|
151 |
+
</div>
|
152 |
+
|
153 |
+
<div class="row">
|
154 |
+
<div class="col s12 m3 label">
|
155 |
+
<label for="sftp_username"><?php echo __("SFTP Username",'xcloner-backup-and-restore')?></label>
|
156 |
+
</div>
|
157 |
+
<div class=" col s12 m6">
|
158 |
+
<input placeholder="<?php echo __("SFTP Username",'xcloner-backup-and-restore')?>" id="sftp_username" type="text" name="xcloner_sftp_username" class="validate" value="<?php echo get_option("xcloner_sftp_username")?>" autocomplete="off" >
|
159 |
+
</div>
|
160 |
+
</div>
|
161 |
+
|
162 |
+
|
163 |
+
<div class="row">
|
164 |
+
<div class="col s12 m3 label">
|
165 |
+
<label for="sftp_password"><?php echo __("SFTP Password",'xcloner-backup-and-restore')?></label>
|
166 |
+
</div>
|
167 |
+
<div class=" col s12 m6">
|
168 |
+
<input placeholder="<?php echo __("SFTP Password",'xcloner-backup-and-restore')?>" id="ftp_spassword" type="password" name="xcloner_sftp_password" class="validate" value="<?php echo get_option("xcloner_sftp_password")?>" autocomplete="off" >
|
169 |
+
</div>
|
170 |
+
</div>
|
171 |
+
|
172 |
+
<div class="row">
|
173 |
+
<div class="col s12 m3 label">
|
174 |
+
<label for="sftp_private_key"><?php echo __("SFTP Private Key",'xcloner-backup-and-restore')?></label>
|
175 |
+
</div>
|
176 |
+
<div class=" col s12 m6">
|
177 |
+
<input placeholder="<?php echo __("SFTP Private Key",'xcloner-backup-and-restore')?>" id="sftp_private_key" type="text" name="xcloner_sftp_private_key" class="validate" value="<?php echo get_option("xcloner_sftp_private_key")?>">
|
178 |
+
</div>
|
179 |
+
</div>
|
180 |
+
|
181 |
+
<div class="row">
|
182 |
+
<div class="col s12 m3 label">
|
183 |
+
<label for="sftp_root"><?php echo __("SFTP Storage Folder",'xcloner-backup-and-restore')?></label>
|
184 |
+
</div>
|
185 |
+
<div class=" col s12 m6">
|
186 |
+
<input placeholder="<?php echo __("SFTP Storage Folder",'xcloner-backup-and-restore')?>" id="sftp_root" type="text" name="xcloner_sftp_path" class="validate" value="<?php echo get_option("xcloner_sftp_path")?>">
|
187 |
+
</div>
|
188 |
+
</div>
|
189 |
+
|
190 |
+
<div class="row">
|
191 |
+
<div class="col s12 m3 label">
|
192 |
+
<label for="sftp_timeout"><?php echo __("SFTP Timeout",'xcloner-backup-and-restore')?></label>
|
193 |
+
</div>
|
194 |
+
<div class=" col s12 m2">
|
195 |
+
<input placeholder="<?php echo __("SFTP Timeout",'xcloner-backup-and-restore')?>" id="sftp_timeout" type="text" name="xcloner_sftp_timeout" class="validate" value="<?php echo get_option("xcloner_sftp_timeout", 30)?>">
|
196 |
+
</div>
|
197 |
+
</div>
|
198 |
+
|
199 |
+
<div class="row">
|
200 |
+
<div class="col s12 m3 label">
|
201 |
+
<label for="sftp_cleanup_days"><?php echo __("SFTP Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
202 |
+
</div>
|
203 |
+
<div class=" col s12 m6">
|
204 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="sftp_cleanup_days" type="text" name="xcloner_sftp_cleanup_days" class="validate" value="<?php echo get_option("xcloner_sftp_cleanup_days")?>">
|
205 |
+
</div>
|
206 |
+
</div>
|
207 |
+
|
208 |
+
<div class="row">
|
209 |
+
<div class="col s6 m4">
|
210 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="sftp"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
211 |
+
<i class="material-icons right">save</i>
|
212 |
+
</button>
|
213 |
+
</div>
|
214 |
+
<div class="col s6 m4">
|
215 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="sftp" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
216 |
+
<i class="material-icons right">import_export</i>
|
217 |
+
</button>
|
218 |
+
</div>
|
219 |
+
</div>
|
220 |
+
|
221 |
+
</div>
|
222 |
+
</li>
|
223 |
+
|
224 |
+
<!-- AWS STORAGE-->
|
225 |
+
<li id="aws">
|
226 |
+
<div class="collapsible-header">
|
227 |
+
<i class="material-icons">computer</i><?php echo __("AWS Storage",'xcloner-backup-and-restore')?>
|
228 |
+
<div class="right">
|
229 |
+
<div class="switch">
|
230 |
+
<label>
|
231 |
+
Off
|
232 |
+
<input type="checkbox" name="xcloner_aws_enable" class="status" value="1" <?php if(get_option("xcloner_aws_enable")) echo "checked"?> \>
|
233 |
+
<span class="lever"></span>
|
234 |
+
On
|
235 |
+
</label>
|
236 |
+
</div>
|
237 |
+
</div>
|
238 |
+
</div>
|
239 |
+
<div class="collapsible-body">
|
240 |
+
|
241 |
+
<div class="row">
|
242 |
+
<div class="col s12 m3 label">
|
243 |
+
|
244 |
+
</div>
|
245 |
+
<div class=" col s12 m6">
|
246 |
+
<p>
|
247 |
+
<?php echo sprintf(__('Visit %s and get your "Key" and "Secret".'), "<a href='https://aws.amazon.com/s3/' target='_blank'>https://aws.amazon.com/s3/</a>")?>
|
248 |
+
</p>
|
249 |
+
</div>
|
250 |
+
</div>
|
251 |
+
|
252 |
+
<div class="row">
|
253 |
+
<div class="col s12 m3 label">
|
254 |
+
<label for="aws_key"><?php echo __("AWS Key",'xcloner-backup-and-restore')?></label>
|
255 |
+
</div>
|
256 |
+
<div class=" col s12 m6">
|
257 |
+
<input placeholder="<?php echo __("AWS Key",'xcloner-backup-and-restore')?>" id="aws_key" type="text" name="xcloner_aws_key" class="validate" value="<?php echo get_option("xcloner_aws_key")?>" autocomplete="off" >
|
258 |
+
</div>
|
259 |
+
</div>
|
260 |
+
|
261 |
+
<div class="row">
|
262 |
+
<div class="col s12 m3 label">
|
263 |
+
<label for="aws_secret"><?php echo __("AWS Secret",'xcloner-backup-and-restore')?></label>
|
264 |
+
</div>
|
265 |
+
<div class=" col s12 m6">
|
266 |
+
<input placeholder="<?php echo __("AWS Secret",'xcloner-backup-and-restore')?>" id="aws_secret" type="text" name="xcloner_aws_secret" class="validate" value="<?php echo get_option("xcloner_aws_secret")?>" autocomplete="off" >
|
267 |
+
</div>
|
268 |
+
</div>
|
269 |
+
|
270 |
+
<div class="row">
|
271 |
+
<div class="col s12 m3 label">
|
272 |
+
<label for="aws_region"><?php echo __("AWS Region",'xcloner-backup-and-restore')?></label>
|
273 |
+
</div>
|
274 |
+
<div class=" col s12 m6">
|
275 |
+
<input placeholder="<?php echo __("AWS Region",'xcloner-backup-and-restore')?>" id="aws_region" type="text" name="xcloner_aws_region" class="validate" value="<?php echo get_option("xcloner_aws_region")?>" autocomplete="off" >
|
276 |
+
</div>
|
277 |
+
</div>
|
278 |
+
|
279 |
+
<div class="row">
|
280 |
+
<div class="col s12 m3 label">
|
281 |
+
<label for="aws_bucket_name"><?php echo __("AWS Bucket Name",'xcloner-backup-and-restore')?></label>
|
282 |
+
</div>
|
283 |
+
<div class=" col s12 m6">
|
284 |
+
<input placeholder="<?php echo __("AWS Bucket Name",'xcloner-backup-and-restore')?>" id="aws_bucket_name" type="text" name="xcloner_aws_bucket_name" class="validate" value="<?php echo get_option("xcloner_aws_bucket_name")?>" autocomplete="off" >
|
285 |
+
</div>
|
286 |
+
</div>
|
287 |
+
|
288 |
+
<div class="row">
|
289 |
+
<div class="col s12 m3 label">
|
290 |
+
<label for="aws_cleanup_days"><?php echo __("AWS Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
291 |
+
</div>
|
292 |
+
<div class=" col s12 m6">
|
293 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="aws_cleanup_days" type="text" name="xcloner_aws_cleanup_days" class="validate" value="<?php echo get_option("xcloner_aws_cleanup_days")?>">
|
294 |
+
</div>
|
295 |
+
</div>
|
296 |
+
|
297 |
+
<div class="row">
|
298 |
+
<div class="col s6 m4">
|
299 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="aws"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
300 |
+
<i class="material-icons right">save</i>
|
301 |
+
</button>
|
302 |
+
</div>
|
303 |
+
<div class="col s6 m4">
|
304 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="aws" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
305 |
+
<i class="material-icons right">import_export</i>
|
306 |
+
</button>
|
307 |
+
</div>
|
308 |
+
</div>
|
309 |
+
|
310 |
+
</div>
|
311 |
+
</li>
|
312 |
+
|
313 |
+
<!-- DROPBOX STORAGE-->
|
314 |
+
<li id="dropbox">
|
315 |
+
<div class="collapsible-header">
|
316 |
+
<i class="material-icons">computer</i><?php echo __("Dropbox Storage",'xcloner-backup-and-restore')?>
|
317 |
+
<div class="right">
|
318 |
+
<div class="switch">
|
319 |
+
<label>
|
320 |
+
Off
|
321 |
+
<input type="checkbox" name="xcloner_dropbox_enable" class="status" value="1" <?php if(get_option("xcloner_dropbox_enable")) echo "checked"?> \>
|
322 |
+
<span class="lever"></span>
|
323 |
+
On
|
324 |
+
</label>
|
325 |
+
</div>
|
326 |
+
</div>
|
327 |
+
</div>
|
328 |
+
<div class="collapsible-body">
|
329 |
+
|
330 |
+
<div class="row">
|
331 |
+
<div class="col s12 m3 label">
|
332 |
+
|
333 |
+
</div>
|
334 |
+
<div class=" col s12 m6">
|
335 |
+
<p>
|
336 |
+
<?php echo sprintf(__('Visit %s and get your "App secret".'), "<a href='https://www.dropbox.com/developers/apps' target='_blank'>https://www.dropbox.com/developers/apps</a>")?>
|
337 |
+
</p>
|
338 |
+
</div>
|
339 |
+
</div>
|
340 |
+
|
341 |
+
<div class="row">
|
342 |
+
<div class="col s12 m3 label">
|
343 |
+
<label for="dropbox_access_token"><?php echo __("Dropbox Access Token",'xcloner-backup-and-restore')?></label>
|
344 |
+
</div>
|
345 |
+
<div class=" col s12 m6">
|
346 |
+
<input placeholder="<?php echo __("Dropbox Access Token",'xcloner-backup-and-restore')?>" id="dropbox_access_token" type="text" name="xcloner_dropbox_access_token" class="validate" value="<?php echo get_option("xcloner_dropbox_access_token")?>" autocomplete="off" >
|
347 |
+
</div>
|
348 |
+
</div>
|
349 |
+
|
350 |
+
|
351 |
+
<div class="row">
|
352 |
+
<div class="col s12 m3 label">
|
353 |
+
<label for="dropbox_app_secret"><?php echo __("Dropbox App Secret",'xcloner-backup-and-restore')?></label>
|
354 |
+
</div>
|
355 |
+
<div class=" col s12 m6">
|
356 |
+
<input placeholder="<?php echo __("Dropbox App Secret",'xcloner-backup-and-restore')?>" id="dropbox_app_secret" type="text" name="xcloner_dropbox_app_secret" class="validate" value="<?php echo get_option("xcloner_dropbox_app_secret")?>" autocomplete="off" >
|
357 |
+
</div>
|
358 |
+
</div>
|
359 |
+
|
360 |
+
<div class="row">
|
361 |
+
<div class="col s12 m3 label">
|
362 |
+
<label for="dropbox_prefix"><?php echo __("Dropbox Prefix",'xcloner-backup-and-restore')?></label>
|
363 |
+
</div>
|
364 |
+
<div class=" col s12 m6">
|
365 |
+
<input placeholder="<?php echo __("Dropbox Prefix",'xcloner-backup-and-restore')?>" id="dropbox_prefix" type="text" name="xcloner_dropbox_prefix" class="validate" value="<?php echo get_option("xcloner_dropbox_prefix")?>">
|
366 |
+
</div>
|
367 |
+
</div>
|
368 |
+
|
369 |
+
<div class="row">
|
370 |
+
<div class="col s12 m3 label">
|
371 |
+
<label for="dropbox_cleanup_days"><?php echo __("Dropbox Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
372 |
+
</div>
|
373 |
+
<div class=" col s12 m6">
|
374 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="dropbox_cleanup_days" type="text" name="xcloner_dropbox_cleanup_days" class="validate" value="<?php echo get_option("xcloner_dropbox_cleanup_days")?>">
|
375 |
+
</div>
|
376 |
+
</div>
|
377 |
+
|
378 |
+
<div class="row">
|
379 |
+
<div class="col s6 m4">
|
380 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="dropbox"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
381 |
+
<i class="material-icons right">save</i>
|
382 |
+
</button>
|
383 |
+
</div>
|
384 |
+
<div class="col s6 m4">
|
385 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="dropbox" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
386 |
+
<i class="material-icons right">import_export</i>
|
387 |
+
</button>
|
388 |
+
</div>
|
389 |
+
</div>
|
390 |
+
|
391 |
+
</div>
|
392 |
+
</li>
|
393 |
+
|
394 |
+
<!-- AZURE STORAGE-->
|
395 |
+
<li id="azure">
|
396 |
+
<div class="collapsible-header">
|
397 |
+
<i class="material-icons">computer</i><?php echo __("Azure Blog Storage",'xcloner-backup-and-restore')?>
|
398 |
+
<div class="right">
|
399 |
+
<div class="switch">
|
400 |
+
<label>
|
401 |
+
Off
|
402 |
+
<input type="checkbox" name="xcloner_azure_enable" class="status" value="1" <?php if(get_option("xcloner_azure_enable")) echo "checked"?> \>
|
403 |
+
<span class="lever"></span>
|
404 |
+
On
|
405 |
+
</label>
|
406 |
+
</div>
|
407 |
+
</div>
|
408 |
+
</div>
|
409 |
+
<div class="collapsible-body">
|
410 |
+
|
411 |
+
<div class="row">
|
412 |
+
<div class="col s12 m3 label">
|
413 |
+
|
414 |
+
</div>
|
415 |
+
<div class=" col s12 m6">
|
416 |
+
<p>
|
417 |
+
<?php echo sprintf(__('Visit %s and get your "Api Key".','xcloner-backup-and-restore'), '<a href="https://azure.microsoft.com/en-us/services/storage/blobs/" target="_blank">https://azure.microsoft.com/en-us/services/storage/blobs/</a>')?>
|
418 |
+
</p>
|
419 |
+
</div>
|
420 |
+
</div>
|
421 |
+
|
422 |
+
<div class="row">
|
423 |
+
<div class="col s12 m3 label">
|
424 |
+
<label for="azure_account_name"><?php echo __("Azure Account Name",'xcloner-backup-and-restore')?></label>
|
425 |
+
</div>
|
426 |
+
<div class=" col s12 m6">
|
427 |
+
<input placeholder="<?php echo __("Azure Account Name",'xcloner-backup-and-restore')?>" id="azure_account_name" type="text" name="xcloner_azure_account_name" class="validate" value="<?php echo get_option("xcloner_azure_account_name")?>" autocomplete="off" >
|
428 |
+
</div>
|
429 |
+
</div>
|
430 |
+
|
431 |
+
|
432 |
+
<div class="row">
|
433 |
+
<div class="col s12 m3 label">
|
434 |
+
<label for="azure_api_key"><?php echo __("Azure Api Key",'xcloner-backup-and-restore')?></label>
|
435 |
+
</div>
|
436 |
+
<div class=" col s12 m6">
|
437 |
+
<input placeholder="<?php echo __("Azure Api Key",'xcloner-backup-and-restore')?>" id="azure_api_key" type="text" name="xcloner_azure_api_key" class="validate" value="<?php echo get_option("xcloner_azure_api_key")?>" autocomplete="off" >
|
438 |
+
</div>
|
439 |
+
</div>
|
440 |
+
|
441 |
+
<div class="row">
|
442 |
+
<div class="col s12 m3 label">
|
443 |
+
<label for="azure_container"><?php echo __("Azure Container",'xcloner-backup-and-restore')?></label>
|
444 |
+
</div>
|
445 |
+
<div class=" col s12 m6">
|
446 |
+
<input placeholder="<?php echo __("Azure Container",'xcloner-backup-and-restore')?>" id="azure_container" type="text" name="xcloner_azure_container" class="validate" value="<?php echo get_option("xcloner_azure_container")?>">
|
447 |
+
</div>
|
448 |
+
</div>
|
449 |
+
|
450 |
+
<div class="row">
|
451 |
+
<div class="col s12 m3 label">
|
452 |
+
<label for="azure_cleanup_days"><?php echo __("Azure Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
453 |
+
</div>
|
454 |
+
<div class=" col s12 m6">
|
455 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="azure_cleanup_days" type="text" name="xcloner_azure_cleanup_days" class="validate" value="<?php echo get_option("xcloner_azure_cleanup_days")?>">
|
456 |
+
</div>
|
457 |
+
</div>
|
458 |
+
|
459 |
+
<div class="row">
|
460 |
+
<div class="col s6 m4">
|
461 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="azure"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
462 |
+
<i class="material-icons right">save</i>
|
463 |
+
</button>
|
464 |
+
</div>
|
465 |
+
<div class="col s6 m4">
|
466 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="azure" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
467 |
+
<i class="material-icons right">import_export</i>
|
468 |
+
</button>
|
469 |
+
</div>
|
470 |
+
</div>
|
471 |
+
|
472 |
+
</div>
|
473 |
+
</li>
|
474 |
+
|
475 |
+
<!-- BACKBLAZE STORAGE-->
|
476 |
+
<li id="backblaze">
|
477 |
+
<div class="collapsible-header">
|
478 |
+
<i class="material-icons">computer</i><?php echo __("BackBlaze Storage",'xcloner-backup-and-restore')?>
|
479 |
+
<div class="right">
|
480 |
+
<div class="switch">
|
481 |
+
<label>
|
482 |
+
Off
|
483 |
+
<input type="checkbox" name="xcloner_backblaze_enable" class="status" value="1" <?php if(get_option("xcloner_backblaze_enable")) echo "checked"?> \>
|
484 |
+
<span class="lever"></span>
|
485 |
+
On
|
486 |
+
</label>
|
487 |
+
</div>
|
488 |
+
</div>
|
489 |
+
</div>
|
490 |
+
<div class="collapsible-body">
|
491 |
+
|
492 |
+
<div class="row">
|
493 |
+
<div class="col s12 m3 label">
|
494 |
+
|
495 |
+
</div>
|
496 |
+
<div class=" col s12 m6">
|
497 |
+
<p>
|
498 |
+
<?php echo sprintf(__('Visit %s and get your Account Id and Application Key.','xcloner-backup-and-restore'), '<a href="https://secure.backblaze.com/b2_buckets.htm" target="_blank">https://secure.backblaze.com/b2_buckets.htm</a>')?>
|
499 |
+
</p>
|
500 |
+
</div>
|
501 |
+
</div>
|
502 |
+
|
503 |
+
<div class="row">
|
504 |
+
<div class="col s12 m3 label">
|
505 |
+
<label for="backblaze_account_id"><?php echo __("BackBlaze Account Id",'xcloner-backup-and-restore')?></label>
|
506 |
+
</div>
|
507 |
+
<div class=" col s12 m6">
|
508 |
+
<input placeholder="<?php echo __("BackBlaze Account Id",'xcloner-backup-and-restore')?>" id="backblaze_account_id" type="text" name="xcloner_backblaze_account_id" class="validate" value="<?php echo get_option("xcloner_backblaze_account_id")?>" autocomplete="off" >
|
509 |
+
</div>
|
510 |
+
</div>
|
511 |
+
|
512 |
+
|
513 |
+
<div class="row">
|
514 |
+
<div class="col s12 m3 label">
|
515 |
+
<label for="backblaze_application_key"><?php echo __("BackBlaze Application Key",'xcloner-backup-and-restore')?></label>
|
516 |
+
</div>
|
517 |
+
<div class=" col s12 m6">
|
518 |
+
<input placeholder="<?php echo __("BackBlaze Application Key",'xcloner-backup-and-restore')?>" id="backblaze_application_key" type="text" name="xcloner_backblaze_application_key" class="validate" value="<?php echo get_option("xcloner_backblaze_application_key")?>" autocomplete="off" >
|
519 |
+
</div>
|
520 |
+
</div>
|
521 |
+
|
522 |
+
<div class="row">
|
523 |
+
<div class="col s12 m3 label">
|
524 |
+
<label for="backblaze_bucket_name"><?php echo __("BackBlaze Bucket Name",'xcloner-backup-and-restore')?></label>
|
525 |
+
</div>
|
526 |
+
<div class=" col s12 m6">
|
527 |
+
<input placeholder="<?php echo __("BackBlaze Bucket Name",'xcloner-backup-and-restore')?>" id="backblaze_bucket_name" type="text" name="xcloner_backblaze_bucket_name" class="validate" value="<?php echo get_option("xcloner_backblaze_bucket_name")?>" autocomplete="off" >
|
528 |
+
</div>
|
529 |
+
</div>
|
530 |
+
|
531 |
+
<div class="row">
|
532 |
+
<div class="col s12 m3 label">
|
533 |
+
<label for="backblaze_cleanup_days"><?php echo __("BackBlaze Cleanup (days)",'xcloner-backup-and-restore')?></label>
|
534 |
+
</div>
|
535 |
+
<div class=" col s12 m6">
|
536 |
+
<input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="backblaze_cleanup_days" type="text" name="xcloner_backblaze_cleanup_days" class="validate" value="<?php echo get_option("xcloner_backblaze_cleanup_days")?>">
|
537 |
+
</div>
|
538 |
+
</div>
|
539 |
+
|
540 |
+
<div class="row">
|
541 |
+
<div class="col s6 m4">
|
542 |
+
<button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="backblaze"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
|
543 |
+
<i class="material-icons right">save</i>
|
544 |
+
</button>
|
545 |
+
</div>
|
546 |
+
<div class="col s6 m4">
|
547 |
+
<button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="backblaze" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
|
548 |
+
<i class="material-icons right">import_export</i>
|
549 |
+
</button>
|
550 |
+
</div>
|
551 |
+
</div>
|
552 |
+
|
553 |
+
</div>
|
554 |
+
</li>
|
555 |
+
|
556 |
+
<!--<li>
|
557 |
+
<div class="collapsible-header"><i class="material-icons">cloud</i>Amazon S3 Storage</div>
|
558 |
+
<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
|
559 |
+
</li>
|
560 |
+
<li>
|
561 |
+
<div class="collapsible-header"><i class="material-icons">cloud</i>Dropbox Storage</div>
|
562 |
+
<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
|
563 |
+
</li>
|
564 |
+
-->
|
565 |
+
</ul>
|
566 |
+
</div>
|
567 |
+
</div>
|
568 |
+
|
569 |
+
</form>
|
570 |
+
|
571 |
+
<script>
|
572 |
+
jQuery(document).ready(function(){
|
573 |
+
|
574 |
+
var remote_storage = new Xcloner_Remote_Storage();
|
575 |
+
|
576 |
+
jQuery(".remote-storage .status").on("change", function(){
|
577 |
+
remote_storage.toggle_status(this);
|
578 |
+
})
|
579 |
+
|
580 |
+
jQuery(".remote-storage-form #action").on("click", function(){
|
581 |
+
var tag = jQuery(this).val()
|
582 |
+
window.location.hash = "#"+tag;
|
583 |
+
})
|
584 |
+
|
585 |
+
if(location.hash)
|
586 |
+
jQuery(location.hash+" div.collapsible-header").addClass("active");
|
587 |
+
|
588 |
+
jQuery('.collapsible').collapsible();
|
589 |
+
|
590 |
+
Materialize.updateTextFields();
|
591 |
+
});
|
592 |
+
|
593 |
+
</script>
|
admin/partials/xcloner_restore_page.php
ADDED
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$xcloner_settings = new Xcloner_Settings();
|
4 |
+
$logger = new Xcloner_Logger();
|
5 |
+
$xcloner_file_system = new Xcloner_File_System();
|
6 |
+
$xcloner_file_transfer = new Xcloner_File_Transfer();
|
7 |
+
|
8 |
+
$start = 0 ;
|
9 |
+
|
10 |
+
$backup_list = $xcloner_file_system->get_latest_backups();
|
11 |
+
|
12 |
+
?>
|
13 |
+
|
14 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
15 |
+
|
16 |
+
<script>
|
17 |
+
var xcloner_auth_key = '<?php echo md5(AUTH_KEY)?>';
|
18 |
+
</script>
|
19 |
+
|
20 |
+
<div class="row xcloner-restore">
|
21 |
+
<div class="col s12">
|
22 |
+
<ul class="collapsible xcloner-restore " data-collapsible="accordion">
|
23 |
+
<li data-step="1" class="restore-script-upload-step steps active show">
|
24 |
+
<div class="collapsible-header active"><i class="material-icons">settings_remote</i><?php echo __("Restore Script Upload",'xcloner-backup-and-restore')?></div>
|
25 |
+
<div class="collapsible-body row">
|
26 |
+
|
27 |
+
<ul class="text-steps">
|
28 |
+
<li><?php echo __("Please download the restore script from",'xcloner-backup-and-restore')?> <a href='#' onclick="window.location=ajaxurl+'?action=download_restore_script&phar=true'"><strong><?php echo __("here",'xcloner-backup-and-restore')?></strong></a>
|
29 |
+
</li>
|
30 |
+
<li>
|
31 |
+
<?php echo __("Extract the files on your new host",'xcloner-backup-and-restore')?>
|
32 |
+
</li>
|
33 |
+
<li>
|
34 |
+
<?php echo __("Provide url below to the <u>xcloner_restore.php</u> restore script, like http://my_restore_site.com/xcloner_restore.php",'xcloner-backup-and-restore')?>
|
35 |
+
</li>
|
36 |
+
<li>
|
37 |
+
<?php echo __("If your server is not web accessible, like a localhost computer, you can use a DynDNS service or install a blank copy of Wordpress with XCloner in the same environment and start the restore from there.",'xcloner-backup-and-restore')?>
|
38 |
+
</li>
|
39 |
+
<?php if(is_ssl()):?>
|
40 |
+
<li>
|
41 |
+
<?php echo __("We have detected your connection to the site as being secure, so your restore script address must start with https://.")?>
|
42 |
+
</li>
|
43 |
+
<?php endif ?>
|
44 |
+
|
45 |
+
</ul>
|
46 |
+
|
47 |
+
<div class="input-field col l9 s12">
|
48 |
+
<input value="<?php echo (is_ssl())?"https://":"http://"?>" id="restore_script_url" type="text" class="validate" placeholder="Url to XCloner Restore Script, example http://myddns.com/xcloner/xcloner_restore.php" >
|
49 |
+
<label for="restore_script_url"></label>
|
50 |
+
<div id="url_validation_status" class="status"></div>
|
51 |
+
</div>
|
52 |
+
<div class="col l3 s12 right-align">
|
53 |
+
<button class="btn waves-effect waves-light" type="submit" id="validate_url" name="action"><?php echo __("Check",'xcloner-backup-and-restore')?>
|
54 |
+
<i class="material-icons right">send</i>
|
55 |
+
</button>
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
</li>
|
59 |
+
|
60 |
+
<li data-step="2" class="backup-upload-step steps">
|
61 |
+
<div class="collapsible-header active"><i class="material-icons">file_upload</i><?php echo __("Upload Local Backup Archive To Remote Host",'xcloner-backup-and-restore')?>
|
62 |
+
</div>
|
63 |
+
<div class="collapsible-body row">
|
64 |
+
<p><?php echo __("You can skip this step if you want to transfer the archive in some other way, make sure you upload it in the same directory as the restore script from the previous step.",'xcloner-backup-and-restore')?></p>
|
65 |
+
<div class="input-field col s12 l7">
|
66 |
+
<select id="backup_file" name="backup_file" class="browser-default">
|
67 |
+
<option value="" disabled selected><?php echo __("Please select a local backup archive to upload to remote host",'xcloner-backup-and-restore')?></option>
|
68 |
+
<?php if(is_array($backup_list)):?>
|
69 |
+
<?php foreach($backup_list as $file):?>
|
70 |
+
<option value="<?php echo $file['basename']?>">
|
71 |
+
<?php echo $file['basename']?> (<?php echo size_format($file['size'])?>)
|
72 |
+
</option>
|
73 |
+
<?php endforeach?>
|
74 |
+
<?php endif ?>
|
75 |
+
</select>
|
76 |
+
|
77 |
+
<label> </label>
|
78 |
+
<div class="progress">
|
79 |
+
<div class="determinate" style="width: 0%"></div>
|
80 |
+
</div>
|
81 |
+
<div class="status"></div>
|
82 |
+
</div>
|
83 |
+
<div class="col s12 l5 right-align">
|
84 |
+
<div class="toggler">
|
85 |
+
<button class="btn waves-effect waves-light upload-backup normal" type="submit" id="" name="action"><?php echo __("Upload",'xcloner-backup-and-restore')?>
|
86 |
+
<i class="material-icons right">send</i>
|
87 |
+
</button>
|
88 |
+
<button class="btn waves-effect waves-light red upload-backup cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
|
89 |
+
<i class="material-icons right">close</i>
|
90 |
+
</button>
|
91 |
+
</div>
|
92 |
+
<button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_upload_backup" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
|
93 |
+
<i class="material-icons right">navigate_next</i>
|
94 |
+
</button>
|
95 |
+
</div>
|
96 |
+
</div>
|
97 |
+
</li>
|
98 |
+
|
99 |
+
<li data-step="3" class="restore-remote-backup-step steps active">
|
100 |
+
<div class="collapsible-header"><i class="material-icons">folder_open</i><?php echo __("Restore Files Backup Available On Remote Host",'xcloner-backup-and-restore')?>
|
101 |
+
<i class="material-icons right" title="Refresh Remote Backup Files List" id="refresh_remote_backup_file">cached</i>
|
102 |
+
|
103 |
+
<div class="switch right">
|
104 |
+
<label>
|
105 |
+
<?php echo __('Verbose Output', 'xcloner-backup-and-restore')?>
|
106 |
+
<input type="checkbox" id="toggle_file_restore_display" name="toggle_file_restore_display" checked value="1">
|
107 |
+
<span class="lever"></span>
|
108 |
+
|
109 |
+
</label>
|
110 |
+
</div>
|
111 |
+
</div>
|
112 |
+
<div class="collapsible-body row">
|
113 |
+
|
114 |
+
<div class=" col s12 l7">
|
115 |
+
<div class="input-field row">
|
116 |
+
<input type="text" name="remote_restore_path" id="remote_restore_path" class="validate" placeholder="Restore Target Path">
|
117 |
+
<label><?php echo __("Remote Restore Target Path",'xcloner-backup-and-restore')?></label>
|
118 |
+
</div>
|
119 |
+
|
120 |
+
<div class="input-field row">
|
121 |
+
<select id="remote_backup_file" name="remote_backup_file" class="browser-default">
|
122 |
+
<option value="" disabled selected><?php echo __("Please select the remote backup file to restore",'xcloner-backup-and-restore')?></option>
|
123 |
+
</select>
|
124 |
+
<label></label>
|
125 |
+
</div>
|
126 |
+
|
127 |
+
<div class="progress">
|
128 |
+
<div class="indeterminate" style="width: 0%"></div>
|
129 |
+
</div>
|
130 |
+
|
131 |
+
<div class="status"></div>
|
132 |
+
<ul class="files-list"></ul>
|
133 |
+
</div>
|
134 |
+
|
135 |
+
<div class="col s12 l5 right-align">
|
136 |
+
<div class="toggler">
|
137 |
+
<button class="btn waves-effect waves-light restore_remote_backup normal " type="submit" id="" name="action"><?php echo __("Restore",'xcloner-backup-and-restore')?>
|
138 |
+
<i class="material-icons right">send</i>
|
139 |
+
</button>
|
140 |
+
<button class="btn waves-effect waves-light red restore_remote_backup cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
|
141 |
+
<i class="material-icons right">close</i>
|
142 |
+
</button>
|
143 |
+
</div>
|
144 |
+
<button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_remote_backup_step" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
|
145 |
+
<i class="material-icons right">navigate_next</i>
|
146 |
+
</button>
|
147 |
+
</div>
|
148 |
+
</div>
|
149 |
+
</li>
|
150 |
+
|
151 |
+
<li data-step="4" class="restore-remote-database-step steps active">
|
152 |
+
<div class="collapsible-header"><i class="material-icons">list</i><?php echo __("Restore Remote Database - Search and Replace",'xcloner-backup-and-restore')?>
|
153 |
+
<i class="material-icons right" title="Refresh Database Backup Files List" id="refresh_database_file">cached</i>
|
154 |
+
</div>
|
155 |
+
<div class="collapsible-body row">
|
156 |
+
|
157 |
+
<div class="col s12">
|
158 |
+
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50" data-tooltip="<?php echo __('Please provide below the mysql connection details for the remote host database.','xcloner-backup-and-restore')?>" data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
159 |
+
<h5><?php echo __('Remote Mysql Details','xcloner-backup-and-restore')?></h5>
|
160 |
+
</div>
|
161 |
+
<div class=" col s12">
|
162 |
+
<div class="input-field col s12 m6">
|
163 |
+
<input type="text" name="remote_mysql_host" id="remote_mysql_host" class="validate" placeholder="Remote Mysql Hostname" value="localhost">
|
164 |
+
<label><?php echo __("Remote Mysql Hostname",'xcloner-backup-and-restore')?></label>
|
165 |
+
</div>
|
166 |
+
|
167 |
+
<div class="input-field col s12 m6">
|
168 |
+
<input type="text" name="remote_mysql_db" id="remote_mysql_db" class="validate" placeholder="Remote Mysql Database">
|
169 |
+
<label><?php echo __("Remote Mysql Database",'xcloner-backup-and-restore')?></label>
|
170 |
+
</div>
|
171 |
+
|
172 |
+
<div class="input-field col s12 m6">
|
173 |
+
<input type="text" name="remote_mysql_user" id="remote_mysql_user" class="validate" placeholder="Remote Mysql Username">
|
174 |
+
<label><?php echo __("Remote Mysql Username",'xcloner-backup-and-restore')?></label>
|
175 |
+
</div>
|
176 |
+
|
177 |
+
|
178 |
+
<div class="input-field col s12 m6">
|
179 |
+
<input type="text" name="remote_mysql_pass" id="remote_mysql_pass" class="validate" placeholder="Remote Mysql Password">
|
180 |
+
<label><?php echo __("Remote Mysql Password",'xcloner-backup-and-restore')?></label>
|
181 |
+
</div>
|
182 |
+
|
183 |
+
</div>
|
184 |
+
<div class="col s12">
|
185 |
+
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50" data-html="true" data-tooltip="<?php echo __('I will attempt to replace all mysql backup records matching the provided Source Url with the provided Target Url. <br />Leave blank the Target Url if you would like to skip this option. <br />As a bonus, I will also replace all matching serialized data and fix it\'s parsing.','xcloner-backup-and-restore')?>" data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
186 |
+
<h5><?php echo __('Remote Mysql Search and Replace','xcloner-backup-and-restore')?></h5>
|
187 |
+
</div>
|
188 |
+
<div class="col s12">
|
189 |
+
<div class="input-field col s12 m6 ">
|
190 |
+
<input type="text" name="wp_home_url" id="wp_home_url" class="validate" placeholder="WP Home Url" value="<?php echo home_url();?>">
|
191 |
+
<label><?php echo __("Source Home Url",'xcloner-backup-and-restore')?></label>
|
192 |
+
</div>
|
193 |
+
|
194 |
+
<div class="input-field col s12 m6 ">
|
195 |
+
<input type="text" name="remote_restore_url" id="remote_restore_url" class="validate" placeholder="Restore Target Url">
|
196 |
+
<label><?php echo __("With Target Home Url",'xcloner-backup-and-restore')?></label>
|
197 |
+
</div>
|
198 |
+
|
199 |
+
<?php if( site_url() != home_url()) : ?>
|
200 |
+
<div class="input-field col s12 m6 ">
|
201 |
+
<input type="text" name="wp_site_url" id="wp_site_url" class="validate" placeholder="WP Site Url" value="<?php echo site_url();?>">
|
202 |
+
<label><?php echo __("Source Site Url",'xcloner-backup-and-restore')?></label>
|
203 |
+
</div>
|
204 |
+
|
205 |
+
<div class="input-field col s12 m6 ">
|
206 |
+
<input type="text" name="remote_restore_site_url" id="remote_restore_site_url" class="validate" placeholder="Restore Target Url">
|
207 |
+
<label><?php echo __("With Target Site Url",'xcloner-backup-and-restore')?></label>
|
208 |
+
</div>
|
209 |
+
|
210 |
+
<?php endif;?>
|
211 |
+
</div>
|
212 |
+
|
213 |
+
<div class=" col s12 l7">
|
214 |
+
<div class="input-field row">
|
215 |
+
<select id="remote_database_file" name="remote_database_file" class="browser-default">
|
216 |
+
<option value="" disabled selected><?php echo __("Please select the remote database backup file to restore",'xcloner-backup-and-restore')?></option>
|
217 |
+
</select>
|
218 |
+
|
219 |
+
<label></label>
|
220 |
+
</div>
|
221 |
+
|
222 |
+
<div class="progress">
|
223 |
+
<div class="determinate" style="width: 0%"></div>
|
224 |
+
</div>
|
225 |
+
|
226 |
+
<div class="status"></div>
|
227 |
+
<div class="query-box">
|
228 |
+
<h6><?php echo __('Use the field below to fix your mysql query and Retry again the Restore', 'xcloner-backup-and-restore')?></h6>
|
229 |
+
<textarea class="query-list" cols="5"></textarea>
|
230 |
+
</div>
|
231 |
+
</div>
|
232 |
+
|
233 |
+
<div class="col s12 l5 right-align">
|
234 |
+
<div class="toggler">
|
235 |
+
<button class="btn waves-effect waves-light restore_remote_mysqldump normal " type="submit" id="" name="action"><?php echo __("Restore",'xcloner-backup-and-restore')?>
|
236 |
+
<i class="material-icons right">send</i>
|
237 |
+
</button>
|
238 |
+
<button class="btn waves-effect waves-light red restore_remote_mysqldump cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
|
239 |
+
<i class="material-icons right">close</i>
|
240 |
+
</button>
|
241 |
+
</div>
|
242 |
+
|
243 |
+
<button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_restore_remote_database_step" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
|
244 |
+
<i class="material-icons right">navigate_next</i>
|
245 |
+
</button>
|
246 |
+
|
247 |
+
</div>
|
248 |
+
|
249 |
+
</div>
|
250 |
+
</li>
|
251 |
+
|
252 |
+
<li data-step="5" class="restore-finish-step steps active">
|
253 |
+
<div class="collapsible-header"><i class="material-icons">folder_open</i><?php echo __("Finishing up...",'xcloner-backup-and-restore')?>
|
254 |
+
</div>
|
255 |
+
<div class="collapsible-body row">
|
256 |
+
|
257 |
+
<div class="row">
|
258 |
+
<div class="col s4">
|
259 |
+
<label><?php echo __("Update wp-config.php mysql details and update the restored site Url",'xcloner-backup-and-restore')?></label>
|
260 |
+
</div>
|
261 |
+
|
262 |
+
<div class="col s8">
|
263 |
+
<div class="switch">
|
264 |
+
<label>
|
265 |
+
Off
|
266 |
+
<input type="checkbox" id="update_remote_site_url" name="update_remote_site_url" checked value="1">
|
267 |
+
<span class="lever"></span>
|
268 |
+
On
|
269 |
+
</label>
|
270 |
+
</div>
|
271 |
+
</div>
|
272 |
+
</div>
|
273 |
+
|
274 |
+
<div class="row">
|
275 |
+
<div class="col s4">
|
276 |
+
<label><?php echo __("Delete Restored Backup Temporary Folder",'xcloner-backup-and-restore')?></label>
|
277 |
+
</div>
|
278 |
+
<div class="col s8">
|
279 |
+
<div class="switch">
|
280 |
+
<label>
|
281 |
+
Off
|
282 |
+
<input type="checkbox" id="delete_backup_temporary_folder" name="delete_backup_temporary_folder" checked value="1">
|
283 |
+
<span class="lever"></span>
|
284 |
+
On
|
285 |
+
</label>
|
286 |
+
</div>
|
287 |
+
</div>
|
288 |
+
</div>
|
289 |
+
|
290 |
+
<div class="row">
|
291 |
+
<div class="col s4">
|
292 |
+
<label><?php echo __("Delete Restore Script",'xcloner-backup-and-restore')?></label>
|
293 |
+
</div>
|
294 |
+
<div class="col s8">
|
295 |
+
<div class="switch">
|
296 |
+
<label>
|
297 |
+
Off
|
298 |
+
<input type="checkbox" id="delete_restore_script" name="delete_restore_script" checked value="1">
|
299 |
+
<span class="lever"></span>
|
300 |
+
On
|
301 |
+
</label>
|
302 |
+
</div>
|
303 |
+
</div>
|
304 |
+
</div>
|
305 |
+
|
306 |
+
<div class=" row col s12">
|
307 |
+
<div class="status"></div>
|
308 |
+
</div>
|
309 |
+
|
310 |
+
<div class=" row col s12 center-align" id="xcloner_restore_finish">
|
311 |
+
<h5><?php echo __("Thank you for using XCloner.",'xcloner-backup-and-restore')?></h5>
|
312 |
+
<h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'),'<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore" target="_blank">Wordpress XCloner forums</a>') ?></h6>
|
313 |
+
<a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow @thinkovi</a>
|
314 |
+
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
315 |
+
</div>
|
316 |
+
|
317 |
+
<div class="col s12 center-align">
|
318 |
+
|
319 |
+
<button class="btn waves-effect waves-light teal" type="submit" id="restore_finish" name="action"><?php echo __("Finish",'xcloner-backup-and-restore')?>
|
320 |
+
<i class="material-icons right">navigate_next</i>
|
321 |
+
</button>
|
322 |
+
</div>
|
323 |
+
</div>
|
324 |
+
</li>
|
325 |
+
|
326 |
+
</ul>
|
327 |
+
</div>
|
328 |
+
</div>
|
329 |
+
|
330 |
+
|
331 |
+
|
admin/partials/xcloner_scheduled_backups_page.php
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$xcloner_scheduler = new Xcloner_Scheduler();
|
3 |
+
$xcloner_remote_storage = new Xcloner_Remote_Storage();
|
4 |
+
$available_storages = $xcloner_remote_storage->get_available_storages();
|
5 |
+
?>
|
6 |
+
<?php if(!defined("DISABLE_WP_CRON") or !DISABLE_WP_CRON): ?>
|
7 |
+
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
8 |
+
<p><strong>
|
9 |
+
<?php echo sprintf(__('We have noticed that DISABLE_WP_CRON is disabled, we recommend enabling that and setting up wp-cron.php to run manually through your hosting account scheduler as explained <a href="%s" target="_blank">here</a>', 'xcloner-backup-and-restore'), "http://www.inmotionhosting.com/support/website/wordpress/disabling-the-wp-cronphp-in-wordpress") ?>
|
10 |
+
</strong>
|
11 |
+
</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
|
12 |
+
</div>
|
13 |
+
<?php endif?>
|
14 |
+
|
15 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
16 |
+
|
17 |
+
<div class="row">
|
18 |
+
<table id="scheduled_backups" class="col s12" cellspacing="0" width="100%">
|
19 |
+
<thead>
|
20 |
+
<tr class="grey lighten-2">
|
21 |
+
<th><?php echo __('ID', 'xcloner-backup-and-restore')?></th>
|
22 |
+
<th><?php echo __('Schedule Name', 'xcloner-backup-and-restore')?></th>
|
23 |
+
<th><?php echo __('Recurrence', 'xcloner-backup-and-restore')?></th>
|
24 |
+
<th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore')?></th>
|
25 |
+
<th><?php echo __('Remote Storage', 'xcloner-backup-and-restore')?></th>
|
26 |
+
<th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore')?></th>
|
27 |
+
<th><?php echo __('Status', 'xcloner-backup-and-restore')?></th>
|
28 |
+
<th class="no-sort"><?php echo __('Action', 'xcloner-backup-and-restore')?></th>
|
29 |
+
</tr>
|
30 |
+
</thead>
|
31 |
+
<tfoot>
|
32 |
+
<tr>
|
33 |
+
<th><?php echo __('ID', 'xcloner-backup-and-restore')?></th>
|
34 |
+
<th><?php echo __('Schedule Name', 'xcloner-backup-and-restore')?></th>
|
35 |
+
<th><?php echo __('Recurrence', 'xcloner-backup-and-restore')?></th>
|
36 |
+
<th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore')?></th>
|
37 |
+
<th><?php echo __('Remote Storage', 'xcloner-backup-and-restore')?></th>
|
38 |
+
<th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore')?></th>
|
39 |
+
<th><?php echo __('Status', 'xcloner-backup-and-restore')?></th>
|
40 |
+
<th><?php echo __('Action', 'xcloner-backup-and-restore')?></th>
|
41 |
+
</tr>
|
42 |
+
</tfoot>
|
43 |
+
<tbody>
|
44 |
+
</tbody>
|
45 |
+
</table>
|
46 |
+
</div>
|
47 |
+
|
48 |
+
<div class="row">
|
49 |
+
<div class="col s12 m6 offset-m6 teal lighten-1" id="server_time">
|
50 |
+
<h2><?php echo __('Current Server Time', 'xcloner-backup-and-restore')?>: <span class="right"><?php echo date("Y/m/d H:i")?></span></h2>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
|
55 |
+
<!-- Modal Structure -->
|
56 |
+
<div id="edit_schedule" class="modal">
|
57 |
+
<form method="POST" action="" id="save_schedule">
|
58 |
+
<input type="hidden" name="id" id="schedule_id_hidden">
|
59 |
+
<input type="hidden" name="action" value="save_schedule">
|
60 |
+
<div class="modal-content">
|
61 |
+
|
62 |
+
<div class="row">
|
63 |
+
<div class="col s12 m6">
|
64 |
+
<h4><?php echo __('Edit Schedule', 'xcloner-backup-and-restore') ?> #<span id="schedule_id"></span></h4>
|
65 |
+
</div>
|
66 |
+
|
67 |
+
<div class="col s12 m6 right-align">
|
68 |
+
<div class="switch">
|
69 |
+
<label>
|
70 |
+
<?php echo __('Off', 'xcloner-backup-and-restore') ?>
|
71 |
+
<input type="checkbox" id="status" name="status" value="1">
|
72 |
+
<span class="lever"></span>
|
73 |
+
<?php echo __('On', 'xcloner-backup-and-restore') ?>
|
74 |
+
</label>
|
75 |
+
</div>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
|
79 |
+
<p>
|
80 |
+
|
81 |
+
<ul class="nav-tab-wrapper content row">
|
82 |
+
<li> <a href="#scheduler_settings" class="nav-tab col s12 m6 nav-tab-active"><?php echo __('Scheduler Settings', 'xcloner-backup-and-restore') ?></a></li>
|
83 |
+
<li> <a href="#advanced_scheduler_settings" class="nav-tab col s12 m6"><?php echo __('Advanced', 'xcloner-backup-and-restore') ?></a></li>
|
84 |
+
</ul>
|
85 |
+
|
86 |
+
<div class="nav-tab-wrapper-content">
|
87 |
+
<div id="scheduler_settings" class="tab-content active">
|
88 |
+
|
89 |
+
<div class="row">
|
90 |
+
<div class="input-field col s12 l12">
|
91 |
+
<input placeholder="" name="schedule_name" id="schedule_name" type="text" required value="">
|
92 |
+
<label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
|
93 |
+
</div>
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<div class="row">
|
97 |
+
<div class="input-field col s12 l6">
|
98 |
+
<input placeholder="" name="schedule_start_date" id="schedule_start_date" type="datetime" value="">
|
99 |
+
<label for="schedule_start_date" class="active"><?php echo __('Schedule Start At', 'xcloner-backup-and-restore') ?>:</label>
|
100 |
+
</div>
|
101 |
+
|
102 |
+
<div class="input-field col s12 l6">
|
103 |
+
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
104 |
+
<option value="" disabled selected><?php echo __('Schedule Recurrence', 'xcloner-backup-and-restore') ?></option>
|
105 |
+
<option value="single"><?php echo __("Don't Repeat",'xcloner-backup-and-restore')?></option>
|
106 |
+
<option value="hourly"><?php echo __("Hourly",'xcloner-backup-and-restore')?></option>
|
107 |
+
<option value="daily"><?php echo __("Daily",'xcloner-backup-and-restore')?></option>
|
108 |
+
<option value="weekly"><?php echo __("Weekly",'xcloner-backup-and-restore')?></option>
|
109 |
+
<option value="monthly"><?php echo __("Monthly",'xcloner-backup-and-restore')?></option>
|
110 |
+
</select>
|
111 |
+
</div>
|
112 |
+
</div>
|
113 |
+
|
114 |
+
<?php if(sizeof($available_storages)):?>
|
115 |
+
<div class="row">
|
116 |
+
<div class="input-field col s12 l6">
|
117 |
+
<select name="schedule_storage" id="schedule_storage" class="validate" >
|
118 |
+
<option value="" selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
|
119 |
+
<?php foreach($available_storages as $storage=>$text):?>
|
120 |
+
<option value="<?php echo $storage?>"><?php echo $text?></option>
|
121 |
+
<?php endforeach?>
|
122 |
+
</select>
|
123 |
+
<label><?php echo __('Send To Remote Storage ', 'xcloner-backup-and-restore') ?></label>
|
124 |
+
</div>
|
125 |
+
</div>
|
126 |
+
<?php endif?>
|
127 |
+
|
128 |
+
<div class="row">
|
129 |
+
<div class="input-field col s12 l12">
|
130 |
+
<input placeholder="" name="email_notification" id="email_notification" type="text" value="">
|
131 |
+
<label for="email_notification"><?php echo __('Email Notification Address', 'xcloner-backup-and-restore') ?></label>
|
132 |
+
</div>
|
133 |
+
</div>
|
134 |
+
|
135 |
+
</div>
|
136 |
+
|
137 |
+
<div id="advanced_scheduler_settings" class="tab-content">
|
138 |
+
<div class="row">
|
139 |
+
<div class="input-field col s12 l12">
|
140 |
+
<input placeholder="" name="backup_name" id="backup_name" type="text" required value="">
|
141 |
+
<label for="backup_name"><?php echo __('Backup Name', 'xcloner-backup-and-restore') ?></label>
|
142 |
+
</div>
|
143 |
+
</div>
|
144 |
+
|
145 |
+
<div class="row">
|
146 |
+
<div class="input-field col s12 l12">
|
147 |
+
<textarea id="table_params" name="table_params" class="materialize-textarea" rows="15"></textarea>
|
148 |
+
<label for="table_params" class="active"><?php echo __('Included Database Data', 'xcloner-backup-and-restore') ?></label>
|
149 |
+
</div>
|
150 |
+
</div>
|
151 |
+
|
152 |
+
<div class="row">
|
153 |
+
<div class="input-field col s12 l12">
|
154 |
+
<textarea id="excluded_files" name="excluded_files" class="materialize-textarea" rows="15"></textarea>
|
155 |
+
<label for="excluded_files" class="active"><?php echo __('Excluded Files', 'xcloner-backup-and-restore') ?></label>
|
156 |
+
</div>
|
157 |
+
</div>
|
158 |
+
</div>
|
159 |
+
</div>
|
160 |
+
|
161 |
+
<div class="row">
|
162 |
+
|
163 |
+
<div class="input-field col s12">
|
164 |
+
<button class="right btn waves-effect waves-light" type="submit" name="action"><?php echo __('Save', 'xcloner-backup-and-restore') ?>
|
165 |
+
<i class="material-icons right">send</i>
|
166 |
+
</button>
|
167 |
+
</div>
|
168 |
+
</div>
|
169 |
+
</p>
|
170 |
+
</div>
|
171 |
+
</form>
|
172 |
+
</div>
|
173 |
+
|
administrator/.htaccess
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
order deny,allow
|
2 |
-
deny from all
|
|
|
|
administrator/backups/.htaccess
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
order deny,allow
|
2 |
-
deny from all
|
|
|
|
administrator/backups/index.html
DELETED
File without changes
|
administrator/index.html
DELETED
File without changes
|
browser/file.gif
DELETED
Binary file
|
browser/filebrowser.css
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
body{
|
2 |
-
font-family:Arial, Helvetica, sans-serif;
|
3 |
-
font-size: 76%;
|
4 |
-
}
|
5 |
-
#browser{
|
6 |
-
width: 90%;
|
7 |
-
border: 1px solid #ddd;
|
8 |
-
padding: 0.2em 1em;
|
9 |
-
margin:1em;
|
10 |
-
}
|
11 |
-
.searching{
|
12 |
-
background: #efefef url(components/com_cloner/browser/timer.gif) no-repeat 46% 46%;
|
13 |
-
}
|
14 |
-
#header {
|
15 |
-
color: #FFFFFF;
|
16 |
-
background-color: #3571CA;
|
17 |
-
padding: 0.2em;
|
18 |
-
}
|
19 |
-
#content {
|
20 |
-
padding: 0.2em;
|
21 |
-
border: 1px solid #999999;
|
22 |
-
}
|
23 |
-
li.file {
|
24 |
-
white-space: nowrap;
|
25 |
-
}
|
26 |
-
li.folder {
|
27 |
-
white-space: nowrap;
|
28 |
-
}
|
29 |
-
li.folder a{
|
30 |
-
font-size: 16px;
|
31 |
-
color: #000000;
|
32 |
-
background: #efefef;
|
33 |
-
|
34 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
browser/files_inpage.php
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
defined( '_VALID_MOS' ) or die( 'Restricted access' );
|
3 |
-
|
4 |
-
$thisApp=$_SERVER['PHP_SELF'] . "?browse=true";
|
5 |
-
|
6 |
-
$fp = @fopen($_CONFIG['exfile'], "w");
|
7 |
-
if($fp){
|
8 |
-
@fwrite($fp, $_CONFIG['cron_exclude']);
|
9 |
-
@fclose($fp);
|
10 |
-
}
|
11 |
-
|
12 |
-
if(isset($_GET['browse'])){
|
13 |
-
$dir = isset($_GET['dir']) ? $_GET['dir'] : '/files';
|
14 |
-
if(strpos($dir, "../")===true){
|
15 |
-
exit;
|
16 |
-
}
|
17 |
-
}else{
|
18 |
-
|
19 |
-
echo "Please wait... we are loading the folder structure";
|
20 |
-
|
21 |
-
}
|
22 |
-
|
23 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
browser/files_xml.php
DELETED
@@ -1,266 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* XCloner
|
4 |
-
* Oficial website: http://www.xcloner.com/
|
5 |
-
* -------------------------------------------
|
6 |
-
* Creator: Liuta Romulus Ovidiu
|
7 |
-
* License: GNU/GPL
|
8 |
-
* Email: admin@xcloner.com
|
9 |
-
* Revision: 1.0
|
10 |
-
* Date: November 2010
|
11 |
-
**/
|
12 |
-
|
13 |
-
defined( '_VALID_MOS' ) or die( 'Restricted access' );
|
14 |
-
|
15 |
-
header("Cache-Control: no-cache");
|
16 |
-
header("Pragma: nocache");
|
17 |
-
header("Content-Type: text/xml; charset=utf-8");
|
18 |
-
|
19 |
-
error_reporting(2);
|
20 |
-
|
21 |
-
include(realpath(dirname(__FILE__))."/../cloner.config.php");
|
22 |
-
include(realpath(dirname(__FILE__)) ."/../common.php");
|
23 |
-
|
24 |
-
$request_dir = str_replace(array(".."), array(""), $_REQUEST['dir']);
|
25 |
-
$dir = realpath(realpath($_CONFIG['backup_path']) . DIRECTORY_SEPARATOR. $request_dir);
|
26 |
-
|
27 |
-
if(!stristr($dir, realpath($_CONFIG['backup_path'])))
|
28 |
-
return false;
|
29 |
-
|
30 |
-
$parent_dir = dirname($dir);
|
31 |
-
|
32 |
-
if(strlen($parent_dir) < strlen($_CONFIG['backup_path']))
|
33 |
-
$parent_dir = "/";
|
34 |
-
|
35 |
-
$parent_dir = str_replace(realpath($_CONFIG['backup_path']),"",$parent_dir);
|
36 |
-
$request_dir = str_replace(realpath($_CONFIG['backup_path']),"",$dir);
|
37 |
-
|
38 |
-
$fulldir = $dir;
|
39 |
-
$f_arr = array();
|
40 |
-
$d_arr =array();
|
41 |
-
$exclude = array();
|
42 |
-
$_COOKIES = array();
|
43 |
-
$exfile = realpath($_CONFIG['backup_path']."/administrator/backups")."/.excl";
|
44 |
-
|
45 |
-
if(isset($_REQUEST['path']) and $_REQUEST['path'])
|
46 |
-
$path = realpath($dir.DIRECTORY_SEPARATOR.$_REQUEST['path']);
|
47 |
-
|
48 |
-
$loc = $_REQUEST['dir'];
|
49 |
-
|
50 |
-
if(!is_dir($_CONFIG['backup_path'])){
|
51 |
-
|
52 |
-
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] does not exist!\"></directory>";
|
53 |
-
exit;
|
54 |
-
|
55 |
-
}elseif(!is_readable($_CONFIG['backup_path'])){
|
56 |
-
|
57 |
-
echo "<directory location=\"Error: Directory $_CONFIG[backup_path] is not readable!\"></directory>";
|
58 |
-
exit;
|
59 |
-
|
60 |
-
}
|
61 |
-
|
62 |
-
|
63 |
-
if($_REQUEST['act'] == "checkall"){
|
64 |
-
|
65 |
-
check($dir, $exfile, 1);
|
66 |
-
|
67 |
-
}
|
68 |
-
elseif($_REQUEST['act'] == "uncheckall"){
|
69 |
-
|
70 |
-
check($dir, $exfile, 0);
|
71 |
-
|
72 |
-
}
|
73 |
-
|
74 |
-
if($loc == "")
|
75 |
-
$loc = "/";
|
76 |
-
|
77 |
-
|
78 |
-
$data = "";
|
79 |
-
|
80 |
-
if($fp = @fopen($exfile,"r")){
|
81 |
-
|
82 |
-
while(!feof($fp)){
|
83 |
-
$data .= fread($fp, 1024);
|
84 |
-
}
|
85 |
-
fclose($fp);
|
86 |
-
}
|
87 |
-
$_COOKIES = explode("\r\n", $data);
|
88 |
-
|
89 |
-
|
90 |
-
$exc = 0;
|
91 |
-
|
92 |
-
if($fp = @fopen($exfile,"w")){
|
93 |
-
|
94 |
-
if(is_array($_COOKIES))
|
95 |
-
|
96 |
-
foreach($_COOKIES as $key=>$value)
|
97 |
-
|
98 |
-
if(trim($value!="")){
|
99 |
-
|
100 |
-
if($value!=$path){
|
101 |
-
|
102 |
-
fwrite($fp, $value."\r\n");
|
103 |
-
|
104 |
-
}else{
|
105 |
-
|
106 |
-
$exc = 1;
|
107 |
-
}
|
108 |
-
}
|
109 |
-
|
110 |
-
if((!$exc)&&(trim($path)!=''))
|
111 |
-
|
112 |
-
fwrite($fp, $path."\r\n");
|
113 |
-
|
114 |
-
fclose($fp);
|
115 |
-
}
|
116 |
-
|
117 |
-
|
118 |
-
$data = "";
|
119 |
-
|
120 |
-
if($fp = @fopen($exfile,"r")){
|
121 |
-
|
122 |
-
while(!feof($fp)){
|
123 |
-
|
124 |
-
$data .= fread($fp, 1024);
|
125 |
-
|
126 |
-
}
|
127 |
-
|
128 |
-
fclose($fp);
|
129 |
-
|
130 |
-
}
|
131 |
-
else{
|
132 |
-
|
133 |
-
echo "<directory location=\"Error: Unable to write to file $exfile\"></directory>";
|
134 |
-
exit;
|
135 |
-
|
136 |
-
}
|
137 |
-
|
138 |
-
$_COOKIES = explode("\r\n", $data);
|
139 |
-
|
140 |
-
|
141 |
-
if(is_array($_COOKIES))
|
142 |
-
foreach($_COOKIES as $key=>$value)
|
143 |
-
if($value!='')
|
144 |
-
{
|
145 |
-
|
146 |
-
$exclude[] = $value;
|
147 |
-
|
148 |
-
|
149 |
-
}
|
150 |
-
|
151 |
-
sort($exclude);
|
152 |
-
|
153 |
-
if (@is_dir($fulldir)){
|
154 |
-
|
155 |
-
if ($root=@opendir($fulldir)){
|
156 |
-
while ($file=@readdir($root)){
|
157 |
-
if(@is_dir($fulldir.DIRECTORY_SEPARATOR.$file)){
|
158 |
-
//is folder
|
159 |
-
if($file=="." || $file==".."){continue;}
|
160 |
-
else{
|
161 |
-
$d_arr[] = $file;
|
162 |
-
}
|
163 |
-
}else{
|
164 |
-
//is file
|
165 |
-
$type=substr($file, strrpos($file, '.'));
|
166 |
-
$f_arr[] = $file;
|
167 |
-
}
|
168 |
-
}
|
169 |
-
}
|
170 |
-
|
171 |
-
sort($f_arr);
|
172 |
-
|
173 |
-
sort($d_arr);
|
174 |
-
|
175 |
-
|
176 |
-
echo "<directory current_dir=\"".htmlspecialchars($request_dir.DIRECTORY_SEPARATOR)."\" location=\"".htmlspecialchars($dir)."\" parent_location=\"".htmlspecialchars($parent_dir)."\" >";
|
177 |
-
|
178 |
-
foreach($d_arr as $file){
|
179 |
-
if(in_array($dir.DIRECTORY_SEPARATOR.$file, $_COOKIES))
|
180 |
-
$check = 'checked';
|
181 |
-
else
|
182 |
-
$check = '';
|
183 |
-
echo "<folder check='$check'>".htmlspecialchars($file)."</folder>";
|
184 |
-
|
185 |
-
}
|
186 |
-
|
187 |
-
foreach($f_arr as $file){
|
188 |
-
if(in_array($dir.DIRECTORY_SEPARATOR.$file, $_COOKIES))
|
189 |
-
$check = 'checked';
|
190 |
-
else
|
191 |
-
$check = '';
|
192 |
-
|
193 |
-
echo "<file check='$check' link=\"#\">".htmlspecialchars($file)."</file>";
|
194 |
-
|
195 |
-
}
|
196 |
-
|
197 |
-
foreach($exclude as $file)
|
198 |
-
echo "<message>".str_replace("","",htmlspecialchars($file))."</message>";
|
199 |
-
|
200 |
-
echo "</directory>";
|
201 |
-
|
202 |
-
|
203 |
-
}
|
204 |
-
|
205 |
-
function check($loc, $exfile, $act ){
|
206 |
-
global $_CONFIG;
|
207 |
-
|
208 |
-
$fulldir = $loc;
|
209 |
-
$flist = array();
|
210 |
-
$_COOKIES = array();
|
211 |
-
if (@is_dir($fulldir)){
|
212 |
-
|
213 |
-
if ($root=@opendir($fulldir)){
|
214 |
-
|
215 |
-
while ($file=readdir($root))
|
216 |
-
if(($file!='.')&&($file != '..'))
|
217 |
-
{
|
218 |
-
|
219 |
-
$flist[] = $loc .DIRECTORY_SEPARATOR. $file;
|
220 |
-
|
221 |
-
}
|
222 |
-
}
|
223 |
-
}
|
224 |
-
|
225 |
-
if($fp = @fopen($exfile,"r")){
|
226 |
-
|
227 |
-
while(!feof($fp)){
|
228 |
-
$data .= fread($fp, 1024);
|
229 |
-
}
|
230 |
-
fclose($fp);
|
231 |
-
}
|
232 |
-
|
233 |
-
$_COOKIES = explode("\r\n", $data);
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
if($act == 1){
|
238 |
-
|
239 |
-
$flist = @array_merge($_COOKIES, $flist);
|
240 |
-
|
241 |
-
}
|
242 |
-
else{
|
243 |
-
|
244 |
-
$flist = @array_diff($_COOKIES, $flist);
|
245 |
-
|
246 |
-
}
|
247 |
-
|
248 |
-
$flist = @array_unique($flist);
|
249 |
-
|
250 |
-
if($fp = @fopen($exfile,"w")){
|
251 |
-
|
252 |
-
foreach($flist as $file){
|
253 |
-
|
254 |
-
fwrite($fp, $file."\r\n");
|
255 |
-
|
256 |
-
}
|
257 |
-
|
258 |
-
fclose($fp);
|
259 |
-
}
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
}
|
265 |
-
|
266 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
browser/folder.gif
DELETED
Binary file
|
browser/timer.gif
DELETED
Binary file
|
browser/xmlhttp.js
DELETED
@@ -1,156 +0,0 @@
|
|
1 |
-
var request;
|
2 |
-
var targetDiv;
|
3 |
-
function loadXMLDoc(url) {
|
4 |
-
// for Mozilla and othes who support XMLHttpRequest
|
5 |
-
if (window.XMLHttpRequest) {
|
6 |
-
request = new XMLHttpRequest();
|
7 |
-
request.onreadystatechange = processXMLRequest;
|
8 |
-
request.open("GET", url, true);
|
9 |
-
request.send(null);
|
10 |
-
// for Interweb Explorer
|
11 |
-
} else if (window.ActiveXObject) {
|
12 |
-
request = new ActiveXObject("Microsoft.XMLHTTP");
|
13 |
-
if(request){
|
14 |
-
request.onreadystatechange = processXMLRequest;
|
15 |
-
request.open("GET", url, true);
|
16 |
-
request.send();
|
17 |
-
}
|
18 |
-
} else{
|
19 |
-
return false;
|
20 |
-
}
|
21 |
-
}
|
22 |
-
|
23 |
-
function processXMLRequest() {
|
24 |
-
// only if data is loaded
|
25 |
-
if (request.readyState == 4) {
|
26 |
-
// only if result of HTTP request was an OK
|
27 |
-
if (request.status == 200 || request.readyState ==304) {
|
28 |
-
useXML(request.responseXML);
|
29 |
-
} else{
|
30 |
-
targetDiv=document.getElementById("browser");
|
31 |
-
targetDiv.innerHTML="Unable to load XML";
|
32 |
-
}
|
33 |
-
}
|
34 |
-
}
|
35 |
-
|
36 |
-
function do_browser(){
|
37 |
-
targetDiv=document.getElementById("browser");
|
38 |
-
|
39 |
-
if(loadXMLDoc("admin-ajax.php?action=files_xml")){
|
40 |
-
targetDiv.className="searching";
|
41 |
-
targetDiv.innerHTML="";
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
function createCookie(name,value,days)
|
46 |
-
{
|
47 |
-
if (days)
|
48 |
-
{
|
49 |
-
var date = new Date();
|
50 |
-
date.setTime(date.getTime()+(days*24*60*60*1000));
|
51 |
-
var expires = "; expires="+date.toGMTString();
|
52 |
-
}
|
53 |
-
else var expires = "";
|
54 |
-
document.cookie = name+"="+value+expires+"; path=/";
|
55 |
-
}
|
56 |
-
|
57 |
-
function readCookie(name)
|
58 |
-
{
|
59 |
-
var nameEQ = name + "=";
|
60 |
-
var ca = document.cookie.split(';');
|
61 |
-
|
62 |
-
for(var i=0;i < ca.length;i++)
|
63 |
-
{
|
64 |
-
var c = ca[i];
|
65 |
-
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
66 |
-
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
67 |
-
}
|
68 |
-
return null;
|
69 |
-
}
|
70 |
-
|
71 |
-
function eraseCookie(name)
|
72 |
-
{
|
73 |
-
createCookie(name,"",-1);
|
74 |
-
}
|
75 |
-
|
76 |
-
function checkp(value, loc){
|
77 |
-
if(readCookie('path_'+value)){
|
78 |
-
eraseCookie('path_'+value);
|
79 |
-
}
|
80 |
-
else{
|
81 |
-
createCookie('path_'+value,value,'1');
|
82 |
-
}
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
}
|
88 |
-
function checkc(value){
|
89 |
-
if(readCookie(value)){
|
90 |
-
check = 'checked';
|
91 |
-
}
|
92 |
-
else{
|
93 |
-
check = '';
|
94 |
-
}
|
95 |
-
return check;
|
96 |
-
}
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
function useXML(xmlInfo){
|
103 |
-
targetDiv.className="";
|
104 |
-
message = "";
|
105 |
-
|
106 |
-
var infoTags=xmlInfo.getElementsByTagName("directory");
|
107 |
-
var loc=infoTags[0].getAttribute("location");
|
108 |
-
var parent_location=infoTags[0].getAttribute("parent_location");
|
109 |
-
var current_dir=infoTags[0].getAttribute("current_dir");
|
110 |
-
if(loc == "")
|
111 |
-
loc1 = 'Path Root';
|
112 |
-
else
|
113 |
-
loc1 = loc;
|
114 |
-
|
115 |
-
var newloc1="admin-ajax.php?action=files_xml&dir=" + current_dir ;
|
116 |
-
|
117 |
-
var stringHTML="<p><b>" + loc1 +"</b> <br /><br /></p>";
|
118 |
-
|
119 |
-
if(loc.indexOf("/")!=-1){
|
120 |
-
var newfile="admin-ajax.php?action=files_xml&dir=" + parent_location.slice(0, loc.lastIndexOf("/"));
|
121 |
-
stringHTML=stringHTML+"<p><a href=\"#\" onclick=\"loadXMLDoc('" + newfile +"')\">[Up a level]</a> <a href='#' onclick=\"loadXMLDoc('" + newloc1 +"&act=checkall')\" >[check all]</a> <a href='#' onclick=\"loadXMLDoc('" + newloc1 +"&act=uncheckall')\" >[uncheck all]</a></p><br />"
|
122 |
-
}
|
123 |
-
if(infoTags[0].hasChildNodes){
|
124 |
-
stringHTML=stringHTML+"<ul>";
|
125 |
-
for(node=infoTags[0].firstChild; node!=null; node=node.nextSibling){
|
126 |
-
|
127 |
-
var newloc="admin-ajax.php?action=files_xml&dir=" + current_dir ;
|
128 |
-
path = node.firstChild.nodeValue;
|
129 |
-
|
130 |
-
if(node.nodeName=="file"){
|
131 |
-
|
132 |
-
stringHTML=stringHTML+"<li class=\"file\"><img src='../wp-content/plugins/xcloner-backup-and-restore/browser/file.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('" + newloc +"&path="+path+"')\" name=cid[] value='"+path+"'><a href=\"" +node.getAttribute('link')+ "\">"+node.firstChild.nodeValue+"</a></li>";
|
133 |
-
|
134 |
-
}
|
135 |
-
if(node.nodeName=="message"){
|
136 |
-
|
137 |
-
|
138 |
-
message = message + "<a href='#' onclick=\"loadXMLDoc('" + newloc+"&path="+node.firstChild.nodeValue+"')\">"+node.firstChild.nodeValue+"</a><br />";
|
139 |
-
|
140 |
-
}
|
141 |
-
if(node.nodeName=="folder"){
|
142 |
-
|
143 |
-
|
144 |
-
var newfile="admin-ajax.php?action=files_xml&dir=" + current_dir+node.firstChild.nodeValue;
|
145 |
-
stringHTML=stringHTML+"<li class=\"folder\"><img src='../wp-content/plugins/xcloner-backup-and-restore/browser/folder.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('"+ newloc +"&path="+path+"')\" name=cid[] value='"+path+"'><a href='#' class=\"folder\" onclick=\"loadXMLDoc('" + newfile+"')\">"+node.firstChild.nodeValue+"</a></li>";
|
146 |
-
}
|
147 |
-
}
|
148 |
-
stringHTML=stringHTML+"</ul>";
|
149 |
-
}
|
150 |
-
else{
|
151 |
-
stringHTML=stringHTML+"<p>No files in this directory</p>";
|
152 |
-
}
|
153 |
-
|
154 |
-
//stringHTML = stringHTML+ "</form>";
|
155 |
-
targetDiv.innerHTML= "<table align='right' width='450'><tr><td align='right'><b>" + "Excluded items list:" + "</b><br />"+ message+"</td></tr></table>" + stringHTML ;
|
156 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/.htaccess
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
order deny,allow
|
2 |
-
deny from all
|
|
|
|
classes/DropboxClient.php
DELETED
@@ -1,672 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* DropPHP - A simple Dropbox client that works without cURL.
|
4 |
-
*
|
5 |
-
* http://fabi.me/en/php-projects/dropphp-dropbox-api-client/
|
6 |
-
*
|
7 |
-
*
|
8 |
-
* @author Fabian Schlieper <fabian@fabi.me>
|
9 |
-
* @copyright Fabian Schlieper 2014
|
10 |
-
* @version 1.7.1
|
11 |
-
* @license See LICENSE
|
12 |
-
*
|
13 |
-
*/
|
14 |
-
|
15 |
-
require_once(dirname(__FILE__)."/OAuthSimple.php");
|
16 |
-
|
17 |
-
class DropboxClient {
|
18 |
-
|
19 |
-
const API_URL = "https://api.dropbox.com/1/";
|
20 |
-
const API_CONTENT_URL = "https://api-content.dropbox.com/1/";
|
21 |
-
|
22 |
-
const BUFFER_SIZE = 4096;
|
23 |
-
|
24 |
-
const MAX_UPLOAD_CHUNK_SIZE = 150000000; // 150MB
|
25 |
-
|
26 |
-
const UPLOAD_CHUNK_SIZE = 4000000; // 4MB
|
27 |
-
|
28 |
-
private $appParams;
|
29 |
-
private $consumerToken;
|
30 |
-
|
31 |
-
private $requestToken;
|
32 |
-
private $accessToken;
|
33 |
-
|
34 |
-
private $locale;
|
35 |
-
private $rootPath;
|
36 |
-
|
37 |
-
private $useCurl;
|
38 |
-
|
39 |
-
function __construct ($app_params, $locale = "en"){
|
40 |
-
$this->appParams = $app_params;
|
41 |
-
if(empty($app_params['app_key']))
|
42 |
-
throw new DropboxException("App Key is empty!");
|
43 |
-
|
44 |
-
$this->consumerToken = array('t' => $this->appParams['app_key'], 's' => $this->appParams['app_secret']);
|
45 |
-
$this->locale = $locale;
|
46 |
-
$this->rootPath = empty($app_params['app_full_access']) ? "sandbox" : "dropbox";
|
47 |
-
|
48 |
-
$this->requestToken = null;
|
49 |
-
$this->accessToken = null;
|
50 |
-
|
51 |
-
$this->useCurl = function_exists('curl_init');
|
52 |
-
}
|
53 |
-
|
54 |
-
function __wakeup() {
|
55 |
-
$this->useCurl = $this->useCurl && function_exists('curl_init');
|
56 |
-
}
|
57 |
-
/**
|
58 |
-
* Sets whether to use cURL if its available or PHP HTTP wrappers otherwise
|
59 |
-
*
|
60 |
-
* @access public
|
61 |
-
* @return boolean Whether to actually use cURL (always false if not installed)
|
62 |
-
*/
|
63 |
-
public function SetUseCUrl($use_it)
|
64 |
-
{
|
65 |
-
return ($this->useCurl = ($use_it && function_exists('curl_init')));
|
66 |
-
}
|
67 |
-
|
68 |
-
// ##################################################
|
69 |
-
// Authorization
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Step 1 of authentication process. Retrieves a request token or returns a previously retrieved one.
|
73 |
-
*
|
74 |
-
* @access public
|
75 |
-
* @param boolean $get_new_token Optional (default false). Wether to retrieve a new request token.
|
76 |
-
* @return array Request Token array.
|
77 |
-
*/
|
78 |
-
public function GetRequestToken($get_new_token=false)
|
79 |
-
{
|
80 |
-
if(!empty($this->requestToken) && !$get_new_token)
|
81 |
-
return $this->requestToken;
|
82 |
-
|
83 |
-
$rt = $this->authCall("oauth/request_token");
|
84 |
-
if(empty($rt) || empty($rt['oauth_token']))
|
85 |
-
throw new DropboxException('Could not get request token!');
|
86 |
-
|
87 |
-
return ($this->requestToken = array('t'=>$rt['oauth_token'], 's'=>$rt['oauth_token_secret']));
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Step 2. Returns a URL the user must be redirected to in order to connect the app to their Dropbox account
|
92 |
-
*
|
93 |
-
* @access public
|
94 |
-
* @param string $return_url URL users are redirected after authorization
|
95 |
-
* @return string URL
|
96 |
-
*/
|
97 |
-
public function BuildAuthorizeUrl($return_url)
|
98 |
-
{
|
99 |
-
$rt = $this->GetRequestToken();
|
100 |
-
if(empty($rt) || empty($rt['t'])) throw new DropboxException('Request Token Invalid ('.print_r($rt,true).').');
|
101 |
-
return "https://www.dropbox.com/1/oauth/authorize?oauth_token=".$rt['t']."&oauth_callback=".urlencode($return_url);
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Step 3. Acquires an access token. This is the final step of authentication.
|
106 |
-
*
|
107 |
-
* @access public
|
108 |
-
* @param array $request_token Optional. The previously retrieved request token. This parameter can only be skipped if the DropboxClient object has been (de)serialized.
|
109 |
-
* @return array Access Token array.
|
110 |
-
*/
|
111 |
-
public function GetAccessToken($request_token = null)
|
112 |
-
{
|
113 |
-
if(!empty($this->accessToken)) return $this->accessToken;
|
114 |
-
|
115 |
-
if(empty($request_token)) $request_token = $this->requestToken;
|
116 |
-
if(empty($request_token)) throw new DropboxException('Request token required!');
|
117 |
-
|
118 |
-
$at = $this->authCall("oauth/access_token", $request_token);
|
119 |
-
if(empty($at))
|
120 |
-
throw new DropboxException(sprintf('Could not get access token! (request token: %s)', $request_token['t']));
|
121 |
-
|
122 |
-
return ($this->accessToken = array('t'=>$at['oauth_token'], 's'=>$at['oauth_token_secret']));
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Sets a previously retrieved (and stored) access token.
|
127 |
-
*
|
128 |
-
* @access public
|
129 |
-
* @param string|object $token The Access Token
|
130 |
-
* @return none
|
131 |
-
*/
|
132 |
-
public function SetAccessToken($token)
|
133 |
-
{
|
134 |
-
if(empty($token['t']) || empty($token['s'])) throw new DropboxException('Passed invalid access token.');
|
135 |
-
$this->accessToken = $token;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Checks if an access token has been set.
|
140 |
-
*
|
141 |
-
* @access public
|
142 |
-
* @return boolean Authorized or not
|
143 |
-
*/
|
144 |
-
public function IsAuthorized()
|
145 |
-
{
|
146 |
-
if(empty($this->accessToken)) return false;
|
147 |
-
return true;
|
148 |
-
}
|
149 |
-
|
150 |
-
|
151 |
-
// ##################################################
|
152 |
-
// API Functions
|
153 |
-
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Retrieves information about the user's account.
|
157 |
-
*
|
158 |
-
* @access public
|
159 |
-
* @return object Account info object. See https://www.dropbox.com/developers/reference/api#account-info
|
160 |
-
*/
|
161 |
-
public function GetAccountInfo()
|
162 |
-
{
|
163 |
-
return $this->apiCall("account/info", "GET");
|
164 |
-
}
|
165 |
-
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get file list of a dropbox folder.
|
169 |
-
*
|
170 |
-
* @access public
|
171 |
-
* @param string|object $dropbox_path Dropbox path of the folder
|
172 |
-
* @return array An array with metadata of files/folders keyed by paths
|
173 |
-
*/
|
174 |
-
public function GetFiles($dropbox_path='', $recursive=false, $include_deleted=false)
|
175 |
-
{
|
176 |
-
if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
|
177 |
-
return $this->getFileTree($dropbox_path, $include_deleted, $recursive ? 1000 : 0);
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Get file or folder metadata
|
182 |
-
*
|
183 |
-
* @access public
|
184 |
-
* @param $dropbox_path string Dropbox path of the file or folder
|
185 |
-
*/
|
186 |
-
public function GetMetadata($dropbox_path, $include_deleted=false, $rev=null)
|
187 |
-
{
|
188 |
-
if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
|
189 |
-
return $this->apiCall("metadata/$this->rootPath/$dropbox_path", "GET", compact('include_deleted','rev'));
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* Download a file to the webserver
|
194 |
-
*
|
195 |
-
* @access public
|
196 |
-
* @param string|object $dropbox_file Dropbox path or metadata object of the file to download.
|
197 |
-
* @param string $dest_path Local path for destination
|
198 |
-
* @param string $rev Optional. The revision of the file to retrieve. This defaults to the most recent revision.
|
199 |
-
* @param callback $progress_changed_callback Optional. Callback that will be called during download with 2 args: 1. bytes loaded, 2. file size
|
200 |
-
* @return object Dropbox file metadata
|
201 |
-
*/
|
202 |
-
public function DownloadFile($dropbox_file, $dest_path='', $rev=null, $progress_changed_callback = null)
|
203 |
-
{
|
204 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path))
|
205 |
-
$dropbox_file = $dropbox_file->path;
|
206 |
-
|
207 |
-
if(empty($dest_path)) $dest_path = basename($dropbox_file);
|
208 |
-
|
209 |
-
$url = $this->cleanUrl(self::API_CONTENT_URL."/files/$this->rootPath/$dropbox_file")
|
210 |
-
. (!empty($rev) ? ('?'.http_build_query(array('rev' => $rev),'','&')) : '');
|
211 |
-
$context = $this->createRequestContext($url, "GET");
|
212 |
-
|
213 |
-
$fh = @fopen($dest_path, 'wb'); // write binary
|
214 |
-
if($fh === false) {
|
215 |
-
@fclose($rh);
|
216 |
-
throw new DropboxException("Could not create file $dest_path !");
|
217 |
-
}
|
218 |
-
|
219 |
-
if($this->useCurl) {
|
220 |
-
curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
|
221 |
-
curl_setopt($context, CURLOPT_RETURNTRANSFER, true);
|
222 |
-
curl_setopt($context, CURLOPT_FILE, $fh);
|
223 |
-
$response_headers = array();
|
224 |
-
self::execCurlAndClose($context, $response_headers);
|
225 |
-
fclose($fh);
|
226 |
-
$meta = self::getMetaFromHeaders($response_headers, true);
|
227 |
-
$bytes_loaded = filesize($dest_path);
|
228 |
-
} else {
|
229 |
-
$rh = @fopen($url, 'rb', false, $context); // read binary
|
230 |
-
if($rh === false)
|
231 |
-
throw new DropboxException("HTTP request to $url failed!");
|
232 |
-
|
233 |
-
|
234 |
-
// get file meta from HTTP header
|
235 |
-
$s_meta = stream_get_meta_data($rh);
|
236 |
-
$meta = self::getMetaFromHeaders($s_meta['wrapper_data'], true);
|
237 |
-
$bytes_loaded = 0;
|
238 |
-
while (!feof($rh)) {
|
239 |
-
if(($s=fwrite($fh, fread($rh, self::BUFFER_SIZE))) === false) {
|
240 |
-
@fclose($rh);
|
241 |
-
@fclose($fh);
|
242 |
-
throw new DropboxException("Writing to file $dest_path failed!'");
|
243 |
-
}
|
244 |
-
$bytes_loaded += $s;
|
245 |
-
if(!empty($progress_changed_callback)) {
|
246 |
-
call_user_func($progress_changed_callback, $bytes_loaded, $meta->bytes);
|
247 |
-
}
|
248 |
-
}
|
249 |
-
|
250 |
-
fclose($rh);
|
251 |
-
fclose($fh);
|
252 |
-
}
|
253 |
-
|
254 |
-
if($meta->bytes != $bytes_loaded)
|
255 |
-
throw new DropboxException("Download size mismatch! (header:{$meta->bytes} vs actual:{$bytes_loaded}; curl:{$this->useCurl})");
|
256 |
-
|
257 |
-
return $meta;
|
258 |
-
}
|
259 |
-
|
260 |
-
/**
|
261 |
-
* Upload a file to dropbox
|
262 |
-
*
|
263 |
-
* @access public
|
264 |
-
* @param $src_file string Local file to upload
|
265 |
-
* @param $dropbox_path string Dropbox path for destination
|
266 |
-
* @return object Dropbox file metadata
|
267 |
-
*/
|
268 |
-
public function UploadFile($src_file, $dropbox_path='', $overwrite=true, $parent_rev=null)
|
269 |
-
{
|
270 |
-
if(empty($dropbox_path)) $dropbox_path = basename($src_file);
|
271 |
-
elseif(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
|
272 |
-
|
273 |
-
// make sure the dropbox_path is not a dir. if it is, append baseneme of $src_file
|
274 |
-
$dropbox_bn = basename($dropbox_path);
|
275 |
-
if(strpos($dropbox_bn,'.') === false) { // check if ext. is missing -> could be a directory!
|
276 |
-
try {
|
277 |
-
$meta = $this->GetMetadata($dropbox_path);
|
278 |
-
if($meta && $meta->is_dir)
|
279 |
-
$dropbox_path = $dropbox_path . '/'. basename($src_file);
|
280 |
-
} catch(Exception $e) {}
|
281 |
-
}
|
282 |
-
|
283 |
-
$file_size = filesize($src_file);
|
284 |
-
|
285 |
-
if($file_size > self::MAX_UPLOAD_CHUNK_SIZE)
|
286 |
-
{
|
287 |
-
$fh = fopen($src_file,'rb');
|
288 |
-
if($fh === false)
|
289 |
-
throw new DropboxException();
|
290 |
-
|
291 |
-
$upload_id = null;
|
292 |
-
$offset = 0;
|
293 |
-
|
294 |
-
|
295 |
-
while(!feof($fh)) {
|
296 |
-
$url = $this->cleanUrl(self::API_CONTENT_URL."/chunked_upload").'?'.http_build_query(compact('upload_id', 'offset'),'','&');
|
297 |
-
$content = fread($fh, self::UPLOAD_CHUNK_SIZE);
|
298 |
-
$context = $this->createRequestContext($url, "PUT", $content);
|
299 |
-
|
300 |
-
if($this->useCurl) {
|
301 |
-
curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
|
302 |
-
$response = json_decode(self::execCurlAndClose($context));
|
303 |
-
} else {
|
304 |
-
$response = json_decode(file_get_contents($url, false, $context));
|
305 |
-
}
|
306 |
-
$offset += strlen($content);
|
307 |
-
unset($content);
|
308 |
-
unset($context);
|
309 |
-
|
310 |
-
self::checkForError($response);
|
311 |
-
|
312 |
-
if(empty($upload_id)) {
|
313 |
-
$upload_id = $response->upload_id;
|
314 |
-
if(empty($upload_id)) throw new DropboxException("Upload ID empty!");
|
315 |
-
}
|
316 |
-
if($offset >= $file_size)
|
317 |
-
break;
|
318 |
-
}
|
319 |
-
|
320 |
-
@fclose($fh);
|
321 |
-
|
322 |
-
return $this->apiCall("commit_chunked_upload/$this->rootPath/$dropbox_path", "POST", compact('overwrite','parent_rev','upload_id'), true);
|
323 |
-
}
|
324 |
-
|
325 |
-
$query = http_build_query(array_merge(compact('overwrite', 'parent_rev'), array('locale' => $this->locale)),'','&');
|
326 |
-
$url = $this->cleanUrl(self::API_CONTENT_URL."/files_put/$this->rootPath/$dropbox_path")."?$query";
|
327 |
-
|
328 |
-
if($this->useCurl) {
|
329 |
-
$context = $this->createRequestContext($url, "PUT");
|
330 |
-
curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
|
331 |
-
$fh = fopen($src_file, 'rb');
|
332 |
-
curl_setopt($context, CURLOPT_PUT, 1);
|
333 |
-
curl_setopt($context, CURLOPT_INFILE, $fh); // file pointer
|
334 |
-
curl_setopt($context, CURLOPT_INFILESIZE, filesize($src_file));
|
335 |
-
$meta = json_decode(self::execCurlAndClose($context));
|
336 |
-
fclose($fh);
|
337 |
-
return self::checkForError($meta);
|
338 |
-
} else {
|
339 |
-
$content = file_get_contents($src_file);
|
340 |
-
if(strlen($content) == 0)
|
341 |
-
throw new DropboxException("Could not read file $src_file or file is empty!");
|
342 |
-
|
343 |
-
$context = $this->createRequestContext($url, "PUT", $content);
|
344 |
-
|
345 |
-
return self::checkForError(json_decode(file_get_contents($url, false, $context)));
|
346 |
-
}
|
347 |
-
}
|
348 |
-
|
349 |
-
/**
|
350 |
-
* Get thumbnail for a specified image
|
351 |
-
*
|
352 |
-
* @access public
|
353 |
-
* @param $dropbox_file string Path to the image
|
354 |
-
* @param $format string Image format of the thumbnail (jpeg or png)
|
355 |
-
* @param $size string Thumbnail size (xs, s, m, l, xl)
|
356 |
-
* @return mime/* Returns the thumbnail as binary image data
|
357 |
-
*/
|
358 |
-
public function GetThumbnail($dropbox_file, $size = 's', $format = 'jpeg', $echo = false)
|
359 |
-
{
|
360 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
|
361 |
-
$url = $this->cleanUrl(self::API_CONTENT_URL."thumbnails/$this->rootPath/$dropbox_file")
|
362 |
-
. '?' . http_build_query(array('format' => $format, 'size' => $size),'','&');
|
363 |
-
$context = $this->createRequestContext($url, "GET");
|
364 |
-
|
365 |
-
if($this->useCurl) {
|
366 |
-
curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
|
367 |
-
curl_setopt($context, CURLOPT_RETURNTRANSFER, true);
|
368 |
-
}
|
369 |
-
|
370 |
-
$thumb = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, NULL, $context);
|
371 |
-
|
372 |
-
if($echo) {
|
373 |
-
header('Content-type: image/'.$format);
|
374 |
-
echo $thumb;
|
375 |
-
unset($thumb);
|
376 |
-
return;
|
377 |
-
}
|
378 |
-
|
379 |
-
return $thumb;
|
380 |
-
}
|
381 |
-
|
382 |
-
|
383 |
-
function GetLink($dropbox_file, $preview=true, $short=true, &$expires=null)
|
384 |
-
{
|
385 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
|
386 |
-
$url = $this->apiCall(($preview?"shares":"media")."/$this->rootPath/$dropbox_file", "POST", array('locale' => null, 'short_url'=> $preview ? $short : null));
|
387 |
-
$expires = strtotime($url->expires);
|
388 |
-
return $url->url;
|
389 |
-
}
|
390 |
-
|
391 |
-
function Delta($cursor)
|
392 |
-
{
|
393 |
-
return $this->apiCall("delta", "POST", compact('cursor'));
|
394 |
-
}
|
395 |
-
|
396 |
-
function GetRevisions($dropbox_file, $rev_limit=10)
|
397 |
-
{
|
398 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
|
399 |
-
return $this->apiCall("revisions/$this->rootPath/$dropbox_file", "GET", compact('rev_limit'));
|
400 |
-
}
|
401 |
-
|
402 |
-
function Restore($dropbox_file, $rev)
|
403 |
-
{
|
404 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
|
405 |
-
return $this->apiCall("restore/$this->rootPath/$dropbox_file", "POST", compact('rev'));
|
406 |
-
}
|
407 |
-
|
408 |
-
function Search($path, $query, $file_limit=1000, $include_deleted=false)
|
409 |
-
{
|
410 |
-
return $this->apiCall("search/$this->rootPath/$path", "POST", compact('query','file_limit','include_deleted'));
|
411 |
-
}
|
412 |
-
|
413 |
-
function GetCopyRef($dropbox_file, &$expires=null)
|
414 |
-
{
|
415 |
-
if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
|
416 |
-
$ref = $this->apiCall("copy_ref/$this->rootPath/$dropbox_file", "GET", array('locale' => null));
|
417 |
-
$expires = strtotime($ref->expires);
|
418 |
-
return $ref->copy_ref;
|
419 |
-
}
|
420 |
-
|
421 |
-
|
422 |
-
function Copy($from_path, $to_path, $copy_ref=false)
|
423 |
-
{
|
424 |
-
if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path;
|
425 |
-
return $this->apiCall("fileops/copy", "POST", array('root'=> $this->rootPath, ($copy_ref ? 'from_copy_ref' : 'from_path') => $from_path, 'to_path' => $to_path));
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Creates a new folder in the DropBox
|
430 |
-
*
|
431 |
-
* @access public
|
432 |
-
* @param $path string The path to the new folder to create
|
433 |
-
* @return object Dropbox folder metadata
|
434 |
-
*/
|
435 |
-
function CreateFolder($path)
|
436 |
-
{
|
437 |
-
return $this->apiCall("fileops/create_folder", "POST", array('root'=> $this->rootPath, 'path' => $path));
|
438 |
-
}
|
439 |
-
|
440 |
-
/**
|
441 |
-
* Delete file or folder
|
442 |
-
*
|
443 |
-
* @access public
|
444 |
-
* @param $path mixed The path or metadata of the file/folder to be deleted.
|
445 |
-
* @return object Dropbox metadata of deleted file or folder
|
446 |
-
*/
|
447 |
-
function Delete($path)
|
448 |
-
{
|
449 |
-
if(is_object($path) && !empty($path->path)) $path = $path->path;
|
450 |
-
return $this->apiCall("fileops/delete", "POST", array('locale' =>null, 'root'=> $this->rootPath, 'path' => $path));
|
451 |
-
}
|
452 |
-
|
453 |
-
function Move($from_path, $to_path)
|
454 |
-
{
|
455 |
-
if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path;
|
456 |
-
return $this->apiCall("fileops/move", "POST", array('root'=> $this->rootPath, 'from_path' => $from_path, 'to_path' => $to_path));
|
457 |
-
}
|
458 |
-
|
459 |
-
function getFileTree($path="", $include_deleted = false, $max_depth = 0, $depth=0)
|
460 |
-
{
|
461 |
-
static $files;
|
462 |
-
if($depth == 0) $files = array();
|
463 |
-
|
464 |
-
$dir = $this->apiCall("metadata/$this->rootPath/$path", "GET", compact('include_deleted'));
|
465 |
-
|
466 |
-
if(empty($dir) || !is_object($dir)) return false;
|
467 |
-
|
468 |
-
if(!empty($dir->error)) throw new DropboxException($dir->error);
|
469 |
-
|
470 |
-
foreach($dir->contents as $item)
|
471 |
-
{
|
472 |
-
$files[trim($item->path,'/')] = $item;
|
473 |
-
if($item->is_dir && $depth < $max_depth)
|
474 |
-
{
|
475 |
-
$this->getFileTree($item->path, $include_deleted, $max_depth, $depth+1);
|
476 |
-
}
|
477 |
-
}
|
478 |
-
|
479 |
-
return $files;
|
480 |
-
}
|
481 |
-
|
482 |
-
function createCurl($url, $http_context)
|
483 |
-
{
|
484 |
-
$ch = curl_init($url);
|
485 |
-
|
486 |
-
$curl_opts = array(
|
487 |
-
CURLOPT_HEADER => false, // exclude header from output
|
488 |
-
//CURLOPT_MUTE => true, // no output!
|
489 |
-
CURLOPT_RETURNTRANSFER => true, // but return!
|
490 |
-
CURLOPT_SSL_VERIFYPEER => false,
|
491 |
-
);
|
492 |
-
|
493 |
-
$curl_opts[CURLOPT_CUSTOMREQUEST] = $http_context['method'];
|
494 |
-
|
495 |
-
if(!empty($http_context['content'])) {
|
496 |
-
$curl_opts[CURLOPT_POSTFIELDS] =& $http_context['content'];
|
497 |
-
if(defined("CURLOPT_POSTFIELDSIZE"))
|
498 |
-
$curl_opts[CURLOPT_POSTFIELDSIZE] = strlen($http_context['content']);
|
499 |
-
}
|
500 |
-
|
501 |
-
$curl_opts[CURLOPT_HTTPHEADER] = array_map('trim',explode("\n",$http_context['header']));
|
502 |
-
|
503 |
-
curl_setopt_array($ch, $curl_opts);
|
504 |
-
return $ch;
|
505 |
-
}
|
506 |
-
|
507 |
-
static private $_curlHeadersRef;
|
508 |
-
static function _curlHeaderCallback($ch, $header)
|
509 |
-
{
|
510 |
-
self::$_curlHeadersRef[] = trim($header);
|
511 |
-
return strlen($header);
|
512 |
-
}
|
513 |
-
|
514 |
-
static function &execCurlAndClose($ch, &$out_response_headers = null)
|
515 |
-
{
|
516 |
-
if(is_array($out_response_headers)) {
|
517 |
-
self::$_curlHeadersRef =& $out_response_headers;
|
518 |
-
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(__CLASS__, '_curlHeaderCallback'));
|
519 |
-
}
|
520 |
-
$res = curl_exec($ch);
|
521 |
-
$err_no = curl_errno($ch);
|
522 |
-
$err_str = curl_error($ch);
|
523 |
-
curl_close($ch);
|
524 |
-
if($err_no || $res === false) {
|
525 |
-
throw new DropboxException("cURL-Error ($err_no): $err_str");
|
526 |
-
}
|
527 |
-
|
528 |
-
return $res;
|
529 |
-
}
|
530 |
-
|
531 |
-
private function createRequestContext($url, $method, &$content=null, $oauth_token=-1)
|
532 |
-
{
|
533 |
-
if($oauth_token === -1)
|
534 |
-
$oauth_token = $this->accessToken;
|
535 |
-
|
536 |
-
$method = strtoupper($method);
|
537 |
-
$http_context = array('method'=>$method, 'header'=> '');
|
538 |
-
|
539 |
-
$oauth = new OAuthSimple($this->consumerToken['t'],$this->consumerToken['s']);
|
540 |
-
|
541 |
-
if(empty($oauth_token) && !empty($this->accessToken))
|
542 |
-
$oauth_token = $this->accessToken;
|
543 |
-
|
544 |
-
if(!empty($oauth_token)) {
|
545 |
-
$oauth->setParameters(array('oauth_token' => $oauth_token['t']));
|
546 |
-
$oauth->signatures(array('oauth_secret'=>$oauth_token['s']));
|
547 |
-
}
|
548 |
-
|
549 |
-
if(!empty($content)) {
|
550 |
-
$post_vars = ($method != "PUT" && preg_match("/^[a-z][a-z0-9_]*=/i", substr($content, 0, 32)));
|
551 |
-
$http_context['header'] .= "Content-Length: ".strlen($content)."\r\n";
|
552 |
-
$http_context['header'] .= "Content-Type: application/".($post_vars?"x-www-form-urlencoded":"octet-stream")."\r\n";
|
553 |
-
$http_context['content'] =& $content;
|
554 |
-
if($method == "POST" && $post_vars)
|
555 |
-
$oauth->setParameters($content);
|
556 |
-
} elseif($method == "POST") {
|
557 |
-
// make sure that content-length is always set when post request (otherwise some wrappers fail!)
|
558 |
-
$http_context['content'] = "";
|
559 |
-
$http_context['header'] .= "Content-Length: 0\r\n";
|
560 |
-
}
|
561 |
-
|
562 |
-
|
563 |
-
// check for query vars in url and add them to oauth parameters (and remove from path)
|
564 |
-
$path = $url;
|
565 |
-
$query = strrchr($url,'?');
|
566 |
-
if(!empty($query)) {
|
567 |
-
$oauth->setParameters(substr($query,1));
|
568 |
-
$path = substr($url, 0, -strlen($query));
|
569 |
-
}
|
570 |
-
|
571 |
-
|
572 |
-
$signed = $oauth->sign(array(
|
573 |
-
'action' => $method,
|
574 |
-
'path'=> $path));
|
575 |
-
//print_r($signed);
|
576 |
-
|
577 |
-
$http_context['header'] .= "Authorization: ".$signed['header']."\r\n";
|
578 |
-
|
579 |
-
return $this->useCurl ? $this->createCurl($url, $http_context) : stream_context_create(array('http'=>$http_context));
|
580 |
-
}
|
581 |
-
|
582 |
-
private function authCall($path, $request_token=null)
|
583 |
-
{
|
584 |
-
$url = $this->cleanUrl(self::API_URL.$path);
|
585 |
-
$dummy = null;
|
586 |
-
$context = $this->createRequestContext($url, "POST", $dummy, $request_token);
|
587 |
-
|
588 |
-
$contents = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context);
|
589 |
-
$data = array();
|
590 |
-
parse_str($contents, $data);
|
591 |
-
return $data;
|
592 |
-
}
|
593 |
-
|
594 |
-
private static function checkForError($resp)
|
595 |
-
{
|
596 |
-
if(!empty($resp->error))
|
597 |
-
throw new DropboxException($resp->error);
|
598 |
-
return $resp;
|
599 |
-
}
|
600 |
-
|
601 |
-
|
602 |
-
private function apiCall($path, $method, $params=array(), $content_call=false)
|
603 |
-
{
|
604 |
-
$url = $this->cleanUrl(($content_call ? self::API_CONTENT_URL : self::API_URL).$path);
|
605 |
-
$content = http_build_query(array_merge(array('locale'=>$this->locale), $params),'','&');
|
606 |
-
|
607 |
-
if($method == "GET") {
|
608 |
-
$url .= "?".$content;
|
609 |
-
$content = null;
|
610 |
-
}
|
611 |
-
|
612 |
-
$context = $this->createRequestContext($url, $method, $content);
|
613 |
-
$json = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context);
|
614 |
-
//if($json === false)
|
615 |
-
// throw new DropboxException();
|
616 |
-
$resp = json_decode($json);
|
617 |
-
return self::checkForError($resp);
|
618 |
-
}
|
619 |
-
|
620 |
-
|
621 |
-
private static function getMetaFromHeaders(&$header_array, $throw_on_error=false)
|
622 |
-
{
|
623 |
-
$obj = json_decode(substr(@array_shift(array_filter($header_array, create_function('$s', 'return stripos($s, "x-dropbox-metadata:") === 0;'))), 20));
|
624 |
-
if($throw_on_error && (empty($obj)||!is_object($obj)))
|
625 |
-
throw new DropboxException("Could not retrieve meta data from header data: ".print_r($header_array,true));
|
626 |
-
if($throw_on_error)
|
627 |
-
self::checkForError ($obj);
|
628 |
-
return $obj;
|
629 |
-
}
|
630 |
-
|
631 |
-
|
632 |
-
function cleanUrl($url) {
|
633 |
-
$p = substr($url,0,8);
|
634 |
-
$url = str_replace('//','/', str_replace('\\','/',substr($url,8)));
|
635 |
-
$url = rawurlencode($url);
|
636 |
-
$url = str_replace('%2F', '/', $url);
|
637 |
-
return $p.$url;
|
638 |
-
}
|
639 |
-
}
|
640 |
-
|
641 |
-
class DropboxException extends Exception {
|
642 |
-
|
643 |
-
public function __construct($err = null, $isDebug = FALSE)
|
644 |
-
{
|
645 |
-
if(is_null($err)) {
|
646 |
-
$el = error_get_last();
|
647 |
-
$this->message = $el['message'];
|
648 |
-
$this->file = $el['file'];
|
649 |
-
$this->line = $el['line'];
|
650 |
-
} else
|
651 |
-
$this->message = $err;
|
652 |
-
self::log_error($err);
|
653 |
-
if ($isDebug)
|
654 |
-
{
|
655 |
-
self::display_error($err, TRUE);
|
656 |
-
}
|
657 |
-
}
|
658 |
-
|
659 |
-
public static function log_error($err)
|
660 |
-
{
|
661 |
-
error_log($err, 0);
|
662 |
-
}
|
663 |
-
|
664 |
-
public static function display_error($err, $kill = FALSE)
|
665 |
-
{
|
666 |
-
print_r($err);
|
667 |
-
if ($kill === FALSE)
|
668 |
-
{
|
669 |
-
die();
|
670 |
-
}
|
671 |
-
}
|
672 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/OAuthSimple.php
DELETED
@@ -1,532 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* OAuthSimple - A simpler version of OAuth
|
4 |
-
*
|
5 |
-
* https://github.com/jrconlin/oauthsimple
|
6 |
-
*
|
7 |
-
* @author jr conlin <src@jrconlin.com>
|
8 |
-
* @copyright unitedHeroes.net 2011
|
9 |
-
* @version 1.3
|
10 |
-
* @license See OAuthSimple_license.txt
|
11 |
-
*
|
12 |
-
*/
|
13 |
-
|
14 |
-
class OAuthSimple {
|
15 |
-
private $_secrets;
|
16 |
-
private $_default_signature_method;
|
17 |
-
private $_action;
|
18 |
-
private $_nonce_chars;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Constructor
|
22 |
-
*
|
23 |
-
* @access public
|
24 |
-
* @param api_key (String) The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
|
25 |
-
* @param shared_secret (String) The shared secret. This value is also usually provided by the site you wish to use.
|
26 |
-
* @return OAuthSimple (Object)
|
27 |
-
*/
|
28 |
-
function __construct ($APIKey = "", $sharedSecret=""){
|
29 |
-
|
30 |
-
if (!empty($APIKey))
|
31 |
-
{
|
32 |
-
$this->_secrets['consumer_key'] = $APIKey;
|
33 |
-
}
|
34 |
-
|
35 |
-
if (!empty($sharedSecret))
|
36 |
-
{
|
37 |
-
$this->_secrets['shared_secret'] = $sharedSecret;
|
38 |
-
}
|
39 |
-
|
40 |
-
$this->_default_signature_method = "HMAC-SHA1";
|
41 |
-
$this->_action = "GET";
|
42 |
-
$this->_nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
43 |
-
|
44 |
-
return $this;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Reset the parameters and URL
|
49 |
-
*
|
50 |
-
* @access public
|
51 |
-
* @return OAuthSimple (Object)
|
52 |
-
*/
|
53 |
-
public function reset() {
|
54 |
-
$this->_parameters = Array();
|
55 |
-
$this->path = NULL;
|
56 |
-
$this->sbs = NULL;
|
57 |
-
|
58 |
-
return $this;
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Set the parameters either from a hash or a string
|
63 |
-
*
|
64 |
-
* @access public
|
65 |
-
* @param(string, object) List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
|
66 |
-
* @return OAuthSimple (Object)
|
67 |
-
*/
|
68 |
-
public function setParameters ($parameters=Array()) {
|
69 |
-
|
70 |
-
if (is_string($parameters))
|
71 |
-
{
|
72 |
-
$parameters = $this->_parseParameterString($parameters);
|
73 |
-
}
|
74 |
-
if (empty($this->_parameters))
|
75 |
-
{
|
76 |
-
$this->_parameters = $parameters;
|
77 |
-
}
|
78 |
-
else if (!empty($parameters))
|
79 |
-
{
|
80 |
-
$this->_parameters = array_merge($this->_parameters,$parameters);
|
81 |
-
}
|
82 |
-
if (empty($this->_parameters['oauth_nonce']))
|
83 |
-
{
|
84 |
-
$this->_getNonce();
|
85 |
-
}
|
86 |
-
if (empty($this->_parameters['oauth_timestamp']))
|
87 |
-
{
|
88 |
-
$this->_getTimeStamp();
|
89 |
-
}
|
90 |
-
if (empty($this->_parameters['oauth_consumer_key']))
|
91 |
-
{
|
92 |
-
$this->_getApiKey();
|
93 |
-
}
|
94 |
-
if (empty($this->_parameters['oauth_token']))
|
95 |
-
{
|
96 |
-
$this->_getAccessToken();
|
97 |
-
}
|
98 |
-
if (empty($this->_parameters['oauth_signature_method']))
|
99 |
-
{
|
100 |
-
$this->setSignatureMethod();
|
101 |
-
}
|
102 |
-
if (empty($this->_parameters['oauth_version']))
|
103 |
-
{
|
104 |
-
$this->_parameters['oauth_version']="1.0";
|
105 |
-
}
|
106 |
-
|
107 |
-
return $this;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Convenience method for setParameters
|
112 |
-
*
|
113 |
-
* @access public
|
114 |
-
* @see setParameters
|
115 |
-
*/
|
116 |
-
public function setQueryString ($parameters)
|
117 |
-
{
|
118 |
-
return $this->setParameters($parameters);
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Set the target URL (does not include the parameters)
|
123 |
-
*
|
124 |
-
* @param path (String) the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
|
125 |
-
* @return OAuthSimple (Object)
|
126 |
-
*/
|
127 |
-
public function setURL ($path)
|
128 |
-
{
|
129 |
-
if (empty($path))
|
130 |
-
{
|
131 |
-
throw new OAuthSimpleException('No path specified for OAuthSimple.setURL');
|
132 |
-
}
|
133 |
-
$this->_path=$path;
|
134 |
-
|
135 |
-
return $this;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Convenience method for setURL
|
140 |
-
*
|
141 |
-
* @param path (String)
|
142 |
-
* @see setURL
|
143 |
-
*/
|
144 |
-
public function setPath ($path)
|
145 |
-
{
|
146 |
-
return $this->_path=$path;
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
|
151 |
-
*
|
152 |
-
* @param action (String) HTTP Action word.
|
153 |
-
* @return OAuthSimple (Object)
|
154 |
-
*/
|
155 |
-
public function setAction ($action)
|
156 |
-
{
|
157 |
-
if (empty($action))
|
158 |
-
{
|
159 |
-
$action = 'GET';
|
160 |
-
}
|
161 |
-
$action = strtoupper($action);
|
162 |
-
if (preg_match('/[^A-Z]/',$action))
|
163 |
-
{
|
164 |
-
throw new OAuthSimpleException('Invalid action specified for OAuthSimple.setAction');
|
165 |
-
}
|
166 |
-
$this->_action = $action;
|
167 |
-
|
168 |
-
return $this;
|
169 |
-
}
|
170 |
-
|
171 |
-
/**
|
172 |
-
* Set the signatures (as well as validate the ones you have)
|
173 |
-
*
|
174 |
-
* @param signatures (object) object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
|
175 |
-
* @return OAuthSimple (Object)
|
176 |
-
*/
|
177 |
-
public function signatures ($signatures)
|
178 |
-
{
|
179 |
-
if (!empty($signatures) && !is_array($signatures))
|
180 |
-
{
|
181 |
-
throw new OAuthSimpleException('Must pass dictionary array to OAuthSimple.signatures');
|
182 |
-
}
|
183 |
-
if (!empty($signatures))
|
184 |
-
{
|
185 |
-
if (empty($this->_secrets))
|
186 |
-
{
|
187 |
-
$this->_secrets=Array();
|
188 |
-
}
|
189 |
-
$this->_secrets=array_merge($this->_secrets,$signatures);
|
190 |
-
}
|
191 |
-
if (isset($this->_secrets['api_key']))
|
192 |
-
{
|
193 |
-
$this->_secrets['consumer_key'] = $this->_secrets['api_key'];
|
194 |
-
}
|
195 |
-
if (isset($this->_secrets['access_token']))
|
196 |
-
{
|
197 |
-
$this->_secrets['oauth_token'] = $this->_secrets['access_token'];
|
198 |
-
}
|
199 |
-
if (isset($this->_secrets['access_secret']))
|
200 |
-
{
|
201 |
-
$this->_secrets['oauth_secret'] = $this->_secrets['access_secret'];
|
202 |
-
}
|
203 |
-
if (isset($this->_secrets['access_token_secret']))
|
204 |
-
{
|
205 |
-
$this->_secrets['oauth_secret'] = $this->_secrets['access_token_secret'];
|
206 |
-
}
|
207 |
-
if (empty($this->_secrets['consumer_key']))
|
208 |
-
{
|
209 |
-
throw new OAuthSimpleException('Missing required consumer_key in OAuthSimple.signatures');
|
210 |
-
}
|
211 |
-
if (empty($this->_secrets['shared_secret']))
|
212 |
-
{
|
213 |
-
throw new OAuthSimpleException('Missing requires shared_secret in OAuthSimple.signatures');
|
214 |
-
}
|
215 |
-
if (!empty($this->_secrets['oauth_token']) && empty($this->_secrets['oauth_secret']))
|
216 |
-
{
|
217 |
-
throw new OAuthSimpleException('Missing oauth_secret for supplied oauth_token in OAuthSimple.signatures');
|
218 |
-
}
|
219 |
-
|
220 |
-
return $this;
|
221 |
-
}
|
222 |
-
|
223 |
-
public function setTokensAndSecrets($signatures)
|
224 |
-
{
|
225 |
-
return $this->signatures($signatures);
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Set the signature method (currently only Plaintext or SHA-MAC1)
|
230 |
-
*
|
231 |
-
* @param method (String) Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
|
232 |
-
* @return OAuthSimple (Object)
|
233 |
-
*/
|
234 |
-
public function setSignatureMethod ($method="")
|
235 |
-
{
|
236 |
-
if (empty($method))
|
237 |
-
{
|
238 |
-
$method = $this->_default_signature_method;
|
239 |
-
}
|
240 |
-
$method = strtoupper($method);
|
241 |
-
switch($method)
|
242 |
-
{
|
243 |
-
case 'PLAINTEXT':
|
244 |
-
case 'HMAC-SHA1':
|
245 |
-
$this->_parameters['oauth_signature_method']=$method;
|
246 |
-
break;
|
247 |
-
default:
|
248 |
-
throw new OAuthSimpleException ("Unknown signing method $method specified for OAuthSimple.setSignatureMethod");
|
249 |
-
break;
|
250 |
-
}
|
251 |
-
|
252 |
-
return $this;
|
253 |
-
}
|
254 |
-
|
255 |
-
/** sign the request
|
256 |
-
*
|
257 |
-
* note: all arguments are optional, provided you've set them using the
|
258 |
-
* other helper functions.
|
259 |
-
*
|
260 |
-
* @param args (Array) hash of arguments for the call {action, path, parameters (array), method, signatures (array)} all arguments are optional.
|
261 |
-
* @return (Array) signed values
|
262 |
-
*/
|
263 |
-
public function sign($args=array())
|
264 |
-
{
|
265 |
-
if (!empty($args['action']))
|
266 |
-
{
|
267 |
-
$this->setAction($args['action']);
|
268 |
-
}
|
269 |
-
if (!empty($args['path']))
|
270 |
-
{
|
271 |
-
$this->setPath($args['path']);
|
272 |
-
}
|
273 |
-
if (!empty($args['method']))
|
274 |
-
{
|
275 |
-
$this->setSignatureMethod($args['method']);
|
276 |
-
}
|
277 |
-
if (!empty($args['signatures']))
|
278 |
-
{
|
279 |
-
$this->signatures($args['signatures']);
|
280 |
-
}
|
281 |
-
if (empty($args['parameters']))
|
282 |
-
{
|
283 |
-
$args['parameters']=array();
|
284 |
-
}
|
285 |
-
$this->setParameters($args['parameters']);
|
286 |
-
$normParams = $this->_normalizedParameters();
|
287 |
-
$this->_parameters['oauth_signature'] = $this->_generateSignature($normParams);
|
288 |
-
|
289 |
-
return Array (
|
290 |
-
'parameters' => $this->_parameters,
|
291 |
-
'signature' => self::_oauthEscape($this->_parameters['oauth_signature']),
|
292 |
-
'signed_url' => $this->_path . '?' . $this->_normalizedParameters(),
|
293 |
-
'header' => $this->getHeaderString(),
|
294 |
-
'sbs'=> $this->sbs
|
295 |
-
);
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Return a formatted "header" string
|
300 |
-
*
|
301 |
-
* NOTE: This doesn't set the "Authorization: " prefix, which is required.
|
302 |
-
* It's not set because various set header functions prefer different
|
303 |
-
* ways to do that.
|
304 |
-
*
|
305 |
-
* @param args (Array)
|
306 |
-
* @return $result (String)
|
307 |
-
*/
|
308 |
-
public function getHeaderString ($args=array())
|
309 |
-
{
|
310 |
-
if (empty($this->_parameters['oauth_signature']))
|
311 |
-
{
|
312 |
-
$this->sign($args);
|
313 |
-
}
|
314 |
-
$result = 'OAuth ';
|
315 |
-
|
316 |
-
foreach ($this->_parameters as $pName => $pValue)
|
317 |
-
{
|
318 |
-
if (strpos($pName,'oauth_') !== 0 || $pName == 'oauth_token_secret2')
|
319 |
-
{
|
320 |
-
continue;
|
321 |
-
}
|
322 |
-
if (is_array($pValue))
|
323 |
-
{
|
324 |
-
foreach ($pValue as $val)
|
325 |
-
{
|
326 |
-
$result .= $pName .'="' . self::_oauthEscape($val) . '", ';
|
327 |
-
}
|
328 |
-
}
|
329 |
-
else
|
330 |
-
{
|
331 |
-
$result .= $pName . '="' . self::_oauthEscape($pValue) . '", ';
|
332 |
-
}
|
333 |
-
}
|
334 |
-
|
335 |
-
return preg_replace('/, $/','',$result);
|
336 |
-
}
|
337 |
-
|
338 |
-
private function _parseParameterString ($paramString)
|
339 |
-
{
|
340 |
-
$elements = explode('&',$paramString);
|
341 |
-
$result = array();
|
342 |
-
foreach ($elements as $element)
|
343 |
-
{
|
344 |
-
list ($key,$token) = explode('=',$element);
|
345 |
-
if ($token)
|
346 |
-
{
|
347 |
-
$token = urldecode($token);
|
348 |
-
}
|
349 |
-
if (!empty($result[$key]))
|
350 |
-
{
|
351 |
-
if (!is_array($result[$key]))
|
352 |
-
{
|
353 |
-
$result[$key] = array($result[$key],$token);
|
354 |
-
}
|
355 |
-
else
|
356 |
-
{
|
357 |
-
array_push($result[$key],$token);
|
358 |
-
}
|
359 |
-
}
|
360 |
-
else
|
361 |
-
$result[$key]=$token;
|
362 |
-
}
|
363 |
-
return $result;
|
364 |
-
}
|
365 |
-
|
366 |
-
|
367 |
-
private static function _oauthEscape($string)
|
368 |
-
{
|
369 |
-
if ($string === 0) { return 0; }
|
370 |
-
if ($string == '0') { return '0'; }
|
371 |
-
if (strlen($string) == 0) { return ''; }
|
372 |
-
if (is_array($string)) {
|
373 |
-
throw new OAuthSimpleException('Array passed to _oauthEscape');
|
374 |
-
}
|
375 |
-
$string = rawurlencode($string);
|
376 |
-
|
377 |
-
$string = str_replace('+','%20',$string);
|
378 |
-
$string = str_replace('!','%21',$string);
|
379 |
-
$string = str_replace('*','%2A',$string);
|
380 |
-
$string = str_replace('\'','%27',$string);
|
381 |
-
$string = str_replace('(','%28',$string);
|
382 |
-
$string = str_replace(')','%29',$string);
|
383 |
-
|
384 |
-
return $string;
|
385 |
-
}
|
386 |
-
|
387 |
-
private function _getNonce($length=5)
|
388 |
-
{
|
389 |
-
$result = '';
|
390 |
-
$cLength = strlen($this->_nonce_chars);
|
391 |
-
for ($i=0; $i < $length; $i++)
|
392 |
-
{
|
393 |
-
$rnum = rand(0,$cLength);
|
394 |
-
$result .= substr($this->_nonce_chars,$rnum,1);
|
395 |
-
}
|
396 |
-
$result = md5($result);
|
397 |
-
$this->_parameters['oauth_nonce'] = $result;
|
398 |
-
|
399 |
-
return $result;
|
400 |
-
}
|
401 |
-
|
402 |
-
private function _getApiKey()
|
403 |
-
{
|
404 |
-
if (empty($this->_secrets['consumer_key']))
|
405 |
-
{
|
406 |
-
throw new OAuthSimpleException('No consumer_key set for OAuthSimple');
|
407 |
-
}
|
408 |
-
$this->_parameters['oauth_consumer_key']=$this->_secrets['consumer_key'];
|
409 |
-
|
410 |
-
return $this->_parameters['oauth_consumer_key'];
|
411 |
-
}
|
412 |
-
|
413 |
-
private function _getAccessToken()
|
414 |
-
{
|
415 |
-
if (!isset($this->_secrets['oauth_secret']))
|
416 |
-
{
|
417 |
-
return '';
|
418 |
-
}
|
419 |
-
if (!isset($this->_secrets['oauth_token']))
|
420 |
-
{
|
421 |
-
throw new OAuthSimpleException('No access token (oauth_token) set for OAuthSimple.');
|
422 |
-
}
|
423 |
-
$this->_parameters['oauth_token'] = $this->_secrets['oauth_token'];
|
424 |
-
|
425 |
-
return $this->_parameters['oauth_token'];
|
426 |
-
}
|
427 |
-
|
428 |
-
private function _getTimeStamp()
|
429 |
-
{
|
430 |
-
return $this->_parameters['oauth_timestamp'] = time();
|
431 |
-
}
|
432 |
-
|
433 |
-
private function _normalizedParameters()
|
434 |
-
{
|
435 |
-
$normalized_keys = array();
|
436 |
-
$return_array = array();
|
437 |
-
|
438 |
-
foreach ( $this->_parameters as $paramName=>$paramValue) {
|
439 |
-
if (!preg_match('/\w+_secret/',$paramName) OR (strpos($paramValue, '@') !== 0 && !file_exists(substr($paramValue, 1))) )
|
440 |
-
{
|
441 |
-
if (is_array($paramValue))
|
442 |
-
{
|
443 |
-
$normalized_keys[self::_oauthEscape($paramName)] = array();
|
444 |
-
foreach($paramValue as $item)
|
445 |
-
{
|
446 |
-
array_push($normalized_keys[self::_oauthEscape($paramName)], self::_oauthEscape($item));
|
447 |
-
}
|
448 |
-
}
|
449 |
-
else
|
450 |
-
{
|
451 |
-
$normalized_keys[self::_oauthEscape($paramName)] = self::_oauthEscape($paramValue);
|
452 |
-
}
|
453 |
-
}
|
454 |
-
}
|
455 |
-
|
456 |
-
ksort($normalized_keys);
|
457 |
-
|
458 |
-
foreach($normalized_keys as $key=>$val)
|
459 |
-
{
|
460 |
-
if (is_array($val))
|
461 |
-
{
|
462 |
-
sort($val);
|
463 |
-
foreach($val as $element)
|
464 |
-
{
|
465 |
-
array_push($return_array, $key . "=" . $element);
|
466 |
-
}
|
467 |
-
}
|
468 |
-
else
|
469 |
-
{
|
470 |
-
array_push($return_array, $key .'='. $val);
|
471 |
-
}
|
472 |
-
|
473 |
-
}
|
474 |
-
|
475 |
-
return join("&", $return_array);
|
476 |
-
}
|
477 |
-
|
478 |
-
|
479 |
-
private function _generateSignature ()
|
480 |
-
{
|
481 |
-
$secretKey = '';
|
482 |
-
if(isset($this->_secrets['shared_secret']))
|
483 |
-
{
|
484 |
-
$secretKey = self::_oauthEscape($this->_secrets['shared_secret']);
|
485 |
-
}
|
486 |
-
|
487 |
-
$secretKey .= '&';
|
488 |
-
if(isset($this->_secrets['oauth_secret']))
|
489 |
-
{
|
490 |
-
$secretKey .= self::_oauthEscape($this->_secrets['oauth_secret']);
|
491 |
-
}
|
492 |
-
|
493 |
-
switch($this->_parameters['oauth_signature_method'])
|
494 |
-
{
|
495 |
-
case 'PLAINTEXT':
|
496 |
-
return urlencode($secretKey);;
|
497 |
-
case 'HMAC-SHA1':
|
498 |
-
$this->sbs = self::_oauthEscape($this->_action).'&'.self::_oauthEscape($this->_path).'&'.self::_oauthEscape($this->_normalizedParameters());
|
499 |
-
|
500 |
-
return base64_encode(hash_hmac('sha1',$this->sbs,$secretKey,TRUE));
|
501 |
-
default:
|
502 |
-
throw new OAuthSimpleException('Unknown signature method for OAuthSimple');
|
503 |
-
break;
|
504 |
-
}
|
505 |
-
}
|
506 |
-
}
|
507 |
-
|
508 |
-
class OAuthSimpleException extends Exception {
|
509 |
-
|
510 |
-
public function __construct($err, $isDebug = FALSE)
|
511 |
-
{
|
512 |
-
self::log_error($err);
|
513 |
-
if ($isDebug)
|
514 |
-
{
|
515 |
-
self::display_error($err, TRUE);
|
516 |
-
}
|
517 |
-
}
|
518 |
-
|
519 |
-
public static function log_error($err)
|
520 |
-
{
|
521 |
-
error_log($err, 0);
|
522 |
-
}
|
523 |
-
|
524 |
-
public static function display_error($err, $kill = FALSE)
|
525 |
-
{
|
526 |
-
print_r($err);
|
527 |
-
if ($kill === FALSE)
|
528 |
-
{
|
529 |
-
die();
|
530 |
-
}
|
531 |
-
}
|
532 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/S3.php
DELETED
@@ -1,1368 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* $Id: S3.php 47 2009-07-20 01:25:40Z don.schonknecht $
|
4 |
-
*
|
5 |
-
* Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
|
6 |
-
*
|
7 |
-
* Redistribution and use in source and binary forms, with or without
|
8 |
-
* modification, are permitted provided that the following conditions are met:
|
9 |
-
*
|
10 |
-
* - Redistributions of source code must retain the above copyright notice,
|
11 |
-
* this list of conditions and the following disclaimer.
|
12 |
-
* - Redistributions in binary form must reproduce the above copyright
|
13 |
-
* notice, this list of conditions and the following disclaimer in the
|
14 |
-
* documentation and/or other materials provided with the distribution.
|
15 |
-
*
|
16 |
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17 |
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18 |
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
19 |
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
20 |
-
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
21 |
-
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
22 |
-
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
23 |
-
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
24 |
-
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
25 |
-
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
26 |
-
* POSSIBILITY OF SUCH DAMAGE.
|
27 |
-
*
|
28 |
-
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
29 |
-
*/
|
30 |
-
|
31 |
-
/** ensure this file is being included by a parent file */
|
32 |
-
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Amazon S3 PHP class
|
36 |
-
*
|
37 |
-
* @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
38 |
-
* @version 0.4.0
|
39 |
-
*/
|
40 |
-
class S3 {
|
41 |
-
// ACL flags
|
42 |
-
const ACL_PRIVATE = 'private';
|
43 |
-
const ACL_PUBLIC_READ = 'public-read';
|
44 |
-
const ACL_PUBLIC_READ_WRITE = 'public-read-write';
|
45 |
-
const ACL_AUTHENTICATED_READ = 'authenticated-read';
|
46 |
-
|
47 |
-
public static $useSSL = true;
|
48 |
-
|
49 |
-
private static $__accessKey; // AWS Access key
|
50 |
-
private static $__secretKey; // AWS Secret key
|
51 |
-
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Constructor - if you're not using the class statically
|
55 |
-
*
|
56 |
-
* @param string $accessKey Access key
|
57 |
-
* @param string $secretKey Secret key
|
58 |
-
* @param boolean $useSSL Enable SSL
|
59 |
-
* @return void
|
60 |
-
*/
|
61 |
-
public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
|
62 |
-
if ($accessKey !== null && $secretKey !== null)
|
63 |
-
self::setAuth($accessKey, $secretKey);
|
64 |
-
self::$useSSL = $useSSL;
|
65 |
-
}
|
66 |
-
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Set AWS access key and secret key
|
70 |
-
*
|
71 |
-
* @param string $accessKey Access key
|
72 |
-
* @param string $secretKey Secret key
|
73 |
-
* @return void
|
74 |
-
*/
|
75 |
-
public static function setAuth($accessKey, $secretKey) {
|
76 |
-
self::$__accessKey = $accessKey;
|
77 |
-
self::$__secretKey = $secretKey;
|
78 |
-
}
|
79 |
-
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Get a list of buckets
|
83 |
-
*
|
84 |
-
* @param boolean $detailed Returns detailed bucket list when true
|
85 |
-
* @return array | false
|
86 |
-
*/
|
87 |
-
public static function listBuckets($detailed = false) {
|
88 |
-
$rest = new S3Request('GET', '', '');
|
89 |
-
$rest = $rest->getResponse();
|
90 |
-
if ($rest->error === false && $rest->code !== 200)
|
91 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
92 |
-
if ($rest->error !== false) {
|
93 |
-
trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
94 |
-
return false;
|
95 |
-
}
|
96 |
-
$results = array();
|
97 |
-
if (!isset($rest->body->Buckets)) return $results;
|
98 |
-
|
99 |
-
if ($detailed) {
|
100 |
-
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
|
101 |
-
$results['owner'] = array(
|
102 |
-
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
|
103 |
-
);
|
104 |
-
$results['buckets'] = array();
|
105 |
-
foreach ($rest->body->Buckets->Bucket as $b)
|
106 |
-
$results['buckets'][] = array(
|
107 |
-
'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
|
108 |
-
);
|
109 |
-
} else
|
110 |
-
foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
|
111 |
-
|
112 |
-
return $results;
|
113 |
-
}
|
114 |
-
|
115 |
-
|
116 |
-
/*
|
117 |
-
* Get contents for a bucket
|
118 |
-
*
|
119 |
-
* If maxKeys is null this method will loop through truncated result sets
|
120 |
-
*
|
121 |
-
* @param string $bucket Bucket name
|
122 |
-
* @param string $prefix Prefix
|
123 |
-
* @param string $marker Marker (last file listed)
|
124 |
-
* @param string $maxKeys Max keys (maximum number of keys to return)
|
125 |
-
* @param string $delimiter Delimiter
|
126 |
-
* @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
|
127 |
-
* @return array | false
|
128 |
-
*/
|
129 |
-
public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) {
|
130 |
-
$rest = new S3Request('GET', $bucket, '');
|
131 |
-
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
132 |
-
if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
|
133 |
-
if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
|
134 |
-
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
135 |
-
$response = $rest->getResponse();
|
136 |
-
if ($response->error === false && $response->code !== 200)
|
137 |
-
$response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
|
138 |
-
if ($response->error !== false) {
|
139 |
-
trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING);
|
140 |
-
return false;
|
141 |
-
}
|
142 |
-
|
143 |
-
$results = array();
|
144 |
-
|
145 |
-
$nextMarker = null;
|
146 |
-
if (isset($response->body, $response->body->Contents))
|
147 |
-
foreach ($response->body->Contents as $c) {
|
148 |
-
$results[(string)$c->Key] = array(
|
149 |
-
'name' => (string)$c->Key,
|
150 |
-
'time' => strtotime((string)$c->LastModified),
|
151 |
-
'size' => (int)$c->Size,
|
152 |
-
'hash' => substr((string)$c->ETag, 1, -1)
|
153 |
-
);
|
154 |
-
$nextMarker = (string)$c->Key;
|
155 |
-
}
|
156 |
-
|
157 |
-
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
158 |
-
foreach ($response->body->CommonPrefixes as $c)
|
159 |
-
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
160 |
-
|
161 |
-
if (isset($response->body, $response->body->IsTruncated) &&
|
162 |
-
(string)$response->body->IsTruncated == 'false') return $results;
|
163 |
-
|
164 |
-
if (isset($response->body, $response->body->NextMarker))
|
165 |
-
$nextMarker = (string)$response->body->NextMarker;
|
166 |
-
|
167 |
-
// Loop through truncated results if maxKeys isn't specified
|
168 |
-
if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
|
169 |
-
do {
|
170 |
-
$rest = new S3Request('GET', $bucket, '');
|
171 |
-
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
172 |
-
$rest->setParameter('marker', $nextMarker);
|
173 |
-
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
174 |
-
|
175 |
-
if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
|
176 |
-
|
177 |
-
if (isset($response->body, $response->body->Contents))
|
178 |
-
foreach ($response->body->Contents as $c) {
|
179 |
-
$results[(string)$c->Key] = array(
|
180 |
-
'name' => (string)$c->Key,
|
181 |
-
'time' => strtotime((string)$c->LastModified),
|
182 |
-
'size' => (int)$c->Size,
|
183 |
-
'hash' => substr((string)$c->ETag, 1, -1)
|
184 |
-
);
|
185 |
-
$nextMarker = (string)$c->Key;
|
186 |
-
}
|
187 |
-
|
188 |
-
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
189 |
-
foreach ($response->body->CommonPrefixes as $c)
|
190 |
-
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
191 |
-
|
192 |
-
if (isset($response->body, $response->body->NextMarker))
|
193 |
-
$nextMarker = (string)$response->body->NextMarker;
|
194 |
-
|
195 |
-
} while ($response !== false && (string)$response->body->IsTruncated == 'true');
|
196 |
-
|
197 |
-
return $results;
|
198 |
-
}
|
199 |
-
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Put a bucket
|
203 |
-
*
|
204 |
-
* @param string $bucket Bucket name
|
205 |
-
* @param constant $acl ACL flag
|
206 |
-
* @param string $location Set as "EU" to create buckets hosted in Europe
|
207 |
-
* @return boolean
|
208 |
-
*/
|
209 |
-
public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) {
|
210 |
-
$rest = new S3Request('PUT', $bucket, '');
|
211 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
212 |
-
|
213 |
-
if ($location !== false) {
|
214 |
-
$dom = new DOMDocument;
|
215 |
-
$createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
|
216 |
-
$locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location));
|
217 |
-
$createBucketConfiguration->appendChild($locationConstraint);
|
218 |
-
$dom->appendChild($createBucketConfiguration);
|
219 |
-
$rest->data = $dom->saveXML();
|
220 |
-
$rest->size = strlen($rest->data);
|
221 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
222 |
-
}
|
223 |
-
$rest = $rest->getResponse();
|
224 |
-
|
225 |
-
if ($rest->error === false && $rest->code !== 200)
|
226 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
227 |
-
if ($rest->error !== false) {
|
228 |
-
trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
|
229 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
230 |
-
return false;
|
231 |
-
}
|
232 |
-
return true;
|
233 |
-
}
|
234 |
-
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Delete an empty bucket
|
238 |
-
*
|
239 |
-
* @param string $bucket Bucket name
|
240 |
-
* @return boolean
|
241 |
-
*/
|
242 |
-
public static function deleteBucket($bucket) {
|
243 |
-
$rest = new S3Request('DELETE', $bucket);
|
244 |
-
$rest = $rest->getResponse();
|
245 |
-
if ($rest->error === false && $rest->code !== 204)
|
246 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
247 |
-
if ($rest->error !== false) {
|
248 |
-
trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
|
249 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
250 |
-
return false;
|
251 |
-
}
|
252 |
-
return true;
|
253 |
-
}
|
254 |
-
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Create input info array for putObject()
|
258 |
-
*
|
259 |
-
* @param string $file Input file
|
260 |
-
* @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
|
261 |
-
* @return array | false
|
262 |
-
*/
|
263 |
-
public static function inputFile($file, $md5sum = true) {
|
264 |
-
if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
|
265 |
-
trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
|
266 |
-
return false;
|
267 |
-
}
|
268 |
-
return array('file' => $file, 'size' => filesize($file),
|
269 |
-
'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
|
270 |
-
base64_encode(md5_file($file, true))) : '');
|
271 |
-
}
|
272 |
-
|
273 |
-
|
274 |
-
/**
|
275 |
-
* Create input array info for putObject() with a resource
|
276 |
-
*
|
277 |
-
* @param string $resource Input resource to read from
|
278 |
-
* @param integer $bufferSize Input byte size
|
279 |
-
* @param string $md5sum MD5 hash to send (optional)
|
280 |
-
* @return array | false
|
281 |
-
*/
|
282 |
-
public static function inputResource(&$resource, $bufferSize, $md5sum = '') {
|
283 |
-
if (!is_resource($resource) || $bufferSize < 0) {
|
284 |
-
trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING);
|
285 |
-
return false;
|
286 |
-
}
|
287 |
-
$input = array('size' => $bufferSize, 'md5sum' => $md5sum);
|
288 |
-
$input['fp'] =& $resource;
|
289 |
-
return $input;
|
290 |
-
}
|
291 |
-
|
292 |
-
|
293 |
-
/**
|
294 |
-
* Put an object
|
295 |
-
*
|
296 |
-
* @param mixed $input Input data
|
297 |
-
* @param string $bucket Bucket name
|
298 |
-
* @param string $uri Object URI
|
299 |
-
* @param constant $acl ACL constant
|
300 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
301 |
-
* @param array $requestHeaders Array of request headers or content type as a string
|
302 |
-
* @return boolean
|
303 |
-
*/
|
304 |
-
public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
305 |
-
if ($input === false) return false;
|
306 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
307 |
-
|
308 |
-
if (is_string($input)) $input = array(
|
309 |
-
'data' => $input, 'size' => strlen($input),
|
310 |
-
'md5sum' => base64_encode(md5($input, true))
|
311 |
-
);
|
312 |
-
|
313 |
-
// Data
|
314 |
-
if (isset($input['fp']))
|
315 |
-
$rest->fp =& $input['fp'];
|
316 |
-
elseif (isset($input['file']))
|
317 |
-
$rest->fp = @fopen($input['file'], 'rb');
|
318 |
-
elseif (isset($input['data']))
|
319 |
-
$rest->data = $input['data'];
|
320 |
-
|
321 |
-
// Content-Length (required)
|
322 |
-
if (isset($input['size']) && $input['size'] >= 0)
|
323 |
-
$rest->size = $input['size'];
|
324 |
-
else {
|
325 |
-
if (isset($input['file']))
|
326 |
-
$rest->size = filesize($input['file']);
|
327 |
-
elseif (isset($input['data']))
|
328 |
-
$rest->size = strlen($input['data']);
|
329 |
-
}
|
330 |
-
|
331 |
-
// Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
|
332 |
-
if (is_array($requestHeaders))
|
333 |
-
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
334 |
-
elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
|
335 |
-
$input['type'] = $requestHeaders;
|
336 |
-
|
337 |
-
// Content-Type
|
338 |
-
if (!isset($input['type'])) {
|
339 |
-
if (isset($requestHeaders['Content-Type']))
|
340 |
-
$input['type'] =& $requestHeaders['Content-Type'];
|
341 |
-
elseif (isset($input['file']))
|
342 |
-
$input['type'] = self::__getMimeType($input['file']);
|
343 |
-
else
|
344 |
-
$input['type'] = 'application/octet-stream';
|
345 |
-
}
|
346 |
-
|
347 |
-
// We need to post with Content-Length and Content-Type, MD5 is optional
|
348 |
-
if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
|
349 |
-
$rest->setHeader('Content-Type', $input['type']);
|
350 |
-
if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
|
351 |
-
|
352 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
353 |
-
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
354 |
-
$rest->getResponse();
|
355 |
-
} else
|
356 |
-
$rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
|
357 |
-
|
358 |
-
if ($rest->response->error === false && $rest->response->code !== 200)
|
359 |
-
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
360 |
-
if ($rest->response->error !== false) {
|
361 |
-
trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
362 |
-
return false;
|
363 |
-
}
|
364 |
-
return true;
|
365 |
-
}
|
366 |
-
|
367 |
-
|
368 |
-
/**
|
369 |
-
* Put an object from a file (legacy function)
|
370 |
-
*
|
371 |
-
* @param string $file Input file path
|
372 |
-
* @param string $bucket Bucket name
|
373 |
-
* @param string $uri Object URI
|
374 |
-
* @param constant $acl ACL constant
|
375 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
376 |
-
* @param string $contentType Content type
|
377 |
-
* @return boolean
|
378 |
-
*/
|
379 |
-
public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) {
|
380 |
-
return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
|
381 |
-
}
|
382 |
-
|
383 |
-
|
384 |
-
/**
|
385 |
-
* Put an object from a string (legacy function)
|
386 |
-
*
|
387 |
-
* @param string $string Input data
|
388 |
-
* @param string $bucket Bucket name
|
389 |
-
* @param string $uri Object URI
|
390 |
-
* @param constant $acl ACL constant
|
391 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
392 |
-
* @param string $contentType Content type
|
393 |
-
* @return boolean
|
394 |
-
*/
|
395 |
-
public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') {
|
396 |
-
return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
|
397 |
-
}
|
398 |
-
|
399 |
-
|
400 |
-
/**
|
401 |
-
* Get an object
|
402 |
-
*
|
403 |
-
* @param string $bucket Bucket name
|
404 |
-
* @param string $uri Object URI
|
405 |
-
* @param mixed $saveTo Filename or resource to write to
|
406 |
-
* @return mixed
|
407 |
-
*/
|
408 |
-
public static function getObject($bucket, $uri, $saveTo = false) {
|
409 |
-
$rest = new S3Request('GET', $bucket, $uri);
|
410 |
-
if ($saveTo !== false) {
|
411 |
-
if (is_resource($saveTo))
|
412 |
-
$rest->fp =& $saveTo;
|
413 |
-
else
|
414 |
-
if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
|
415 |
-
$rest->file = realpath($saveTo);
|
416 |
-
else
|
417 |
-
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
418 |
-
}
|
419 |
-
if ($rest->response->error === false) $rest->getResponse();
|
420 |
-
|
421 |
-
if ($rest->response->error === false && $rest->response->code !== 200)
|
422 |
-
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
423 |
-
if ($rest->response->error !== false) {
|
424 |
-
trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
|
425 |
-
$rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
426 |
-
return false;
|
427 |
-
}
|
428 |
-
return $rest->response;
|
429 |
-
}
|
430 |
-
|
431 |
-
|
432 |
-
/**
|
433 |
-
* Get object information
|
434 |
-
*
|
435 |
-
* @param string $bucket Bucket name
|
436 |
-
* @param string $uri Object URI
|
437 |
-
* @param boolean $returnInfo Return response information
|
438 |
-
* @return mixed | false
|
439 |
-
*/
|
440 |
-
public static function getObjectInfo($bucket, $uri, $returnInfo = true) {
|
441 |
-
$rest = new S3Request('HEAD', $bucket, $uri);
|
442 |
-
$rest = $rest->getResponse();
|
443 |
-
if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
|
444 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
445 |
-
if ($rest->error !== false) {
|
446 |
-
trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
|
447 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
448 |
-
return false;
|
449 |
-
}
|
450 |
-
return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
|
451 |
-
}
|
452 |
-
|
453 |
-
|
454 |
-
/**
|
455 |
-
* Copy an object
|
456 |
-
*
|
457 |
-
* @param string $bucket Source bucket name
|
458 |
-
* @param string $uri Source object URI
|
459 |
-
* @param string $bucket Destination bucket name
|
460 |
-
* @param string $uri Destination object URI
|
461 |
-
* @param constant $acl ACL constant
|
462 |
-
* @param array $metaHeaders Optional array of x-amz-meta-* headers
|
463 |
-
* @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
|
464 |
-
* @return mixed | false
|
465 |
-
*/
|
466 |
-
public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
467 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
468 |
-
$rest->setHeader('Content-Length', 0);
|
469 |
-
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
470 |
-
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
471 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
472 |
-
$rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
|
473 |
-
if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
|
474 |
-
$rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
|
475 |
-
$rest = $rest->getResponse();
|
476 |
-
if ($rest->error === false && $rest->code !== 200)
|
477 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
478 |
-
if ($rest->error !== false) {
|
479 |
-
trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
|
480 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
481 |
-
return false;
|
482 |
-
}
|
483 |
-
return isset($rest->body->LastModified, $rest->body->ETag) ? array(
|
484 |
-
'time' => strtotime((string)$rest->body->LastModified),
|
485 |
-
'hash' => substr((string)$rest->body->ETag, 1, -1)
|
486 |
-
) : false;
|
487 |
-
}
|
488 |
-
|
489 |
-
|
490 |
-
/**
|
491 |
-
* Set logging for a bucket
|
492 |
-
*
|
493 |
-
* @param string $bucket Bucket name
|
494 |
-
* @param string $targetBucket Target bucket (where logs are stored)
|
495 |
-
* @param string $targetPrefix Log prefix (e,g; domain.com-)
|
496 |
-
* @return boolean
|
497 |
-
*/
|
498 |
-
public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) {
|
499 |
-
// The S3 log delivery group has to be added to the target bucket's ACP
|
500 |
-
if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) {
|
501 |
-
// Only add permissions to the target bucket when they do not exist
|
502 |
-
$aclWriteSet = false;
|
503 |
-
$aclReadSet = false;
|
504 |
-
foreach ($acp['acl'] as $acl)
|
505 |
-
if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') {
|
506 |
-
if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
|
507 |
-
elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
|
508 |
-
}
|
509 |
-
if (!$aclWriteSet) $acp['acl'][] = array(
|
510 |
-
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
|
511 |
-
);
|
512 |
-
if (!$aclReadSet) $acp['acl'][] = array(
|
513 |
-
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
|
514 |
-
);
|
515 |
-
if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
|
516 |
-
}
|
517 |
-
|
518 |
-
$dom = new DOMDocument;
|
519 |
-
$bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
|
520 |
-
$bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
|
521 |
-
if ($targetBucket !== null) {
|
522 |
-
if ($targetPrefix == null) $targetPrefix = $bucket . '-';
|
523 |
-
$loggingEnabled = $dom->createElement('LoggingEnabled');
|
524 |
-
$loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
|
525 |
-
$loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
|
526 |
-
// TODO: Add TargetGrants?
|
527 |
-
$bucketLoggingStatus->appendChild($loggingEnabled);
|
528 |
-
}
|
529 |
-
$dom->appendChild($bucketLoggingStatus);
|
530 |
-
|
531 |
-
$rest = new S3Request('PUT', $bucket, '');
|
532 |
-
$rest->setParameter('logging', null);
|
533 |
-
$rest->data = $dom->saveXML();
|
534 |
-
$rest->size = strlen($rest->data);
|
535 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
536 |
-
$rest = $rest->getResponse();
|
537 |
-
if ($rest->error === false && $rest->code !== 200)
|
538 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
539 |
-
if ($rest->error !== false) {
|
540 |
-
trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
|
541 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
542 |
-
return false;
|
543 |
-
}
|
544 |
-
return true;
|
545 |
-
}
|
546 |
-
|
547 |
-
|
548 |
-
/**
|
549 |
-
* Get logging status for a bucket
|
550 |
-
*
|
551 |
-
* This will return false if logging is not enabled.
|
552 |
-
* Note: To enable logging, you also need to grant write access to the log group
|
553 |
-
*
|
554 |
-
* @param string $bucket Bucket name
|
555 |
-
* @return array | false
|
556 |
-
*/
|
557 |
-
public static function getBucketLogging($bucket) {
|
558 |
-
$rest = new S3Request('GET', $bucket, '');
|
559 |
-
$rest->setParameter('logging', null);
|
560 |
-
$rest = $rest->getResponse();
|
561 |
-
if ($rest->error === false && $rest->code !== 200)
|
562 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
563 |
-
if ($rest->error !== false) {
|
564 |
-
trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
|
565 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
566 |
-
return false;
|
567 |
-
}
|
568 |
-
if (!isset($rest->body->LoggingEnabled)) return false; // No logging
|
569 |
-
return array(
|
570 |
-
'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
|
571 |
-
'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
|
572 |
-
);
|
573 |
-
}
|
574 |
-
|
575 |
-
|
576 |
-
/**
|
577 |
-
* Disable bucket logging
|
578 |
-
*
|
579 |
-
* @param string $bucket Bucket name
|
580 |
-
* @return boolean
|
581 |
-
*/
|
582 |
-
public static function disableBucketLogging($bucket) {
|
583 |
-
return self::setBucketLogging($bucket, null);
|
584 |
-
}
|
585 |
-
|
586 |
-
|
587 |
-
/**
|
588 |
-
* Get a bucket's location
|
589 |
-
*
|
590 |
-
* @param string $bucket Bucket name
|
591 |
-
* @return string | false
|
592 |
-
*/
|
593 |
-
public static function getBucketLocation($bucket) {
|
594 |
-
$rest = new S3Request('GET', $bucket, '');
|
595 |
-
$rest->setParameter('location', null);
|
596 |
-
$rest = $rest->getResponse();
|
597 |
-
if ($rest->error === false && $rest->code !== 200)
|
598 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
599 |
-
if ($rest->error !== false) {
|
600 |
-
trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
|
601 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
602 |
-
return false;
|
603 |
-
}
|
604 |
-
return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
|
605 |
-
}
|
606 |
-
|
607 |
-
|
608 |
-
/**
|
609 |
-
* Set object or bucket Access Control Policy
|
610 |
-
*
|
611 |
-
* @param string $bucket Bucket name
|
612 |
-
* @param string $uri Object URI
|
613 |
-
* @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
|
614 |
-
* @return boolean
|
615 |
-
*/
|
616 |
-
public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) {
|
617 |
-
$dom = new DOMDocument;
|
618 |
-
$dom->formatOutput = true;
|
619 |
-
$accessControlPolicy = $dom->createElement('AccessControlPolicy');
|
620 |
-
$accessControlList = $dom->createElement('AccessControlList');
|
621 |
-
|
622 |
-
// It seems the owner has to be passed along too
|
623 |
-
$owner = $dom->createElement('Owner');
|
624 |
-
$owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
|
625 |
-
$owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
|
626 |
-
$accessControlPolicy->appendChild($owner);
|
627 |
-
|
628 |
-
foreach ($acp['acl'] as $g) {
|
629 |
-
$grant = $dom->createElement('Grant');
|
630 |
-
$grantee = $dom->createElement('Grantee');
|
631 |
-
$grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
632 |
-
if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted)
|
633 |
-
$grantee->setAttribute('xsi:type', 'CanonicalUser');
|
634 |
-
$grantee->appendChild($dom->createElement('ID', $g['id']));
|
635 |
-
} elseif (isset($g['email'])) { // AmazonCustomerByEmail
|
636 |
-
$grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
|
637 |
-
$grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
|
638 |
-
} elseif ($g['type'] == 'Group') { // Group
|
639 |
-
$grantee->setAttribute('xsi:type', 'Group');
|
640 |
-
$grantee->appendChild($dom->createElement('URI', $g['uri']));
|
641 |
-
}
|
642 |
-
$grant->appendChild($grantee);
|
643 |
-
$grant->appendChild($dom->createElement('Permission', $g['permission']));
|
644 |
-
$accessControlList->appendChild($grant);
|
645 |
-
}
|
646 |
-
|
647 |
-
$accessControlPolicy->appendChild($accessControlList);
|
648 |
-
$dom->appendChild($accessControlPolicy);
|
649 |
-
|
650 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
651 |
-
$rest->setParameter('acl', null);
|
652 |
-
$rest->data = $dom->saveXML();
|
653 |
-
$rest->size = strlen($rest->data);
|
654 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
655 |
-
$rest = $rest->getResponse();
|
656 |
-
if ($rest->error === false && $rest->code !== 200)
|
657 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
658 |
-
if ($rest->error !== false) {
|
659 |
-
trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
660 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
661 |
-
return false;
|
662 |
-
}
|
663 |
-
return true;
|
664 |
-
}
|
665 |
-
|
666 |
-
|
667 |
-
/**
|
668 |
-
* Get object or bucket Access Control Policy
|
669 |
-
*
|
670 |
-
* @param string $bucket Bucket name
|
671 |
-
* @param string $uri Object URI
|
672 |
-
* @return mixed | false
|
673 |
-
*/
|
674 |
-
public static function getAccessControlPolicy($bucket, $uri = '') {
|
675 |
-
$rest = new S3Request('GET', $bucket, $uri);
|
676 |
-
$rest->setParameter('acl', null);
|
677 |
-
$rest = $rest->getResponse();
|
678 |
-
if ($rest->error === false && $rest->code !== 200)
|
679 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
680 |
-
if ($rest->error !== false) {
|
681 |
-
trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
682 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
683 |
-
return false;
|
684 |
-
}
|
685 |
-
|
686 |
-
$acp = array();
|
687 |
-
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) {
|
688 |
-
$acp['owner'] = array(
|
689 |
-
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
|
690 |
-
);
|
691 |
-
}
|
692 |
-
if (isset($rest->body->AccessControlList)) {
|
693 |
-
$acp['acl'] = array();
|
694 |
-
foreach ($rest->body->AccessControlList->Grant as $grant) {
|
695 |
-
foreach ($grant->Grantee as $grantee) {
|
696 |
-
if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
|
697 |
-
$acp['acl'][] = array(
|
698 |
-
'type' => 'CanonicalUser',
|
699 |
-
'id' => (string)$grantee->ID,
|
700 |
-
'name' => (string)$grantee->DisplayName,
|
701 |
-
'permission' => (string)$grant->Permission
|
702 |
-
);
|
703 |
-
elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
|
704 |
-
$acp['acl'][] = array(
|
705 |
-
'type' => 'AmazonCustomerByEmail',
|
706 |
-
'email' => (string)$grantee->EmailAddress,
|
707 |
-
'permission' => (string)$grant->Permission
|
708 |
-
);
|
709 |
-
elseif (isset($grantee->URI)) // Group
|
710 |
-
$acp['acl'][] = array(
|
711 |
-
'type' => 'Group',
|
712 |
-
'uri' => (string)$grantee->URI,
|
713 |
-
'permission' => (string)$grant->Permission
|
714 |
-
);
|
715 |
-
else continue;
|
716 |
-
}
|
717 |
-
}
|
718 |
-
}
|
719 |
-
return $acp;
|
720 |
-
}
|
721 |
-
|
722 |
-
|
723 |
-
/**
|
724 |
-
* Delete an object
|
725 |
-
*
|
726 |
-
* @param string $bucket Bucket name
|
727 |
-
* @param string $uri Object URI
|
728 |
-
* @return boolean
|
729 |
-
*/
|
730 |
-
public static function deleteObject($bucket, $uri) {
|
731 |
-
$rest = new S3Request('DELETE', $bucket, $uri);
|
732 |
-
$rest = $rest->getResponse();
|
733 |
-
if ($rest->error === false && $rest->code !== 204)
|
734 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
735 |
-
if ($rest->error !== false) {
|
736 |
-
trigger_error(sprintf("S3::deleteObject(): [%s] %s",
|
737 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
738 |
-
return false;
|
739 |
-
}
|
740 |
-
return true;
|
741 |
-
}
|
742 |
-
|
743 |
-
|
744 |
-
/**
|
745 |
-
* Get a query string authenticated URL
|
746 |
-
*
|
747 |
-
* @param string $bucket Bucket name
|
748 |
-
* @param string $uri Object URI
|
749 |
-
* @param integer $lifetime Lifetime in seconds
|
750 |
-
* @param boolean $hostBucket Use the bucket name as the hostname
|
751 |
-
* @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
|
752 |
-
* @return string
|
753 |
-
*/
|
754 |
-
public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) {
|
755 |
-
$expires = time() + $lifetime;
|
756 |
-
$uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
|
757 |
-
return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
|
758 |
-
$hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
|
759 |
-
urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
|
760 |
-
}
|
761 |
-
|
762 |
-
/**
|
763 |
-
* Get upload POST parameters for form uploads
|
764 |
-
*
|
765 |
-
* @param string $bucket Bucket name
|
766 |
-
* @param string $uriPrefix Object URI prefix
|
767 |
-
* @param constant $acl ACL constant
|
768 |
-
* @param integer $lifetime Lifetime in seconds
|
769 |
-
* @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
|
770 |
-
* @param string $successRedirect Redirect URL or 200 / 201 status code
|
771 |
-
* @param array $amzHeaders Array of x-amz-meta-* headers
|
772 |
-
* @param array $headers Array of request headers or content type as a string
|
773 |
-
* @param boolean $flashVars Includes additional "Filename" variable posted by Flash
|
774 |
-
* @return object
|
775 |
-
*/
|
776 |
-
public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) {
|
777 |
-
// Create policy object
|
778 |
-
$policy = new stdClass;
|
779 |
-
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
|
780 |
-
$policy->conditions = array();
|
781 |
-
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
|
782 |
-
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
|
783 |
-
|
784 |
-
$obj = new stdClass; // 200 for non-redirect uploads
|
785 |
-
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
786 |
-
$obj->success_action_status = (string)$successRedirect;
|
787 |
-
else // URL
|
788 |
-
$obj->success_action_redirect = $successRedirect;
|
789 |
-
array_push($policy->conditions, $obj);
|
790 |
-
|
791 |
-
array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
|
792 |
-
if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
|
793 |
-
foreach (array_keys($headers) as $headerKey)
|
794 |
-
array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
|
795 |
-
foreach ($amzHeaders as $headerKey => $headerVal) {
|
796 |
-
$obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj);
|
797 |
-
}
|
798 |
-
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
799 |
-
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
800 |
-
|
801 |
-
// Create parameters
|
802 |
-
$params = new stdClass;
|
803 |
-
$params->AWSAccessKeyId = self::$__accessKey;
|
804 |
-
$params->key = $uriPrefix.'${filename}';
|
805 |
-
$params->acl = $acl;
|
806 |
-
$params->policy = $policy; unset($policy);
|
807 |
-
$params->signature = self::__getHash($params->policy);
|
808 |
-
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
809 |
-
$params->success_action_status = (string)$successRedirect;
|
810 |
-
else
|
811 |
-
$params->success_action_redirect = $successRedirect;
|
812 |
-
foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
813 |
-
foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
814 |
-
return $params;
|
815 |
-
}
|
816 |
-
|
817 |
-
/**
|
818 |
-
* Create a CloudFront distribution
|
819 |
-
*
|
820 |
-
* @param string $bucket Bucket name
|
821 |
-
* @param boolean $enabled Enabled (true/false)
|
822 |
-
* @param array $cnames Array containing CNAME aliases
|
823 |
-
* @param string $comment Use the bucket name as the hostname
|
824 |
-
* @return array | false
|
825 |
-
*/
|
826 |
-
public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') {
|
827 |
-
self::$useSSL = true; // CloudFront requires SSL
|
828 |
-
$rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
829 |
-
$rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames);
|
830 |
-
$rest->size = strlen($rest->data);
|
831 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
832 |
-
$rest = self::__getCloudFrontResponse($rest);
|
833 |
-
|
834 |
-
if ($rest->error === false && $rest->code !== 201)
|
835 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
836 |
-
if ($rest->error !== false) {
|
837 |
-
trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s",
|
838 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
839 |
-
return false;
|
840 |
-
} elseif ($rest->body instanceof SimpleXMLElement)
|
841 |
-
return self::__parseCloudFrontDistributionConfig($rest->body);
|
842 |
-
return false;
|
843 |
-
}
|
844 |
-
|
845 |
-
|
846 |
-
/**
|
847 |
-
* Get CloudFront distribution info
|
848 |
-
*
|
849 |
-
* @param string $distributionId Distribution ID from listDistributions()
|
850 |
-
* @return array | false
|
851 |
-
*/
|
852 |
-
public static function getDistribution($distributionId) {
|
853 |
-
self::$useSSL = true; // CloudFront requires SSL
|
854 |
-
$rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
|
855 |
-
$rest = self::__getCloudFrontResponse($rest);
|
856 |
-
|
857 |
-
if ($rest->error === false && $rest->code !== 200)
|
858 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
859 |
-
if ($rest->error !== false) {
|
860 |
-
trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s",
|
861 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
862 |
-
return false;
|
863 |
-
} elseif ($rest->body instanceof SimpleXMLElement) {
|
864 |
-
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
865 |
-
$dist['hash'] = $rest->headers['hash'];
|
866 |
-
return $dist;
|
867 |
-
}
|
868 |
-
return false;
|
869 |
-
}
|
870 |
-
|
871 |
-
|
872 |
-
/**
|
873 |
-
* Update a CloudFront distribution
|
874 |
-
*
|
875 |
-
* @param array $dist Distribution array info identical to output of getDistribution()
|
876 |
-
* @return array | false
|
877 |
-
*/
|
878 |
-
public static function updateDistribution($dist) {
|
879 |
-
self::$useSSL = true; // CloudFront requires SSL
|
880 |
-
$rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
|
881 |
-
$rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']);
|
882 |
-
$rest->size = strlen($rest->data);
|
883 |
-
$rest->setHeader('If-Match', $dist['hash']);
|
884 |
-
$rest = self::__getCloudFrontResponse($rest);
|
885 |
-
|
886 |
-
if ($rest->error === false && $rest->code !== 200)
|
887 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
888 |
-
if ($rest->error !== false) {
|
889 |
-
trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s",
|
890 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
891 |
-
return false;
|
892 |
-
} else {
|
893 |
-
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
894 |
-
$dist['hash'] = $rest->headers['hash'];
|
895 |
-
return $dist;
|
896 |
-
}
|
897 |
-
return false;
|
898 |
-
}
|
899 |
-
|
900 |
-
|
901 |
-
/**
|
902 |
-
* Delete a CloudFront distribution
|
903 |
-
*
|
904 |
-
* @param array $dist Distribution array info identical to output of getDistribution()
|
905 |
-
* @return boolean
|
906 |
-
*/
|
907 |
-
public static function deleteDistribution($dist) {
|
908 |
-
self::$useSSL = true; // CloudFront requires SSL
|
909 |
-
$rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
|
910 |
-
$rest->setHeader('If-Match', $dist['hash']);
|
911 |
-
$rest = self::__getCloudFrontResponse($rest);
|
912 |
-
|
913 |
-
if ($rest->error === false && $rest->code !== 204)
|
914 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
915 |
-
if ($rest->error !== false) {
|
916 |
-
trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
|
917 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
918 |
-
return false;
|
919 |
-
}
|
920 |
-
return true;
|
921 |
-
}
|
922 |
-
|
923 |
-
|
924 |
-
/**
|
925 |
-
* Get a list of CloudFront distributions
|
926 |
-
*
|
927 |
-
* @return array
|
928 |
-
*/
|
929 |
-
public static function listDistributions() {
|
930 |
-
self::$useSSL = true; // CloudFront requires SSL
|
931 |
-
$rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
932 |
-
$rest = self::__getCloudFrontResponse($rest);
|
933 |
-
|
934 |
-
if ($rest->error === false && $rest->code !== 200)
|
935 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
936 |
-
if ($rest->error !== false) {
|
937 |
-
trigger_error(sprintf("S3::listDistributions(): [%s] %s",
|
938 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
939 |
-
return false;
|
940 |
-
} elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
|
941 |
-
$list = array();
|
942 |
-
if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
|
943 |
-
//$info['marker'] = (string)$rest->body->Marker;
|
944 |
-
//$info['maxItems'] = (int)$rest->body->MaxItems;
|
945 |
-
//$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
|
946 |
-
}
|
947 |
-
foreach ($rest->body->DistributionSummary as $summary) {
|
948 |
-
$list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
|
949 |
-
}
|
950 |
-
return $list;
|
951 |
-
}
|
952 |
-
return array();
|
953 |
-
}
|
954 |
-
|
955 |
-
|
956 |
-
/**
|
957 |
-
* Get a DistributionConfig DOMDocument
|
958 |
-
*
|
959 |
-
* @internal Used to create XML in createDistribution() and updateDistribution()
|
960 |
-
* @param string $bucket Origin bucket
|
961 |
-
* @param boolean $enabled Enabled (true/false)
|
962 |
-
* @param string $comment Comment to append
|
963 |
-
* @param string $callerReference Caller reference
|
964 |
-
* @param array $cnames Array of CNAME aliases
|
965 |
-
* @return string
|
966 |
-
*/
|
967 |
-
private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) {
|
968 |
-
$dom = new DOMDocument('1.0', 'UTF-8');
|
969 |
-
$dom->formatOutput = true;
|
970 |
-
$distributionConfig = $dom->createElement('DistributionConfig');
|
971 |
-
$distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/');
|
972 |
-
$distributionConfig->appendChild($dom->createElement('Origin', $bucket));
|
973 |
-
$distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
|
974 |
-
foreach ($cnames as $cname)
|
975 |
-
$distributionConfig->appendChild($dom->createElement('CNAME', $cname));
|
976 |
-
if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
|
977 |
-
$distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
|
978 |
-
$dom->appendChild($distributionConfig);
|
979 |
-
return $dom->saveXML();
|
980 |
-
}
|
981 |
-
|
982 |
-
|
983 |
-
/**
|
984 |
-
* Parse a CloudFront distribution config
|
985 |
-
*
|
986 |
-
* @internal Used to parse the CloudFront DistributionConfig node to an array
|
987 |
-
* @param object &$node DOMNode
|
988 |
-
* @return array
|
989 |
-
*/
|
990 |
-
private static function __parseCloudFrontDistributionConfig(&$node) {
|
991 |
-
$dist = array();
|
992 |
-
if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) {
|
993 |
-
$dist['id'] = (string)$node->Id;
|
994 |
-
$dist['status'] = (string)$node->Status;
|
995 |
-
$dist['time'] = strtotime((string)$node->LastModifiedTime);
|
996 |
-
$dist['domain'] = (string)$node->DomainName;
|
997 |
-
}
|
998 |
-
if (isset($node->CallerReference))
|
999 |
-
$dist['callerReference'] = (string)$node->CallerReference;
|
1000 |
-
if (isset($node->Comment))
|
1001 |
-
$dist['comment'] = (string)$node->Comment;
|
1002 |
-
if (isset($node->Enabled, $node->Origin)) {
|
1003 |
-
$dist['origin'] = (string)$node->Origin;
|
1004 |
-
$dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
|
1005 |
-
} elseif (isset($node->DistributionConfig)) {
|
1006 |
-
$dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig));
|
1007 |
-
}
|
1008 |
-
if (isset($node->CNAME)) {
|
1009 |
-
$dist['cnames'] = array();
|
1010 |
-
foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname;
|
1011 |
-
}
|
1012 |
-
return $dist;
|
1013 |
-
}
|
1014 |
-
|
1015 |
-
|
1016 |
-
/**
|
1017 |
-
* Grab CloudFront response
|
1018 |
-
*
|
1019 |
-
* @internal Used to parse the CloudFront S3Request::getResponse() output
|
1020 |
-
* @param object &$rest S3Request instance
|
1021 |
-
* @return object
|
1022 |
-
*/
|
1023 |
-
private static function __getCloudFrontResponse(&$rest) {
|
1024 |
-
$rest->getResponse();
|
1025 |
-
if ($rest->response->error === false && isset($rest->response->body) &&
|
1026 |
-
is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml') {
|
1027 |
-
$rest->response->body = simplexml_load_string($rest->response->body);
|
1028 |
-
// Grab CloudFront errors
|
1029 |
-
if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
|
1030 |
-
$rest->response->body->Error->Message)) {
|
1031 |
-
$rest->response->error = array(
|
1032 |
-
'code' => (string)$rest->response->body->Error->Code,
|
1033 |
-
'message' => (string)$rest->response->body->Error->Message
|
1034 |
-
);
|
1035 |
-
unset($rest->response->body);
|
1036 |
-
}
|
1037 |
-
}
|
1038 |
-
return $rest->response;
|
1039 |
-
}
|
1040 |
-
|
1041 |
-
|
1042 |
-
/**
|
1043 |
-
* Get MIME type for file
|
1044 |
-
*
|
1045 |
-
* @internal Used to get mime types
|
1046 |
-
* @param string &$file File path
|
1047 |
-
* @return string
|
1048 |
-
*/
|
1049 |
-
public static function __getMimeType(&$file) {
|
1050 |
-
$type = false;
|
1051 |
-
// Fileinfo documentation says fileinfo_open() will use the
|
1052 |
-
// MAGIC env var for the magic file
|
1053 |
-
if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
|
1054 |
-
($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) {
|
1055 |
-
if (($type = finfo_file($finfo, $file)) !== false) {
|
1056 |
-
// Remove the charset and grab the last content-type
|
1057 |
-
$type = explode(' ', str_replace('; charset=', ';charset=', $type));
|
1058 |
-
$type = array_pop($type);
|
1059 |
-
$type = explode(';', $type);
|
1060 |
-
$type = trim(array_shift($type));
|
1061 |
-
}
|
1062 |
-
finfo_close($finfo);
|
1063 |
-
|
1064 |
-
// If anyone is still using mime_content_type()
|
1065 |
-
} elseif (function_exists('mime_content_type'))
|
1066 |
-
$type = trim(mime_content_type($file));
|
1067 |
-
|
1068 |
-
if ($type !== false && strlen($type) > 0) return $type;
|
1069 |
-
|
1070 |
-
// Otherwise do it the old fashioned way
|
1071 |
-
static $exts = array(
|
1072 |
-
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
1073 |
-
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
1074 |
-
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
1075 |
-
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
1076 |
-
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
1077 |
-
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
1078 |
-
'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
|
1079 |
-
'css' => 'text/css', 'js' => 'text/javascript',
|
1080 |
-
'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
|
1081 |
-
'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
|
1082 |
-
'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
|
1083 |
-
'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
|
1084 |
-
);
|
1085 |
-
$ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
|
1086 |
-
return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
|
1087 |
-
}
|
1088 |
-
|
1089 |
-
|
1090 |
-
/**
|
1091 |
-
* Generate the auth string: "AWS AccessKey:Signature"
|
1092 |
-
*
|
1093 |
-
* @internal Used by S3Request::getResponse()
|
1094 |
-
* @param string $string String to sign
|
1095 |
-
* @return string
|
1096 |
-
*/
|
1097 |
-
public static function __getSignature($string) {
|
1098 |
-
return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
|
1102 |
-
/**
|
1103 |
-
* Creates a HMAC-SHA1 hash
|
1104 |
-
*
|
1105 |
-
* This uses the hash extension if loaded
|
1106 |
-
*
|
1107 |
-
* @internal Used by __getSignature()
|
1108 |
-
* @param string $string String to sign
|
1109 |
-
* @return string
|
1110 |
-
*/
|
1111 |
-
private static function __getHash($string) {
|
1112 |
-
return base64_encode(extension_loaded('hash') ?
|
1113 |
-
hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
|
1114 |
-
(str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
|
1115 |
-
pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
|
1116 |
-
(str_repeat(chr(0x36), 64))) . $string)))));
|
1117 |
-
}
|
1118 |
-
|
1119 |
-
}
|
1120 |
-
|
1121 |
-
final class S3Request {
|
1122 |
-
private $verb, $bucket, $uri, $resource = '', $parameters = array(),
|
1123 |
-
$amzHeaders = array(), $headers = array(
|
1124 |
-
'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
|
1125 |
-
);
|
1126 |
-
public $fp = false, $size = 0, $data = false, $response;
|
1127 |
-
|
1128 |
-
|
1129 |
-
/**
|
1130 |
-
* Constructor
|
1131 |
-
*
|
1132 |
-
* @param string $verb Verb
|
1133 |
-
* @param string $bucket Bucket name
|
1134 |
-
* @param string $uri Object URI
|
1135 |
-
* @return mixed
|
1136 |
-
*/
|
1137 |
-
function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') {
|
1138 |
-
$this->verb = $verb;
|
1139 |
-
$this->bucket = strtolower($bucket);
|
1140 |
-
$this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
|
1141 |
-
|
1142 |
-
if ($this->bucket !== '') {
|
1143 |
-
$this->headers['Host'] = $this->bucket.'.'.$defaultHost;
|
1144 |
-
$this->resource = '/'.$this->bucket.$this->uri;
|
1145 |
-
} else {
|
1146 |
-
$this->headers['Host'] = $defaultHost;
|
1147 |
-
//$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri;
|
1148 |
-
$this->resource = $this->uri;
|
1149 |
-
}
|
1150 |
-
$this->headers['Date'] = gmdate('D, d M Y H:i:s T');
|
1151 |
-
|
1152 |
-
$this->response = new STDClass;
|
1153 |
-
$this->response->error = false;
|
1154 |
-
}
|
1155 |
-
|
1156 |
-
|
1157 |
-
/**
|
1158 |
-
* Set request parameter
|
1159 |
-
*
|
1160 |
-
* @param string $key Key
|
1161 |
-
* @param string $value Value
|
1162 |
-
* @return void
|
1163 |
-
*/
|
1164 |
-
public function setParameter($key, $value) {
|
1165 |
-
$this->parameters[$key] = $value;
|
1166 |
-
}
|
1167 |
-
|
1168 |
-
|
1169 |
-
/**
|
1170 |
-
* Set request header
|
1171 |
-
*
|
1172 |
-
* @param string $key Key
|
1173 |
-
* @param string $value Value
|
1174 |
-
* @return void
|
1175 |
-
*/
|
1176 |
-
public function setHeader($key, $value) {
|
1177 |
-
$this->headers[$key] = $value;
|
1178 |
-
}
|
1179 |
-
|
1180 |
-
|
1181 |
-
/**
|
1182 |
-
* Set x-amz-meta-* header
|
1183 |
-
*
|
1184 |
-
* @param string $key Key
|
1185 |
-
* @param string $value Value
|
1186 |
-
* @return void
|
1187 |
-
*/
|
1188 |
-
public function setAmzHeader($key, $value) {
|
1189 |
-
$this->amzHeaders[$key] = $value;
|
1190 |
-
}
|
1191 |
-
|
1192 |
-
|
1193 |
-
/**
|
1194 |
-
* Get the S3 response
|
1195 |
-
*
|
1196 |
-
* @return object | false
|
1197 |
-
*/
|
1198 |
-
public function getResponse() {
|
1199 |
-
$query = '';
|
1200 |
-
if (sizeof($this->parameters) > 0) {
|
1201 |
-
$query = substr($this->uri, -1) !== '?' ? '?' : '&';
|
1202 |
-
foreach ($this->parameters as $var => $value)
|
1203 |
-
if ($value == null || $value == '') $query .= $var.'&';
|
1204 |
-
// Parameters should be encoded (thanks Sean O'Dea)
|
1205 |
-
else $query .= $var.'='.rawurlencode($value).'&';
|
1206 |
-
$query = substr($query, 0, -1);
|
1207 |
-
$this->uri .= $query;
|
1208 |
-
|
1209 |
-
if (array_key_exists('acl', $this->parameters) ||
|
1210 |
-
array_key_exists('location', $this->parameters) ||
|
1211 |
-
array_key_exists('torrent', $this->parameters) ||
|
1212 |
-
array_key_exists('logging', $this->parameters))
|
1213 |
-
$this->resource .= $query;
|
1214 |
-
}
|
1215 |
-
$url = ((S3::$useSSL && extension_loaded('openssl')) ?
|
1216 |
-
'https://':'http://').$this->headers['Host'].$this->uri;
|
1217 |
-
//var_dump($this->bucket, $this->uri, $this->resource, $url);
|
1218 |
-
|
1219 |
-
// Basic setup
|
1220 |
-
$curl = curl_init();
|
1221 |
-
curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
|
1222 |
-
|
1223 |
-
if (S3::$useSSL) {
|
1224 |
-
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
|
1225 |
-
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
|
1226 |
-
}
|
1227 |
-
|
1228 |
-
curl_setopt($curl, CURLOPT_URL, $url);
|
1229 |
-
|
1230 |
-
// Headers
|
1231 |
-
$headers = array(); $amz = array();
|
1232 |
-
foreach ($this->amzHeaders as $header => $value)
|
1233 |
-
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
1234 |
-
foreach ($this->headers as $header => $value)
|
1235 |
-
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
1236 |
-
|
1237 |
-
// Collect AMZ headers for signature
|
1238 |
-
foreach ($this->amzHeaders as $header => $value)
|
1239 |
-
if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
|
1240 |
-
|
1241 |
-
// AMZ headers must be sorted
|
1242 |
-
if (sizeof($amz) > 0) {
|
1243 |
-
sort($amz);
|
1244 |
-
$amz = "\n".implode("\n", $amz);
|
1245 |
-
} else $amz = '';
|
1246 |
-
|
1247 |
-
// Authorization string (CloudFront stringToSign should only contain a date)
|
1248 |
-
$headers[] = 'Authorization: ' . S3::__getSignature(
|
1249 |
-
$this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
|
1250 |
-
$this->verb."\n".$this->headers['Content-MD5']."\n".
|
1251 |
-
$this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
|
1252 |
-
);
|
1253 |
-
|
1254 |
-
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
1255 |
-
curl_setopt($curl, CURLOPT_HEADER, false);
|
1256 |
-
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
|
1257 |
-
curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
|
1258 |
-
curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
|
1259 |
-
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
1260 |
-
|
1261 |
-
// Request types
|
1262 |
-
switch ($this->verb) {
|
1263 |
-
case 'GET': break;
|
1264 |
-
case 'PUT': case 'POST': // POST only used for CloudFront
|
1265 |
-
if ($this->fp !== false) {
|
1266 |
-
curl_setopt($curl, CURLOPT_PUT, true);
|
1267 |
-
curl_setopt($curl, CURLOPT_INFILE, $this->fp);
|
1268 |
-
if ($this->size >= 0)
|
1269 |
-
curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
|
1270 |
-
} elseif ($this->data !== false) {
|
1271 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
1272 |
-
curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
|
1273 |
-
if ($this->size >= 0)
|
1274 |
-
curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
|
1275 |
-
} else
|
1276 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
1277 |
-
break;
|
1278 |
-
case 'HEAD':
|
1279 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
1280 |
-
curl_setopt($curl, CURLOPT_NOBODY, true);
|
1281 |
-
break;
|
1282 |
-
case 'DELETE':
|
1283 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
1284 |
-
break;
|
1285 |
-
default: break;
|
1286 |
-
}
|
1287 |
-
|
1288 |
-
// Execute, grab errors
|
1289 |
-
if (curl_exec($curl))
|
1290 |
-
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
1291 |
-
else
|
1292 |
-
$this->response->error = array(
|
1293 |
-
'code' => curl_errno($curl),
|
1294 |
-
'message' => curl_error($curl),
|
1295 |
-
'resource' => $this->resource
|
1296 |
-
);
|
1297 |
-
|
1298 |
-
@curl_close($curl);
|
1299 |
-
|
1300 |
-
// Parse body into XML
|
1301 |
-
if ($this->response->error === false && isset($this->response->headers['type']) &&
|
1302 |
-
$this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
|
1303 |
-
$this->response->body = simplexml_load_string($this->response->body);
|
1304 |
-
|
1305 |
-
// Grab S3 errors
|
1306 |
-
if (!in_array($this->response->code, array(200, 204)) &&
|
1307 |
-
isset($this->response->body->Code, $this->response->body->Message)) {
|
1308 |
-
$this->response->error = array(
|
1309 |
-
'code' => (string)$this->response->body->Code,
|
1310 |
-
'message' => (string)$this->response->body->Message
|
1311 |
-
);
|
1312 |
-
if (isset($this->response->body->Resource))
|
1313 |
-
$this->response->error['resource'] = (string)$this->response->body->Resource;
|
1314 |
-
unset($this->response->body);
|
1315 |
-
}
|
1316 |
-
}
|
1317 |
-
|
1318 |
-
// Clean up file resources
|
1319 |
-
if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
|
1320 |
-
|
1321 |
-
return $this->response;
|
1322 |
-
}
|
1323 |
-
|
1324 |
-
|
1325 |
-
/**
|
1326 |
-
* CURL write callback
|
1327 |
-
*
|
1328 |
-
* @param resource &$curl CURL resource
|
1329 |
-
* @param string &$data Data
|
1330 |
-
* @return integer
|
1331 |
-
*/
|
1332 |
-
private function __responseWriteCallback(&$curl, &$data) {
|
1333 |
-
if ($this->response->code == 200 && $this->fp !== false)
|
1334 |
-
return fwrite($this->fp, $data);
|
1335 |
-
else
|
1336 |
-
$this->response->body .= $data;
|
1337 |
-
return strlen($data);
|
1338 |
-
}
|
1339 |
-
|
1340 |
-
|
1341 |
-
/**
|
1342 |
-
* CURL header callback
|
1343 |
-
*
|
1344 |
-
* @param resource &$curl CURL resource
|
1345 |
-
* @param string &$data Data
|
1346 |
-
* @return integer
|
1347 |
-
*/
|
1348 |
-
private function __responseHeaderCallback(&$curl, &$data) {
|
1349 |
-
if (($strlen = strlen($data)) <= 2) return $strlen;
|
1350 |
-
if (substr($data, 0, 4) == 'HTTP')
|
1351 |
-
$this->response->code = (int)substr($data, 9, 3);
|
1352 |
-
else {
|
1353 |
-
list($header, $value) = explode(': ', trim($data), 2);
|
1354 |
-
if ($header == 'Last-Modified')
|
1355 |
-
$this->response->headers['time'] = strtotime($value);
|
1356 |
-
elseif ($header == 'Content-Length')
|
1357 |
-
$this->response->headers['size'] = (int)$value;
|
1358 |
-
elseif ($header == 'Content-Type')
|
1359 |
-
$this->response->headers['type'] = $value;
|
1360 |
-
elseif ($header == 'ETag')
|
1361 |
-
$this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
|
1362 |
-
elseif (preg_match('/^x-amz-meta-.*$/', $header))
|
1363 |
-
$this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
|
1364 |
-
}
|
1365 |
-
return $strlen;
|
1366 |
-
}
|
1367 |
-
|
1368 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/error.class.php
DELETED
File without changes
|
classes/fileRecursion.php
DELETED
@@ -1,477 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* fileRecursion.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
class fileRecursion{
|
25 |
-
|
26 |
-
public static $debug = 0;
|
27 |
-
|
28 |
-
private static $fp;
|
29 |
-
private static $fpd;
|
30 |
-
private static $fpe;
|
31 |
-
private static $d_arr;
|
32 |
-
private static $f_arr;
|
33 |
-
private static $BACKUP_EXTENSIONS = array("tar", "zip", "tgz", "tar.gz");
|
34 |
-
private static $INCL_EXTENSIONS = array("sql", "txt");
|
35 |
-
|
36 |
-
public static $excludeList = array();
|
37 |
-
public static $count;
|
38 |
-
public static $TEMP_PERM = ".excl";
|
39 |
-
public static $TEMP_D_ARR = "tmp/.dir";
|
40 |
-
public static $TEMP_EXCL = "tmp/.excl";
|
41 |
-
public static $TEMP_DIR = "/opt/lampp/htdocs/joomla/administrator/backups"; //exclude other backups
|
42 |
-
public static $START_DIR = "/"; # Backups Start Dir
|
43 |
-
public static $EXCLUDE_FILES_SIZE = -1; //disabled
|
44 |
-
public static $TEMP_OVERSIZED_FILE = "tmp/.oversized_files";
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
public static function setData($data) {
|
49 |
-
|
50 |
-
self::$TEMP_PERM = $data['TEMP_PERM'];
|
51 |
-
self::$TEMP_EXCL = $data['TEMP_EXCL'];
|
52 |
-
self::$TEMP_D_ARR = $data['TEMP_D_ARR'];
|
53 |
-
self::$TEMP_DIR = $data['TEMP_DIR'];
|
54 |
-
self::$START_DIR = $data['START_DIR'];
|
55 |
-
self::$EXCLUDE_FILES_SIZE = $data['EXCLUDE_FILES_SIZE'];
|
56 |
-
self::$TEMP_OVERSIZED_FILE = $data['TEMP_OVERSIZED_FILE'];
|
57 |
-
}
|
58 |
-
|
59 |
-
/*
|
60 |
-
* Init the recursion system
|
61 |
-
* name: init
|
62 |
-
* @param string $startDir Initial directory
|
63 |
-
* @return
|
64 |
-
*/
|
65 |
-
public static function init($startDir = ""){
|
66 |
-
|
67 |
-
///if(self::$init)
|
68 |
-
//@unlink(PERM);
|
69 |
-
|
70 |
-
if($startDir != ""){
|
71 |
-
self::debug("Starting fresh, deleting ". self::$TEMP_PERM);
|
72 |
-
@unlink(self::$TEMP_PERM);
|
73 |
-
self::$d_arr[] = $startDir;
|
74 |
-
}
|
75 |
-
else{
|
76 |
-
self::debug("Starting a new queue ". self::$TEMP_D_ARR);
|
77 |
-
self::debug("Opened directory $dir");
|
78 |
-
self::$d_arr = array_filter(explode("\n", file_get_contents(self::$TEMP_D_ARR)));
|
79 |
-
}
|
80 |
-
|
81 |
-
self::$fp = fopen(self::$TEMP_PERM, "a");
|
82 |
-
self::$fpd = fopen(self::$TEMP_D_ARR, "w");
|
83 |
-
self::$fpe = fopen(self::$TEMP_OVERSIZED_FILE, "a");
|
84 |
-
|
85 |
-
self::initEXCL();
|
86 |
-
|
87 |
-
if($startDir != ""){
|
88 |
-
$inclFiles = self::getInclFiles();
|
89 |
-
self::writePermFiles($inclFiles, "F", 1);
|
90 |
-
}
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
/*
|
95 |
-
* We close the stuff left opened
|
96 |
-
* name: close
|
97 |
-
* @param
|
98 |
-
* @return
|
99 |
-
*/
|
100 |
-
public static function close(){
|
101 |
-
|
102 |
-
@fclose(self::$fp );
|
103 |
-
@fclose(self::$fpd );
|
104 |
-
@fclose(self::$fpe );
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
-
/*
|
109 |
-
* Count the number of files saved in TEMP_PERM
|
110 |
-
* name: countPermFiles
|
111 |
-
* @param
|
112 |
-
* @return array $return($num, $size) (number of files saved, size of total files)
|
113 |
-
*/
|
114 |
-
public static function countPermFiles(){
|
115 |
-
|
116 |
-
$handle = fopen(self::$TEMP_PERM, "r");
|
117 |
-
$return['count'] = 0;
|
118 |
-
$return['size'] = 0;
|
119 |
-
|
120 |
-
while (($buffer = fgets($handle, 4096)) !== false) {
|
121 |
-
|
122 |
-
$return['count']++;
|
123 |
-
|
124 |
-
$data = @explode("|", str_replace("\n", "", $buffer));
|
125 |
-
//if($data[3] == 'F')
|
126 |
-
$return['size'] = $return['size'] + $data[2];
|
127 |
-
}
|
128 |
-
fclose($handle);
|
129 |
-
|
130 |
-
return $return;
|
131 |
-
|
132 |
-
}
|
133 |
-
|
134 |
-
/*
|
135 |
-
* Return the backup files from TEMP_DIR
|
136 |
-
* name: getBackupFiles
|
137 |
-
* @param
|
138 |
-
* @return array $backupFiles files list
|
139 |
-
*/
|
140 |
-
public static function getBackupFiles(){
|
141 |
-
|
142 |
-
$files = scandir(self::$TEMP_DIR);
|
143 |
-
$backupFiles = array();
|
144 |
-
|
145 |
-
foreach($files as $file){
|
146 |
-
$info = pathinfo(self::$TEMP_DIR."/".$file);
|
147 |
-
|
148 |
-
if(in_array($info['extension'], self::$BACKUP_EXTENSIONS)){
|
149 |
-
//self::debug("Found previous files: ".$info['basename']);
|
150 |
-
$backupFiles[sizeof($backupFiles)] = $info['dirname']."/".$info['basename'];
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
self::debug("Found previous backup: ".implode(".",$backupFiles));
|
155 |
-
return $backupFiles;
|
156 |
-
|
157 |
-
}
|
158 |
-
|
159 |
-
/*
|
160 |
-
* Return the force include files from TEMP_DIR
|
161 |
-
* name: getInclFiles
|
162 |
-
* @param
|
163 |
-
* @return array $backupFiles files list
|
164 |
-
*/
|
165 |
-
public static function getInclFiles(){
|
166 |
-
|
167 |
-
self::debug("Reading the ".self::$TEMP_DIR ." for inclusion files");
|
168 |
-
if(self::isNotExcluded(self::$TEMP_DIR))
|
169 |
-
return;
|
170 |
-
|
171 |
-
$files = scandir(self::$TEMP_DIR);
|
172 |
-
$backupFiles = array();
|
173 |
-
|
174 |
-
foreach($files as $file){
|
175 |
-
$info = pathinfo(self::$TEMP_DIR."/".$file);
|
176 |
-
|
177 |
-
if(in_array($info['extension'], self::$INCL_EXTENSIONS)){
|
178 |
-
self::debug("Found previous files: ".$info['basename']);
|
179 |
-
$backupFiles[sizeof($backupFiles)] = $info['dirname']."/".$info['basename'];
|
180 |
-
}
|
181 |
-
}
|
182 |
-
|
183 |
-
self::debug("Found previous backup: ".implode(".",$backupFiles));
|
184 |
-
return $backupFiles;
|
185 |
-
|
186 |
-
}
|
187 |
-
|
188 |
-
/*
|
189 |
-
* Initialize the excluded file list
|
190 |
-
* name: initEXCL
|
191 |
-
* @param
|
192 |
-
* @return
|
193 |
-
*/
|
194 |
-
public static function initEXCL(){
|
195 |
-
|
196 |
-
//adding files from the TEMP_EXCL file
|
197 |
-
if(file_exists(self::$TEMP_EXCL))
|
198 |
-
self::$excludeList = array_filter(explode("\n", file_get_contents(self::$TEMP_EXCL)));
|
199 |
-
|
200 |
-
//excluding existing backup archives
|
201 |
-
$excludeBackupFiles = self::getBackupFiles();
|
202 |
-
foreach($excludeBackupFiles as $file){
|
203 |
-
self::$excludeList[sizeof(self::$excludeList)] = $file;
|
204 |
-
}
|
205 |
-
//self::debug(self::$TEMP_EXCL);
|
206 |
-
self::debug("Excluded list:".implode("\n", self::$excludeList));
|
207 |
-
|
208 |
-
}
|
209 |
-
|
210 |
-
/*
|
211 |
-
* Check if we processed the full directory
|
212 |
-
* name: isQueueFinished
|
213 |
-
* @param
|
214 |
-
* @return
|
215 |
-
*/
|
216 |
-
public static function isQueueFinished(){
|
217 |
-
|
218 |
-
$return = true;
|
219 |
-
|
220 |
-
if(sizeof(self::$d_arr) != 0){
|
221 |
-
$return = false;
|
222 |
-
}
|
223 |
-
|
224 |
-
return $return;
|
225 |
-
|
226 |
-
}
|
227 |
-
|
228 |
-
/*
|
229 |
-
* End recursion file system
|
230 |
-
* name: end
|
231 |
-
* @param
|
232 |
-
* @return
|
233 |
-
*/
|
234 |
-
public static function end(){
|
235 |
-
|
236 |
-
fclose(self::$fp);
|
237 |
-
fclose(self::$fpd);
|
238 |
-
|
239 |
-
self::debug("All done, existing... ");
|
240 |
-
|
241 |
-
}
|
242 |
-
|
243 |
-
/*
|
244 |
-
* Send debug messages
|
245 |
-
*
|
246 |
-
* name: debug
|
247 |
-
* @param string $message
|
248 |
-
* @return
|
249 |
-
*/
|
250 |
-
public static function debug($message, $force=0){
|
251 |
-
|
252 |
-
if((self::$debug) || ($force)){
|
253 |
-
print($message."<br />\n");
|
254 |
-
}
|
255 |
-
|
256 |
-
return;
|
257 |
-
|
258 |
-
}
|
259 |
-
|
260 |
-
/*
|
261 |
-
* Start the recursion
|
262 |
-
*
|
263 |
-
* name: start
|
264 |
-
* @param
|
265 |
-
* @return
|
266 |
-
*/
|
267 |
-
public static function start(){
|
268 |
-
|
269 |
-
self::debug("Start ");
|
270 |
-
foreach(self::$d_arr as $key=>$startdir)
|
271 |
-
if($startdir != ""){
|
272 |
-
|
273 |
-
self::debug("Processing ". $startdir);
|
274 |
-
|
275 |
-
unset(self::$d_arr[$key]);
|
276 |
-
|
277 |
-
if(self::isNotExcluded($startdir)){
|
278 |
-
self::writePermFile($startdir, "D");
|
279 |
-
self::$count++;
|
280 |
-
self::getDirectories($startdir);
|
281 |
-
}else{
|
282 |
-
|
283 |
-
self::debug("$startdir excluded");
|
284 |
-
}
|
285 |
-
|
286 |
-
}
|
287 |
-
|
288 |
-
self::$d_arr = array_filter(self::$d_arr);
|
289 |
-
if(sizeof(self::$d_arr) != 0){
|
290 |
-
|
291 |
-
$data = implode("\n", self::$d_arr);
|
292 |
-
fwrite(self::$fpd, $data);
|
293 |
-
self::debug("Found $data");
|
294 |
-
self::$count++;
|
295 |
-
}
|
296 |
-
else{
|
297 |
-
self::debug("Queue finished");
|
298 |
-
}
|
299 |
-
|
300 |
-
}
|
301 |
-
|
302 |
-
/*
|
303 |
-
* Check if the file is not in the exclusion list
|
304 |
-
*
|
305 |
-
* name: isNotExcluded
|
306 |
-
* @param string $file System File
|
307 |
-
* @return
|
308 |
-
*/
|
309 |
-
public static function isNotExcluded($file){
|
310 |
-
|
311 |
-
$excluded = true;
|
312 |
-
|
313 |
-
foreach(self::$excludeList as $exclFile){
|
314 |
-
$mfile = str_replace(array("/","\\","\n","\r"), array("",""), trim($file));
|
315 |
-
$mexclFile = str_replace(array("/","\\","\n","\r"), array("",""), ($exclFile));
|
316 |
-
|
317 |
-
self::debug("exclude:".$mfile."--".$mexclFile);
|
318 |
-
$string = stristr($mfile, $mexclFile);
|
319 |
-
if($string != ""){
|
320 |
-
$excluded = false;
|
321 |
-
self::debug("$file excluded");
|
322 |
-
return $excluded;
|
323 |
-
}else
|
324 |
-
self::debug("$file not excluded # $string");
|
325 |
-
}
|
326 |
-
|
327 |
-
return $excluded;
|
328 |
-
|
329 |
-
}
|
330 |
-
|
331 |
-
|
332 |
-
/*
|
333 |
-
* Return the size of a file, tries to overcome the 4GB php filesize limitation
|
334 |
-
*
|
335 |
-
* name: getFileSize
|
336 |
-
* @param string $file file path
|
337 |
-
* @return string $sizeInBytes return the size in bytes of the file, PHP only returns values up to 4GB
|
338 |
-
*/
|
339 |
-
public static function getFileSize($file){
|
340 |
-
|
341 |
-
$sizeInBytes = sprintf("%u", filesize($file));
|
342 |
-
if ((!$sizeInBytes) and (function_exists("exec"))){
|
343 |
-
$command = "ls -l \"$file\" | cut -d \" \" -f 5";
|
344 |
-
$sizeInBytes = @exec($command);
|
345 |
-
}
|
346 |
-
|
347 |
-
return $sizeInBytes;
|
348 |
-
|
349 |
-
}
|
350 |
-
|
351 |
-
public static function getOverLimitFiles(){
|
352 |
-
@fclose(self::$fpe);
|
353 |
-
$files = explode("\n", file_get_contents(self::$TEMP_OVERSIZED_FILE));
|
354 |
-
|
355 |
-
return array_diff($files, array(""));
|
356 |
-
}
|
357 |
-
|
358 |
-
public static function writeExcludedFile($file, $fsize = 0){
|
359 |
-
|
360 |
-
self::debug("Excluded $file from list as it is bigger than ". self::$EXCLUDE_FILES_SIZE." MB!!!");
|
361 |
-
|
362 |
-
if(self::$fpe){
|
363 |
-
fwrite(self::$fpe, $file."\t(".$fsize." bytes)\n");
|
364 |
-
}
|
365 |
-
|
366 |
-
}
|
367 |
-
|
368 |
-
/*
|
369 |
-
* Writing file details(path, permissions, size) to file
|
370 |
-
*
|
371 |
-
* name: writePermFile
|
372 |
-
* @param file handler $fp file handler of where to write
|
373 |
-
* @param string $file File to write
|
374 |
-
* @return
|
375 |
-
*/
|
376 |
-
public static function writePermFile($file, $append = "", $force = 0){
|
377 |
-
|
378 |
-
$file = realpath($file);
|
379 |
-
|
380 |
-
if((self::isNotExcluded($file)) or ($force)){
|
381 |
-
// we check if file is not excluded
|
382 |
-
$fperm = substr(sprintf('%o', @fileperms($file)), -4);
|
383 |
-
$fsize = self::getFileSize($file);
|
384 |
-
$sizeLimit = (self::$EXCLUDE_FILES_SIZE)*1024*1024; // we limit by MB
|
385 |
-
|
386 |
-
if(intval(self::$EXCLUDE_FILES_SIZE) > -1){
|
387 |
-
if(($fsize > $sizeLimit) and is_file($file)){
|
388 |
-
//we check if file is larger than $EXCLUDE_FILES_SIZE
|
389 |
-
self::writeExcludedFile($file, $fsize);
|
390 |
-
return;
|
391 |
-
}
|
392 |
-
}
|
393 |
-
|
394 |
-
$file = str_replace(self::$START_DIR, "", str_replace("\\","/", $file));
|
395 |
-
|
396 |
-
fwrite(self::$fp, $file."|".$fperm."|".$fsize."|".$append."\n");
|
397 |
-
self::debug($file ." added to list");
|
398 |
-
}
|
399 |
-
else{
|
400 |
-
self::debug("$file excluded");
|
401 |
-
}
|
402 |
-
return;
|
403 |
-
}
|
404 |
-
|
405 |
-
/*
|
406 |
-
* Handle an array of files
|
407 |
-
*
|
408 |
-
* name: writePermFiles
|
409 |
-
* @param file handler $fp File handler of where to write
|
410 |
-
* @param array $files The array of files
|
411 |
-
* @return
|
412 |
-
*/
|
413 |
-
public static function writePermFiles($files, $append = "", $force = 0){
|
414 |
-
|
415 |
-
if(is_array($files)){
|
416 |
-
foreach($files as $file){
|
417 |
-
self::writePermFile($file, $append, $force);
|
418 |
-
}
|
419 |
-
}else{
|
420 |
-
self::writePermFile($files, $append, $force);
|
421 |
-
}
|
422 |
-
return;
|
423 |
-
}
|
424 |
-
|
425 |
-
/*
|
426 |
-
* Recurse the directory $dir and get all files in it
|
427 |
-
*
|
428 |
-
* name: getDirectories
|
429 |
-
* @param string $dir Directory to scan
|
430 |
-
* @param array &f_arr File list array
|
431 |
-
* @param array &fd_arr Directory list array
|
432 |
-
* @return
|
433 |
-
*/
|
434 |
-
public static function getDirectories($dir){
|
435 |
-
global $_CONFIG;
|
436 |
-
|
437 |
-
self::debug("Processing $dir");
|
438 |
-
|
439 |
-
if(!stristr(realpath($dir), realpath($_CONFIG['backup_path']))){
|
440 |
-
|
441 |
-
return false;
|
442 |
-
}
|
443 |
-
|
444 |
-
if(is_dir($dir)) {
|
445 |
-
self::debug("OK directory $dir");
|
446 |
-
if($dh = opendir($dir)) {
|
447 |
-
|
448 |
-
self::debug("Opened directory $dir");
|
449 |
-
|
450 |
-
while(($file = readdir($dh)) !== false) {
|
451 |
-
if($file != "." && $file != "..") {
|
452 |
-
|
453 |
-
$cfile = $dir."/".$file;
|
454 |
-
|
455 |
-
if(@is_dir($cfile))
|
456 |
-
self::$d_arr[] = $cfile;
|
457 |
-
else{
|
458 |
-
|
459 |
-
self::writePermFile($cfile, "F");
|
460 |
-
self::$count++;
|
461 |
-
}
|
462 |
-
}
|
463 |
-
}
|
464 |
-
@closedir($dh);
|
465 |
-
}else{
|
466 |
-
self::debug("Unable to open $dir");
|
467 |
-
}
|
468 |
-
}else{
|
469 |
-
self::debug($dir." is not directory");
|
470 |
-
}
|
471 |
-
|
472 |
-
|
473 |
-
return;
|
474 |
-
|
475 |
-
}
|
476 |
-
|
477 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/index.html
DELETED
File without changes
|
classes/main.class.php
DELETED
@@ -1,116 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* main.class.php
|
4 |
-
*
|
5 |
-
* Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
class Main{
|
24 |
-
|
25 |
-
public static $_CONFIG;
|
26 |
-
|
27 |
-
|
28 |
-
/*
|
29 |
-
*
|
30 |
-
* name: init
|
31 |
-
* @param
|
32 |
-
* @return
|
33 |
-
*/
|
34 |
-
public static function init($_CONFIG){
|
35 |
-
self::$_CONFIG = $_CONFIG;
|
36 |
-
}
|
37 |
-
|
38 |
-
/*
|
39 |
-
*
|
40 |
-
* name: unknown
|
41 |
-
* @param
|
42 |
-
* @return
|
43 |
-
*/
|
44 |
-
public static function initBackup($backupName){
|
45 |
-
|
46 |
-
self::generateBackupName($backupName);
|
47 |
-
|
48 |
-
}
|
49 |
-
|
50 |
-
/*
|
51 |
-
* Will cleanup the temporary directory
|
52 |
-
*
|
53 |
-
* name: cleanUp
|
54 |
-
* @param
|
55 |
-
* @return
|
56 |
-
*/
|
57 |
-
public static function cleanUp(){
|
58 |
-
|
59 |
-
$dir = self::$_CONFIG['temp_dir'] ;
|
60 |
-
|
61 |
-
if (@is_dir($dir)) {
|
62 |
-
if ($dh = @opendir($dir)) {
|
63 |
-
while (($file = @readdir($dh)) !== false) {
|
64 |
-
if(($file!=".") and ($file!="..")){
|
65 |
-
if(($file[0] == ".") and ($file[0] != ".htaccess"))
|
66 |
-
//cleanup temp files
|
67 |
-
@unlink($dir."/".$file);
|
68 |
-
elseif(strstr( $file, "-sql.sql") != "")
|
69 |
-
//cleanup sql files
|
70 |
-
@unlink($dir."/".$file);
|
71 |
-
|
72 |
-
}
|
73 |
-
}
|
74 |
-
closedir($dh);
|
75 |
-
}
|
76 |
-
}
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
-
public static function generateBackupName($backupName, $backupDatabase = 0, $dbbackup_drop = 0){
|
81 |
-
|
82 |
-
$domainname = $_SERVER['HTTP_HOST'];
|
83 |
-
|
84 |
-
if ((self::$_CONFIG['mem']) && ($_CONFIG['backup_refresh'])) {
|
85 |
-
$f_ext = '.tar';
|
86 |
-
$_CONFIG['tarcompress'] = '';
|
87 |
-
} elseif (self::$_CONFIG['backup_compress']) {
|
88 |
-
$f_ext = '.tgz';
|
89 |
-
$_CONFIG['tarcompress'] = 'z';
|
90 |
-
} else {
|
91 |
-
$f_ext = '.tar';
|
92 |
-
$_CONFIG['tarcompress'] = '';
|
93 |
-
}
|
94 |
-
|
95 |
-
|
96 |
-
if ($backupName == "") {
|
97 |
-
if ($backupDatabase == 1) {
|
98 |
-
if ($_REQUEST['dbbackup_drop']) {
|
99 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-drop' . $f_ext;
|
100 |
-
} else {
|
101 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-nodrop' . $f_ext;
|
102 |
-
}
|
103 |
-
} else
|
104 |
-
$filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-nosql' . $f_ext;
|
105 |
-
} else {
|
106 |
-
$filename = $_REQUEST['bname'] . $f_ext;
|
107 |
-
}
|
108 |
-
|
109 |
-
return $filename;
|
110 |
-
|
111 |
-
}
|
112 |
-
|
113 |
-
}
|
114 |
-
|
115 |
-
|
116 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/mysqlBackup.class.php
DELETED
@@ -1,480 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* mysqlBackup.class.php
|
4 |
-
*
|
5 |
-
* Copyright 2014 Ovidiu Liuta <info@thinkovi.com>
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
20 |
-
* MA 02110-1301, USA.
|
21 |
-
*/
|
22 |
-
|
23 |
-
|
24 |
-
class DB{
|
25 |
-
|
26 |
-
public static $dbHostname = "localhost";
|
27 |
-
public static $dbUsername = "root";
|
28 |
-
public static $dbPassword = "";
|
29 |
-
public static $dbDatabase = "";
|
30 |
-
public static $excludedTables = array();
|
31 |
-
|
32 |
-
public static $debug = 0;
|
33 |
-
public static $recordsPerSession = 10000;
|
34 |
-
public static $dbCompatibility = "";
|
35 |
-
public static $dbDropSyntax = 0;
|
36 |
-
public static $countRecords = 0;
|
37 |
-
|
38 |
-
private static $link;
|
39 |
-
private static $db_selected;
|
40 |
-
|
41 |
-
public static $TEMP_DBPROCESS_FILE = "tmp/.database";
|
42 |
-
public static $TEMP_DUMP_FILE = "tmp/database-sql.sql";
|
43 |
-
|
44 |
-
/*
|
45 |
-
*Return any error
|
46 |
-
*
|
47 |
-
* name: error
|
48 |
-
* @param string $message
|
49 |
-
* @return
|
50 |
-
*/
|
51 |
-
public function error($message, $force = ""){
|
52 |
-
|
53 |
-
$return = "";
|
54 |
-
$date = date("M j, Y @ H:i:s");
|
55 |
-
|
56 |
-
if((self::$debug) && ($force)){
|
57 |
-
//we have debug message as force is 1
|
58 |
-
printf("Debug(%s) - %s \n", $date, $message);
|
59 |
-
}
|
60 |
-
|
61 |
-
if(!$force){
|
62 |
-
//we have an error message
|
63 |
-
printf("Error(%s) - %s \n", $date, $message);
|
64 |
-
}
|
65 |
-
|
66 |
-
return;
|
67 |
-
|
68 |
-
}
|
69 |
-
|
70 |
-
/*
|
71 |
-
* Initialize the database connection
|
72 |
-
*
|
73 |
-
* name: init
|
74 |
-
* @param array $data {'dbHostname', 'dbUsername', 'dbPassword', 'dbDatabase'}
|
75 |
-
* @return
|
76 |
-
*/
|
77 |
-
public function init($data, $start = 0){
|
78 |
-
|
79 |
-
self::$dbHostname = $data['dbHostname'];
|
80 |
-
self::$dbUsername = $data['dbUsername'];
|
81 |
-
self::$dbPassword = $data['dbPassword'];
|
82 |
-
self::$dbDatabase = $data['dbDatabase'];
|
83 |
-
self::$excludedTables = $data['excludedTables'];
|
84 |
-
self::$TEMP_DBPROCESS_FILE = $data['TEMP_DBPROCESS_FILE'];
|
85 |
-
self::$TEMP_DUMP_FILE = $data['TEMP_DUMP_FILE'];
|
86 |
-
self::$recordsPerSession = $data['recordsPerSession'];
|
87 |
-
self::$dbCompatibility = $data['dbCompatibility'];
|
88 |
-
self::$dbDropSyntax = $data['dbDropSyntax'];
|
89 |
-
|
90 |
-
self::connect();
|
91 |
-
self::headers();
|
92 |
-
|
93 |
-
if($start){
|
94 |
-
@unlink(self::$TEMP_DBPROCESS_FILE);
|
95 |
-
}
|
96 |
-
|
97 |
-
}
|
98 |
-
|
99 |
-
/*
|
100 |
-
* Connect to the database
|
101 |
-
*
|
102 |
-
* name: connect
|
103 |
-
* @param
|
104 |
-
* @return
|
105 |
-
*/
|
106 |
-
public function connect(){
|
107 |
-
|
108 |
-
self::$link = new mysqli(self::$dbHostname, self::$dbUsername, self::$dbPassword, self::$dbDatabase);
|
109 |
-
if (mysqli_connect_errno()) {
|
110 |
-
printf("Connect failed: %s\n", mysqli_connect_error());
|
111 |
-
exit();
|
112 |
-
}
|
113 |
-
|
114 |
-
}
|
115 |
-
|
116 |
-
/*
|
117 |
-
* Disconnect from the database
|
118 |
-
*
|
119 |
-
* name: disconnect
|
120 |
-
* @param
|
121 |
-
* @return
|
122 |
-
*/
|
123 |
-
public function disconnect(){
|
124 |
-
|
125 |
-
//mysqli_close(self::$link);
|
126 |
-
|
127 |
-
}
|
128 |
-
|
129 |
-
/*
|
130 |
-
* Send some special headers after the connection is initialized
|
131 |
-
*
|
132 |
-
* name: headers
|
133 |
-
* @param
|
134 |
-
* @return
|
135 |
-
*/
|
136 |
-
private function headers(){
|
137 |
-
|
138 |
-
self::query("SET SQL_QUOTE_SHOW_CREATE=1;");
|
139 |
-
self::query("SET sql_mode = 0;");
|
140 |
-
mysqli_set_charset(self::$link, 'utf8');
|
141 |
-
if (self::$dbCompatibility)
|
142 |
-
self::query("SET sql_mode=" . self::$dbCompatibility . ";");
|
143 |
-
|
144 |
-
}
|
145 |
-
|
146 |
-
/*
|
147 |
-
* Run a mysql qeury
|
148 |
-
*
|
149 |
-
* name: query
|
150 |
-
* @param string $query Query to run
|
151 |
-
* @return $result or false
|
152 |
-
*/
|
153 |
-
public function query($query){
|
154 |
-
|
155 |
-
$result = mysqli_query(self::$link, $query.";");
|
156 |
-
self::error($query, 1);
|
157 |
-
|
158 |
-
if (!$result) {
|
159 |
-
self::error('Invalid query: ' . mysqli_error(self::$link));
|
160 |
-
return false;
|
161 |
-
}
|
162 |
-
else{
|
163 |
-
return $result;
|
164 |
-
}
|
165 |
-
|
166 |
-
}
|
167 |
-
|
168 |
-
|
169 |
-
/*
|
170 |
-
* Returns an array of tables from a database and mark $2excluded ones
|
171 |
-
*
|
172 |
-
* name: lisTables
|
173 |
-
* @param array $excluded array of tables to mark as excluded
|
174 |
-
* @return array $tablesList
|
175 |
-
*/
|
176 |
-
public function listTables($excluded){
|
177 |
-
|
178 |
-
$tablesList = array("");
|
179 |
-
$inc = 0;
|
180 |
-
|
181 |
-
$result = self::query("SHOW TABLES in `".self::$dbDatabase."`");
|
182 |
-
|
183 |
-
while ($row = mysqli_fetch_array( $result)){
|
184 |
-
$tablesList[$inc]['table'] = $row[0];
|
185 |
-
|
186 |
-
if(is_array($excluded))
|
187 |
-
if( in_array($row[0], $excluded) )
|
188 |
-
$tablesList[$inc]['excluded'] = 1;
|
189 |
-
$inc++;
|
190 |
-
}
|
191 |
-
|
192 |
-
return $tablesList;
|
193 |
-
|
194 |
-
}
|
195 |
-
|
196 |
-
public function writeTempFile(){
|
197 |
-
|
198 |
-
$tables = self::listTables(self::$excludedTables);
|
199 |
-
|
200 |
-
$fp = fopen(self::$TEMP_DBPROCESS_FILE, "a");
|
201 |
-
|
202 |
-
if($fp){
|
203 |
-
|
204 |
-
fwrite($fp, sprintf("###newdump###\t%s\t%s\n", self::$dbDatabase, self::$TEMP_DUMP_FILE));
|
205 |
-
|
206 |
-
// write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
|
207 |
-
foreach($tables as $key=>$table) if($table!= ""){
|
208 |
-
|
209 |
-
$tables[$key]['records'] = 0;
|
210 |
-
|
211 |
-
if(!$tables[$key]['excluded'])
|
212 |
-
$tables[$key]['records'] = self::countRecords($tables[$key]['table']);
|
213 |
-
|
214 |
-
$tmp = sprintf("`%s`.`%s`\t%s\t%s\n", self::$dbDatabase, $tables[$key]['table'], $tables[$key]['records'], $tables[$key]['excluded']);
|
215 |
-
fwrite($fp, $tmp);
|
216 |
-
}
|
217 |
-
|
218 |
-
fwrite($fp, "###enddump###\n");
|
219 |
-
fclose($fp);
|
220 |
-
}
|
221 |
-
else{
|
222 |
-
self::error("Unable to open for writing file ".self::$TEMP_DBPROCESS_FILE);
|
223 |
-
}
|
224 |
-
|
225 |
-
}
|
226 |
-
|
227 |
-
/*
|
228 |
-
* Returns the number of records from a table
|
229 |
-
*
|
230 |
-
* name: countRecords
|
231 |
-
* @param string $table - the source table
|
232 |
-
* @return int $count
|
233 |
-
*/
|
234 |
-
public function countRecords($table){
|
235 |
-
|
236 |
-
$table = "`".self::$dbDatabase."`.`$table`";
|
237 |
-
|
238 |
-
$result = self::query("SELECT count(*) FROM $table;");
|
239 |
-
|
240 |
-
$count = mysqli_fetch_row($result);
|
241 |
-
|
242 |
-
return intval($count[0]) ;// not max limit on 32 bit systems 2147483647; on 64 bit 9223372036854775807
|
243 |
-
|
244 |
-
}
|
245 |
-
|
246 |
-
/*
|
247 |
-
* Processing the mysql backup incrementally
|
248 |
-
*
|
249 |
-
* name: processIncremental
|
250 |
-
* @param
|
251 |
-
* int $startAtLine - at which line from the perm.txt file to start reading
|
252 |
-
* int startAtRecord - at which record to start from the table found at $startAtLine
|
253 |
-
* string $dumpfie - where to save the data
|
254 |
-
* string $dbCompatibility - MYSQL40, MYSQ32, none=default
|
255 |
-
* int $dbDropSyntax - check if the DROP TABLE syntax should be added
|
256 |
-
* @return array $return
|
257 |
-
*/
|
258 |
-
public function processIncremental($startAtLine= 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility= "", $dbDropSyntax= ""){
|
259 |
-
|
260 |
-
$count = 0;
|
261 |
-
$return = array();
|
262 |
-
|
263 |
-
self::error("Starting new process at line $startAtLine from record $startAtRecord", 1);
|
264 |
-
|
265 |
-
$fp = fopen(self::$TEMP_DBPROCESS_FILE, "r");
|
266 |
-
if($fp){
|
267 |
-
|
268 |
-
while (($buffer = fgets($fp, 4096)) !== false){
|
269 |
-
|
270 |
-
if($count == $startAtLine){
|
271 |
-
|
272 |
-
$buffer = str_replace("\n", "", $buffer);
|
273 |
-
$tableInfo =explode("\t", $buffer);
|
274 |
-
//print_r($tableInfo);
|
275 |
-
if($tableInfo[0] == "###newdump###"){
|
276 |
-
// we create a new mysql dump file
|
277 |
-
if($dumpfile != ""){
|
278 |
-
// we finished a previous one and write the footers
|
279 |
-
$return['dumpsize'] = self::dataFooters($dumpfile);
|
280 |
-
}
|
281 |
-
|
282 |
-
$dump = fopen($tableInfo[2], "w");
|
283 |
-
fwrite($dump, self::dataHeaders($tableInfo[1]));
|
284 |
-
$startAtLine++;
|
285 |
-
fclose($dump);
|
286 |
-
$dumpfile = $tableInfo[2];
|
287 |
-
|
288 |
-
$return['newDump'] = 1;
|
289 |
-
//break;
|
290 |
-
}
|
291 |
-
else{
|
292 |
-
//we export the table
|
293 |
-
if($tableInfo[0] == "###enddump###")
|
294 |
-
$return['endDump'] = 1;
|
295 |
-
|
296 |
-
$fd = fopen($dumpfile, "a");
|
297 |
-
|
298 |
-
if($fd){
|
299 |
-
|
300 |
-
$next = $startAtRecord + self::$recordsPerSession;
|
301 |
-
// $tableInfo[1] number of records in the table
|
302 |
-
$table = explode("`.`", $tableInfo[0]);
|
303 |
-
$tableName = str_replace("`", "", $table[1]);
|
304 |
-
$databaseName = str_replace("`", "", $table[0]);
|
305 |
-
|
306 |
-
//return something to the browser
|
307 |
-
$return['tableName'] = $tableName;
|
308 |
-
$return['databaseName'] = $databaseName;
|
309 |
-
$return['totalRecords'] = $tableInfo[1];
|
310 |
-
|
311 |
-
//if(intval($return['totalRecords']) != 0)
|
312 |
-
if(trim($tableName) !="" and !$tableInfo[2])
|
313 |
-
self::exportTable($databaseName, $tableName, $startAtRecord, self::$recordsPerSession, $fd);
|
314 |
-
|
315 |
-
fclose($fd);
|
316 |
-
|
317 |
-
if($next > $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
|
318 |
-
{
|
319 |
-
$startAtLine ++;
|
320 |
-
$startAtRecord = 0;
|
321 |
-
}else{
|
322 |
-
$startAtRecord = $startAtRecord + self::$recordsPerSession;
|
323 |
-
}
|
324 |
-
|
325 |
-
//$return['dbCompatibility'] = self::$dbCompatibility;
|
326 |
-
//$return['dbDropSyntax'] = self::$dbDropSyntax;
|
327 |
-
$return['startAtLine'] = $startAtLine;
|
328 |
-
$return['startAtRecord'] = $startAtRecord;
|
329 |
-
$return['dumpfile'] = $dumpfile;
|
330 |
-
|
331 |
-
return $return;
|
332 |
-
break;
|
333 |
-
|
334 |
-
}else{
|
335 |
-
self::error("Unable to open for writing file $dumpfile");
|
336 |
-
}
|
337 |
-
}
|
338 |
-
|
339 |
-
}
|
340 |
-
|
341 |
-
$count++;
|
342 |
-
|
343 |
-
|
344 |
-
}
|
345 |
-
|
346 |
-
//while is finished, lets go home...
|
347 |
-
if($dumpfile != ""){
|
348 |
-
// we finished a previous one and write the footers
|
349 |
-
$return['dumpsize'] = self::dataFooters($dumpfile);
|
350 |
-
}
|
351 |
-
$return['finished'] = 1;
|
352 |
-
$return['startAtLine'] = $startAtLine;
|
353 |
-
|
354 |
-
return $return;
|
355 |
-
|
356 |
-
}else{
|
357 |
-
self::error("Unable to open for reading file ".self::$TEMP_DBPROCESS_FILE);
|
358 |
-
}
|
359 |
-
|
360 |
-
|
361 |
-
}
|
362 |
-
|
363 |
-
|
364 |
-
/*
|
365 |
-
* Exporting the table records
|
366 |
-
*
|
367 |
-
* name: exportTable
|
368 |
-
* @param
|
369 |
-
* string $databaseName - database name of the table
|
370 |
-
* string tableName - table name
|
371 |
-
* int $start - where to start from
|
372 |
-
* int $limit - how many records
|
373 |
-
* handler $fd - file handler where to write the records
|
374 |
-
* @return
|
375 |
-
*/
|
376 |
-
public function exportTable($databaseName, $tableName, $start, $limit, $fd){
|
377 |
-
|
378 |
-
if($start == 0)
|
379 |
-
self::dumpStructure($databaseName, $tableName, $fd);
|
380 |
-
|
381 |
-
$start = intval($start);
|
382 |
-
$limit = intval($limit);
|
383 |
-
//exporting the table content now
|
384 |
-
|
385 |
-
$result = self::query("SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;");
|
386 |
-
if($result){
|
387 |
-
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
|
388 |
-
|
389 |
-
fwrite($fd, "INSERT INTO `$tableName` VALUES (");
|
390 |
-
$arr = $row;
|
391 |
-
$buffer = "";
|
392 |
-
self::$countRecords++;
|
393 |
-
|
394 |
-
foreach ($arr as $key => $value) {
|
395 |
-
$value = mysqli_real_escape_string(self::$link, $value);
|
396 |
-
$buffer .= "'".$value."', ";
|
397 |
-
}
|
398 |
-
$buffer = rtrim($buffer, ', ') . ");\n";
|
399 |
-
fwrite($fd, $buffer);
|
400 |
-
unset($buffer);
|
401 |
-
|
402 |
-
}
|
403 |
-
}
|
404 |
-
|
405 |
-
}
|
406 |
-
|
407 |
-
public function dumpStructure($databaseName, $tableName ,$fd){
|
408 |
-
|
409 |
-
fwrite($fd, "\n#\n# Table structure for table `$tableName`\n#\n\n");
|
410 |
-
|
411 |
-
if (self::$dbDropSyntax)
|
412 |
-
fwrite($fd, "\nDROP table IF EXISTS `$tableName`;\n");
|
413 |
-
|
414 |
-
$result = self::query("SHOW CREATE table `$databaseName`.`$tableName`;");
|
415 |
-
if($result){
|
416 |
-
$row = mysqli_fetch_row( $result);
|
417 |
-
fwrite($fd, $row[1].";\n");
|
418 |
-
}
|
419 |
-
|
420 |
-
fwrite($fd, "\n#\n# End Structure for table `$tableName`\n#\n\n");
|
421 |
-
fwrite($fd, "#\n# Dumping data for table `$tableName`\n#\n\n");
|
422 |
-
return;
|
423 |
-
|
424 |
-
}
|
425 |
-
|
426 |
-
public function dataFooters($dumpfile){
|
427 |
-
|
428 |
-
// we finished the dump file, not return the size of it
|
429 |
-
$ftemp = fopen($dumpfile, "a");
|
430 |
-
if($ftemp){
|
431 |
-
fwrite($ftemp, "\n#\n# Finished at: ".date("M j, Y \a\\t H:i")."\n#");
|
432 |
-
fclose($ftemp);
|
433 |
-
}else{
|
434 |
-
self::error("Unable to open file $ftemp for writing");
|
435 |
-
}
|
436 |
-
|
437 |
-
return sprintf("%u", filesize($dumpfile));
|
438 |
-
|
439 |
-
}
|
440 |
-
|
441 |
-
public function resetcountRecords(){
|
442 |
-
self::$countRecords = 0;
|
443 |
-
|
444 |
-
return self::$countRecords;
|
445 |
-
}
|
446 |
-
|
447 |
-
public function getcountRecords(){
|
448 |
-
return self::$countRecords;
|
449 |
-
}
|
450 |
-
|
451 |
-
|
452 |
-
public function dataHeaders($database){
|
453 |
-
|
454 |
-
$return = "";
|
455 |
-
|
456 |
-
$return .= "#\n";
|
457 |
-
$return .= "# Powered by XCloner Site Backup\n";
|
458 |
-
$return .= "# http://www.xcloner.com\n";
|
459 |
-
$return .= "#\n";
|
460 |
-
$return .= "# Host: " . $_SERVER['HTTP_HOST'] . "\n";
|
461 |
-
$return .= "# Generation Time: " . date("M j, Y \a\\t H:i") . "\n";
|
462 |
-
$return .= "# PHP Version: " . phpversion() . "\n";
|
463 |
-
$return .= "# Mysql Compatibility: ". self::$dbCompatibility . "\n";
|
464 |
-
|
465 |
-
$result = self::query("SHOW VARIABLES LIKE \"%version%\";");
|
466 |
-
if($result){
|
467 |
-
while($row = mysqli_fetch_array($result)){
|
468 |
-
|
469 |
-
$return .= "# MYSQL ".$row[0].": ".$row[1]."\n";
|
470 |
-
|
471 |
-
}
|
472 |
-
}
|
473 |
-
|
474 |
-
$return .= "#\n# Database : `" . $database . "`\n# --------------------------------------------------------\n\n";
|
475 |
-
return $return;
|
476 |
-
|
477 |
-
}
|
478 |
-
|
479 |
-
|
480 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/AES.php
DELETED
@@ -1,594 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of AES.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
12 |
-
* {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
13 |
-
* it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
|
14 |
-
* is called, again, at which point, it'll be recalculated.
|
15 |
-
*
|
16 |
-
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
|
17 |
-
* make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
18 |
-
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
19 |
-
*
|
20 |
-
* Here's a short example of how to use this library:
|
21 |
-
* <code>
|
22 |
-
* <?php
|
23 |
-
* include('Crypt/AES.php');
|
24 |
-
*
|
25 |
-
* $aes = new Crypt_AES();
|
26 |
-
*
|
27 |
-
* $aes->setKey('abcdefghijklmnop');
|
28 |
-
*
|
29 |
-
* $size = 10 * 1024;
|
30 |
-
* $plaintext = '';
|
31 |
-
* for ($i = 0; $i < $size; $i++) {
|
32 |
-
* $plaintext.= 'a';
|
33 |
-
* }
|
34 |
-
*
|
35 |
-
* echo $aes->decrypt($aes->encrypt($plaintext));
|
36 |
-
* ?>
|
37 |
-
* </code>
|
38 |
-
*
|
39 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
40 |
-
* of this software and associated documentation files (the "Software"), to deal
|
41 |
-
* in the Software without restriction, including without limitation the rights
|
42 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
43 |
-
* copies of the Software, and to permit persons to whom the Software is
|
44 |
-
* furnished to do so, subject to the following conditions:
|
45 |
-
*
|
46 |
-
* The above copyright notice and this permission notice shall be included in
|
47 |
-
* all copies or substantial portions of the Software.
|
48 |
-
*
|
49 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
50 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
51 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
52 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
53 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
54 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
55 |
-
* THE SOFTWARE.
|
56 |
-
*
|
57 |
-
* @category Crypt
|
58 |
-
* @package Crypt_AES
|
59 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
60 |
-
* @copyright MMVIII Jim Wigginton
|
61 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
62 |
-
* @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
|
63 |
-
* @link http://phpseclib.sourceforge.net
|
64 |
-
*/
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Include Crypt_Rijndael
|
68 |
-
*/
|
69 |
-
require_once 'Rijndael.php';
|
70 |
-
|
71 |
-
/**#@+
|
72 |
-
* @access public
|
73 |
-
* @see Crypt_AES::encrypt()
|
74 |
-
* @see Crypt_AES::decrypt()
|
75 |
-
*/
|
76 |
-
/**
|
77 |
-
* Encrypt / decrypt using the Counter mode.
|
78 |
-
*
|
79 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
80 |
-
*
|
81 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
82 |
-
*/
|
83 |
-
define('CRYPT_AES_MODE_CTR', -1);
|
84 |
-
/**
|
85 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
86 |
-
*
|
87 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
88 |
-
*/
|
89 |
-
define('CRYPT_AES_MODE_ECB', 1);
|
90 |
-
/**
|
91 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
92 |
-
*
|
93 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
94 |
-
*/
|
95 |
-
define('CRYPT_AES_MODE_CBC', 2);
|
96 |
-
/**
|
97 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
98 |
-
*
|
99 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
100 |
-
*/
|
101 |
-
define('CRYPT_AES_MODE_CFB', 3);
|
102 |
-
/**
|
103 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
104 |
-
*
|
105 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
106 |
-
*/
|
107 |
-
define('CRYPT_AES_MODE_OFB', 4);
|
108 |
-
/**#@-*/
|
109 |
-
|
110 |
-
/**#@+
|
111 |
-
* @access private
|
112 |
-
* @see Crypt_AES::Crypt_AES()
|
113 |
-
*/
|
114 |
-
/**
|
115 |
-
* Toggles the internal implementation
|
116 |
-
*/
|
117 |
-
define('CRYPT_AES_MODE_INTERNAL', 1);
|
118 |
-
/**
|
119 |
-
* Toggles the mcrypt implementation
|
120 |
-
*/
|
121 |
-
define('CRYPT_AES_MODE_MCRYPT', 2);
|
122 |
-
/**#@-*/
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Pure-PHP implementation of AES.
|
126 |
-
*
|
127 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
128 |
-
* @version 0.1.0
|
129 |
-
* @access public
|
130 |
-
* @package Crypt_AES
|
131 |
-
*/
|
132 |
-
class Crypt_AES extends Crypt_Rijndael {
|
133 |
-
/**
|
134 |
-
* mcrypt resource for encryption
|
135 |
-
*
|
136 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
137 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
138 |
-
*
|
139 |
-
* @see Crypt_AES::encrypt()
|
140 |
-
* @var String
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $enmcrypt;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* mcrypt resource for decryption
|
147 |
-
*
|
148 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
149 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
150 |
-
*
|
151 |
-
* @see Crypt_AES::decrypt()
|
152 |
-
* @var String
|
153 |
-
* @access private
|
154 |
-
*/
|
155 |
-
var $demcrypt;
|
156 |
-
|
157 |
-
/**
|
158 |
-
* mcrypt resource for CFB mode
|
159 |
-
*
|
160 |
-
* @see Crypt_AES::encrypt()
|
161 |
-
* @see Crypt_AES::decrypt()
|
162 |
-
* @var String
|
163 |
-
* @access private
|
164 |
-
*/
|
165 |
-
var $ecb;
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Default Constructor.
|
169 |
-
*
|
170 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
171 |
-
* CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
|
172 |
-
*
|
173 |
-
* @param optional Integer $mode
|
174 |
-
* @return Crypt_AES
|
175 |
-
* @access public
|
176 |
-
*/
|
177 |
-
function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
|
178 |
-
{
|
179 |
-
if ( !defined('CRYPT_AES_MODE') ) {
|
180 |
-
switch (true) {
|
181 |
-
case extension_loaded('mcrypt'):
|
182 |
-
// i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
183 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
184 |
-
// a lot of point...
|
185 |
-
define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
|
186 |
-
break;
|
187 |
-
default:
|
188 |
-
define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
|
189 |
-
}
|
190 |
-
}
|
191 |
-
|
192 |
-
switch ( CRYPT_AES_MODE ) {
|
193 |
-
case CRYPT_AES_MODE_MCRYPT:
|
194 |
-
switch ($mode) {
|
195 |
-
case CRYPT_AES_MODE_ECB:
|
196 |
-
$this->paddable = true;
|
197 |
-
$this->mode = MCRYPT_MODE_ECB;
|
198 |
-
break;
|
199 |
-
case CRYPT_AES_MODE_CTR:
|
200 |
-
// ctr doesn't have a constant associated with it even though it appears to be fairly widely
|
201 |
-
// supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
|
202 |
-
// include a compatibility layer. the layer has been implemented but, for now, is commented out.
|
203 |
-
$this->mode = 'ctr';
|
204 |
-
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
|
205 |
-
break;
|
206 |
-
case CRYPT_AES_MODE_CFB:
|
207 |
-
$this->mode = 'ncfb';
|
208 |
-
break;
|
209 |
-
case CRYPT_AES_MODE_OFB:
|
210 |
-
$this->mode = MCRYPT_MODE_NOFB;
|
211 |
-
break;
|
212 |
-
case CRYPT_AES_MODE_CBC:
|
213 |
-
default:
|
214 |
-
$this->paddable = true;
|
215 |
-
$this->mode = MCRYPT_MODE_CBC;
|
216 |
-
}
|
217 |
-
|
218 |
-
$this->debuffer = $this->enbuffer = '';
|
219 |
-
|
220 |
-
break;
|
221 |
-
default:
|
222 |
-
switch ($mode) {
|
223 |
-
case CRYPT_AES_MODE_ECB:
|
224 |
-
$this->paddable = true;
|
225 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
|
226 |
-
break;
|
227 |
-
case CRYPT_AES_MODE_CTR:
|
228 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CTR;
|
229 |
-
break;
|
230 |
-
case CRYPT_AES_MODE_CFB:
|
231 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CFB;
|
232 |
-
break;
|
233 |
-
case CRYPT_AES_MODE_OFB:
|
234 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_OFB;
|
235 |
-
break;
|
236 |
-
case CRYPT_AES_MODE_CBC:
|
237 |
-
default:
|
238 |
-
$this->paddable = true;
|
239 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
|
244 |
-
parent::Crypt_Rijndael($this->mode);
|
245 |
-
}
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Dummy function
|
250 |
-
*
|
251 |
-
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
|
252 |
-
*
|
253 |
-
* @access public
|
254 |
-
* @param Integer $length
|
255 |
-
*/
|
256 |
-
function setBlockLength($length)
|
257 |
-
{
|
258 |
-
return;
|
259 |
-
}
|
260 |
-
|
261 |
-
/**
|
262 |
-
* Encrypts a message.
|
263 |
-
*
|
264 |
-
* $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
|
265 |
-
* same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
|
266 |
-
* URL:
|
267 |
-
*
|
268 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
269 |
-
*
|
270 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
271 |
-
* strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
|
272 |
-
* length.
|
273 |
-
*
|
274 |
-
* @see Crypt_AES::decrypt()
|
275 |
-
* @access public
|
276 |
-
* @param String $plaintext
|
277 |
-
*/
|
278 |
-
function encrypt($plaintext)
|
279 |
-
{
|
280 |
-
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
281 |
-
$changed = $this->changed;
|
282 |
-
$this->_mcryptSetup();
|
283 |
-
/*
|
284 |
-
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
285 |
-
$iv = $this->encryptIV;
|
286 |
-
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
|
287 |
-
$ciphertext = $plaintext ^ $xor;
|
288 |
-
if ($this->continuousBuffer) {
|
289 |
-
$this->encryptIV = $iv;
|
290 |
-
}
|
291 |
-
return $ciphertext;
|
292 |
-
}
|
293 |
-
*/
|
294 |
-
// re: http://phpseclib.sourceforge.net/cfb-demo.phps
|
295 |
-
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
|
296 |
-
// rewritten CFB implementation the above outputs the same thing twice.
|
297 |
-
if ($this->mode == 'ncfb') {
|
298 |
-
if ($changed) {
|
299 |
-
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
300 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
301 |
-
}
|
302 |
-
|
303 |
-
if (strlen($this->enbuffer)) {
|
304 |
-
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
|
305 |
-
$this->enbuffer.= $ciphertext;
|
306 |
-
if (strlen($this->enbuffer) == 16) {
|
307 |
-
$this->encryptIV = $this->enbuffer;
|
308 |
-
$this->enbuffer = '';
|
309 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
310 |
-
}
|
311 |
-
$plaintext = substr($plaintext, strlen($ciphertext));
|
312 |
-
} else {
|
313 |
-
$ciphertext = '';
|
314 |
-
}
|
315 |
-
|
316 |
-
$last_pos = strlen($plaintext) & 0xFFFFFFF0;
|
317 |
-
$ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
|
318 |
-
|
319 |
-
if (strlen($plaintext) & 0xF) {
|
320 |
-
if (strlen($ciphertext)) {
|
321 |
-
$this->encryptIV = substr($ciphertext, -16);
|
322 |
-
}
|
323 |
-
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
324 |
-
$this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
325 |
-
$ciphertext.= $this->enbuffer;
|
326 |
-
}
|
327 |
-
|
328 |
-
return $ciphertext;
|
329 |
-
}
|
330 |
-
|
331 |
-
if ($this->paddable) {
|
332 |
-
$plaintext = $this->_pad($plaintext);
|
333 |
-
}
|
334 |
-
|
335 |
-
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
336 |
-
|
337 |
-
if (!$this->continuousBuffer) {
|
338 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
339 |
-
}
|
340 |
-
|
341 |
-
return $ciphertext;
|
342 |
-
}
|
343 |
-
|
344 |
-
return parent::encrypt($plaintext);
|
345 |
-
}
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Decrypts a message.
|
349 |
-
*
|
350 |
-
* If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
|
351 |
-
*
|
352 |
-
* @see Crypt_AES::encrypt()
|
353 |
-
* @access public
|
354 |
-
* @param String $ciphertext
|
355 |
-
*/
|
356 |
-
function decrypt($ciphertext)
|
357 |
-
{
|
358 |
-
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
359 |
-
$changed = $this->changed;
|
360 |
-
$this->_mcryptSetup();
|
361 |
-
/*
|
362 |
-
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
363 |
-
$iv = $this->decryptIV;
|
364 |
-
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
|
365 |
-
$plaintext = $ciphertext ^ $xor;
|
366 |
-
if ($this->continuousBuffer) {
|
367 |
-
$this->decryptIV = $iv;
|
368 |
-
}
|
369 |
-
return $plaintext;
|
370 |
-
}
|
371 |
-
*/
|
372 |
-
if ($this->mode == 'ncfb') {
|
373 |
-
if ($changed) {
|
374 |
-
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
375 |
-
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
376 |
-
}
|
377 |
-
|
378 |
-
if (strlen($this->debuffer)) {
|
379 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
380 |
-
|
381 |
-
$this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
|
382 |
-
if (strlen($this->debuffer) == 16) {
|
383 |
-
$this->decryptIV = $this->debuffer;
|
384 |
-
$this->debuffer = '';
|
385 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
386 |
-
}
|
387 |
-
$ciphertext = substr($ciphertext, strlen($plaintext));
|
388 |
-
} else {
|
389 |
-
$plaintext = '';
|
390 |
-
}
|
391 |
-
|
392 |
-
$last_pos = strlen($ciphertext) & 0xFFFFFFF0;
|
393 |
-
$plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
|
394 |
-
|
395 |
-
if (strlen($ciphertext) & 0xF) {
|
396 |
-
if (strlen($plaintext)) {
|
397 |
-
$this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
|
398 |
-
}
|
399 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
400 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
401 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
402 |
-
}
|
403 |
-
|
404 |
-
return $plaintext;
|
405 |
-
}
|
406 |
-
|
407 |
-
if ($this->paddable) {
|
408 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
409 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
410 |
-
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
|
411 |
-
}
|
412 |
-
|
413 |
-
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
414 |
-
|
415 |
-
if (!$this->continuousBuffer) {
|
416 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
417 |
-
}
|
418 |
-
|
419 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
420 |
-
}
|
421 |
-
|
422 |
-
return parent::decrypt($ciphertext);
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* Setup mcrypt
|
427 |
-
*
|
428 |
-
* Validates all the variables.
|
429 |
-
*
|
430 |
-
* @access private
|
431 |
-
*/
|
432 |
-
function _mcryptSetup()
|
433 |
-
{
|
434 |
-
if (!$this->changed) {
|
435 |
-
return;
|
436 |
-
}
|
437 |
-
|
438 |
-
if (!$this->explicit_key_length) {
|
439 |
-
// this just copied from Crypt_Rijndael::_setup()
|
440 |
-
$length = strlen($this->key) >> 2;
|
441 |
-
if ($length > 8) {
|
442 |
-
$length = 8;
|
443 |
-
} else if ($length < 4) {
|
444 |
-
$length = 4;
|
445 |
-
}
|
446 |
-
$this->Nk = $length;
|
447 |
-
$this->key_size = $length << 2;
|
448 |
-
}
|
449 |
-
|
450 |
-
switch ($this->Nk) {
|
451 |
-
case 4: // 128
|
452 |
-
$this->key_size = 16;
|
453 |
-
break;
|
454 |
-
case 5: // 160
|
455 |
-
case 6: // 192
|
456 |
-
$this->key_size = 24;
|
457 |
-
break;
|
458 |
-
case 7: // 224
|
459 |
-
case 8: // 256
|
460 |
-
$this->key_size = 32;
|
461 |
-
}
|
462 |
-
|
463 |
-
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
|
464 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
|
465 |
-
|
466 |
-
if (!isset($this->enmcrypt)) {
|
467 |
-
$mode = $this->mode;
|
468 |
-
//$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
|
469 |
-
|
470 |
-
$this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
471 |
-
$this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
472 |
-
} // else should mcrypt_generic_deinit be called?
|
473 |
-
|
474 |
-
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
475 |
-
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
476 |
-
|
477 |
-
$this->changed = false;
|
478 |
-
}
|
479 |
-
|
480 |
-
/**
|
481 |
-
* Encrypts a block
|
482 |
-
*
|
483 |
-
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
|
484 |
-
*
|
485 |
-
* @see Crypt_Rijndael::_encryptBlock()
|
486 |
-
* @access private
|
487 |
-
* @param String $in
|
488 |
-
* @return String
|
489 |
-
*/
|
490 |
-
function _encryptBlock($in)
|
491 |
-
{
|
492 |
-
$state = unpack('N*word', $in);
|
493 |
-
|
494 |
-
$Nr = $this->Nr;
|
495 |
-
$w = $this->w;
|
496 |
-
$t0 = $this->t0;
|
497 |
-
$t1 = $this->t1;
|
498 |
-
$t2 = $this->t2;
|
499 |
-
$t3 = $this->t3;
|
500 |
-
|
501 |
-
// addRoundKey and reindex $state
|
502 |
-
$state = array(
|
503 |
-
$state['word1'] ^ $w[0][0],
|
504 |
-
$state['word2'] ^ $w[0][1],
|
505 |
-
$state['word3'] ^ $w[0][2],
|
506 |
-
$state['word4'] ^ $w[0][3]
|
507 |
-
);
|
508 |
-
|
509 |
-
// shiftRows + subWord + mixColumns + addRoundKey
|
510 |
-
// we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
|
511 |
-
// only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
|
512 |
-
for ($round = 1; $round < $this->Nr; $round++) {
|
513 |
-
$state = array(
|
514 |
-
$t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
|
515 |
-
$t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
|
516 |
-
$t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
|
517 |
-
$t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
|
518 |
-
);
|
519 |
-
|
520 |
-
}
|
521 |
-
|
522 |
-
// subWord
|
523 |
-
$state = array(
|
524 |
-
$this->_subWord($state[0]),
|
525 |
-
$this->_subWord($state[1]),
|
526 |
-
$this->_subWord($state[2]),
|
527 |
-
$this->_subWord($state[3])
|
528 |
-
);
|
529 |
-
|
530 |
-
// shiftRows + addRoundKey
|
531 |
-
$state = array(
|
532 |
-
($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
|
533 |
-
($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
|
534 |
-
($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
|
535 |
-
($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
|
536 |
-
);
|
537 |
-
|
538 |
-
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
539 |
-
}
|
540 |
-
|
541 |
-
/**
|
542 |
-
* Decrypts a block
|
543 |
-
*
|
544 |
-
* Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
|
545 |
-
*
|
546 |
-
* @see Crypt_Rijndael::_decryptBlock()
|
547 |
-
* @access private
|
548 |
-
* @param String $in
|
549 |
-
* @return String
|
550 |
-
*/
|
551 |
-
function _decryptBlock($in)
|
552 |
-
{
|
553 |
-
$state = unpack('N*word', $in);
|
554 |
-
|
555 |
-
$Nr = $this->Nr;
|
556 |
-
$dw = $this->dw;
|
557 |
-
$dt0 = $this->dt0;
|
558 |
-
$dt1 = $this->dt1;
|
559 |
-
$dt2 = $this->dt2;
|
560 |
-
$dt3 = $this->dt3;
|
561 |
-
|
562 |
-
// addRoundKey and reindex $state
|
563 |
-
$state = array(
|
564 |
-
$state['word1'] ^ $dw[$this->Nr][0],
|
565 |
-
$state['word2'] ^ $dw[$this->Nr][1],
|
566 |
-
$state['word3'] ^ $dw[$this->Nr][2],
|
567 |
-
$state['word4'] ^ $dw[$this->Nr][3]
|
568 |
-
);
|
569 |
-
|
570 |
-
|
571 |
-
// invShiftRows + invSubBytes + invMixColumns + addRoundKey
|
572 |
-
for ($round = $this->Nr - 1; $round > 0; $round--) {
|
573 |
-
$state = array(
|
574 |
-
$dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
|
575 |
-
$dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
|
576 |
-
$dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
|
577 |
-
$dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
|
578 |
-
);
|
579 |
-
}
|
580 |
-
|
581 |
-
// invShiftRows + invSubWord + addRoundKey
|
582 |
-
$state = array(
|
583 |
-
$this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
|
584 |
-
$this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
|
585 |
-
$this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
|
586 |
-
$this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
|
587 |
-
);
|
588 |
-
|
589 |
-
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
590 |
-
}
|
591 |
-
}
|
592 |
-
|
593 |
-
// vim: ts=4:sw=4:et:
|
594 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/DES.php
DELETED
@@ -1,1245 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of DES.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Useful resources are as follows:
|
12 |
-
*
|
13 |
-
* - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
|
14 |
-
* - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
|
15 |
-
* - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
|
16 |
-
*
|
17 |
-
* Here's a short example of how to use this library:
|
18 |
-
* <code>
|
19 |
-
* <?php
|
20 |
-
* include('Crypt/DES.php');
|
21 |
-
*
|
22 |
-
* $des = new Crypt_DES();
|
23 |
-
*
|
24 |
-
* $des->setKey('abcdefgh');
|
25 |
-
*
|
26 |
-
* $size = 10 * 1024;
|
27 |
-
* $plaintext = '';
|
28 |
-
* for ($i = 0; $i < $size; $i++) {
|
29 |
-
* $plaintext.= 'a';
|
30 |
-
* }
|
31 |
-
*
|
32 |
-
* echo $des->decrypt($des->encrypt($plaintext));
|
33 |
-
* ?>
|
34 |
-
* </code>
|
35 |
-
*
|
36 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
37 |
-
* of this software and associated documentation files (the "Software"), to deal
|
38 |
-
* in the Software without restriction, including without limitation the rights
|
39 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
40 |
-
* copies of the Software, and to permit persons to whom the Software is
|
41 |
-
* furnished to do so, subject to the following conditions:
|
42 |
-
*
|
43 |
-
* The above copyright notice and this permission notice shall be included in
|
44 |
-
* all copies or substantial portions of the Software.
|
45 |
-
*
|
46 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
47 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
48 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
49 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
50 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
51 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
52 |
-
* THE SOFTWARE.
|
53 |
-
*
|
54 |
-
* @category Crypt
|
55 |
-
* @package Crypt_DES
|
56 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
57 |
-
* @copyright MMVII Jim Wigginton
|
58 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
59 |
-
* @version $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
|
60 |
-
* @link http://phpseclib.sourceforge.net
|
61 |
-
*/
|
62 |
-
|
63 |
-
/**#@+
|
64 |
-
* @access private
|
65 |
-
* @see Crypt_DES::_prepareKey()
|
66 |
-
* @see Crypt_DES::_processBlock()
|
67 |
-
*/
|
68 |
-
/**
|
69 |
-
* Contains array_reverse($keys[CRYPT_DES_DECRYPT])
|
70 |
-
*/
|
71 |
-
define('CRYPT_DES_ENCRYPT', 0);
|
72 |
-
/**
|
73 |
-
* Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
|
74 |
-
*/
|
75 |
-
define('CRYPT_DES_DECRYPT', 1);
|
76 |
-
/**#@-*/
|
77 |
-
|
78 |
-
/**#@+
|
79 |
-
* @access public
|
80 |
-
* @see Crypt_DES::encrypt()
|
81 |
-
* @see Crypt_DES::decrypt()
|
82 |
-
*/
|
83 |
-
/**
|
84 |
-
* Encrypt / decrypt using the Counter mode.
|
85 |
-
*
|
86 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
87 |
-
*
|
88 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
89 |
-
*/
|
90 |
-
define('CRYPT_DES_MODE_CTR', -1);
|
91 |
-
/**
|
92 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
93 |
-
*
|
94 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
95 |
-
*/
|
96 |
-
define('CRYPT_DES_MODE_ECB', 1);
|
97 |
-
/**
|
98 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
99 |
-
*
|
100 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
101 |
-
*/
|
102 |
-
define('CRYPT_DES_MODE_CBC', 2);
|
103 |
-
/**
|
104 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
105 |
-
*
|
106 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
107 |
-
*/
|
108 |
-
define('CRYPT_DES_MODE_CFB', 3);
|
109 |
-
/**
|
110 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
111 |
-
*
|
112 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
113 |
-
*/
|
114 |
-
define('CRYPT_DES_MODE_OFB', 4);
|
115 |
-
/**#@-*/
|
116 |
-
|
117 |
-
/**#@+
|
118 |
-
* @access private
|
119 |
-
* @see Crypt_DES::Crypt_DES()
|
120 |
-
*/
|
121 |
-
/**
|
122 |
-
* Toggles the internal implementation
|
123 |
-
*/
|
124 |
-
define('CRYPT_DES_MODE_INTERNAL', 1);
|
125 |
-
/**
|
126 |
-
* Toggles the mcrypt implementation
|
127 |
-
*/
|
128 |
-
define('CRYPT_DES_MODE_MCRYPT', 2);
|
129 |
-
/**#@-*/
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Pure-PHP implementation of DES.
|
133 |
-
*
|
134 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
135 |
-
* @version 0.1.0
|
136 |
-
* @access public
|
137 |
-
* @package Crypt_DES
|
138 |
-
*/
|
139 |
-
class Crypt_DES {
|
140 |
-
/**
|
141 |
-
* The Key Schedule
|
142 |
-
*
|
143 |
-
* @see Crypt_DES::setKey()
|
144 |
-
* @var Array
|
145 |
-
* @access private
|
146 |
-
*/
|
147 |
-
var $keys = "\0\0\0\0\0\0\0\0";
|
148 |
-
|
149 |
-
/**
|
150 |
-
* The Encryption Mode
|
151 |
-
*
|
152 |
-
* @see Crypt_DES::Crypt_DES()
|
153 |
-
* @var Integer
|
154 |
-
* @access private
|
155 |
-
*/
|
156 |
-
var $mode;
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Continuous Buffer status
|
160 |
-
*
|
161 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
162 |
-
* @var Boolean
|
163 |
-
* @access private
|
164 |
-
*/
|
165 |
-
var $continuousBuffer = false;
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Padding status
|
169 |
-
*
|
170 |
-
* @see Crypt_DES::enablePadding()
|
171 |
-
* @var Boolean
|
172 |
-
* @access private
|
173 |
-
*/
|
174 |
-
var $padding = true;
|
175 |
-
|
176 |
-
/**
|
177 |
-
* The Initialization Vector
|
178 |
-
*
|
179 |
-
* @see Crypt_DES::setIV()
|
180 |
-
* @var String
|
181 |
-
* @access private
|
182 |
-
*/
|
183 |
-
var $iv = "\0\0\0\0\0\0\0\0";
|
184 |
-
|
185 |
-
/**
|
186 |
-
* A "sliding" Initialization Vector
|
187 |
-
*
|
188 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
189 |
-
* @var String
|
190 |
-
* @access private
|
191 |
-
*/
|
192 |
-
var $encryptIV = "\0\0\0\0\0\0\0\0";
|
193 |
-
|
194 |
-
/**
|
195 |
-
* A "sliding" Initialization Vector
|
196 |
-
*
|
197 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
198 |
-
* @var String
|
199 |
-
* @access private
|
200 |
-
*/
|
201 |
-
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
202 |
-
|
203 |
-
/**
|
204 |
-
* mcrypt resource for encryption
|
205 |
-
*
|
206 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
207 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
208 |
-
*
|
209 |
-
* @see Crypt_DES::encrypt()
|
210 |
-
* @var String
|
211 |
-
* @access private
|
212 |
-
*/
|
213 |
-
var $enmcrypt;
|
214 |
-
|
215 |
-
/**
|
216 |
-
* mcrypt resource for decryption
|
217 |
-
*
|
218 |
-
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
219 |
-
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
220 |
-
*
|
221 |
-
* @see Crypt_DES::decrypt()
|
222 |
-
* @var String
|
223 |
-
* @access private
|
224 |
-
*/
|
225 |
-
var $demcrypt;
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Does the enmcrypt resource need to be (re)initialized?
|
229 |
-
*
|
230 |
-
* @see Crypt_DES::setKey()
|
231 |
-
* @see Crypt_DES::setIV()
|
232 |
-
* @var Boolean
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
var $enchanged = true;
|
236 |
-
|
237 |
-
/**
|
238 |
-
* Does the demcrypt resource need to be (re)initialized?
|
239 |
-
*
|
240 |
-
* @see Crypt_DES::setKey()
|
241 |
-
* @see Crypt_DES::setIV()
|
242 |
-
* @var Boolean
|
243 |
-
* @access private
|
244 |
-
*/
|
245 |
-
var $dechanged = true;
|
246 |
-
|
247 |
-
/**
|
248 |
-
* Is the mode one that is paddable?
|
249 |
-
*
|
250 |
-
* @see Crypt_DES::Crypt_DES()
|
251 |
-
* @var Boolean
|
252 |
-
* @access private
|
253 |
-
*/
|
254 |
-
var $paddable = false;
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Encryption buffer for CTR, OFB and CFB modes
|
258 |
-
*
|
259 |
-
* @see Crypt_DES::encrypt()
|
260 |
-
* @var String
|
261 |
-
* @access private
|
262 |
-
*/
|
263 |
-
var $enbuffer = '';
|
264 |
-
|
265 |
-
/**
|
266 |
-
* Decryption buffer for CTR, OFB and CFB modes
|
267 |
-
*
|
268 |
-
* @see Crypt_DES::decrypt()
|
269 |
-
* @var String
|
270 |
-
* @access private
|
271 |
-
*/
|
272 |
-
var $debuffer = '';
|
273 |
-
|
274 |
-
/**
|
275 |
-
* mcrypt resource for CFB mode
|
276 |
-
*
|
277 |
-
* @see Crypt_DES::encrypt()
|
278 |
-
* @see Crypt_DES::decrypt()
|
279 |
-
* @var String
|
280 |
-
* @access private
|
281 |
-
*/
|
282 |
-
var $ecb;
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Default Constructor.
|
286 |
-
*
|
287 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
288 |
-
* CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
289 |
-
*
|
290 |
-
* @param optional Integer $mode
|
291 |
-
* @return Crypt_DES
|
292 |
-
* @access public
|
293 |
-
*/
|
294 |
-
function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
|
295 |
-
{
|
296 |
-
if ( !defined('CRYPT_DES_MODE') ) {
|
297 |
-
switch (true) {
|
298 |
-
case extension_loaded('mcrypt'):
|
299 |
-
// i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
300 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
301 |
-
// a lot of point...
|
302 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
|
303 |
-
break;
|
304 |
-
default:
|
305 |
-
define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
|
306 |
-
}
|
307 |
-
}
|
308 |
-
|
309 |
-
switch ( CRYPT_DES_MODE ) {
|
310 |
-
case CRYPT_DES_MODE_MCRYPT:
|
311 |
-
switch ($mode) {
|
312 |
-
case CRYPT_DES_MODE_ECB:
|
313 |
-
$this->paddable = true;
|
314 |
-
$this->mode = MCRYPT_MODE_ECB;
|
315 |
-
break;
|
316 |
-
case CRYPT_DES_MODE_CTR:
|
317 |
-
$this->mode = 'ctr';
|
318 |
-
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
|
319 |
-
break;
|
320 |
-
case CRYPT_DES_MODE_CFB:
|
321 |
-
$this->mode = 'ncfb';
|
322 |
-
break;
|
323 |
-
case CRYPT_DES_MODE_OFB:
|
324 |
-
$this->mode = MCRYPT_MODE_NOFB;
|
325 |
-
break;
|
326 |
-
case CRYPT_DES_MODE_CBC:
|
327 |
-
default:
|
328 |
-
$this->paddable = true;
|
329 |
-
$this->mode = MCRYPT_MODE_CBC;
|
330 |
-
}
|
331 |
-
|
332 |
-
break;
|
333 |
-
default:
|
334 |
-
switch ($mode) {
|
335 |
-
case CRYPT_DES_MODE_ECB:
|
336 |
-
case CRYPT_DES_MODE_CBC:
|
337 |
-
$this->paddable = true;
|
338 |
-
$this->mode = $mode;
|
339 |
-
break;
|
340 |
-
case CRYPT_DES_MODE_CTR:
|
341 |
-
case CRYPT_DES_MODE_CFB:
|
342 |
-
case CRYPT_DES_MODE_OFB:
|
343 |
-
$this->mode = $mode;
|
344 |
-
break;
|
345 |
-
default:
|
346 |
-
$this->paddable = true;
|
347 |
-
$this->mode = CRYPT_DES_MODE_CBC;
|
348 |
-
}
|
349 |
-
}
|
350 |
-
}
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Sets the key.
|
354 |
-
*
|
355 |
-
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
|
356 |
-
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
|
357 |
-
* null byte if it is less then eight characters long.
|
358 |
-
*
|
359 |
-
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
360 |
-
*
|
361 |
-
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
362 |
-
*
|
363 |
-
* @access public
|
364 |
-
* @param String $key
|
365 |
-
*/
|
366 |
-
function setKey($key)
|
367 |
-
{
|
368 |
-
$this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
|
369 |
-
$this->changed = true;
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Sets the initialization vector. (optional)
|
374 |
-
*
|
375 |
-
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
|
376 |
-
* to be all zero's.
|
377 |
-
*
|
378 |
-
* @access public
|
379 |
-
* @param String $iv
|
380 |
-
*/
|
381 |
-
function setIV($iv)
|
382 |
-
{
|
383 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
|
384 |
-
$this->changed = true;
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Generate CTR XOR encryption key
|
389 |
-
*
|
390 |
-
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
391 |
-
* plaintext / ciphertext in CTR mode.
|
392 |
-
*
|
393 |
-
* @see Crypt_DES::decrypt()
|
394 |
-
* @see Crypt_DES::encrypt()
|
395 |
-
* @access public
|
396 |
-
* @param Integer $length
|
397 |
-
* @param String $iv
|
398 |
-
*/
|
399 |
-
function _generate_xor($length, &$iv)
|
400 |
-
{
|
401 |
-
$xor = '';
|
402 |
-
$num_blocks = ($length + 7) >> 3;
|
403 |
-
for ($i = 0; $i < $num_blocks; $i++) {
|
404 |
-
$xor.= $iv;
|
405 |
-
for ($j = 4; $j <= 8; $j+=4) {
|
406 |
-
$temp = substr($iv, -$j, 4);
|
407 |
-
switch ($temp) {
|
408 |
-
case "\xFF\xFF\xFF\xFF":
|
409 |
-
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
410 |
-
break;
|
411 |
-
case "\x7F\xFF\xFF\xFF":
|
412 |
-
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
413 |
-
break 2;
|
414 |
-
default:
|
415 |
-
extract(unpack('Ncount', $temp));
|
416 |
-
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
417 |
-
break 2;
|
418 |
-
}
|
419 |
-
}
|
420 |
-
}
|
421 |
-
|
422 |
-
return $xor;
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* Encrypts a message.
|
427 |
-
*
|
428 |
-
* $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
|
429 |
-
* same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
|
430 |
-
* URL:
|
431 |
-
*
|
432 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
433 |
-
*
|
434 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
435 |
-
* strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
|
436 |
-
* length.
|
437 |
-
*
|
438 |
-
* @see Crypt_DES::decrypt()
|
439 |
-
* @access public
|
440 |
-
* @param String $plaintext
|
441 |
-
*/
|
442 |
-
function encrypt($plaintext)
|
443 |
-
{
|
444 |
-
if ($this->paddable) {
|
445 |
-
$plaintext = $this->_pad($plaintext);
|
446 |
-
}
|
447 |
-
|
448 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
449 |
-
if ($this->enchanged) {
|
450 |
-
if (!isset($this->enmcrypt)) {
|
451 |
-
$this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
452 |
-
}
|
453 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
454 |
-
if ($this->mode != 'ncfb') {
|
455 |
-
$this->enchanged = false;
|
456 |
-
}
|
457 |
-
}
|
458 |
-
|
459 |
-
if ($this->mode != 'ncfb') {
|
460 |
-
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
461 |
-
} else {
|
462 |
-
if ($this->enchanged) {
|
463 |
-
$this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
|
464 |
-
mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
|
465 |
-
$this->enchanged = false;
|
466 |
-
}
|
467 |
-
|
468 |
-
if (strlen($this->enbuffer)) {
|
469 |
-
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
|
470 |
-
$this->enbuffer.= $ciphertext;
|
471 |
-
if (strlen($this->enbuffer) == 8) {
|
472 |
-
$this->encryptIV = $this->enbuffer;
|
473 |
-
$this->enbuffer = '';
|
474 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
475 |
-
}
|
476 |
-
$plaintext = substr($plaintext, strlen($ciphertext));
|
477 |
-
} else {
|
478 |
-
$ciphertext = '';
|
479 |
-
}
|
480 |
-
|
481 |
-
$last_pos = strlen($plaintext) & 0xFFFFFFF8;
|
482 |
-
$ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
|
483 |
-
|
484 |
-
if (strlen($plaintext) & 0x7) {
|
485 |
-
if (strlen($ciphertext)) {
|
486 |
-
$this->encryptIV = substr($ciphertext, -8);
|
487 |
-
}
|
488 |
-
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
489 |
-
$this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
490 |
-
$ciphertext.= $this->enbuffer;
|
491 |
-
}
|
492 |
-
}
|
493 |
-
|
494 |
-
if (!$this->continuousBuffer) {
|
495 |
-
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
496 |
-
}
|
497 |
-
|
498 |
-
return $ciphertext;
|
499 |
-
}
|
500 |
-
|
501 |
-
if (!is_array($this->keys)) {
|
502 |
-
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
503 |
-
}
|
504 |
-
|
505 |
-
$buffer = &$this->enbuffer;
|
506 |
-
$continuousBuffer = $this->continuousBuffer;
|
507 |
-
$ciphertext = '';
|
508 |
-
switch ($this->mode) {
|
509 |
-
case CRYPT_DES_MODE_ECB:
|
510 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
511 |
-
$ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
|
512 |
-
}
|
513 |
-
break;
|
514 |
-
case CRYPT_DES_MODE_CBC:
|
515 |
-
$xor = $this->encryptIV;
|
516 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
517 |
-
$block = substr($plaintext, $i, 8);
|
518 |
-
$block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
|
519 |
-
$xor = $block;
|
520 |
-
$ciphertext.= $block;
|
521 |
-
}
|
522 |
-
if ($this->continuousBuffer) {
|
523 |
-
$this->encryptIV = $xor;
|
524 |
-
}
|
525 |
-
break;
|
526 |
-
case CRYPT_DES_MODE_CTR:
|
527 |
-
$xor = $this->encryptIV;
|
528 |
-
if (strlen($buffer)) {
|
529 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
530 |
-
$block = substr($plaintext, $i, 8);
|
531 |
-
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
532 |
-
$key = $this->_string_shift($buffer, 8);
|
533 |
-
$ciphertext.= $block ^ $key;
|
534 |
-
}
|
535 |
-
} else {
|
536 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
537 |
-
$block = substr($plaintext, $i, 8);
|
538 |
-
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
539 |
-
$ciphertext.= $block ^ $key;
|
540 |
-
}
|
541 |
-
}
|
542 |
-
if ($this->continuousBuffer) {
|
543 |
-
$this->encryptIV = $xor;
|
544 |
-
if ($start = strlen($plaintext) & 7) {
|
545 |
-
$buffer = substr($key, $start) . $buffer;
|
546 |
-
}
|
547 |
-
}
|
548 |
-
break;
|
549 |
-
case CRYPT_DES_MODE_CFB:
|
550 |
-
if (!empty($buffer['xor'])) {
|
551 |
-
$ciphertext = $plaintext ^ $buffer['xor'];
|
552 |
-
$iv = $buffer['encrypted'] . $ciphertext;
|
553 |
-
$start = strlen($ciphertext);
|
554 |
-
$buffer['encrypted'].= $ciphertext;
|
555 |
-
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
556 |
-
} else {
|
557 |
-
$ciphertext = '';
|
558 |
-
$iv = $this->encryptIV;
|
559 |
-
$start = 0;
|
560 |
-
}
|
561 |
-
|
562 |
-
for ($i = $start; $i < strlen($plaintext); $i+=8) {
|
563 |
-
$block = substr($plaintext, $i, 8);
|
564 |
-
$xor = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
565 |
-
$iv = $block ^ $xor;
|
566 |
-
if ($continuousBuffer && strlen($iv) != 8) {
|
567 |
-
$buffer = array(
|
568 |
-
'encrypted' => $iv,
|
569 |
-
'xor' => substr($xor, strlen($iv))
|
570 |
-
);
|
571 |
-
}
|
572 |
-
$ciphertext.= $iv;
|
573 |
-
}
|
574 |
-
|
575 |
-
if ($this->continuousBuffer) {
|
576 |
-
$this->encryptIV = $iv;
|
577 |
-
}
|
578 |
-
break;
|
579 |
-
case CRYPT_DES_MODE_OFB:
|
580 |
-
$xor = $this->encryptIV;
|
581 |
-
if (strlen($buffer)) {
|
582 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
583 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
584 |
-
$buffer.= $xor;
|
585 |
-
$key = $this->_string_shift($buffer, 8);
|
586 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $key;
|
587 |
-
}
|
588 |
-
} else {
|
589 |
-
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
590 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
591 |
-
$ciphertext.= substr($plaintext, $i, 8) ^ $xor;
|
592 |
-
}
|
593 |
-
$key = $xor;
|
594 |
-
}
|
595 |
-
if ($this->continuousBuffer) {
|
596 |
-
$this->encryptIV = $xor;
|
597 |
-
if ($start = strlen($plaintext) & 7) {
|
598 |
-
$buffer = substr($key, $start) . $buffer;
|
599 |
-
}
|
600 |
-
}
|
601 |
-
}
|
602 |
-
|
603 |
-
return $ciphertext;
|
604 |
-
}
|
605 |
-
|
606 |
-
/**
|
607 |
-
* Decrypts a message.
|
608 |
-
*
|
609 |
-
* If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
|
610 |
-
*
|
611 |
-
* @see Crypt_DES::encrypt()
|
612 |
-
* @access public
|
613 |
-
* @param String $ciphertext
|
614 |
-
*/
|
615 |
-
function decrypt($ciphertext)
|
616 |
-
{
|
617 |
-
if ($this->paddable) {
|
618 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
619 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
620 |
-
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
621 |
-
}
|
622 |
-
|
623 |
-
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
624 |
-
if ($this->dechanged) {
|
625 |
-
if (!isset($this->demcrypt)) {
|
626 |
-
$this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
627 |
-
}
|
628 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
629 |
-
if ($this->mode != 'ncfb') {
|
630 |
-
$this->dechanged = false;
|
631 |
-
}
|
632 |
-
}
|
633 |
-
|
634 |
-
if ($this->mode != 'ncfb') {
|
635 |
-
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
636 |
-
} else {
|
637 |
-
if ($this->dechanged) {
|
638 |
-
$this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
|
639 |
-
mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
|
640 |
-
$this->dechanged = false;
|
641 |
-
}
|
642 |
-
|
643 |
-
if (strlen($this->debuffer)) {
|
644 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
645 |
-
|
646 |
-
$this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
|
647 |
-
if (strlen($this->debuffer) == 8) {
|
648 |
-
$this->decryptIV = $this->debuffer;
|
649 |
-
$this->debuffer = '';
|
650 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
651 |
-
}
|
652 |
-
$ciphertext = substr($ciphertext, strlen($plaintext));
|
653 |
-
} else {
|
654 |
-
$plaintext = '';
|
655 |
-
}
|
656 |
-
|
657 |
-
$last_pos = strlen($ciphertext) & 0xFFFFFFF8;
|
658 |
-
$plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
|
659 |
-
|
660 |
-
if (strlen($ciphertext) & 0x7) {
|
661 |
-
if (strlen($plaintext)) {
|
662 |
-
$this->decryptIV = substr($ciphertext, $last_pos - 8, 8);
|
663 |
-
}
|
664 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
665 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
666 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
667 |
-
}
|
668 |
-
|
669 |
-
return $plaintext;
|
670 |
-
}
|
671 |
-
|
672 |
-
if (!$this->continuousBuffer) {
|
673 |
-
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
674 |
-
}
|
675 |
-
|
676 |
-
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
677 |
-
}
|
678 |
-
|
679 |
-
if (!is_array($this->keys)) {
|
680 |
-
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
681 |
-
}
|
682 |
-
|
683 |
-
$buffer = &$this->debuffer;
|
684 |
-
$continuousBuffer = $this->continuousBuffer;
|
685 |
-
$plaintext = '';
|
686 |
-
switch ($this->mode) {
|
687 |
-
case CRYPT_DES_MODE_ECB:
|
688 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
689 |
-
$plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
|
690 |
-
}
|
691 |
-
break;
|
692 |
-
case CRYPT_DES_MODE_CBC:
|
693 |
-
$xor = $this->decryptIV;
|
694 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
695 |
-
$block = substr($ciphertext, $i, 8);
|
696 |
-
$plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
|
697 |
-
$xor = $block;
|
698 |
-
}
|
699 |
-
if ($this->continuousBuffer) {
|
700 |
-
$this->decryptIV = $xor;
|
701 |
-
}
|
702 |
-
break;
|
703 |
-
case CRYPT_DES_MODE_CTR:
|
704 |
-
$xor = $this->decryptIV;
|
705 |
-
if (strlen($buffer)) {
|
706 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
707 |
-
$block = substr($ciphertext, $i, 8);
|
708 |
-
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
709 |
-
$key = $this->_string_shift($buffer, 8);
|
710 |
-
$plaintext.= $block ^ $key;
|
711 |
-
}
|
712 |
-
} else {
|
713 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
714 |
-
$block = substr($ciphertext, $i, 8);
|
715 |
-
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
716 |
-
$plaintext.= $block ^ $key;
|
717 |
-
}
|
718 |
-
}
|
719 |
-
if ($this->continuousBuffer) {
|
720 |
-
$this->decryptIV = $xor;
|
721 |
-
if ($start = strlen($ciphertext) % 8) {
|
722 |
-
$buffer = substr($key, $start) . $buffer;
|
723 |
-
}
|
724 |
-
}
|
725 |
-
break;
|
726 |
-
case CRYPT_DES_MODE_CFB:
|
727 |
-
if (!empty($buffer['ciphertext'])) {
|
728 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
729 |
-
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
730 |
-
if (strlen($buffer['ciphertext']) == 8) {
|
731 |
-
$xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
|
732 |
-
$buffer['ciphertext'] = '';
|
733 |
-
}
|
734 |
-
$start = strlen($plaintext);
|
735 |
-
$block = $this->decryptIV;
|
736 |
-
} else {
|
737 |
-
$plaintext = '';
|
738 |
-
$xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
739 |
-
$start = 0;
|
740 |
-
}
|
741 |
-
|
742 |
-
for ($i = $start; $i < strlen($ciphertext); $i+=8) {
|
743 |
-
$block = substr($ciphertext, $i, 8);
|
744 |
-
$plaintext.= $block ^ $xor;
|
745 |
-
if ($continuousBuffer && strlen($block) != 8) {
|
746 |
-
$buffer['ciphertext'].= $block;
|
747 |
-
$block = $xor;
|
748 |
-
} else if (strlen($block) == 8) {
|
749 |
-
$xor = $this->_processBlock($block, CRYPT_DES_ENCRYPT);
|
750 |
-
}
|
751 |
-
}
|
752 |
-
if ($this->continuousBuffer) {
|
753 |
-
$this->decryptIV = $block;
|
754 |
-
}
|
755 |
-
break;
|
756 |
-
case CRYPT_DES_MODE_OFB:
|
757 |
-
$xor = $this->decryptIV;
|
758 |
-
if (strlen($buffer)) {
|
759 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
760 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
761 |
-
$buffer.= $xor;
|
762 |
-
$key = $this->_string_shift($buffer, 8);
|
763 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $key;
|
764 |
-
}
|
765 |
-
} else {
|
766 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
767 |
-
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
768 |
-
$plaintext.= substr($ciphertext, $i, 8) ^ $xor;
|
769 |
-
}
|
770 |
-
$key = $xor;
|
771 |
-
}
|
772 |
-
if ($this->continuousBuffer) {
|
773 |
-
$this->decryptIV = $xor;
|
774 |
-
if ($start = strlen($ciphertext) % 8) {
|
775 |
-
$buffer = substr($key, $start) . $buffer;
|
776 |
-
}
|
777 |
-
}
|
778 |
-
}
|
779 |
-
|
780 |
-
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
781 |
-
}
|
782 |
-
|
783 |
-
/**
|
784 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
785 |
-
*
|
786 |
-
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
787 |
-
* will yield different outputs:
|
788 |
-
*
|
789 |
-
* <code>
|
790 |
-
* echo $des->encrypt(substr($plaintext, 0, 8));
|
791 |
-
* echo $des->encrypt(substr($plaintext, 8, 8));
|
792 |
-
* </code>
|
793 |
-
* <code>
|
794 |
-
* echo $des->encrypt($plaintext);
|
795 |
-
* </code>
|
796 |
-
*
|
797 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
798 |
-
* another, as demonstrated with the following:
|
799 |
-
*
|
800 |
-
* <code>
|
801 |
-
* $des->encrypt(substr($plaintext, 0, 8));
|
802 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
803 |
-
* </code>
|
804 |
-
* <code>
|
805 |
-
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
806 |
-
* </code>
|
807 |
-
*
|
808 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
809 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
810 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
811 |
-
*
|
812 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
813 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
814 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
815 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
816 |
-
*
|
817 |
-
* @see Crypt_DES::disableContinuousBuffer()
|
818 |
-
* @access public
|
819 |
-
*/
|
820 |
-
function enableContinuousBuffer()
|
821 |
-
{
|
822 |
-
$this->continuousBuffer = true;
|
823 |
-
}
|
824 |
-
|
825 |
-
/**
|
826 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
827 |
-
*
|
828 |
-
* The default behavior.
|
829 |
-
*
|
830 |
-
* @see Crypt_DES::enableContinuousBuffer()
|
831 |
-
* @access public
|
832 |
-
*/
|
833 |
-
function disableContinuousBuffer()
|
834 |
-
{
|
835 |
-
$this->continuousBuffer = false;
|
836 |
-
$this->encryptIV = $this->iv;
|
837 |
-
$this->decryptIV = $this->iv;
|
838 |
-
}
|
839 |
-
|
840 |
-
/**
|
841 |
-
* Pad "packets".
|
842 |
-
*
|
843 |
-
* DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
|
844 |
-
* a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
|
845 |
-
*
|
846 |
-
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
|
847 |
-
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
848 |
-
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
849 |
-
* transmitted separately)
|
850 |
-
*
|
851 |
-
* @see Crypt_DES::disablePadding()
|
852 |
-
* @access public
|
853 |
-
*/
|
854 |
-
function enablePadding()
|
855 |
-
{
|
856 |
-
$this->padding = true;
|
857 |
-
}
|
858 |
-
|
859 |
-
/**
|
860 |
-
* Do not pad packets.
|
861 |
-
*
|
862 |
-
* @see Crypt_DES::enablePadding()
|
863 |
-
* @access public
|
864 |
-
*/
|
865 |
-
function disablePadding()
|
866 |
-
{
|
867 |
-
$this->padding = false;
|
868 |
-
}
|
869 |
-
|
870 |
-
/**
|
871 |
-
* Pads a string
|
872 |
-
*
|
873 |
-
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
|
874 |
-
* 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
|
875 |
-
*
|
876 |
-
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
877 |
-
* and padding will, hence forth, be enabled.
|
878 |
-
*
|
879 |
-
* @see Crypt_DES::_unpad()
|
880 |
-
* @access private
|
881 |
-
*/
|
882 |
-
function _pad($text)
|
883 |
-
{
|
884 |
-
$length = strlen($text);
|
885 |
-
|
886 |
-
if (!$this->padding) {
|
887 |
-
if (($length & 7) == 0) {
|
888 |
-
return $text;
|
889 |
-
} else {
|
890 |
-
user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
|
891 |
-
$this->padding = true;
|
892 |
-
}
|
893 |
-
}
|
894 |
-
|
895 |
-
$pad = 8 - ($length & 7);
|
896 |
-
return str_pad($text, $length + $pad, chr($pad));
|
897 |
-
}
|
898 |
-
|
899 |
-
/**
|
900 |
-
* Unpads a string
|
901 |
-
*
|
902 |
-
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
903 |
-
* and false will be returned.
|
904 |
-
*
|
905 |
-
* @see Crypt_DES::_pad()
|
906 |
-
* @access private
|
907 |
-
*/
|
908 |
-
function _unpad($text)
|
909 |
-
{
|
910 |
-
if (!$this->padding) {
|
911 |
-
return $text;
|
912 |
-
}
|
913 |
-
|
914 |
-
$length = ord($text[strlen($text) - 1]);
|
915 |
-
|
916 |
-
if (!$length || $length > 8) {
|
917 |
-
return false;
|
918 |
-
}
|
919 |
-
|
920 |
-
return substr($text, 0, -$length);
|
921 |
-
}
|
922 |
-
|
923 |
-
/**
|
924 |
-
* Encrypts or decrypts a 64-bit block
|
925 |
-
*
|
926 |
-
* $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
|
927 |
-
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
|
928 |
-
* idea of what this function does.
|
929 |
-
*
|
930 |
-
* @access private
|
931 |
-
* @param String $block
|
932 |
-
* @param Integer $mode
|
933 |
-
* @return String
|
934 |
-
*/
|
935 |
-
function _processBlock($block, $mode)
|
936 |
-
{
|
937 |
-
// s-boxes. in the official DES docs, they're described as being matrices that
|
938 |
-
// one accesses by using the first and last bits to determine the row and the
|
939 |
-
// middle four bits to determine the column. in this implementation, they've
|
940 |
-
// been converted to vectors
|
941 |
-
static $sbox = array(
|
942 |
-
array(
|
943 |
-
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
|
944 |
-
3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
|
945 |
-
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
|
946 |
-
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
|
947 |
-
),
|
948 |
-
array(
|
949 |
-
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
|
950 |
-
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
|
951 |
-
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
|
952 |
-
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
|
953 |
-
),
|
954 |
-
array(
|
955 |
-
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
|
956 |
-
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
|
957 |
-
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
|
958 |
-
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
|
959 |
-
),
|
960 |
-
array(
|
961 |
-
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
|
962 |
-
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
|
963 |
-
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
|
964 |
-
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
|
965 |
-
),
|
966 |
-
array(
|
967 |
-
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
|
968 |
-
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
|
969 |
-
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
|
970 |
-
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
|
971 |
-
),
|
972 |
-
array(
|
973 |
-
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
|
974 |
-
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
|
975 |
-
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
|
976 |
-
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
|
977 |
-
),
|
978 |
-
array(
|
979 |
-
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
|
980 |
-
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
|
981 |
-
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
|
982 |
-
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
|
983 |
-
),
|
984 |
-
array(
|
985 |
-
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
|
986 |
-
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
|
987 |
-
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
|
988 |
-
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
|
989 |
-
)
|
990 |
-
);
|
991 |
-
|
992 |
-
$keys = $this->keys;
|
993 |
-
|
994 |
-
$temp = unpack('Na/Nb', $block);
|
995 |
-
$block = array($temp['a'], $temp['b']);
|
996 |
-
|
997 |
-
// because php does arithmetic right shifts, if the most significant bits are set, right
|
998 |
-
// shifting those into the correct position will add 1's - not 0's. this will intefere
|
999 |
-
// with the | operation unless a second & is done. so we isolate these bits and left shift
|
1000 |
-
// them into place. we then & each block with 0x7FFFFFFF to prevennt 1's from being added
|
1001 |
-
// for any other shifts.
|
1002 |
-
$msb = array(
|
1003 |
-
($block[0] >> 31) & 1,
|
1004 |
-
($block[1] >> 31) & 1
|
1005 |
-
);
|
1006 |
-
$block[0] &= 0x7FFFFFFF;
|
1007 |
-
$block[1] &= 0x7FFFFFFF;
|
1008 |
-
|
1009 |
-
// we isolate the appropriate bit in the appropriate integer and shift as appropriate. in
|
1010 |
-
// some cases, there are going to be multiple bits in the same integer that need to be shifted
|
1011 |
-
// in the same way. we combine those into one shift operation.
|
1012 |
-
$block = array(
|
1013 |
-
(($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |
|
1014 |
-
(($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) |
|
1015 |
-
(($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |
|
1016 |
-
(($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) |
|
1017 |
-
(($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |
|
1018 |
-
(($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) |
|
1019 |
-
(($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) |
|
1020 |
-
(($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) |
|
1021 |
-
(($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) |
|
1022 |
-
(($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) |
|
1023 |
-
(($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) |
|
1024 |
-
(($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) |
|
1025 |
-
(($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |
|
1026 |
-
(($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)
|
1027 |
-
,
|
1028 |
-
(($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |
|
1029 |
-
(($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) |
|
1030 |
-
(($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) |
|
1031 |
-
(($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) |
|
1032 |
-
( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) |
|
1033 |
-
(($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) |
|
1034 |
-
(($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) |
|
1035 |
-
(($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) |
|
1036 |
-
(($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) |
|
1037 |
-
(($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) |
|
1038 |
-
(($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |
|
1039 |
-
(($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) |
|
1040 |
-
(($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |
|
1041 |
-
(($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |
|
1042 |
-
($msb[1] << 28) | ($msb[0] << 24)
|
1043 |
-
);
|
1044 |
-
|
1045 |
-
for ($i = 0; $i < 16; $i++) {
|
1046 |
-
// start of "the Feistel (F) function" - see the following URL:
|
1047 |
-
// http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
|
1048 |
-
$temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)
|
1049 |
-
| (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)
|
1050 |
-
| (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)
|
1051 |
-
| (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)
|
1052 |
-
| (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)
|
1053 |
-
| (($sbox[5][(($block[1] & 0x00001F80) >> 7) ^ $keys[$mode][$i][5]]) << 8)
|
1054 |
-
| (($sbox[6][(($block[1] & 0x000001F8) >> 3) ^ $keys[$mode][$i][6]]) << 4)
|
1055 |
-
| ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);
|
1056 |
-
|
1057 |
-
$msb = ($temp >> 31) & 1;
|
1058 |
-
$temp &= 0x7FFFFFFF;
|
1059 |
-
$newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5)
|
1060 |
-
| (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)
|
1061 |
-
| (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6)
|
1062 |
-
| (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9)
|
1063 |
-
| (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)
|
1064 |
-
| (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8)
|
1065 |
-
| (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16)
|
1066 |
-
| (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15)
|
1067 |
-
| (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)
|
1068 |
-
| (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3)
|
1069 |
-
| (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7)
|
1070 |
-
| (($temp & 0x00200000) >> 19) | ($msb << 23);
|
1071 |
-
// end of "the Feistel (F) function" - $newBlock is F's output
|
1072 |
-
|
1073 |
-
$temp = $block[1];
|
1074 |
-
$block[1] = $block[0] ^ $newBlock;
|
1075 |
-
$block[0] = $temp;
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
$msb = array(
|
1079 |
-
($block[0] >> 31) & 1,
|
1080 |
-
($block[1] >> 31) & 1
|
1081 |
-
);
|
1082 |
-
$block[0] &= 0x7FFFFFFF;
|
1083 |
-
$block[1] &= 0x7FFFFFFF;
|
1084 |
-
|
1085 |
-
$block = array(
|
1086 |
-
(($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) |
|
1087 |
-
(($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |
|
1088 |
-
(($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |
|
1089 |
-
(($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |
|
1090 |
-
(($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) |
|
1091 |
-
(($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) |
|
1092 |
-
(($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) |
|
1093 |
-
(($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |
|
1094 |
-
(($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |
|
1095 |
-
(($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) |
|
1096 |
-
(($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) |
|
1097 |
-
(($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |
|
1098 |
-
(($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |
|
1099 |
-
(($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9)
|
1100 |
-
,
|
1101 |
-
(($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) |
|
1102 |
-
(($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) |
|
1103 |
-
(($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |
|
1104 |
-
(($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |
|
1105 |
-
(($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) |
|
1106 |
-
( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) |
|
1107 |
-
(($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) |
|
1108 |
-
(($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |
|
1109 |
-
(($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |
|
1110 |
-
(($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) |
|
1111 |
-
(($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) |
|
1112 |
-
(($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |
|
1113 |
-
(($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |
|
1114 |
-
($msb[0] << 7) | ($msb[1] << 6)
|
1115 |
-
);
|
1116 |
-
|
1117 |
-
return pack('NN', $block[0], $block[1]);
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
/**
|
1121 |
-
* Creates the key schedule.
|
1122 |
-
*
|
1123 |
-
* @access private
|
1124 |
-
* @param String $key
|
1125 |
-
* @return Array
|
1126 |
-
*/
|
1127 |
-
function _prepareKey($key)
|
1128 |
-
{
|
1129 |
-
static $shifts = array( // number of key bits shifted per round
|
1130 |
-
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
1131 |
-
);
|
1132 |
-
|
1133 |
-
// pad the key and remove extra characters as appropriate.
|
1134 |
-
$key = str_pad(substr($key, 0, 8), 8, chr(0));
|
1135 |
-
|
1136 |
-
$temp = unpack('Na/Nb', $key);
|
1137 |
-
$key = array($temp['a'], $temp['b']);
|
1138 |
-
$msb = array(
|
1139 |
-
($key[0] >> 31) & 1,
|
1140 |
-
($key[1] >> 31) & 1
|
1141 |
-
);
|
1142 |
-
$key[0] &= 0x7FFFFFFF;
|
1143 |
-
$key[1] &= 0x7FFFFFFF;
|
1144 |
-
|
1145 |
-
$key = array(
|
1146 |
-
(($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
|
1147 |
-
(($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) |
|
1148 |
-
(($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
|
1149 |
-
(($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) |
|
1150 |
-
(($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
|
1151 |
-
(($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
|
1152 |
-
(($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) |
|
1153 |
-
(($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
|
1154 |
-
,
|
1155 |
-
(($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
|
1156 |
-
(($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) |
|
1157 |
-
(($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) |
|
1158 |
-
(($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) |
|
1159 |
-
(($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) |
|
1160 |
-
(($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) |
|
1161 |
-
(($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) |
|
1162 |
-
(($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) |
|
1163 |
-
(($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
|
1164 |
-
(($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) |
|
1165 |
-
(($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
|
1166 |
-
(($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) |
|
1167 |
-
(($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
|
1168 |
-
($msb[1] << 24) | ($msb[0] << 20)
|
1169 |
-
);
|
1170 |
-
|
1171 |
-
$keys = array();
|
1172 |
-
for ($i = 0; $i < 16; $i++) {
|
1173 |
-
$key[0] <<= $shifts[$i];
|
1174 |
-
$temp = ($key[0] & 0xF0000000) >> 28;
|
1175 |
-
$key[0] = ($key[0] | $temp) & 0x0FFFFFFF;
|
1176 |
-
|
1177 |
-
$key[1] <<= $shifts[$i];
|
1178 |
-
$temp = ($key[1] & 0xF0000000) >> 28;
|
1179 |
-
$key[1] = ($key[1] | $temp) & 0x0FFFFFFF;
|
1180 |
-
|
1181 |
-
$temp = array(
|
1182 |
-
(($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) |
|
1183 |
-
(($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) |
|
1184 |
-
(($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
|
1185 |
-
,
|
1186 |
-
(($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) |
|
1187 |
-
(($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
|
1188 |
-
(($key[1] & 0x00000080) >> 6)
|
1189 |
-
,
|
1190 |
-
( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) |
|
1191 |
-
(($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
|
1192 |
-
(($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20)
|
1193 |
-
,
|
1194 |
-
(($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) |
|
1195 |
-
(($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) |
|
1196 |
-
(($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
|
1197 |
-
,
|
1198 |
-
(($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) |
|
1199 |
-
(($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
|
1200 |
-
(($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1)
|
1201 |
-
,
|
1202 |
-
(($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
|
1203 |
-
(($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) |
|
1204 |
-
(($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8)
|
1205 |
-
,
|
1206 |
-
(($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) |
|
1207 |
-
(($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) |
|
1208 |
-
(($key[0] & 0x00400000) >> 21)
|
1209 |
-
,
|
1210 |
-
(($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) |
|
1211 |
-
(($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) |
|
1212 |
-
(($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
|
1213 |
-
);
|
1214 |
-
|
1215 |
-
$keys[] = $temp;
|
1216 |
-
}
|
1217 |
-
|
1218 |
-
$temp = array(
|
1219 |
-
CRYPT_DES_ENCRYPT => $keys,
|
1220 |
-
CRYPT_DES_DECRYPT => array_reverse($keys)
|
1221 |
-
);
|
1222 |
-
|
1223 |
-
return $temp;
|
1224 |
-
}
|
1225 |
-
|
1226 |
-
/**
|
1227 |
-
* String Shift
|
1228 |
-
*
|
1229 |
-
* Inspired by array_shift
|
1230 |
-
*
|
1231 |
-
* @param String $string
|
1232 |
-
* @param optional Integer $index
|
1233 |
-
* @return String
|
1234 |
-
* @access private
|
1235 |
-
*/
|
1236 |
-
function _string_shift(&$string, $index = 1)
|
1237 |
-
{
|
1238 |
-
$substr = substr($string, 0, $index);
|
1239 |
-
$string = substr($string, $index);
|
1240 |
-
return $substr;
|
1241 |
-
}
|
1242 |
-
}
|
1243 |
-
|
1244 |
-
// vim: ts=4:sw=4:et:
|
1245 |
-
// vim6: fdl=1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/RC4.php
DELETED
@@ -1,505 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of RC4.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Useful resources are as follows:
|
12 |
-
*
|
13 |
-
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
|
14 |
-
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
|
15 |
-
*
|
16 |
-
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
|
17 |
-
* ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
|
18 |
-
*
|
19 |
-
* Here's a short example of how to use this library:
|
20 |
-
* <code>
|
21 |
-
* <?php
|
22 |
-
* include('Crypt/RC4.php');
|
23 |
-
*
|
24 |
-
* $rc4 = new Crypt_RC4();
|
25 |
-
*
|
26 |
-
* $rc4->setKey('abcdefgh');
|
27 |
-
*
|
28 |
-
* $size = 10 * 1024;
|
29 |
-
* $plaintext = '';
|
30 |
-
* for ($i = 0; $i < $size; $i++) {
|
31 |
-
* $plaintext.= 'a';
|
32 |
-
* }
|
33 |
-
*
|
34 |
-
* echo $rc4->decrypt($rc4->encrypt($plaintext));
|
35 |
-
* ?>
|
36 |
-
* </code>
|
37 |
-
*
|
38 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
39 |
-
* of this software and associated documentation files (the "Software"), to deal
|
40 |
-
* in the Software without restriction, including without limitation the rights
|
41 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
42 |
-
* copies of the Software, and to permit persons to whom the Software is
|
43 |
-
* furnished to do so, subject to the following conditions:
|
44 |
-
*
|
45 |
-
* The above copyright notice and this permission notice shall be included in
|
46 |
-
* all copies or substantial portions of the Software.
|
47 |
-
*
|
48 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
49 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
50 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
51 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
52 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
53 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
54 |
-
* THE SOFTWARE.
|
55 |
-
*
|
56 |
-
* @category Crypt
|
57 |
-
* @package Crypt_RC4
|
58 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
59 |
-
* @copyright MMVII Jim Wigginton
|
60 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
61 |
-
* @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
|
62 |
-
* @link http://phpseclib.sourceforge.net
|
63 |
-
*/
|
64 |
-
|
65 |
-
/**#@+
|
66 |
-
* @access private
|
67 |
-
* @see Crypt_RC4::Crypt_RC4()
|
68 |
-
*/
|
69 |
-
/**
|
70 |
-
* Toggles the internal implementation
|
71 |
-
*/
|
72 |
-
define('CRYPT_RC4_MODE_INTERNAL', 1);
|
73 |
-
/**
|
74 |
-
* Toggles the mcrypt implementation
|
75 |
-
*/
|
76 |
-
define('CRYPT_RC4_MODE_MCRYPT', 2);
|
77 |
-
/**#@-*/
|
78 |
-
|
79 |
-
/**#@+
|
80 |
-
* @access private
|
81 |
-
* @see Crypt_RC4::_crypt()
|
82 |
-
*/
|
83 |
-
define('CRYPT_RC4_ENCRYPT', 0);
|
84 |
-
define('CRYPT_RC4_DECRYPT', 1);
|
85 |
-
/**#@-*/
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Pure-PHP implementation of RC4.
|
89 |
-
*
|
90 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
91 |
-
* @version 0.1.0
|
92 |
-
* @access public
|
93 |
-
* @package Crypt_RC4
|
94 |
-
*/
|
95 |
-
class Crypt_RC4 {
|
96 |
-
/**
|
97 |
-
* The Key
|
98 |
-
*
|
99 |
-
* @see Crypt_RC4::setKey()
|
100 |
-
* @var String
|
101 |
-
* @access private
|
102 |
-
*/
|
103 |
-
var $key = "\0";
|
104 |
-
|
105 |
-
/**
|
106 |
-
* The Key Stream for encryption
|
107 |
-
*
|
108 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
109 |
-
*
|
110 |
-
* @see Crypt_RC4::setKey()
|
111 |
-
* @var Array
|
112 |
-
* @access private
|
113 |
-
*/
|
114 |
-
var $encryptStream = false;
|
115 |
-
|
116 |
-
/**
|
117 |
-
* The Key Stream for decryption
|
118 |
-
*
|
119 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
120 |
-
*
|
121 |
-
* @see Crypt_RC4::setKey()
|
122 |
-
* @var Array
|
123 |
-
* @access private
|
124 |
-
*/
|
125 |
-
var $decryptStream = false;
|
126 |
-
|
127 |
-
/**
|
128 |
-
* The $i and $j indexes for encryption
|
129 |
-
*
|
130 |
-
* @see Crypt_RC4::_crypt()
|
131 |
-
* @var Integer
|
132 |
-
* @access private
|
133 |
-
*/
|
134 |
-
var $encryptIndex = 0;
|
135 |
-
|
136 |
-
/**
|
137 |
-
* The $i and $j indexes for decryption
|
138 |
-
*
|
139 |
-
* @see Crypt_RC4::_crypt()
|
140 |
-
* @var Integer
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $decryptIndex = 0;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* MCrypt parameters
|
147 |
-
*
|
148 |
-
* @see Crypt_RC4::setMCrypt()
|
149 |
-
* @var Array
|
150 |
-
* @access private
|
151 |
-
*/
|
152 |
-
var $mcrypt = array('', '');
|
153 |
-
|
154 |
-
/**
|
155 |
-
* The Encryption Algorithm
|
156 |
-
*
|
157 |
-
* Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
|
158 |
-
*
|
159 |
-
* @see Crypt_RC4::Crypt_RC4()
|
160 |
-
* @var Integer
|
161 |
-
* @access private
|
162 |
-
*/
|
163 |
-
var $mode;
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Continuous Buffer status
|
167 |
-
*
|
168 |
-
* @see Crypt_RC4::enableContinuousBuffer()
|
169 |
-
* @var Boolean
|
170 |
-
* @access private
|
171 |
-
*/
|
172 |
-
var $continuousBuffer = false;
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Default Constructor.
|
176 |
-
*
|
177 |
-
* Determines whether or not the mcrypt extension should be used.
|
178 |
-
*
|
179 |
-
* @param optional Integer $mode
|
180 |
-
* @return Crypt_RC4
|
181 |
-
* @access public
|
182 |
-
*/
|
183 |
-
function Crypt_RC4()
|
184 |
-
{
|
185 |
-
if ( !defined('CRYPT_RC4_MODE') ) {
|
186 |
-
switch (true) {
|
187 |
-
case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')):
|
188 |
-
// i'd check to see if rc4 was supported, by doing in_array('arcfour', mcrypt_list_algorithms('')),
|
189 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
190 |
-
// a lot of point...
|
191 |
-
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
|
192 |
-
break;
|
193 |
-
default:
|
194 |
-
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
switch ( CRYPT_RC4_MODE ) {
|
199 |
-
case CRYPT_RC4_MODE_MCRYPT:
|
200 |
-
switch (true) {
|
201 |
-
case defined('MCRYPT_ARCFOUR'):
|
202 |
-
$this->mode = MCRYPT_ARCFOUR;
|
203 |
-
break;
|
204 |
-
case defined('MCRYPT_RC4');
|
205 |
-
$this->mode = MCRYPT_RC4;
|
206 |
-
}
|
207 |
-
}
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Sets the key.
|
212 |
-
*
|
213 |
-
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
|
214 |
-
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
|
215 |
-
*
|
216 |
-
* @access public
|
217 |
-
* @param String $key
|
218 |
-
*/
|
219 |
-
function setKey($key)
|
220 |
-
{
|
221 |
-
$this->key = $key;
|
222 |
-
|
223 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
224 |
-
return;
|
225 |
-
}
|
226 |
-
|
227 |
-
$keyLength = strlen($key);
|
228 |
-
$keyStream = array();
|
229 |
-
for ($i = 0; $i < 256; $i++) {
|
230 |
-
$keyStream[$i] = $i;
|
231 |
-
}
|
232 |
-
$j = 0;
|
233 |
-
for ($i = 0; $i < 256; $i++) {
|
234 |
-
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
|
235 |
-
$temp = $keyStream[$i];
|
236 |
-
$keyStream[$i] = $keyStream[$j];
|
237 |
-
$keyStream[$j] = $temp;
|
238 |
-
}
|
239 |
-
|
240 |
-
$this->encryptIndex = $this->decryptIndex = array(0, 0);
|
241 |
-
$this->encryptStream = $this->decryptStream = $keyStream;
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* Dummy function.
|
246 |
-
*
|
247 |
-
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
|
248 |
-
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
|
249 |
-
* calling setKey().
|
250 |
-
*
|
251 |
-
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
|
252 |
-
* the IV's are relatively easy to predict, an attack described by
|
253 |
-
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
|
254 |
-
* can be used to quickly guess at the rest of the key. The following links elaborate:
|
255 |
-
*
|
256 |
-
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
|
257 |
-
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
|
258 |
-
*
|
259 |
-
* @param String $iv
|
260 |
-
* @see Crypt_RC4::setKey()
|
261 |
-
* @access public
|
262 |
-
*/
|
263 |
-
function setIV($iv)
|
264 |
-
{
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* Sets MCrypt parameters. (optional)
|
269 |
-
*
|
270 |
-
* If MCrypt is being used, empty strings will be used, unless otherwise specified.
|
271 |
-
*
|
272 |
-
* @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
|
273 |
-
* @access public
|
274 |
-
* @param optional Integer $algorithm_directory
|
275 |
-
* @param optional Integer $mode_directory
|
276 |
-
*/
|
277 |
-
function setMCrypt($algorithm_directory = '', $mode_directory = '')
|
278 |
-
{
|
279 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
280 |
-
$this->mcrypt = array($algorithm_directory, $mode_directory);
|
281 |
-
$this->_closeMCrypt();
|
282 |
-
}
|
283 |
-
}
|
284 |
-
|
285 |
-
/**
|
286 |
-
* Encrypts a message.
|
287 |
-
*
|
288 |
-
* @see Crypt_RC4::_crypt()
|
289 |
-
* @access public
|
290 |
-
* @param String $plaintext
|
291 |
-
*/
|
292 |
-
function encrypt($plaintext)
|
293 |
-
{
|
294 |
-
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* Decrypts a message.
|
299 |
-
*
|
300 |
-
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
|
301 |
-
* Atleast if the continuous buffer is disabled.
|
302 |
-
*
|
303 |
-
* @see Crypt_RC4::_crypt()
|
304 |
-
* @access public
|
305 |
-
* @param String $ciphertext
|
306 |
-
*/
|
307 |
-
function decrypt($ciphertext)
|
308 |
-
{
|
309 |
-
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
|
310 |
-
}
|
311 |
-
|
312 |
-
/**
|
313 |
-
* Encrypts or decrypts a message.
|
314 |
-
*
|
315 |
-
* @see Crypt_RC4::encrypt()
|
316 |
-
* @see Crypt_RC4::decrypt()
|
317 |
-
* @access private
|
318 |
-
* @param String $text
|
319 |
-
* @param Integer $mode
|
320 |
-
*/
|
321 |
-
function _crypt($text, $mode)
|
322 |
-
{
|
323 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
324 |
-
$keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';
|
325 |
-
|
326 |
-
if ($this->$keyStream === false) {
|
327 |
-
$this->$keyStream = mcrypt_module_open($this->mode, $this->mcrypt[0], MCRYPT_MODE_STREAM, $this->mcrypt[1]);
|
328 |
-
mcrypt_generic_init($this->$keyStream, $this->key, '');
|
329 |
-
} else if (!$this->continuousBuffer) {
|
330 |
-
mcrypt_generic_init($this->$keyStream, $this->key, '');
|
331 |
-
}
|
332 |
-
$newText = mcrypt_generic($this->$keyStream, $text);
|
333 |
-
if (!$this->continuousBuffer) {
|
334 |
-
mcrypt_generic_deinit($this->$keyStream);
|
335 |
-
}
|
336 |
-
|
337 |
-
return $newText;
|
338 |
-
}
|
339 |
-
|
340 |
-
if ($this->encryptStream === false) {
|
341 |
-
$this->setKey($this->key);
|
342 |
-
}
|
343 |
-
|
344 |
-
switch ($mode) {
|
345 |
-
case CRYPT_RC4_ENCRYPT:
|
346 |
-
$keyStream = $this->encryptStream;
|
347 |
-
list($i, $j) = $this->encryptIndex;
|
348 |
-
break;
|
349 |
-
case CRYPT_RC4_DECRYPT:
|
350 |
-
$keyStream = $this->decryptStream;
|
351 |
-
list($i, $j) = $this->decryptIndex;
|
352 |
-
}
|
353 |
-
|
354 |
-
$newText = '';
|
355 |
-
for ($k = 0; $k < strlen($text); $k++) {
|
356 |
-
$i = ($i + 1) & 255;
|
357 |
-
$j = ($j + $keyStream[$i]) & 255;
|
358 |
-
$temp = $keyStream[$i];
|
359 |
-
$keyStream[$i] = $keyStream[$j];
|
360 |
-
$keyStream[$j] = $temp;
|
361 |
-
$temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];
|
362 |
-
$newText.= chr(ord($text[$k]) ^ $temp);
|
363 |
-
}
|
364 |
-
|
365 |
-
if ($this->continuousBuffer) {
|
366 |
-
switch ($mode) {
|
367 |
-
case CRYPT_RC4_ENCRYPT:
|
368 |
-
$this->encryptStream = $keyStream;
|
369 |
-
$this->encryptIndex = array($i, $j);
|
370 |
-
break;
|
371 |
-
case CRYPT_RC4_DECRYPT:
|
372 |
-
$this->decryptStream = $keyStream;
|
373 |
-
$this->decryptIndex = array($i, $j);
|
374 |
-
}
|
375 |
-
}
|
376 |
-
|
377 |
-
return $newText;
|
378 |
-
}
|
379 |
-
|
380 |
-
/**
|
381 |
-
* Treat consecutive "packets" as if they are a continuous buffer.
|
382 |
-
*
|
383 |
-
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
384 |
-
* will yield different outputs:
|
385 |
-
*
|
386 |
-
* <code>
|
387 |
-
* echo $rc4->encrypt(substr($plaintext, 0, 8));
|
388 |
-
* echo $rc4->encrypt(substr($plaintext, 8, 8));
|
389 |
-
* </code>
|
390 |
-
* <code>
|
391 |
-
* echo $rc4->encrypt($plaintext);
|
392 |
-
* </code>
|
393 |
-
*
|
394 |
-
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
395 |
-
* another, as demonstrated with the following:
|
396 |
-
*
|
397 |
-
* <code>
|
398 |
-
* $rc4->encrypt(substr($plaintext, 0, 8));
|
399 |
-
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
400 |
-
* </code>
|
401 |
-
* <code>
|
402 |
-
* echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
|
403 |
-
* </code>
|
404 |
-
*
|
405 |
-
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
406 |
-
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
407 |
-
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
408 |
-
*
|
409 |
-
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
410 |
-
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
411 |
-
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
412 |
-
* however, they are also less intuitive and more likely to cause you problems.
|
413 |
-
*
|
414 |
-
* @see Crypt_RC4::disableContinuousBuffer()
|
415 |
-
* @access public
|
416 |
-
*/
|
417 |
-
function enableContinuousBuffer()
|
418 |
-
{
|
419 |
-
$this->continuousBuffer = true;
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* Treat consecutive packets as if they are a discontinuous buffer.
|
424 |
-
*
|
425 |
-
* The default behavior.
|
426 |
-
*
|
427 |
-
* @see Crypt_RC4::enableContinuousBuffer()
|
428 |
-
* @access public
|
429 |
-
*/
|
430 |
-
function disableContinuousBuffer()
|
431 |
-
{
|
432 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {
|
433 |
-
$this->encryptIndex = $this->decryptIndex = array(0, 0);
|
434 |
-
$this->setKey($this->key);
|
435 |
-
}
|
436 |
-
|
437 |
-
$this->continuousBuffer = false;
|
438 |
-
}
|
439 |
-
|
440 |
-
/**
|
441 |
-
* Dummy function.
|
442 |
-
*
|
443 |
-
* Since RC4 is a stream cipher and not a block cipher, no padding is necessary. The only reason this function is
|
444 |
-
* included is so that you can switch between a block cipher and a stream cipher transparently.
|
445 |
-
*
|
446 |
-
* @see Crypt_RC4::disablePadding()
|
447 |
-
* @access public
|
448 |
-
*/
|
449 |
-
function enablePadding()
|
450 |
-
{
|
451 |
-
}
|
452 |
-
|
453 |
-
/**
|
454 |
-
* Dummy function.
|
455 |
-
*
|
456 |
-
* @see Crypt_RC4::enablePadding()
|
457 |
-
* @access public
|
458 |
-
*/
|
459 |
-
function disablePadding()
|
460 |
-
{
|
461 |
-
}
|
462 |
-
|
463 |
-
/**
|
464 |
-
* Class destructor.
|
465 |
-
*
|
466 |
-
* Will be called, automatically, if you're using PHP5. If you're using PHP4, call it yourself. Only really
|
467 |
-
* needs to be called if mcrypt is being used.
|
468 |
-
*
|
469 |
-
* @access public
|
470 |
-
*/
|
471 |
-
function __destruct()
|
472 |
-
{
|
473 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
474 |
-
$this->_closeMCrypt();
|
475 |
-
}
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* Properly close the MCrypt objects.
|
480 |
-
*
|
481 |
-
* @access prviate
|
482 |
-
*/
|
483 |
-
function _closeMCrypt()
|
484 |
-
{
|
485 |
-
if ( $this->encryptStream !== false ) {
|
486 |
-
if ( $this->continuousBuffer ) {
|
487 |
-
mcrypt_generic_deinit($this->encryptStream);
|
488 |
-
}
|
489 |
-
|
490 |
-
mcrypt_module_close($this->encryptStream);
|
491 |
-
|
492 |
-
$this->encryptStream = false;
|
493 |
-
}
|
494 |
-
|
495 |
-
if ( $this->decryptStream !== false ) {
|
496 |
-
if ( $this->continuousBuffer ) {
|
497 |
-
mcrypt_generic_deinit($this->decryptStream);
|
498 |
-
}
|
499 |
-
|
500 |
-
mcrypt_module_close($this->decryptStream);
|
501 |
-
|
502 |
-
$this->decryptStream = false;
|
503 |
-
}
|
504 |
-
}
|
505 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/Random.php
DELETED
@@ -1,133 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Random Number Generator
|
6 |
-
*
|
7 |
-
* PHP versions 4 and 5
|
8 |
-
*
|
9 |
-
* Here's a short example of how to use this library:
|
10 |
-
* <code>
|
11 |
-
* <?php
|
12 |
-
* include('Crypt/Random.php');
|
13 |
-
*
|
14 |
-
* echo crypt_random();
|
15 |
-
* ?>
|
16 |
-
* </code>
|
17 |
-
*
|
18 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
19 |
-
* of this software and associated documentation files (the "Software"), to deal
|
20 |
-
* in the Software without restriction, including without limitation the rights
|
21 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
22 |
-
* copies of the Software, and to permit persons to whom the Software is
|
23 |
-
* furnished to do so, subject to the following conditions:
|
24 |
-
*
|
25 |
-
* The above copyright notice and this permission notice shall be included in
|
26 |
-
* all copies or substantial portions of the Software.
|
27 |
-
*
|
28 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
29 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
30 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
31 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
32 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
33 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
34 |
-
* THE SOFTWARE.
|
35 |
-
*
|
36 |
-
* @category Crypt
|
37 |
-
* @package Crypt_Random
|
38 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
39 |
-
* @copyright MMVII Jim Wigginton
|
40 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
41 |
-
* @version $Id: Random.php,v 1.9 2010/04/24 06:40:48 terrafrost Exp $
|
42 |
-
* @link http://phpseclib.sourceforge.net
|
43 |
-
*/
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Generate a random value.
|
47 |
-
*
|
48 |
-
* On 32-bit machines, the largest distance that can exist between $min and $max is 2**31.
|
49 |
-
* If $min and $max are farther apart than that then the last ($max - range) numbers.
|
50 |
-
*
|
51 |
-
* Depending on how this is being used, it may be worth while to write a replacement. For example,
|
52 |
-
* a PHP-based web app that stores its data in an SQL database can collect more entropy than this function
|
53 |
-
* can.
|
54 |
-
*
|
55 |
-
* @param optional Integer $min
|
56 |
-
* @param optional Integer $max
|
57 |
-
* @return Integer
|
58 |
-
* @access public
|
59 |
-
*/
|
60 |
-
function crypt_random($min = 0, $max = 0x7FFFFFFF)
|
61 |
-
{
|
62 |
-
if ($min == $max) {
|
63 |
-
return $min;
|
64 |
-
}
|
65 |
-
|
66 |
-
// see http://en.wikipedia.org/wiki//dev/random
|
67 |
-
static $urandom = true;
|
68 |
-
if ($urandom === true) {
|
69 |
-
// Warning's will be output unles the error suppression operator is used. Errors such as
|
70 |
-
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
|
71 |
-
$urandom = @fopen('/dev/urandom', 'rb');
|
72 |
-
}
|
73 |
-
if (!is_bool($urandom)) {
|
74 |
-
extract(unpack('Nrandom', fread($urandom, 4)));
|
75 |
-
|
76 |
-
// say $min = 0 and $max = 3. if we didn't do abs() then we could have stuff like this:
|
77 |
-
// -4 % 3 + 0 = -1, even though -1 < $min
|
78 |
-
return abs($random) % ($max - $min) + $min;
|
79 |
-
}
|
80 |
-
|
81 |
-
/* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.
|
82 |
-
Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:
|
83 |
-
|
84 |
-
http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
|
85 |
-
|
86 |
-
The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:
|
87 |
-
|
88 |
-
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_2/ext/standard/php_rand.h?view=markup */
|
89 |
-
if (version_compare(PHP_VERSION, '5.2.5', '<=')) {
|
90 |
-
static $seeded;
|
91 |
-
if (!isset($seeded)) {
|
92 |
-
$seeded = true;
|
93 |
-
mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
static $crypto;
|
98 |
-
|
99 |
-
// The CSPRNG's Yarrow and Fortuna periodically reseed. This function can be reseeded by hitting F5
|
100 |
-
// in the browser and reloading the page.
|
101 |
-
|
102 |
-
if (!isset($crypto)) {
|
103 |
-
$key = $iv = '';
|
104 |
-
for ($i = 0; $i < 8; $i++) {
|
105 |
-
$key.= pack('n', mt_rand(0, 0xFFFF));
|
106 |
-
$iv .= pack('n', mt_rand(0, 0xFFFF));
|
107 |
-
}
|
108 |
-
switch (true) {
|
109 |
-
case class_exists('Crypt_AES'):
|
110 |
-
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
111 |
-
break;
|
112 |
-
case class_exists('Crypt_TripleDES'):
|
113 |
-
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
114 |
-
break;
|
115 |
-
case class_exists('Crypt_DES'):
|
116 |
-
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
117 |
-
break;
|
118 |
-
case class_exists('Crypt_RC4'):
|
119 |
-
$crypto = new Crypt_RC4();
|
120 |
-
break;
|
121 |
-
default:
|
122 |
-
extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF)))));
|
123 |
-
return abs($random) % ($max - $min) + $min;
|
124 |
-
}
|
125 |
-
$crypto->setKey($key);
|
126 |
-
$crypto->setIV($iv);
|
127 |
-
$crypto->enableContinuousBuffer();
|
128 |
-
}
|
129 |
-
|
130 |
-
extract(unpack('Nrandom', $crypto->encrypt("\0\0\0\0")));
|
131 |
-
return abs($random) % ($max - $min) + $min;
|
132 |
-
}
|
133 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/phpseclib/Crypt/Rijndael.php
DELETED
@@ -1,1424 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of Rijndael.
|
6 |
-
*
|
7 |
-
* Does not use mcrypt, even when available, for reasons that are explained below.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
12 |
-
* {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
13 |
-
* {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
14 |
-
* 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until
|
15 |
-
* {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
16 |
-
*
|
17 |
-
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
18 |
-
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
19 |
-
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
|
20 |
-
* algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
|
21 |
-
* are first defined as valid key / block lengths in
|
22 |
-
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
|
23 |
-
* Extensions: Other block and Cipher Key lengths.
|
24 |
-
*
|
25 |
-
* {@internal The variable names are the same as those in
|
26 |
-
* {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
|
27 |
-
*
|
28 |
-
* Here's a short example of how to use this library:
|
29 |
-
* <code>
|
30 |
-
* <?php
|
31 |
-
* include('Crypt/Rijndael.php');
|
32 |
-
*
|
33 |
-
* $rijndael = new Crypt_Rijndael();
|
34 |
-
*
|
35 |
-
* $rijndael->setKey('abcdefghijklmnop');
|
36 |
-
*
|
37 |
-
* $size = 10 * 1024;
|
38 |
-
* $plaintext = '';
|
39 |
-
* for ($i = 0; $i < $size; $i++) {
|
40 |
-
* $plaintext.= 'a';
|
41 |
-
* }
|
42 |
-
*
|
43 |
-
* echo $rijndael->decrypt($rijndael->encrypt($plaintext));
|
44 |
-
* ?>
|
45 |
-
* </code>
|
46 |
-
*
|
47 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
48 |
-
* of this software and associated documentation files (the "Software"), to deal
|
49 |
-
* in the Software without restriction, including without limitation the rights
|
50 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
51 |
-
* copies of the Software, and to permit persons to whom the Software is
|
52 |
-
* furnished to do so, subject to the following conditions:
|
53 |
-
*
|
54 |
-
* The above copyright notice and this permission notice shall be included in
|
55 |
-
* all copies or substantial portions of the Software.
|
56 |
-
*
|
57 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
58 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
59 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
60 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
61 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
62 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
63 |
-
* THE SOFTWARE.
|
64 |
-
*
|
65 |
-
* @category Crypt
|
66 |
-
* @package Crypt_Rijndael
|
67 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
68 |
-
* @copyright MMVIII Jim Wigginton
|
69 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
70 |
-
* @version $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
|
71 |
-
* @link http://phpseclib.sourceforge.net
|
72 |
-
*/
|
73 |
-
|
74 |
-
/**#@+
|
75 |
-
* @access public
|
76 |
-
* @see Crypt_Rijndael::encrypt()
|
77 |
-
* @see Crypt_Rijndael::decrypt()
|
78 |
-
*/
|
79 |
-
/**
|
80 |
-
* Encrypt / decrypt using the Counter mode.
|
81 |
-
*
|
82 |
-
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
83 |
-
*
|
84 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
85 |
-
*/
|
86 |
-
define('CRYPT_RIJNDAEL_MODE_CTR', -1);
|
87 |
-
/**
|
88 |
-
* Encrypt / decrypt using the Electronic Code Book mode.
|
89 |
-
*
|
90 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
91 |
-
*/
|
92 |
-
define('CRYPT_RIJNDAEL_MODE_ECB', 1);
|
93 |
-
/**
|
94 |
-
* Encrypt / decrypt using the Code Book Chaining mode.
|
95 |
-
*
|
96 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
97 |
-
*/
|
98 |
-
define('CRYPT_RIJNDAEL_MODE_CBC', 2);
|
99 |
-
/**
|
100 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
101 |
-
*
|
102 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
103 |
-
*/
|
104 |
-
define('CRYPT_RIJNDAEL_MODE_CFB', 3);
|
105 |
-
/**
|
106 |
-
* Encrypt / decrypt using the Cipher Feedback mode.
|
107 |
-
*
|
108 |
-
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
109 |
-
*/
|
110 |
-
define('CRYPT_RIJNDAEL_MODE_OFB', 4);
|
111 |
-
/**#@-*/
|
112 |
-
|
113 |
-
/**#@+
|
114 |
-
* @access private
|
115 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
116 |
-
*/
|
117 |
-
/**
|
118 |
-
* Toggles the internal implementation
|
119 |
-
*/
|
120 |
-
define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);
|
121 |
-
/**
|
122 |
-
* Toggles the mcrypt implementation
|
123 |
-
*/
|
124 |
-
define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);
|
125 |
-
/**#@-*/
|
126 |
-
|
127 |
-
/**
|
128 |
-
* Pure-PHP implementation of Rijndael.
|
129 |
-
*
|
130 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
131 |
-
* @version 0.1.0
|
132 |
-
* @access public
|
133 |
-
* @package Crypt_Rijndael
|
134 |
-
*/
|
135 |
-
class Crypt_Rijndael {
|
136 |
-
/**
|
137 |
-
* The Encryption Mode
|
138 |
-
*
|
139 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
140 |
-
* @var Integer
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $mode;
|
144 |
-
|
145 |
-
/**
|
146 |
-
* The Key
|
147 |
-
*
|
148 |
-
* @see Crypt_Rijndael::setKey()
|
149 |
-
* @var String
|
150 |
-
* @access private
|
151 |
-
*/
|
152 |
-
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
153 |
-
|
154 |
-
/**
|
155 |
-
* The Initialization Vector
|
156 |
-
*
|
157 |
-
* @see Crypt_Rijndael::setIV()
|
158 |
-
* @var String
|
159 |
-
* @access private
|
160 |
-
*/
|
161 |
-
var $iv = '';
|
162 |
-
|
163 |
-
/**
|
164 |
-
* A "sliding" Initialization Vector
|
165 |
-
*
|
166 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
167 |
-
* @var String
|
168 |
-
* @access private
|
169 |
-
*/
|
170 |
-
var $encryptIV = '';
|
171 |
-
|
172 |
-
/**
|
173 |
-
* A "sliding" Initialization Vector
|
174 |
-
*
|
175 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
176 |
-
* @var String
|
177 |
-
* @access private
|
178 |
-
*/
|
179 |
-
var $decryptIV = '';
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Continuous Buffer status
|
183 |
-
*
|
184 |
-
* @see Crypt_Rijndael::enableContinuousBuffer()
|
185 |
-
* @var Boolean
|
186 |
-
* @access private
|
187 |
-
*/
|
188 |
-
var $continuousBuffer = false;
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Padding status
|
192 |
-
*
|
193 |
-
* @see Crypt_Rijndael::enablePadding()
|
194 |
-
* @var Boolean
|
195 |
-
* @access private
|
196 |
-
*/
|
197 |
-
var $padding = true;
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Does the key schedule need to be (re)calculated?
|
201 |
-
*
|
202 |
-
* @see setKey()
|
203 |
-
* @see setBlockLength()
|
204 |
-
* @see setKeyLength()
|
205 |
-
* @var Boolean
|
206 |
-
* @access private
|
207 |
-
*/
|
208 |
-
var $changed = true;
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Has the key length explicitly been set or should it be derived from the key, itself?
|
212 |
-
*
|
213 |
-
* @see setKeyLength()
|
214 |
-
* @var Boolean
|
215 |
-
* @access private
|
216 |
-
*/
|
217 |
-
var $explicit_key_length = false;
|
218 |
-
|
219 |
-
/**
|
220 |
-
* The Key Schedule
|
221 |
-
*
|
222 |
-
* @see _setup()
|
223 |
-
* @var Array
|
224 |
-
* @access private
|
225 |
-
*/
|
226 |
-
var $w;
|
227 |
-
|
228 |
-
/**
|
229 |
-
* The Inverse Key Schedule
|
230 |
-
*
|
231 |
-
* @see _setup()
|
232 |
-
* @var Array
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
var $dw;
|
236 |
-
|
237 |
-
/**
|
238 |
-
* The Block Length
|
239 |
-
*
|
240 |
-
* @see setBlockLength()
|
241 |
-
* @var Integer
|
242 |
-
* @access private
|
243 |
-
* @internal The max value is 32, the min value is 16. All valid values are multiples of 4. Exists in conjunction with
|
244 |
-
* $Nb because we need this value and not $Nb to pad strings appropriately.
|
245 |
-
*/
|
246 |
-
var $block_size = 16;
|
247 |
-
|
248 |
-
/**
|
249 |
-
* The Block Length divided by 32
|
250 |
-
*
|
251 |
-
* @see setBlockLength()
|
252 |
-
* @var Integer
|
253 |
-
* @access private
|
254 |
-
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
255 |
-
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
256 |
-
* derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
257 |
-
* of that, we'll just precompute it once.
|
258 |
-
*
|
259 |
-
*/
|
260 |
-
var $Nb = 4;
|
261 |
-
|
262 |
-
/**
|
263 |
-
* The Key Length
|
264 |
-
*
|
265 |
-
* @see setKeyLength()
|
266 |
-
* @var Integer
|
267 |
-
* @access private
|
268 |
-
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $key_size
|
269 |
-
* because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
|
270 |
-
* derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
271 |
-
* of that, we'll just precompute it once.
|
272 |
-
*/
|
273 |
-
var $key_size = 16;
|
274 |
-
|
275 |
-
/**
|
276 |
-
* The Key Length divided by 32
|
277 |
-
*
|
278 |
-
* @see setKeyLength()
|
279 |
-
* @var Integer
|
280 |
-
* @access private
|
281 |
-
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
282 |
-
*/
|
283 |
-
var $Nk = 4;
|
284 |
-
|
285 |
-
/**
|
286 |
-
* The Number of Rounds
|
287 |
-
*
|
288 |
-
* @var Integer
|
289 |
-
* @access private
|
290 |
-
* @internal The max value is 14, the min value is 10.
|
291 |
-
*/
|
292 |
-
var $Nr;
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Shift offsets
|
296 |
-
*
|
297 |
-
* @var Array
|
298 |
-
* @access private
|
299 |
-
*/
|
300 |
-
var $c;
|
301 |
-
|
302 |
-
/**
|
303 |
-
* Precomputed mixColumns table
|
304 |
-
*
|
305 |
-
* @see Crypt_Rijndael()
|
306 |
-
* @var Array
|
307 |
-
* @access private
|
308 |
-
*/
|
309 |
-
var $t0;
|
310 |
-
|
311 |
-
/**
|
312 |
-
* Precomputed mixColumns table
|
313 |
-
*
|
314 |
-
* @see Crypt_Rijndael()
|
315 |
-
* @var Array
|
316 |
-
* @access private
|
317 |
-
*/
|
318 |
-
var $t1;
|
319 |
-
|
320 |
-
/**
|
321 |
-
* Precomputed mixColumns table
|
322 |
-
*
|
323 |
-
* @see Crypt_Rijndael()
|
324 |
-
* @var Array
|
325 |
-
* @access private
|
326 |
-
*/
|
327 |
-
var $t2;
|
328 |
-
|
329 |
-
/**
|
330 |
-
* Precomputed mixColumns table
|
331 |
-
*
|
332 |
-
* @see Crypt_Rijndael()
|
333 |
-
* @var Array
|
334 |
-
* @access private
|
335 |
-
*/
|
336 |
-
var $t3;
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Precomputed invMixColumns table
|
340 |
-
*
|
341 |
-
* @see Crypt_Rijndael()
|
342 |
-
* @var Array
|
343 |
-
* @access private
|
344 |
-
*/
|
345 |
-
var $dt0;
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Precomputed invMixColumns table
|
349 |
-
*
|
350 |
-
* @see Crypt_Rijndael()
|
351 |
-
* @var Array
|
352 |
-
* @access private
|
353 |
-
*/
|
354 |
-
var $dt1;
|
355 |
-
|
356 |
-
/**
|
357 |
-
* Precomputed invMixColumns table
|
358 |
-
*
|
359 |
-
* @see Crypt_Rijndael()
|
360 |
-
* @var Array
|
361 |
-
* @access private
|
362 |
-
*/
|
363 |
-
var $dt2;
|
364 |
-
|
365 |
-
/**
|
366 |
-
* Precomputed invMixColumns table
|
367 |
-
*
|
368 |
-
* @see Crypt_Rijndael()
|
369 |
-
* @var Array
|
370 |
-
* @access private
|
371 |
-
*/
|
372 |
-
var $dt3;
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Is the mode one that is paddable?
|
376 |
-
*
|
377 |
-
* @see Crypt_Rijndael::Crypt_Rijndael()
|
378 |
-
* @var Boolean
|
379 |
-
* @access private
|
380 |
-
*/
|
381 |
-
var $paddable = false;
|
382 |
-
|
383 |
-
/**
|
384 |
-
* Encryption buffer for CTR, OFB and CFB modes
|
385 |
-
*
|
386 |
-
* @see Crypt_Rijndael::encrypt()
|
387 |
-
* @var String
|
388 |
-
* @access private
|
389 |
-
*/
|
390 |
-
var $enbuffer = array('encrypted' => '', 'xor' => '');
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Decryption buffer for CTR, OFB and CFB modes
|
394 |
-
*
|
395 |
-
* @see Crypt_Rijndael::decrypt()
|
396 |
-
* @var String
|
397 |
-
* @access private
|
398 |
-
*/
|
399 |
-
var $debuffer = array('ciphertext' => '');
|
400 |
-
|
401 |
-
/**
|
402 |
-
* Default Constructor.
|
403 |
-
*
|
404 |
-
* Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
|
405 |
-
* CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC. If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
|
406 |
-
*
|
407 |
-
* @param optional Integer $mode
|
408 |
-
* @return Crypt_Rijndael
|
409 |
-
* @access public
|
410 |
-
*/
|
411 |
-
function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
|
412 |
-
{
|
413 |
-
switch ($mode) {
|
414 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
415 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
416 |
-
$this->paddable = true;
|
417 |
-
$this->mode = $mode;
|
418 |
-
break;
|
419 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
420 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
421 |
-
case CRYPT_RIJNDAEL_MODE_OFB:
|
422 |
-
$this->mode = $mode;
|
423 |
-
break;
|
424 |
-
default:
|
425 |
-
$this->paddable = true;
|
426 |
-
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
427 |
-
}
|
428 |
-
|
429 |
-
$t3 = &$this->t3;
|
430 |
-
$t2 = &$this->t2;
|
431 |
-
$t1 = &$this->t1;
|
432 |
-
$t0 = &$this->t0;
|
433 |
-
|
434 |
-
$dt3 = &$this->dt3;
|
435 |
-
$dt2 = &$this->dt2;
|
436 |
-
$dt1 = &$this->dt1;
|
437 |
-
$dt0 = &$this->dt0;
|
438 |
-
|
439 |
-
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
|
440 |
-
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
|
441 |
-
// those are the names we'll use.
|
442 |
-
$t3 = array(
|
443 |
-
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
444 |
-
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
445 |
-
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
446 |
-
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
447 |
-
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
448 |
-
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
449 |
-
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
450 |
-
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
451 |
-
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
452 |
-
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
453 |
-
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
454 |
-
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
455 |
-
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
456 |
-
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
457 |
-
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
458 |
-
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
459 |
-
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
460 |
-
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
461 |
-
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
462 |
-
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
463 |
-
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
464 |
-
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
465 |
-
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
466 |
-
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
467 |
-
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
468 |
-
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
469 |
-
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
470 |
-
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
471 |
-
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
472 |
-
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
473 |
-
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
474 |
-
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
|
475 |
-
);
|
476 |
-
|
477 |
-
$dt3 = array(
|
478 |
-
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
|
479 |
-
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
|
480 |
-
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
|
481 |
-
0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
|
482 |
-
0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
|
483 |
-
0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
|
484 |
-
0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
|
485 |
-
0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
|
486 |
-
0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
|
487 |
-
0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
|
488 |
-
0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
|
489 |
-
0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
|
490 |
-
0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
|
491 |
-
0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
|
492 |
-
0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
|
493 |
-
0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
|
494 |
-
0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
|
495 |
-
0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
|
496 |
-
0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
|
497 |
-
0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
|
498 |
-
0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
|
499 |
-
0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
|
500 |
-
0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
|
501 |
-
0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
|
502 |
-
0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
|
503 |
-
0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
|
504 |
-
0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
|
505 |
-
0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
|
506 |
-
0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
|
507 |
-
0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
|
508 |
-
0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
|
509 |
-
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
|
510 |
-
);
|
511 |
-
|
512 |
-
for ($i = 0; $i < 256; $i++) {
|
513 |
-
$t2[$i << 8] = (($t3[$i] << 8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF);
|
514 |
-
$t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF);
|
515 |
-
$t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >> 8) & 0x00FFFFFF);
|
516 |
-
|
517 |
-
$dt2[$i << 8] = (($this->dt3[$i] << 8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF);
|
518 |
-
$dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF);
|
519 |
-
$dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >> 8) & 0x00FFFFFF);
|
520 |
-
}
|
521 |
-
}
|
522 |
-
|
523 |
-
/**
|
524 |
-
* Sets the key.
|
525 |
-
*
|
526 |
-
* Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
|
527 |
-
* whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
|
528 |
-
* up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
|
529 |
-
* excess bits.
|
530 |
-
*
|
531 |
-
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
532 |
-
*
|
533 |
-
* @access public
|
534 |
-
* @param String $key
|
535 |
-
*/
|
536 |
-
function setKey($key)
|
537 |
-
{
|
538 |
-
$this->key = $key;
|
539 |
-
$this->changed = true;
|
540 |
-
}
|
541 |
-
|
542 |
-
/**
|
543 |
-
* Sets the initialization vector. (optional)
|
544 |
-
*
|
545 |
-
* SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed
|
546 |
-
* to be all zero's.
|
547 |
-
*
|
548 |
-
* @access public
|
549 |
-
* @param String $iv
|
550 |
-
*/
|
551 |
-
function setIV($iv)
|
552 |
-
{
|
553 |
-
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0));;
|
554 |
-
}
|
555 |
-
|
556 |
-
/**
|
557 |
-
* Sets the key length
|
558 |
-
*
|
559 |
-
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
560 |
-
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
561 |
-
*
|
562 |
-
* @access public
|
563 |
-
* @param Integer $length
|
564 |
-
*/
|
565 |
-
function setKeyLength($length)
|
566 |
-
{
|
567 |
-
$length >>= 5;
|
568 |
-
if ($length > 8) {
|
569 |
-
$length = 8;
|
570 |
-
} else if ($length < 4) {
|
571 |
-
$length = 4;
|
572 |
-
}
|
573 |
-
$this->Nk = $length;
|
574 |
-
$this->key_size = $length << 2;
|
575 |
-
|
576 |
-
$this->explicit_key_length = true;
|
577 |
-
$this->changed = true;
|
578 |
-
}
|
579 |
-
|
580 |
-
/**
|
581 |
-
* Sets the block length
|
582 |
-
*
|
583 |
-
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
584 |
-
* 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
|
585 |
-
*
|
586 |
-
* @access public
|
587 |
-
* @param Integer $length
|
588 |
-
*/
|
589 |
-
function setBlockLength($length)
|
590 |
-
{
|
591 |
-
$length >>= 5;
|
592 |
-
if ($length > 8) {
|
593 |
-
$length = 8;
|
594 |
-
} else if ($length < 4) {
|
595 |
-
$length = 4;
|
596 |
-
}
|
597 |
-
$this->Nb = $length;
|
598 |
-
$this->block_size = $length << 2;
|
599 |
-
$this->changed = true;
|
600 |
-
}
|
601 |
-
|
602 |
-
/**
|
603 |
-
* Generate CTR XOR encryption key
|
604 |
-
*
|
605 |
-
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
606 |
-
* plaintext / ciphertext in CTR mode.
|
607 |
-
*
|
608 |
-
* @see Crypt_Rijndael::decrypt()
|
609 |
-
* @see Crypt_Rijndael::encrypt()
|
610 |
-
* @access public
|
611 |
-
* @param Integer $length
|
612 |
-
* @param String $iv
|
613 |
-
*/
|
614 |
-
function _generate_xor($length, &$iv)
|
615 |
-
{
|
616 |
-
$xor = '';
|
617 |
-
$block_size = $this->block_size;
|
618 |
-
$num_blocks = floor(($length + ($block_size - 1)) / $block_size);
|
619 |
-
for ($i = 0; $i < $num_blocks; $i++) {
|
620 |
-
$xor.= $iv;
|
621 |
-
for ($j = 4; $j <= $block_size; $j+=4) {
|
622 |
-
$temp = substr($iv, -$j, 4);
|
623 |
-
switch ($temp) {
|
624 |
-
case "\xFF\xFF\xFF\xFF":
|
625 |
-
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
626 |
-
break;
|
627 |
-
case "\x7F\xFF\xFF\xFF":
|
628 |
-
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
629 |
-
break 2;
|
630 |
-
default:
|
631 |
-
extract(unpack('Ncount', $temp));
|
632 |
-
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
633 |
-
break 2;
|
634 |
-
}
|
635 |
-
}
|
636 |
-
}
|
637 |
-
|
638 |
-
return $xor;
|
639 |
-
}
|
640 |
-
|
641 |
-
/**
|
642 |
-
* Encrypts a message.
|
643 |
-
*
|
644 |
-
* $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other Rjindael
|
645 |
-
* implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
|
646 |
-
* necessary are discussed in the following
|
647 |
-
* URL:
|
648 |
-
*
|
649 |
-
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
650 |
-
*
|
651 |
-
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
652 |
-
* strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
|
653 |
-
* length.
|
654 |
-
*
|
655 |
-
* @see Crypt_Rijndael::decrypt()
|
656 |
-
* @access public
|
657 |
-
* @param String $plaintext
|
658 |
-
*/
|
659 |
-
function encrypt($plaintext)
|
660 |
-
{
|
661 |
-
$this->_setup();
|
662 |
-
if ($this->paddable) {
|
663 |
-
$plaintext = $this->_pad($plaintext);
|
664 |
-
}
|
665 |
-
|
666 |
-
$block_size = $this->block_size;
|
667 |
-
$buffer = &$this->enbuffer;
|
668 |
-
$continuousBuffer = $this->continuousBuffer;
|
669 |
-
$ciphertext = '';
|
670 |
-
switch ($this->mode) {
|
671 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
672 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
673 |
-
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
|
674 |
-
}
|
675 |
-
break;
|
676 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
677 |
-
$xor = $this->encryptIV;
|
678 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
679 |
-
$block = substr($plaintext, $i, $block_size);
|
680 |
-
$block = $this->_encryptBlock($block ^ $xor);
|
681 |
-
$xor = $block;
|
682 |
-
$ciphertext.= $block;
|
683 |
-
}
|
684 |
-
if ($this->continuousBuffer) {
|
685 |
-
$this->encryptIV = $xor;
|
686 |
-
}
|
687 |
-
break;
|
688 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
689 |
-
$xor = $this->encryptIV;
|
690 |
-
if (!empty($buffer)) {
|
691 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
692 |
-
$block = substr($plaintext, $i, $block_size);
|
693 |
-
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
694 |
-
$key = $this->_string_shift($buffer, $block_size);
|
695 |
-
$ciphertext.= $block ^ $key;
|
696 |
-
}
|
697 |
-
} else {
|
698 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
699 |
-
$block = substr($plaintext, $i, $block_size);
|
700 |
-
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
701 |
-
$ciphertext.= $block ^ $key;
|
702 |
-
}
|
703 |
-
}
|
704 |
-
if ($this->continuousBuffer) {
|
705 |
-
$this->encryptIV = $xor;
|
706 |
-
if ($start = strlen($plaintext) % $block_size) {
|
707 |
-
$buffer = substr($key, $start) . $buffer;
|
708 |
-
}
|
709 |
-
}
|
710 |
-
break;
|
711 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
712 |
-
if (!empty($buffer['xor'])) {
|
713 |
-
$ciphertext = $plaintext ^ $buffer['xor'];
|
714 |
-
$iv = $buffer['encrypted'] . $ciphertext;
|
715 |
-
$start = strlen($ciphertext);
|
716 |
-
$buffer['encrypted'].= $ciphertext;
|
717 |
-
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
718 |
-
} else {
|
719 |
-
$ciphertext = '';
|
720 |
-
$iv = $this->encryptIV;
|
721 |
-
$start = 0;
|
722 |
-
}
|
723 |
-
|
724 |
-
for ($i = $start; $i < strlen($plaintext); $i+=$block_size) {
|
725 |
-
$block = substr($plaintext, $i, $block_size);
|
726 |
-
$xor = $this->_encryptBlock($iv);
|
727 |
-
$iv = $block ^ $xor;
|
728 |
-
if ($continuousBuffer && strlen($iv) != $block_size) {
|
729 |
-
$buffer = array(
|
730 |
-
'encrypted' => $iv,
|
731 |
-
'xor' => substr($xor, strlen($iv))
|
732 |
-
);
|
733 |
-
}
|
734 |
-
$ciphertext.= $iv;
|
735 |
-
}
|
736 |
-
|
737 |
-
if ($this->continuousBuffer) {
|
738 |
-
$this->encryptIV = $iv;
|
739 |
-
}
|
740 |
-
break;
|
741 |
-
case CRYPT_RIJNDAEL_MODE_OFB:
|
742 |
-
$xor = $this->encryptIV;
|
743 |
-
if (strlen($buffer)) {
|
744 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
745 |
-
$xor = $this->_encryptBlock($xor);
|
746 |
-
$buffer.= $xor;
|
747 |
-
$key = $this->_string_shift($buffer, $block_size);
|
748 |
-
$ciphertext.= substr($plaintext, $i, $block_size) ^ $key;
|
749 |
-
}
|
750 |
-
} else {
|
751 |
-
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
752 |
-
$xor = $this->_encryptBlock($xor);
|
753 |
-
$ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
|
754 |
-
}
|
755 |
-
$key = $xor;
|
756 |
-
}
|
757 |
-
if ($this->continuousBuffer) {
|
758 |
-
$this->encryptIV = $xor;
|
759 |
-
if ($start = strlen($plaintext) % $block_size) {
|
760 |
-
$buffer = substr($key, $start) . $buffer;
|
761 |
-
}
|
762 |
-
}
|
763 |
-
}
|
764 |
-
|
765 |
-
return $ciphertext;
|
766 |
-
}
|
767 |
-
|
768 |
-
/**
|
769 |
-
* Decrypts a message.
|
770 |
-
*
|
771 |
-
* If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
|
772 |
-
* it is.
|
773 |
-
*
|
774 |
-
* @see Crypt_Rijndael::encrypt()
|
775 |
-
* @access public
|
776 |
-
* @param String $ciphertext
|
777 |
-
*/
|
778 |
-
function decrypt($ciphertext)
|
779 |
-
{
|
780 |
-
$this->_setup();
|
781 |
-
|
782 |
-
if ($this->paddable) {
|
783 |
-
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
784 |
-
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
785 |
-
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
|
786 |
-
}
|
787 |
-
|
788 |
-
$block_size = $this->block_size;
|
789 |
-
$buffer = &$this->debuffer;
|
790 |
-
$continuousBuffer = $this->continuousBuffer;
|
791 |
-
$plaintext = '';
|
792 |
-
switch ($this->mode) {
|
793 |
-
case CRYPT_RIJNDAEL_MODE_ECB:
|
794 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
795 |
-
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
|
796 |
-
}
|
797 |
-
break;
|
798 |
-
case CRYPT_RIJNDAEL_MODE_CBC:
|
799 |
-
$xor = $this->decryptIV;
|
800 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
801 |
-
$block = substr($ciphertext, $i, $block_size);
|
802 |
-
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
803 |
-
$xor = $block;
|
804 |
-
}
|
805 |
-
if ($this->continuousBuffer) {
|
806 |
-
$this->decryptIV = $xor;
|
807 |
-
}
|
808 |
-
break;
|
809 |
-
case CRYPT_RIJNDAEL_MODE_CTR:
|
810 |
-
$xor = $this->decryptIV;
|
811 |
-
if (strlen($buffer)) {
|
812 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
813 |
-
$block = substr($ciphertext, $i, $block_size);
|
814 |
-
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
815 |
-
$key = $this->_string_shift($buffer, $block_size);
|
816 |
-
$plaintext.= $block ^ $key;
|
817 |
-
}
|
818 |
-
} else {
|
819 |
-
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
820 |
-
$block = substr($ciphertext, $i, $block_size);
|
821 |
-
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
822 |
-
$plaintext.= $block ^ $key;
|
823 |
-
}
|
824 |
-
}
|
825 |
-
if ($this->continuousBuffer) {
|
826 |
-
$this->decryptIV = $xor;
|
827 |
-
if ($start = strlen($ciphertext) % $block_size) {
|
828 |
-
$buffer = substr($key, $start) . $buffer;
|
829 |
-
}
|
830 |
-
}
|
831 |
-
break;
|
832 |
-
case CRYPT_RIJNDAEL_MODE_CFB:
|
833 |
-
if (!empty($buffer['ciphertext'])) {
|
834 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
835 |
-
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
836 |
-
if (strlen($buffer['ciphertext']) == $block_size) {
|
837 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|