Compare commits
No commits in common. "2.2" and "master" have entirely different histories.
17
.gitignore
vendored
|
@ -1,11 +1,8 @@
|
|||
favicon.*
|
||||
.htconfig.php
|
||||
\#*
|
||||
wip/*
|
||||
include/jquery-1.4.2.min.js
|
||||
*.log
|
||||
*.out
|
||||
*.version*
|
||||
push*
|
||||
langup
|
||||
home.html
|
||||
.htaccess
|
||||
.htconfig.php
|
||||
#*
|
||||
favicon.*
|
||||
tests/coverage.html
|
||||
/vendor
|
||||
/nbproject/private/
|
||||
|
|
|
@ -8,14 +8,16 @@ Deny from all
|
|||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
|
||||
# Protect repo directory from browsing
|
||||
# Protect repository directory from browsing
|
||||
RewriteRule "(^|/)\.git" - [F]
|
||||
|
||||
# Rewrite current-style URLs of the form 'index.php?q=x'.
|
||||
# Also place auth information into REMOTE_USER for sites running
|
||||
# in CGI mode.
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
|
||||
|
||||
</IfModule>
|
||||
|
116
INSTALL.txt
|
@ -1,116 +0,0 @@
|
|||
|
||||
Friendika Installation
|
||||
|
||||
We've tried very hard to ensure that Friendika will run on commodity hosting
|
||||
platforms - such as those used to host Wordpress blogs and Drupal websites.
|
||||
But be aware that Friendika is more than a simple web application. It is a
|
||||
complex communications system which more closely resembles an email server
|
||||
than a web server. For reliability and performance, messages are delivered in
|
||||
the background and are queued for later delivery when sites are down. This
|
||||
kind of functionality requires a bit more of the host system than the typical
|
||||
blog. Not every PHP/MySQL hosting provider will be able to support Friendika.
|
||||
Many will. But please review the requirements and confirm these with your
|
||||
hosting provider prior to installation.
|
||||
|
||||
Before you begin: Choose a domain name or subdomain name for your server.
|
||||
Put some thought into this - because changing it is currently not-supported.
|
||||
Things will break, and some of your friends may have difficulty communicating
|
||||
with you. We plan to address this limitation in a future release.
|
||||
|
||||
|
||||
1. Requirements
|
||||
- Apache with mod-rewrite enabled and "Options All" so you can use a
|
||||
local .htaccess file
|
||||
|
||||
- PHP 5.2+. The later the better. You'll need 5.3 for encryption of key
|
||||
exchange conversations
|
||||
encryption support
|
||||
- PHP *command line* access with register_argc_argv set to true in the
|
||||
php.ini file
|
||||
- curl, gd, mysql, and openssl extensions
|
||||
- some form of email server or email gateway such that PHP mail() works
|
||||
- mcrypt (optional; used for end-to-end message encryption)
|
||||
|
||||
- Mysql 5.x
|
||||
|
||||
- ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks
|
||||
(Windows) [Note: other options are presented in Section 8 of this document]
|
||||
|
||||
- Installation into a top-level domain or sub-domain (without a
|
||||
directory/path component in the URL) is preferred. Directory paths will
|
||||
not be as convenient to use and have not been thoroughly tested.
|
||||
|
||||
[Dreamhost.com offers all of the necessary hosting features at a
|
||||
reasonable price. If your hosting provider doesn't allow Unix shell access,
|
||||
you might have trouble getting everything to work.]
|
||||
|
||||
2. Unpack the Friendika files into the root of your web server document area.
|
||||
|
||||
- If you copy the directory tree to your webserver, make sure
|
||||
that you also copy .htaccess - as "dot" files are often hidden
|
||||
and aren't normally copied.
|
||||
|
||||
3. Create an empty database and note the access details (hostname, username,
|
||||
password, database name).
|
||||
|
||||
|
||||
4. If you know in advance that it will be impossible for the web server to
|
||||
write or create files in your web directory, create an empty file called
|
||||
.htconfig.php and make it writable by the web server.
|
||||
|
||||
5. Visit your website with a web browser and follow the instructions. Please
|
||||
note any error messages and correct these before continuing.
|
||||
|
||||
6. *If* the automated installation fails for any reason, check the following:
|
||||
|
||||
- ".htconfig.php" exists
|
||||
If not, edit htconfig.php and change system settings. Rename
|
||||
to .htconfig.php
|
||||
- Database is populated.
|
||||
If not, import the contents of "database.sql" with phpmyadmin
|
||||
or mysql command line
|
||||
|
||||
7. At this point visit your website again, and register your personal account.
|
||||
Registration errors should all be recoverable automatically.
|
||||
If you get any *critical* failure at this point, it generally indicates the
|
||||
database was not installed correctly. You might wish to move/rename
|
||||
.htconfig.php to another name and empty (called 'dropping') the database
|
||||
tables, so that you can start fresh.
|
||||
|
||||
****************************************************************************
|
||||
****************************************************************************
|
||||
******** THIS NEXT STEP IS IMPORTANT!!!! ***********
|
||||
****************************************************************************
|
||||
****************************************************************************
|
||||
|
||||
8. Set up a cron job or scheduled task to run the poller once every 5-10
|
||||
minutes to pick up the recent "public" postings of your friends. Example:
|
||||
|
||||
cd /base/directory; /path/to/php include/poller.php
|
||||
|
||||
Change "/base/directory", and "/path/to/php" as appropriate for your situation.
|
||||
|
||||
If you are using a Linux server, run "crontab -e" and add a line like the
|
||||
one shown, substituting for your unique paths and settings:
|
||||
|
||||
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php include/poller.php
|
||||
|
||||
You can generally find the location of PHP by executing "which php". If you
|
||||
have troubles with this section please contact your hosting provider for
|
||||
assistance. Friendika will not work correctly if you cannot perform this step.
|
||||
|
||||
Alternative: You may be able to use the 'poormancron' plugin to perform this
|
||||
step if you are using a recent Friendika release. To do this, edit the file
|
||||
".htconfig.php" and look for a line describing your plugins. On a fresh
|
||||
installation, it will look like
|
||||
|
||||
$a->config['system']['addon'] = 'js_upload';
|
||||
|
||||
This indicates the "js_upload" addon module is enabled. You may add additional
|
||||
addons/plugins using this same line in the configuration file. Change it to
|
||||
read
|
||||
|
||||
$a->config['system']['addon'] = 'js_upload,poormancron';
|
||||
|
||||
and save your changes.
|
||||
|
42
LICENSE
|
@ -1,42 +0,0 @@
|
|||
* Friendika
|
||||
* Copyright (c) 2010, 2011 Mike Macgirvin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Friendika nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Mike Macgirvin ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Mike Macgirvin BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Friendika incorporates other software which may be licensed under different
|
||||
terms and conditions. Some system libraries which are supplied with and
|
||||
incorporated into Friendika were provided by their respective authors under
|
||||
the LGPL (Lesser GNU Public License) and may result in legal encumberance if
|
||||
you make any code changes to these libraries.
|
||||
|
||||
Addon or "plugin" modules (projects by other authors and fully contained within
|
||||
the 'addon' and 'theme' directories) are licensed under terms provided by the
|
||||
respective software author or authors of those works, and MAY include copyleft
|
||||
licenses such as GPLv3, AGPL, and/or commercial licenses. For the purposes of
|
||||
licensing, addon modules and themes are considered separate standalone works,
|
||||
where the "work as a whole" is defined as the embodiment of the theme or
|
||||
addon module.
|
||||
|
||||
|
||||
|
2
Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
test:
|
||||
cd tests && phpunit --coverage-html=coverage.html && x-www-browser ./coverage.html/index.html
|
86
README
|
@ -1,86 +0,0 @@
|
|||
|
||||
*************
|
||||
* Friendika *
|
||||
*************
|
||||
|
||||
Friendika Communications Server
|
||||
|
||||
http://project.friendika.com
|
||||
|
||||
|
||||
Friendika is a web application for managing social communications. Some
|
||||
would call it a "social network" or "distributed social network". We think
|
||||
both terms have been over-used, and don't adequately describe Friendika's
|
||||
capabilities - though Friendika can also fill those roles.
|
||||
|
||||
At its essence, Friendika is a web application which can monitor various
|
||||
information and social activity streams, and which also lets you participate
|
||||
in online conversations with friends and associates, using a variety of network
|
||||
protocols. These are combined into an overview of your various communications
|
||||
and activities - regardless of network origin.
|
||||
|
||||
Friendika also manages your personal profiles and photo albums and lets
|
||||
you securely present each of these to specific audiences. Your communications
|
||||
can be either open and public, or closed and private. You can easily create
|
||||
"groups" of contacts with which you can partition your conversations into
|
||||
private social circles, and which cannot be seen outside the circle.
|
||||
|
||||
Friendika is decentralised. Any account on any Friendika server can connect
|
||||
with any account on any other Friendika server. You can also connect to and
|
||||
interact directly with friends on Status.Net and other federated social web
|
||||
services (e.g. identi.ca, GNU-Social, etc.).
|
||||
|
||||
Outgoing communications can be directed at these networks and also
|
||||
existing accounts on Facebook and Twitter - or even delivered to email
|
||||
contacts.
|
||||
|
||||
Incoming data streams aren't limited to traditional social networks.
|
||||
They may include most any service which provides a syndication feed (both RSS
|
||||
and Atom). This allows you to view communications from friends in other
|
||||
diverse social networks - such as Diaspora, Google Buzz, and millions of
|
||||
blogs, news services, and other websites. You can also import
|
||||
contacts from (and write to) anybody that is accessible from your email
|
||||
INBOX and view them in your social stream. Over time we will try to
|
||||
build two-way bridges to other services so that you can freely
|
||||
interact in both directions with anybody on an accessible network that
|
||||
allows it.
|
||||
|
||||
Communications between Friendika servers are private and encrypted,
|
||||
using military grade encryption - and require mutual identity provenance
|
||||
before any data is exchanged. These same crypto mechanisms provide remote
|
||||
password-less authentication; allowing you to post to profiles and view private
|
||||
photo collections on other servers - without encountering any login and/or
|
||||
authorisation dialogues when visiting these sites.
|
||||
|
||||
Friendika has no boundaries and no central ownership of the data generated
|
||||
within the network. Anybody with a commodity PHP/MySQL web server or hosting
|
||||
account can provide a server, and each individual server can then support
|
||||
up to several thousand participating members - each with their own unique
|
||||
communication and privacy needs. This allows Friendika to scale to global
|
||||
levels and mimics the decentralised architecture of the web itself.
|
||||
|
||||
If you are creating a website which requires social interaction, Friendika
|
||||
can also take the place of blog software, forum software and feed readers, and
|
||||
also provide individualised communications and content management - or
|
||||
simply be used as an alternative to traditional "monolithic" social networks.
|
||||
|
||||
Friendika is also free - in every sense of the word.
|
||||
|
||||
Choose freedom - join us.
|
||||
|
||||
Find out more about the project at http://project.friendika.com
|
||||
|
||||
*******************
|
||||
Friendika Demo Site
|
||||
*******************
|
||||
|
||||
http://demo.friendika.com
|
||||
|
||||
*******************
|
||||
Friendika Downloads
|
||||
*******************
|
||||
|
||||
http://github.com/friendika/friendika/tarball/master
|
||||
|
||||
|
||||
|
142
README.md
Normal file
|
@ -0,0 +1,142 @@
|
|||
# Decentralized Friendica Directory
|
||||
|
||||
## Installing
|
||||
|
||||
### 1. Copy configuration
|
||||
|
||||
Copy the `htconfig.php` to `.htconfig.php` and enter the database credentials.
|
||||
|
||||
### 2. Initialize the database
|
||||
|
||||
Create a database with a username and a password.
|
||||
Then import ````dfrndir.sql```` to it.
|
||||
|
||||
mysql -u YOURDBUSER -p YOURDBNAME < dfrnlr.sql
|
||||
|
||||
### 3. Create an autoloader with composer
|
||||
|
||||
Make sure you have [composer](https://getcomposer.org/download/) installed globally, or rewrite the command to use a `.phar`.
|
||||
|
||||
```sh
|
||||
composer dump-autoload
|
||||
```
|
||||
|
||||
### 4. Set up the cronjobs.
|
||||
|
||||
Example cronjob using `www-data` user.
|
||||
|
||||
```
|
||||
*/30 * * * * www-data cd /var/www/friendica-directory; php include/cron_maintain.php
|
||||
*/5 * * * * www-data cd /var/www/friendica-directory; php include/cron_sync.php
|
||||
```
|
||||
|
||||
### 5. Copy .htaccess-dist to .htaccess and make local modifications
|
||||
|
||||
## How syncing works
|
||||
|
||||
The new syncing features include: pushing and pulling.
|
||||
|
||||
### Pushing
|
||||
|
||||
Submissions you receive can be submitted to other directories using a push target.
|
||||
|
||||
You do this by creating an entry in the sync-targets table with the push bit set to `1`.
|
||||
Also, you must enable pushing in your `.htconfig` settings.
|
||||
|
||||
The next time `include/cron_sync.php` is run from your cronjob, the queued items will be submitted to your push targets.
|
||||
|
||||
### Pulling
|
||||
|
||||
For pulling to work, the target server must enable pulling.
|
||||
This makes the `/sync/pull/all` and `/sync/pull/since/[when]` methods work on that server.
|
||||
|
||||
Next you can add an entry in the sync-targets table with the pull bit set to `1`.
|
||||
Also, you must enable pulling in your `.htconfig` settings.
|
||||
|
||||
The next time `include/cron_sync.php` is run from your cronjob, the pulling sources will be checked.
|
||||
New items will be queued in your pull queue.
|
||||
The queue will be gradually cleared based on your `syncing.max_pull_items` settings.
|
||||
You can check the backlog of this queue at the `/admin` page.
|
||||
|
||||
**Note**: If you set the bit for pulling or pushing in the MySQL console, it won't be visible in a `SELECT` query.
|
||||
MySQL will however inform you about changed rows after `UPDATE` queries.
|
||||
|
||||
## How submissions are processed
|
||||
|
||||
1. The /submit endpoint takes a `?url=` parameter.
|
||||
This parameter is an encoded URL, the original ASCII is treated as binary and base16 encoded.
|
||||
This URL should be a profile location, such as `https://fc.oscp.info/profile/admin`.
|
||||
This URL will be checked in the database for existing accounts.
|
||||
This check includes a normalization, http vs https is ignored as well as www. prefixes.
|
||||
|
||||
2. If noscrape is supported by the site, this will be used instead of a scrape request.
|
||||
In this case `https://fc.oscp.info/noscrape/admin`.
|
||||
If noscrape fails or is not supported, the url provided (as is) will be scraped for meta information.
|
||||
* `<meta name="dfrn-global-visibility" content="true" />`
|
||||
* `<meta name="friendica.community" content="true" />`
|
||||
or `<meta name="friendika.community" content="true" />`
|
||||
* `<meta name="keywords" content="these,are,your,public,tags" />`
|
||||
* `<link rel="dfrn-*" href="https://fc.oscp.info/*" />`
|
||||
any dfrn-* prefixed link and it's href attribute.
|
||||
* `.vcard .fn` as `fn`
|
||||
* `.vcard .title` as `pdesc`
|
||||
* `.vcard .photo` as `photo`
|
||||
* `.vcard .key` as `key`
|
||||
* `.vcard .locality` as `locality`
|
||||
* `.vcard .region` as `region`
|
||||
* `.vcard .postal-code` as `postal-code`
|
||||
* `.vcard .country-name` as `country-name`
|
||||
|
||||
3. If the `dfrn-global-visibility` value is set to false. Any existing records will be deleted.
|
||||
And the process exits here.
|
||||
|
||||
4. A submission is IGNORED when at least the following data could not be scraped.
|
||||
* `key` the public key from the hCard.
|
||||
* `dfrn-request` required for the DFRN protocol.
|
||||
* `dfrn-confirm` required for the DFRN protocol.
|
||||
* `dfrn-notify` required for the DFRN protocol.
|
||||
* `dfrn-poll` required for the DFRN protocol.
|
||||
|
||||
5. If the profile existed in the database and the profile is not explicitly set to
|
||||
public using the `dfrn-global-visibility` meta tag. It will be deleted.
|
||||
|
||||
6. If the profile existed in the database and the profile lacks either an `fn` or `photo`
|
||||
attribute, it will be deleted.
|
||||
|
||||
7. The profile is now inserted/updated based on the found information.
|
||||
Notable database fields are:
|
||||
* `homepage` the originally (decoded) `?url=` parameter.
|
||||
* `nurl` the normalized URL created to remove http vs https and www vs non-www urls.
|
||||
* `created` the creation date and time in UTC (now if the entry did not exist yet).
|
||||
* `updated` the current date and time in UTC.
|
||||
|
||||
8. If an insert has occurred, the URL will now be used to check for duplicates.
|
||||
The highest insert ID will be kept, anything else deleted.
|
||||
|
||||
9. If provided, your public tags are now split by ` ` (space character) and stored in the tags table.
|
||||
This uses your normalized URL as unique key for your profile.
|
||||
|
||||
10. The `photo` provided will be downloaded and resized to 80x80, regardless of source size.
|
||||
|
||||
11. Should there somehow have been an error at this point such as that there is no profile ID known.
|
||||
Everything will get deleted based on the original `?url=` parameter.
|
||||
|
||||
## Note about search
|
||||
|
||||
The Directory uses MySQL fulltext capabilities to index profiles and offer a search feature.
|
||||
However, the default minimum word size MySQL will index is 4, which ignores words like `PHP` and `USA`.
|
||||
|
||||
To index words smaller than 4 characters, you will have to edit your my.cnf/my.ini file to include this:
|
||||
|
||||
````
|
||||
[mysqld]
|
||||
ft_min_word_len = 3
|
||||
````
|
||||
|
||||
Then restart your MySQL server.
|
||||
|
||||
If you already had data in your profile table, you will need to rebuild the index by executing the following query:
|
||||
|
||||
````
|
||||
REPAIR TABLE `profile` QUICK;
|
||||
````
|
43
Vagrantfile
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
server_ip = "192.168.33.10"
|
||||
server_memory = "384" # MB
|
||||
server_timezone = "UTC"
|
||||
|
||||
public_folder = "/vagrant"
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
|
||||
# Set server to Ubuntu 14.04
|
||||
config.vm.box = "ubuntu/trusty64"
|
||||
|
||||
# Disable automatic box update checking. If you disable this, then
|
||||
# boxes will only be checked for updates when the user runs
|
||||
# `vagrant box outdated`. This is not recommended.
|
||||
# config.vm.box_check_update = false
|
||||
|
||||
# Create a hostname, don't forget to put it to the `hosts` file
|
||||
# This will point to the server's default virtual host
|
||||
# TO DO: Make this work with virtualhost along-side xip.io URL
|
||||
config.vm.hostname = "friendica.dev"
|
||||
|
||||
# Create a static IP
|
||||
config.vm.network :private_network, ip: server_ip
|
||||
|
||||
# Share a folder between host and guest
|
||||
config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", owner: "www-data", group: "vagrant"
|
||||
|
||||
# Provider-specific configuration so you can fine-tune various
|
||||
# backing providers for Vagrant. These expose provider-specific options.
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
# # Display the VirtualBox GUI when booting the machine
|
||||
# vb.gui = true
|
||||
#
|
||||
# # Customize the amount of memory on the VM:
|
||||
vb.memory = server_memory
|
||||
end
|
||||
|
||||
# Enable provisioning with a shell script.
|
||||
config.vm.provision "shell", path: "./util/vagrant_provision.sh"
|
||||
# run: "always"
|
||||
# run: "once"
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
|
||||
Friendika addons/plugins license terms are under the control of the project
|
||||
author or authors.
|
||||
|
||||
Developers are free to set their own license terms on addons/plugins as
|
||||
standalone works. These license terms apply only to the covered addon or
|
||||
plugin.
|
||||
|
||||
Addons/plugins may be licensed under copyleft or other license terms. Although
|
||||
these projects may require Friendika to operate, no addon or plugin may
|
||||
mandate any changes to the Friendika project license.
|
186
addon/README
|
@ -1,186 +0,0 @@
|
|||
Friendika Addon/Plugin development
|
||||
|
||||
This is an early specification and hook details may be subject to change.
|
||||
|
||||
Please see the sample addon 'randplace' for a working example of using these features.
|
||||
|
||||
|
||||
You must register plugins with the system in the .htconfig.php file.
|
||||
|
||||
$a->config['system']['addon'] = 'plugin1name, plugin2name, another_name';
|
||||
|
||||
Plugin names cannot contain spaces and are used as filenames.
|
||||
|
||||
|
||||
Register your plugin hooks during installation.
|
||||
|
||||
register_hook($hookname, $file, $function);
|
||||
|
||||
$hookname is a string and corresponds to a known Friendika hook
|
||||
$file is a pathname relative to the top-level Friendika directory.
|
||||
This *should* be 'addon/plugin_name/plugin_name.php' in most cases.
|
||||
$function is a string and is the name of the function which will be executed
|
||||
when the hook is called.
|
||||
|
||||
|
||||
Your hook functions will be called with at least one and possibly two arguments
|
||||
|
||||
function myhook_function(&$a, &$b) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
If you wish to make changes to the calling data, you must declare them as
|
||||
reference variables (with '&') during function declaration.
|
||||
|
||||
$a is the Friendika 'App' class - which contains a wealth of information
|
||||
about the current state of Friendika, such as which module has been called,
|
||||
configuration info, the page contents at the point the hook was invoked, profile
|
||||
and user information, etc. It is recommeded you call this '$a' to match its usage
|
||||
elsewhere.
|
||||
|
||||
$b can be called anything you like. This is information which is specific to the hook
|
||||
currently being processed, and generally contains information that is being immediately
|
||||
processed or acted on that you can use, display, or alter. Remember to declare it with
|
||||
'&' if you wish to alter it.
|
||||
|
||||
|
||||
Current hooks:
|
||||
|
||||
'authenticate' - called when a user attempts to login.
|
||||
$b is an array
|
||||
'username' => the supplied username
|
||||
'password' => the supplied password
|
||||
'authenticated' => set this to non-zero to authenticate the user.
|
||||
'user_record' => successful authentication must also return a valid user record from the database
|
||||
|
||||
|
||||
'logged_in' - called after a user has successfully logged in.
|
||||
$b contains the $a->user array
|
||||
|
||||
|
||||
'display_item' - called when formatting a post for display.
|
||||
$b is an array
|
||||
'item' => The item (array) details pulled from the database
|
||||
'output' => the (string) HTML representation of this item prior to adding it
|
||||
to the page
|
||||
|
||||
'post_local' - called when a status post or comment is entered on the local system
|
||||
$b is the item array of the information to be stored in the database
|
||||
{Please note: body contents are bbcode - not HTML)
|
||||
|
||||
'post_local_end' - called when a local status post or comment has been stored on the local system
|
||||
$b is the item array of the information which has just been stored in the database
|
||||
{Please note: body contents are bbcode - not HTML)
|
||||
|
||||
|
||||
'post_remote' - called when receiving a post from another source. This may also be used
|
||||
to post local activity or system generated messages.
|
||||
$b is the item array of information to be stored in the database and the item
|
||||
body is bbcode.
|
||||
|
||||
'settings_form' - called when generating the HTML for the user Settings page
|
||||
$b is the (string) HTML of the settings page before the final '</form>' tag.
|
||||
|
||||
'settings_post' - called when the Settings pages are submitted.
|
||||
$b is the $_POST array
|
||||
|
||||
'plugin_settings' - called when generating the HTML for the addon settings page
|
||||
$b is the (string) HTML of the addon settings page before the final '</form>' tag.
|
||||
|
||||
'plugin_settings_post' - called when the Addon Settings pages are submitted.
|
||||
$b is the $_POST array
|
||||
|
||||
'profile_post' - called when posting a profile page.
|
||||
$b is the $_POST array
|
||||
|
||||
'profile_edit' - called prior to output of profile edit page
|
||||
$b is array
|
||||
'profile' => profile (array) record from the database
|
||||
'entry' => the (string) HTML of the generated entry
|
||||
|
||||
'profile_advanced' - called when the HTML is generated for the 'Advanced profile',
|
||||
corresponding to the 'Profile' tab within a person's profile page.
|
||||
$b is the (string) HTML representation of the generated profile
|
||||
|
||||
'directory_item' - called from the Directory page when formatting an item for display
|
||||
$b is an array
|
||||
'contact' => contact (array) record for the person from the database
|
||||
'entry' => the (string) HTML of the generated entry
|
||||
|
||||
'profile_sidebar_enter' - called prior to generating the sidebar "short" profile for a page
|
||||
$b is (array) the person's profile array
|
||||
|
||||
'profile_sidebar' - called when generating the sidebar "short" profile for a page
|
||||
$b is an array
|
||||
'profile' => profile (array) record for the person from the database
|
||||
'entry' => the (string) HTML of the generated entry
|
||||
|
||||
'contact_block_end' - called when formatting the block of contacts/friends on a
|
||||
profile sidebar has completed
|
||||
$b is an array
|
||||
'contacts' => contact array of entries
|
||||
'output' => the (string) generated HTML of the contact block
|
||||
|
||||
'bbcode' - called during conversion of bbcode to html
|
||||
$b is (string) converted text
|
||||
|
||||
'html2bbcode' - called during conversion of html to bbcode (e.g. remote message posting)
|
||||
$b is (string) converted text
|
||||
|
||||
|
||||
'page_header' - called after building the page navigation section
|
||||
$b is (string) HTML of nav region
|
||||
|
||||
|
||||
'personal_xrd' - called prior to output of personal XRD file.
|
||||
$b is an array
|
||||
'user' => the user record for the person
|
||||
'xml' => the complete XML to be output
|
||||
|
||||
|
||||
'home_content' - called prior to output home page content, shown to unlogged users
|
||||
$b is (string) HTML of section region
|
||||
|
||||
'contact_edit' - called when editing contact details on an individual from the Contacts page
|
||||
$b is (array)
|
||||
'contact' => contact record (array) of target contact
|
||||
'output' => the (string) generated HTML of the contact edit page
|
||||
|
||||
'contact_edit_post' - called when posting the contact edit page
|
||||
$b is the $_POST array
|
||||
|
||||
'init_1' - called just after DB has been opened and before session start
|
||||
$b is not used or passed
|
||||
|
||||
'page_end' - called after HTML content functions have completed
|
||||
$b is (string) HTML of content div
|
||||
|
||||
'jot_plugin' - add tools to jot toolbar
|
||||
$b is (string) HTML for tool icon
|
||||
|
||||
|
||||
*** = subject to change
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Not yet documented:
|
||||
|
||||
'atom_feed' ***
|
||||
|
||||
'atom_feed_end' ***
|
||||
|
||||
'parse_atom' ***
|
||||
|
||||
'atom_author' ***
|
||||
|
||||
'atom_entry' ***
|
||||
|
||||
'parse_link' ***
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
<?php
|
||||
|
||||
function calc_install() {
|
||||
register_hook('app_menu', 'addon/calc/calc.php', 'calc_app_menu');
|
||||
}
|
||||
|
||||
function calc_uninstall() {
|
||||
unregister_hook('app_menu', 'addon/calc/calc.php', 'calc_app_menu');
|
||||
|
||||
}
|
||||
|
||||
function calc_app_menu($a,&$b) {
|
||||
$b['app_menu'] .= '<div class="app-title"><a href="calc">Calculator</a></div>';
|
||||
}
|
||||
|
||||
|
||||
function calc_module() {}
|
||||
|
||||
|
||||
|
||||
|
||||
function calc_init($a) {
|
||||
|
||||
$x = <<< EOT
|
||||
|
||||
<script language="JavaScript">
|
||||
/**************************************
|
||||
* www.FemaleNerd.com *
|
||||
**************************************/
|
||||
|
||||
// Declare global variables
|
||||
var displayText = ""
|
||||
var num1
|
||||
var num2
|
||||
var operatorType
|
||||
|
||||
// Write to display
|
||||
function addDisplay(n){
|
||||
id = document.getElementById("display");
|
||||
id.value = ""
|
||||
displayText += n
|
||||
id.value = displayText
|
||||
}
|
||||
|
||||
// Addition
|
||||
function addNumbers() {
|
||||
if (displayText == "") {
|
||||
displayText = result
|
||||
}
|
||||
num1 = parseFloat(displayText)
|
||||
operatorType = "add"
|
||||
displayText = ""
|
||||
}
|
||||
|
||||
// Subtraction
|
||||
function subtractNumbers() {
|
||||
if (displayText == "") {
|
||||
displayText = result
|
||||
}
|
||||
num1 = parseFloat(displayText)
|
||||
operatorType = "subtract"
|
||||
displayText = ""
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
function multiplyNumbers() {
|
||||
if (displayText == "") {
|
||||
displayText = result
|
||||
}
|
||||
num1 = parseFloat(displayText)
|
||||
operatorType = "multiply"
|
||||
displayText = ""
|
||||
}
|
||||
|
||||
// Division
|
||||
function divideNumbers() {
|
||||
if (displayText == "") {
|
||||
displayText = result
|
||||
}
|
||||
num1 = parseFloat(displayText)
|
||||
operatorType = "divide"
|
||||
displayText = ""
|
||||
}
|
||||
|
||||
// Sine
|
||||
function sin() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = Math.sin(num1)
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Cosine
|
||||
function cos() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = Math.cos(num1)
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// ArcSine
|
||||
function arcSin() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = Math.asin(num1)
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// ArcCosine
|
||||
function arcCos() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = Math.acos(num1)
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Square root
|
||||
function sqrt() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = Math.sqrt(num1)
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Square number (number to the power of two)
|
||||
function square() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = num1 * num1
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Convert degrees to radians
|
||||
function degToRad() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = num1 * Math.PI / 180
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Convert radians to degrees
|
||||
function radToDeg() {
|
||||
id = document.getElementById("display");
|
||||
if (displayText == "") {
|
||||
num1 = result
|
||||
}
|
||||
else {
|
||||
num1 = parseFloat(displayText)
|
||||
}
|
||||
if (num1 != "") {
|
||||
result = num1 * 180 / Math.PI
|
||||
id.value = result
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
alert("Please write the number first")
|
||||
}
|
||||
}
|
||||
|
||||
// Calculations
|
||||
function calculate() {
|
||||
id = document.getElementById("display");
|
||||
|
||||
if (displayText != "") {
|
||||
num2 = parseFloat(displayText)
|
||||
// Calc: Addition
|
||||
if (operatorType == "add") {
|
||||
result = num1 + num2
|
||||
id.value = result
|
||||
}
|
||||
// Calc: Subtraction
|
||||
if (operatorType == "subtract") {
|
||||
result = num1 - num2
|
||||
id.value = result
|
||||
}
|
||||
// Calc: Multiplication
|
||||
if (operatorType == "multiply") {
|
||||
result = num1 * num2
|
||||
id.value = result
|
||||
}
|
||||
// Calc: Division
|
||||
if (operatorType == "divide") {
|
||||
result = num1 / num2
|
||||
id.value = result
|
||||
}
|
||||
displayText = ""
|
||||
}
|
||||
else {
|
||||
id.value = "Oops! Error!"
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the display
|
||||
function clearDisplay() {
|
||||
id = document.getElementById("display");
|
||||
|
||||
displayText = ""
|
||||
id.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
EOT;
|
||||
$a->page['htmlhead'] .= $x;
|
||||
}
|
||||
|
||||
function calc_content($app) {
|
||||
|
||||
$o = '';
|
||||
|
||||
$o .= <<< EOT
|
||||
|
||||
<h3>Calculator</h3>
|
||||
<br /><br />
|
||||
<table>
|
||||
<tbody><tr><td>
|
||||
<table bgcolor="#af9999" border="1">
|
||||
<tbody><tr><td>
|
||||
<table border="1" cellpadding="2" cellspacing="2">
|
||||
<form name="calc">
|
||||
<!--
|
||||
<TR><TD VALIGN=top colspan=6 ALIGN="center"> <H2>Calculator</H2> </TD>
|
||||
-->
|
||||
<tbody><tr>
|
||||
<td colspan="5"><input size="22" id="display" name="display" type="text"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="one" value=" 1 " onclick="addDisplay(1)" type="button"></td>
|
||||
<td><input name="two" value=" 2 " onclick="addDisplay(2)" type="button"></td>
|
||||
<td><input name="three" value=" 3 " onclick="addDisplay(3)" type="button"></td>
|
||||
<td><input name="plus" value=" + " onclick="addNumbers()" type="button"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="four" value=" 4 " onclick="addDisplay(4)" type="button"></td>
|
||||
<td><input name="five" value=" 5 " onclick="addDisplay(5)" type="button"></td>
|
||||
<td><input name="six" value=" 6 " onclick="addDisplay(6)" type="button"></td>
|
||||
<td><input name="minus" value=" - " onclick="subtractNumbers()" type="button"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="seven" value=" 7 " onclick="addDisplay(7)" type="button"></td>
|
||||
<td><input name="eight" value=" 8 " onclick="addDisplay(8)" type="button"></td>
|
||||
<td><input name="nine" value=" 9 " onclick="addDisplay(9)" type="button"></td>
|
||||
<td><input name="multiplication" value=" * " onclick="multiplyNumbers()" type="button"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="zero" value=" 0 " onclick="addDisplay(0)" type="button"></td>
|
||||
<td><input name="pi" value=" Pi " onclick="addDisplay(Math.PI)" type="button"> </td>
|
||||
<td><input name="dot" value=" . " onclick='addDisplay(".")' type="button"></td>
|
||||
<td><input name="division" value=" / " onclick="divideNumbers()" type="button"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="sqareroot" value="sqrt" onclick="sqrt()" type="button"></td>
|
||||
<td><input name="squarex" value=" x^2" onclick="square()" type="button"></td>
|
||||
<td><input name="deg-rad" value="d2r " onclick="degToRad()" type="button"></td>
|
||||
<td><input name="rad-deg" value="r2d " onclick="radToDeg()" type="button"></td>
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td><input name="sine" value=" sin " onclick="sin()" type="button"></td>
|
||||
<td><input name="arcsine" value="asin" onclick="arcSin()" type="button"></td>
|
||||
<td><input name="cosine" value="cos" onclick="cos()" type="button"></td>
|
||||
<td><input name="arccosine" value="acs" onclick="arcCos()" type="button"></td>
|
||||
|
||||
</tr><tr align="left" valign="middle">
|
||||
<td colspan="2"><input name="clear" value=" Clear " onclick="clearDisplay()" type="button"></td>
|
||||
<td colspan="3"><input name="enter" value=" = " onclick="calculate()" type="button"></td>
|
||||
|
||||
</tr></tbody></table>
|
||||
</form>
|
||||
|
||||
<!--
|
||||
<TD VALIGN=top>
|
||||
<B>NOTE:</B> All sine and cosine calculations are
|
||||
<br>done in radians. Remember to convert first
|
||||
<br>if using degrees.
|
||||
</TD>
|
||||
-->
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
EOT;
|
||||
return $o;
|
||||
|
||||
}
|
|
@ -1,283 +0,0 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 4.0 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Stanislav Okhvat <stanis@ngs.ru> |
|
||||
// | Co-authored by : CVH, Chris Hansel <chris@cpi-service.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: UnitConvertor.php,v 1.00 2002/02/20 11:40:00 stasokhvat Exp $
|
||||
|
||||
/**
|
||||
* UnitConvertor is able to convert between different units and currencies.
|
||||
*
|
||||
* @author Stanislav Okhvat <stanis@sibfair.nsk.su, stanis@ngs.ru>
|
||||
* @version $Id: UnitConvertor.php,v 1.00 2002/03/01 17:00:00 stasokhvat Exp $
|
||||
* @package UnitConvertor
|
||||
* @access public
|
||||
* @history 01.03.2002 Implemented the code for regular and offset-based
|
||||
* conversions
|
||||
*
|
||||
* 13.12.2004
|
||||
* By Chris Hansel (CVH): changed getConvSpecs in order to have it look up
|
||||
* intermediary conversions (also see comments in check_key).
|
||||
*
|
||||
* Intermediary conversions are useful when no conversion ratio is specified
|
||||
* between two units when we calculate between the two. For example, we want
|
||||
* to convert between Fahrenheit and Kelvin, and we have only
|
||||
* specified how to convert Centigrade<->Fahrenheit and
|
||||
* Centigrade<->Kelvin. While a direct (Fahrenheit->Kelvin) or
|
||||
* reverse (Kelvin->Fahrenheit) lookups fail, looking for an intermediary
|
||||
* unit linking the two (Centigrade) helps us do the conversion.
|
||||
*
|
||||
* 13.12.2004
|
||||
* Chris Hansel (CVH): $to_array argument of addConversion method can now
|
||||
* contain units as 'unit1/unit2/unit3', when all units stand for the same
|
||||
* thing. See examples in unitconv.php
|
||||
*/
|
||||
class UnitConvertor
|
||||
{
|
||||
/**
|
||||
* Stores conversion ratios.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $conversion_table = array();
|
||||
|
||||
/**
|
||||
* Decimal point character (default is "." - American - set in constructor).
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $decimal_point;
|
||||
|
||||
/**
|
||||
* Thousands separator (default is "," - American - set in constructor).
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $thousand_separator;
|
||||
|
||||
/**
|
||||
* For future use
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $bases = array();
|
||||
|
||||
/**
|
||||
* Constructor. Initializes the UnitConvertor object with the most important
|
||||
* properties.
|
||||
*
|
||||
* @param string decimal point character
|
||||
* @param string thousand separator character
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function UnitConvertor($dec_point = '.', $thousand_sep = ',')
|
||||
{
|
||||
$this->decimal_point = $dec_point;
|
||||
$this->thousand_separator = $thousand_sep;
|
||||
|
||||
} // end func UnitConvertor
|
||||
|
||||
/**
|
||||
* Adds a conversion ratio to the conversion table.
|
||||
*
|
||||
* @param string the name of unit from which to convert
|
||||
* @param array array(
|
||||
* "pound"=>array("ratio"=>'', "offset"=>'')
|
||||
* )
|
||||
* "pound" - name of unit to set conversion ration to
|
||||
* "ratio" - 'double' conversion ratio which, when
|
||||
* multiplied by the number of $from_unit units produces
|
||||
* the result
|
||||
* "offset" - an offset from 0 which will be added to
|
||||
* the result when converting (needed for temperature
|
||||
* conversions and defaults to 0).
|
||||
* @return boolean true if successful, false otherwise
|
||||
* @access public
|
||||
*/
|
||||
function addConversion($from_unit, $to_array)
|
||||
{
|
||||
if (!isset($this->conversion_table[$from_unit])) {
|
||||
while(list($key, $val) = each($to_array))
|
||||
{
|
||||
if (strstr($key, '/'))
|
||||
{
|
||||
$to_units = explode('/', $key);
|
||||
foreach ($to_units as $to_unit)
|
||||
{
|
||||
$this->bases[$from_unit][] = $to_unit;
|
||||
|
||||
if (!is_array($val))
|
||||
{
|
||||
$this->conversion_table[$from_unit."_".$to_unit] = array("ratio"=>$val, "offset"=>0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->conversion_table[$from_unit."_".$to_unit] =
|
||||
array(
|
||||
"ratio"=>$val['ratio'],
|
||||
"offset"=>(isset($val['offset']) ? $val['offset'] : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bases[$from_unit][] = $key;
|
||||
|
||||
if (!is_array($val))
|
||||
{
|
||||
$this->conversion_table[$from_unit."_".$key] = array("ratio"=>$val, "offset"=>0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->conversion_table[$from_unit."_".$key] =
|
||||
array(
|
||||
"ratio"=>$val['ratio'],
|
||||
"offset"=>(isset($val['offset']) ? $val['offset'] : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
} // end func addConversion
|
||||
|
||||
/**
|
||||
* Converts from one unit to another using specified precision.
|
||||
*
|
||||
* @param double value to convert
|
||||
* @param string name of the source unit from which to convert
|
||||
* @param string name of the target unit to which we are converting
|
||||
* @param integer double precision of the end result
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function convert($value, $from_unit, $to_unit, $precision)
|
||||
{
|
||||
if ($this->getConvSpecs($from_unit, $to_unit, $value, $converted ))
|
||||
{
|
||||
return number_format($converted , (int)$precision, $this->decimal_point, $this->thousand_separator);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} // end func
|
||||
|
||||
/**
|
||||
* CVH : changed this Function getConvSpecs in order to have it look up
|
||||
* intermediary Conversions from the
|
||||
* "base" unit being that one that has the highest hierarchical order in one
|
||||
* "logical" Conversion_Array
|
||||
* when taking $conv->addConversion('km',
|
||||
* array('meter'=>1000, 'dmeter'=>10000, 'centimeter'=>100000,
|
||||
* 'millimeter'=>1000000, 'mile'=>0.62137, 'naut.mile'=>0.53996,
|
||||
* 'inch(es)/zoll'=>39370, 'ft/foot/feet'=>3280.8, 'yd/yard'=>1093.6));
|
||||
* "km" would be the logical base unit for all units of dinstance, thus,
|
||||
* if the function fails to find a direct or reverse conversion in the table
|
||||
* it is only logical to suspect that if there is a chance
|
||||
* converting the value it only is via the "base" unit, and so
|
||||
* there is not even a need for a recursive search keeping the perfomance
|
||||
* acceptable and the ressource small...
|
||||
*
|
||||
* CVH check_key checks for a key in the Conversiontable and returns a value
|
||||
*/
|
||||
function check_key( $key) {
|
||||
if ( array_key_exists ($key,$this->conversion_table)) {
|
||||
if (! empty($this->conversion_table[$key])) {
|
||||
return $this->conversion_table[$key];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key function. Finds the conversion ratio and offset from one unit to another.
|
||||
*
|
||||
* @param string name of the source unit from which to convert
|
||||
* @param string name of the target unit to which we are converting
|
||||
* @param double conversion ratio found. Returned by reference.
|
||||
* @param double offset which needs to be added (or subtracted, if negative)
|
||||
* to the result to convert correctly.
|
||||
* For temperature or some scientific conversions,
|
||||
* i.e. Fahrenheit -> Celcius
|
||||
* @return boolean true if ratio and offset are found for the supplied
|
||||
* units, false otherwise
|
||||
* @access private
|
||||
*/
|
||||
function getConvSpecs($from_unit, $to_unit, $value, &$converted)
|
||||
{
|
||||
$key = $from_unit."_".$to_unit;
|
||||
$revkey = $to_unit."_".$from_unit;
|
||||
$found = false;
|
||||
if ($ct_arr = $this->check_key($key)) {
|
||||
// Conversion Specs found directly
|
||||
$ratio = (double)$ct_arr['ratio'];
|
||||
$offset = $ct_arr['offset'];
|
||||
$converted = (double)(($value * $ratio)+ $offset);
|
||||
|
||||
return true;
|
||||
} // not found in direct order, try reverse order
|
||||
elseif ($ct_arr = $this->check_key($revkey)) {
|
||||
$ratio = (double)(1/$ct_arr['ratio']);
|
||||
$offset = -$ct_arr['offset'];
|
||||
$converted = (double)(($value + $offset) * $ratio);
|
||||
|
||||
return true;
|
||||
} // not found test for intermediary conversion
|
||||
else {
|
||||
// return ratio = 1 if keyparts match
|
||||
if ($key == $revkey) {
|
||||
$ratio = 1;
|
||||
$offset = 0;
|
||||
$converted = $value;
|
||||
return true;
|
||||
}
|
||||
// otherwise search intermediary
|
||||
reset($this->conversion_table);
|
||||
while (list($convk, $i1_value) = each($this->conversion_table)) {
|
||||
// split the key into parts
|
||||
$keyparts = preg_split("/_/",$convk);
|
||||
// return ratio = 1 if keyparts match
|
||||
|
||||
// Now test if either part matches the from or to unit
|
||||
if ($keyparts[1] == $to_unit && ($i2_value = $this->check_key($keyparts[0]."_".$from_unit))) {
|
||||
// an intermediary $keyparts[0] was found
|
||||
// now let us put things together intermediary 1 and 2
|
||||
$converted = (double)(((($value - $i2_value['offset']) / $i2_value['ratio']) * $i1_value['ratio'])+ $i1_value['offset']);
|
||||
|
||||
$found = true;
|
||||
|
||||
} elseif ($keyparts[1] == $from_unit && ($i2_value = $this->check_key($keyparts[0]."_".$to_unit))) {
|
||||
// an intermediary $keyparts[0] was found
|
||||
// now let us put things together intermediary 2 and 1
|
||||
$converted = (double)(((($value - $i1_value['offset']) / $i1_value['ratio']) + $i2_value['offset']) * $i2_value['ratio']);
|
||||
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
|
||||
} // end func getConvSpecs
|
||||
|
||||
} // end class UnitConvertor
|
||||
?>
|
|
@ -1,223 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
function convert_install() {
|
||||
register_hook('app_menu', 'addon/convert/convert.php', 'convert_app_menu');
|
||||
}
|
||||
|
||||
function convert_uninstall() {
|
||||
unregister_hook('app_menu', 'addon/convert/convert.php', 'convert_app_menu');
|
||||
}
|
||||
|
||||
function convert_app_menu($a,&$b) {
|
||||
$b['app_menu'] .= '<div class="app-title"><a href="convert">Units Conversion</a></div>';
|
||||
}
|
||||
|
||||
|
||||
function convert_module() {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function convert_content($app) {
|
||||
|
||||
include("UnitConvertor.php");
|
||||
|
||||
class TP_Converter extends UnitConvertor {
|
||||
function TP_Converter($lang = "en")
|
||||
{
|
||||
if ($lang != 'en' ) {
|
||||
$dec_point = '.'; $thousand_sep = "'";
|
||||
} else {
|
||||
$dec_point = '.'; $thousand_sep = ",";
|
||||
}
|
||||
|
||||
$this->UnitConvertor($dec_point , $thousand_sep );
|
||||
|
||||
} // end func UnitConvertor
|
||||
|
||||
function find_base_unit($from,$to) {
|
||||
while (list($skey,$sval) = each($this->bases)) {
|
||||
if ($skey == $from || $to == $skey || in_array($to,$sval) || in_array($from,$sval)) {
|
||||
return $skey;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTable($value, $from_unit, $to_unit, $precision) {
|
||||
|
||||
if ($base_unit = $this->find_base_unit($from_unit,$to_unit)) {
|
||||
|
||||
// A baseunit was found now lets convert from -> $base_unit
|
||||
|
||||
$cell ['value'] = $this->convert($value, $from_unit, $base_unit, $precision)." ".$base_unit;
|
||||
$cell ['class'] = ($base_unit == $from_unit || $base_unit == $to_unit) ? "framedred": "";
|
||||
$cells[] = $cell;
|
||||
// We now have the base unit and value now lets produce the table;
|
||||
while (list($key,$val) = each($this->bases[$base_unit])) {
|
||||
$cell ['value'] = $this->convert($value, $from_unit, $val, $precision)." ".$val;
|
||||
$cell ['class'] = ($val == $from_unit || $val == $to_unit) ? "framedred": "";
|
||||
$cells[] = $cell;
|
||||
}
|
||||
|
||||
$cc = count($cells);
|
||||
$string = "<table class=\"framed grayish\" border=\"1\" cellpadding=\"5\" width=\"80%\" align=\"center\"><tr>";
|
||||
$string .= "<td rowspan=\"$cc\" align=\"center\">$value $from_unit</td>";
|
||||
$i=0;
|
||||
foreach ($cells as $cell) {
|
||||
if ($i==0) {
|
||||
$string .= "<td class=\"".$cell['class']."\">".$cell['value']."</td>";
|
||||
$i++;
|
||||
} else {
|
||||
$string .= "</tr><tr><td class=\"".$cell['class']."\">".$cell['value']."</td>";
|
||||
}
|
||||
}
|
||||
$string .= "</tr></table>";
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$conv = new TP_Converter('en');
|
||||
|
||||
|
||||
$conversions = array(
|
||||
'Temperature'=>array('base' =>'Celsius',
|
||||
'conv'=>array(
|
||||
'Fahrenheit'=>array('ratio'=>1.8, 'offset'=>32),
|
||||
'Kelvin'=>array('ratio'=>1, 'offset'=>273),
|
||||
'Reaumur'=>0.8
|
||||
)
|
||||
),
|
||||
'Weight' => array('base' =>'kg',
|
||||
'conv'=>array(
|
||||
'g'=>1000,
|
||||
'mg'=>1000000,
|
||||
't'=>0.001,
|
||||
'grain'=>15432,
|
||||
'oz'=>35.274,
|
||||
'lb'=>2.2046,
|
||||
'cwt(UK)' => 0.019684,
|
||||
'cwt(US)' => 0.022046,
|
||||
'ton (US)' => 0.0011023,
|
||||
'ton (UK)' => 0.0009842
|
||||
)
|
||||
),
|
||||
'Distance' => array('base' =>'km',
|
||||
'conv'=>array(
|
||||
'm'=>1000,
|
||||
'dm'=>10000,
|
||||
'cm'=>100000,
|
||||
'mm'=>1000000,
|
||||
'mile'=>0.62137,
|
||||
'naut.mile'=>0.53996,
|
||||
'inch(es)'=>39370,
|
||||
'ft'=>3280.8,
|
||||
'yd'=>1093.6,
|
||||
'furlong'=>4.970969537898672,
|
||||
'fathom'=>546.8066491688539
|
||||
)
|
||||
),
|
||||
'Area' => array('base' =>'km 2',
|
||||
'conv'=>array(
|
||||
'ha'=>100,
|
||||
'acre'=>247.105,
|
||||
'm 2'=>pow(1000,2),
|
||||
'dm 2'=>pow(10000,2),
|
||||
'cm 2'=>pow(100000,2),
|
||||
'mm 2'=>pow(1000000,2),
|
||||
'mile 2'=>pow(0.62137,2),
|
||||
'naut.miles 2'=>pow(0.53996,2),
|
||||
'in 2'=>pow(39370,2),
|
||||
'ft 2'=>pow(3280.8,2),
|
||||
'yd 2'=>pow(1093.6,2),
|
||||
)
|
||||
),
|
||||
'Volume' => array('base' =>'m 3',
|
||||
'conv'=>array(
|
||||
'in 3'=>61023.6,
|
||||
'ft 3'=>35.315,
|
||||
'cm 3'=>pow(10,6),
|
||||
'dm 3'=>1000,
|
||||
'litre'=>1000,
|
||||
'hl'=>10,
|
||||
'yd 3'=>1.30795,
|
||||
'gal(US)'=>264.172,
|
||||
'gal(UK)'=>219.969,
|
||||
'pint' => 2113.376,
|
||||
'quart' => 1056.688,
|
||||
'cup' => 4266.753,
|
||||
'fl oz' => 33814.02,
|
||||
'tablespoon' => 67628.04,
|
||||
'teaspoon' => 202884.1,
|
||||
'pt (UK)'=>1000/0.56826,
|
||||
'barrel petroleum'=>1000/158.99,
|
||||
'Register Tons'=>2.832,
|
||||
'Ocean Tons'=>1.1327
|
||||
)
|
||||
),
|
||||
'Speed' =>array('base' =>'kmph',
|
||||
'conv'=>array(
|
||||
'mps'=>0.0001726031,
|
||||
'milesph'=>0.62137,
|
||||
'knots'=>0.53996,
|
||||
'mach STP'=>0.0008380431,
|
||||
'c (warp)'=>9.265669e-10
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
while (list($key,$val) = each($conversions)) {
|
||||
$conv->addConversion($val['base'], $val['conv']);
|
||||
$list[$key][] = $val['base'];
|
||||
while (list($ukey,$uval) = each($val['conv'])) {
|
||||
$list[$key][] = $ukey;
|
||||
}
|
||||
}
|
||||
|
||||
$o .= '<h3>Unit Conversions</h3>';
|
||||
|
||||
|
||||
if (isset($_POST['from_unit']) && isset($_POST['value'])) {
|
||||
$_POST['value'] = $_POST['value'] + 0;
|
||||
|
||||
|
||||
$o .= ($conv->getTable($_POST['value'], $_POST['from_unit'], $_POST['to_unit'], 5))."</p>";
|
||||
} else {
|
||||
$o .= "<p>Select:</p>";
|
||||
}
|
||||
|
||||
if(isset($_POST['value']))
|
||||
$value = $_POST['value'];
|
||||
else
|
||||
$value = '';
|
||||
|
||||
$o .= '<form action="convert" method="post" name="conversion">';
|
||||
$o .= '<input name="value" type="text" id="value" value="' . $value . '" size="10" maxlength="10" />';
|
||||
$o .= '<select name="from_unit" size="12">';
|
||||
|
||||
|
||||
|
||||
reset($list);
|
||||
while(list($key,$val) = each($list)) {
|
||||
$o .= "\n\t<optgroup label=\"$key\">";
|
||||
while(list($ukey,$uval) = each($val)) {
|
||||
$selected = (($uval == $_POST['from_unit']) ? ' selected="selected" ' : '');
|
||||
$o .= "\n\t\t<option value=\"$uval\" $selected >$uval</option>";
|
||||
}
|
||||
$o .= "\n\t</optgroup>";
|
||||
}
|
||||
|
||||
$o .= '</select>';
|
||||
|
||||
$o .= '<input type="submit" name="Submit" value="Submit" /></form>';
|
||||
|
||||
return $o;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
#facebook-enable-wrapper {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#facebook-disable-wrapper {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#facebook-post-default-form input {
|
||||
margin-top: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
|
@ -1,803 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Installing the Friendika/Facebook connector
|
||||
*
|
||||
* 1. register an API key for your site from developer.facebook.com
|
||||
* a. We'd be very happy if you include "Friendika" in the application name
|
||||
* to increase name recognition. The Friendika icons are also present
|
||||
* in the images directory and may be uploaded as a Facebook app icon.
|
||||
* Use images/friendika-16.jpg for the Icon and images/friendika-128.jpg for the Logo.
|
||||
* b. The url should be your site URL with a trailing slash.
|
||||
* You may use http://portal.friendika.com/privacy as the privacy policy
|
||||
* URL unless your site has different requirements, and
|
||||
* http://portal.friendika.com as the Terms of Service URL unless
|
||||
* you have different requirements. (Friendika is a software application
|
||||
* and does not require Terms of Service, though your installation of it might).
|
||||
* c. Set the following values in your .htconfig.php file
|
||||
* $a->config['facebook']['appid'] = 'xxxxxxxxxxx';
|
||||
* $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
||||
* Replace with the settings Facebook gives you.
|
||||
* 2. Enable the facebook plugin by including it in .htconfig.php - e.g.
|
||||
* $a->config['system']['addon'] = 'plugin1,plugin2,facebook';
|
||||
* 3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
||||
* and click 'Install Facebook Connector'.
|
||||
* 4. This will ask you to login to Facebook and grant permission to the
|
||||
* plugin to do its stuff. Allow it to do so.
|
||||
* 5. You're done. To turn it off visit the Plugin Settings page again and
|
||||
* 'Remove Facebook posting'.
|
||||
*
|
||||
* Vidoes and embeds will not be posted if there is no other content. Links
|
||||
* and images will be converted to a format suitable for the Facebook API and
|
||||
* long posts truncated - with a link to view the full post.
|
||||
*
|
||||
* Facebook contacts will not be able to view private photos, as they are not able to
|
||||
* authenticate to your site to establish identity. We will address this
|
||||
* in a future release.
|
||||
*/
|
||||
|
||||
define('FACEBOOK_MAXPOSTLEN', 420);
|
||||
|
||||
/* declare the facebook_module function so that /facebook url requests will land here */
|
||||
|
||||
function facebook_module() {}
|
||||
|
||||
|
||||
|
||||
/* If a->argv[1] is a nickname, this is a callback from Facebook oauth requests. */
|
||||
|
||||
function facebook_init(&$a) {
|
||||
|
||||
if($a->argc != 2)
|
||||
return;
|
||||
$nick = $a->argv[1];
|
||||
if(strlen($nick))
|
||||
$r = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
|
||||
dbesc($nick)
|
||||
);
|
||||
if(! count($r))
|
||||
return;
|
||||
|
||||
$uid = $r[0]['uid'];
|
||||
$auth_code = (($_GET['code']) ? $_GET['code'] : '');
|
||||
$error = (($_GET['error_description']) ? $_GET['error_description'] : '');
|
||||
|
||||
|
||||
if($error)
|
||||
logger('facebook_init: Error: ' . $error);
|
||||
|
||||
if($auth_code && $uid) {
|
||||
|
||||
$appid = get_config('facebook','appid');
|
||||
$appsecret = get_config('facebook', 'appsecret');
|
||||
|
||||
$x = fetch_url('https://graph.facebook.com/oauth/access_token?client_id='
|
||||
. $appid . '&client_secret=' . $appsecret . '&redirect_uri='
|
||||
. urlencode($a->get_baseurl() . '/facebook/' . $nick)
|
||||
. '&code=' . $auth_code);
|
||||
|
||||
logger('facebook_init: returned access token: ' . $x, LOGGER_DATA);
|
||||
|
||||
if(strpos($x,'access_token=') !== false) {
|
||||
$token = str_replace('access_token=', '', $x);
|
||||
if(strpos($token,'&') !== false)
|
||||
$token = substr($token,0,strpos($token,'&'));
|
||||
set_pconfig($uid,'facebook','access_token',$token);
|
||||
set_pconfig($uid,'facebook','post','1');
|
||||
fb_get_self($uid);
|
||||
fb_get_friends($uid);
|
||||
fb_consume_all($uid);
|
||||
|
||||
}
|
||||
|
||||
// todo: is this a browser session or a server session? where do we go?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function fb_get_self($uid) {
|
||||
$access_token = get_pconfig($uid,'facebook','access_token');
|
||||
if(! $access_token)
|
||||
return;
|
||||
$s = fetch_url('https://graph.facebook.com/me/?access_token=' . $access_token);
|
||||
if($s) {
|
||||
$j = json_decode($s);
|
||||
set_pconfig($uid,'facebook','self_id',(string) $j->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fb_get_friends($uid) {
|
||||
|
||||
$access_token = get_pconfig($uid,'facebook','access_token');
|
||||
if(! $access_token)
|
||||
return;
|
||||
$s = fetch_url('https://graph.facebook.com/me/friends?access_token=' . $access_token);
|
||||
if($s) {
|
||||
logger('facebook: fb_get_friends: ' . $s, LOGGER_DATA);
|
||||
$j = json_decode($s);
|
||||
logger('facebook: fb_get_friends: json: ' . print_r($j,true), LOGGER_DATA);
|
||||
foreach($j->data as $person) {
|
||||
$s = fetch_url('https://graph.facebook.com/' . $person->id . '?access_token=' . $access_token);
|
||||
if($s) {
|
||||
$jp = json_decode($s);
|
||||
logger('fb_get_friends: info: ' . print_r($jp,true), LOGGER_DATA);
|
||||
|
||||
// always use numeric link for consistency
|
||||
|
||||
$jp->link = 'http://facebook.com/profile.php?id=' . $person->id;
|
||||
|
||||
// check if we already have a contact
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($jp->link)
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
|
||||
// check that we have all the photos, this has been known to fail on occasion
|
||||
|
||||
if((! $r[0]['photo']) || (! $r[0]['thumb']) || (! $r[0]['micro'])) {
|
||||
require_once("Photo.php");
|
||||
|
||||
$photos = import_profile_photo('https://graph.facebook.com/' . $jp->id . '/picture', $uid, $r[0]['id']);
|
||||
|
||||
$r = q("UPDATE `contact` SET `photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name-date` = '%s',
|
||||
`uri-date` = '%s',
|
||||
`avatar-date` = '%s'
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
// create contact record
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `addr`, `alias`, `notify`, `poll`,
|
||||
`name`, `nick`, `photo`, `network`, `rel`, `priority`,
|
||||
`writable`, `blocked`, `readonly`, `pending` )
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($jp->link),
|
||||
dbesc(''),
|
||||
dbesc(''),
|
||||
dbesc($jp->id),
|
||||
dbesc('facebook ' . $jp->id),
|
||||
dbesc($jp->name),
|
||||
dbesc(($jp->nickname) ? $jp->nickname : strtolower($jp->first_name)),
|
||||
dbesc('https://graph.facebook.com/' . $jp->id . '/picture'),
|
||||
dbesc(NETWORK_FACEBOOK),
|
||||
intval(REL_BUD),
|
||||
intval(1),
|
||||
intval(1)
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($jp->link),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! count($r)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contact = $r[0];
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
require_once("Photo.php");
|
||||
|
||||
$photos = import_profile_photo($r[0]['photo'],$uid,$contact_id);
|
||||
|
||||
$r = q("UPDATE `contact` SET `photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name-date` = '%s',
|
||||
`uri-date` = '%s',
|
||||
`avatar-date` = '%s'
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact_id)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function facebook_post(&$a) {
|
||||
|
||||
if(local_user()){
|
||||
$value = ((x($_POST,'post_by_default')) ? intval($_POST['post_by_default']) : 0);
|
||||
set_pconfig(local_user(),'facebook','post_by_default', $value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function facebook_content(&$a) {
|
||||
|
||||
if(! local_user()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return '';
|
||||
}
|
||||
|
||||
if($a->argc > 1 && $a->argv[1] === 'remove') {
|
||||
del_pconfig(local_user(),'facebook','post');
|
||||
notice( t('Facebook disabled') . EOL);
|
||||
}
|
||||
|
||||
if($a->argc > 1 && $a->argv[1] === 'friends') {
|
||||
fb_get_friends(local_user());
|
||||
notice( t('Updating contacts') . EOL);
|
||||
}
|
||||
|
||||
|
||||
$fb_installed = get_pconfig(local_user(),'facebook','post');
|
||||
|
||||
$appid = get_config('facebook','appid');
|
||||
|
||||
if(! $appid) {
|
||||
notice( t('Facebook API key is missing.') . EOL);
|
||||
return '';
|
||||
}
|
||||
|
||||
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="'
|
||||
. $a->get_baseurl() . '/addon/facebook/facebook.css' . '" media="all" />' . "\r\n";
|
||||
|
||||
$o .= '<h3>' . t('Facebook Connect') . '</h3>';
|
||||
|
||||
if(! $fb_installed) {
|
||||
$o .= '<div id="facebook-enable-wrapper">';
|
||||
|
||||
$o .= '<a href="https://www.facebook.com/dialog/oauth?client_id=' . $appid . '&redirect_uri='
|
||||
. $a->get_baseurl() . '/facebook/' . $a->user['nickname'] . '&scope=publish_stream,read_stream,offline_access">' . t('Install Facebook connector for this account.') . '</a>';
|
||||
$o .= '</div>';
|
||||
}
|
||||
|
||||
if($fb_installed) {
|
||||
$o .= '<div id="facebook-disable-wrapper">';
|
||||
|
||||
$o .= '<a href="' . $a->get_baseurl() . '/facebook/remove' . '">' . t('Remove Facebook connector') . '</a></div>';
|
||||
|
||||
$o .= '<div id="facebook-post-default-form">';
|
||||
$o .= '<form action="facebook" method="post" >';
|
||||
$post_by_default = get_pconfig(local_user(),'facebook','post_by_default');
|
||||
$checked = (($post_by_default) ? ' checked="checked" ' : '');
|
||||
$o .= '<input type="checkbox" name="post_by_default" value="1"' . $checked . '/>' . ' ' . t('Post to Facebook by default') . '<br />';
|
||||
$o .= '<input type="submit" name="submit" value="' . t('Submit') . '" /></form></div>';
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function facebook_install() {
|
||||
register_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook');
|
||||
register_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets');
|
||||
register_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
|
||||
register_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron');
|
||||
}
|
||||
|
||||
|
||||
function facebook_uninstall() {
|
||||
unregister_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook');
|
||||
unregister_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets');
|
||||
unregister_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings');
|
||||
unregister_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron');
|
||||
}
|
||||
|
||||
|
||||
function facebook_cron($a,$b) {
|
||||
|
||||
$last = get_config('facebook','last_poll');
|
||||
|
||||
$poll_interval = intval(get_config('facebook','poll_interval'));
|
||||
if(! $poll_interval)
|
||||
$poll_interval = 3600;
|
||||
|
||||
if($last) {
|
||||
$next = $last + $poll_interval;
|
||||
if($next > time())
|
||||
return;
|
||||
}
|
||||
|
||||
logger('facebook_cron');
|
||||
|
||||
set_config('facebook','last_poll', time());
|
||||
|
||||
$r = q("SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'post' AND `v` = '1' ");
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
// check for new friends once a day
|
||||
$last_friend_check = get_pconfig($rr['uid'],'facebook','friend_check');
|
||||
if($last_friend_check)
|
||||
$next_friend_check = $last_friend_check + 86400;
|
||||
if($next_friend_check <= time()) {
|
||||
fb_get_friends($rr['uid']);
|
||||
set_pconfig($rr['uid'],'facebook','friend_check',time());
|
||||
}
|
||||
fb_consume_all($rr['uid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function facebook_plugin_settings(&$a,&$b) {
|
||||
|
||||
$b .= '<div class="settings-block">';
|
||||
$b .= '<h3>' . t('Facebook') . '</h3>';
|
||||
$b .= '<a href="facebook">' . t('Facebook Connector Settings') . '</a><br />';
|
||||
$b .= '</div>';
|
||||
|
||||
}
|
||||
|
||||
function facebook_jot_nets(&$a,&$b) {
|
||||
if(! local_user())
|
||||
return;
|
||||
|
||||
$fb_post = get_pconfig(local_user(),'facebook','post');
|
||||
if(intval($fb_post) == 1) {
|
||||
$fb_defpost = get_pconfig(local_user(),'facebook','post_by_default');
|
||||
$selected = ((intval($fb_defpost) == 1) ? ' checked="checked" ' : '');
|
||||
$b .= '<div class="profile-jot-net"><input type="checkbox" name="facebook_enable"' . $selected . 'value="1" /> '
|
||||
. t('Post to Facebook') . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function facebook_post_hook(&$a,&$b) {
|
||||
|
||||
/**
|
||||
* Post to Facebook stream
|
||||
*/
|
||||
|
||||
require_once('include/group.php');
|
||||
|
||||
logger('Facebook post');
|
||||
|
||||
$reply = false;
|
||||
$likes = false;
|
||||
|
||||
if((local_user()) && (local_user() == $b['uid'])) {
|
||||
|
||||
if($b['parent']) {
|
||||
$r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($b['parent']),
|
||||
intval(local_user())
|
||||
);
|
||||
if(count($r) && substr($r[0]['uri'],0,4) === 'fb::')
|
||||
$reply = substr($r[0]['uri'],4);
|
||||
elseif(count($r) && substr($r[0]['extid'],0,4) === 'fb::')
|
||||
$reply = substr($r[0]['extid'],4);
|
||||
else
|
||||
return;
|
||||
logger('facebook reply id=' . $reply);
|
||||
}
|
||||
|
||||
if($b['private'] && $reply == false) {
|
||||
$allow_people = expand_acl($b['allow_cid']);
|
||||
$allow_groups = expand_groups(expand_acl($b['allow_gid']));
|
||||
$deny_people = expand_acl($b['deny_cid']);
|
||||
$deny_groups = expand_groups(expand_acl($b['deny_gid']));
|
||||
|
||||
$recipients = array_unique(array_merge($allow_people,$allow_groups));
|
||||
$deny = array_unique(array_merge($deny_people,$deny_groups));
|
||||
|
||||
$allow_str = dbesc(implode(', ',$recipients));
|
||||
if($allow_str) {
|
||||
$r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $allow_str ) AND `network` = 'face'");
|
||||
$allow_arr = array();
|
||||
if(count($r))
|
||||
foreach($r as $rr)
|
||||
$allow_arr[] = $rr['notify'];
|
||||
}
|
||||
|
||||
$deny_str = dbesc(implode(', ',$deny));
|
||||
if($deny_str) {
|
||||
$r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $deny_str ) AND `network` = 'face'");
|
||||
$deny_arr = array();
|
||||
if(count($r))
|
||||
foreach($r as $rr)
|
||||
$deny_arr[] = $rr['notify'];
|
||||
}
|
||||
|
||||
if(count($deny_arr) && (! count($allow_arr))) {
|
||||
|
||||
// One or more FB folks were denied access but nobody on FB was specifically allowed access.
|
||||
// This might cause the post to be open to public on Facebook, but only to selected members
|
||||
// on another network. Since this could potentially leak a post to somebody who was denied,
|
||||
// we will skip posting it to Facebook with a slightly vague but relevant message that will
|
||||
// hopefully lead somebody to this code comment for a better explanation of what went wrong.
|
||||
|
||||
notice( t('Post to Facebook cancelled because of multi-network access permission conflict.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if it's a private message but no Facebook members are allowed or denied, skip Facebook post
|
||||
|
||||
if((! count($allow_arr)) && (! count($deny_arr)))
|
||||
return;
|
||||
}
|
||||
|
||||
if($b['verb'] == ACTIVITY_LIKE)
|
||||
$likes = true;
|
||||
|
||||
|
||||
$appid = get_config('facebook', 'appid' );
|
||||
$secret = get_config('facebook', 'appsecret' );
|
||||
|
||||
if($appid && $secret) {
|
||||
|
||||
logger('facebook: have appid+secret');
|
||||
|
||||
$fb_post = intval(get_pconfig(local_user(),'facebook','post'));
|
||||
$fb_enable = (($fb_post && x($_POST,'facebook_enable')) ? intval($_POST['facebook_enable']) : 0);
|
||||
$fb_token = get_pconfig(local_user(),'facebook','access_token');
|
||||
|
||||
logger('facebook: $fb_post: ' . $fb_post . ' $fb_enable: ' . $fb_enable . ' $fb_token: ' . $fb_token,LOGGER_DEBUG);
|
||||
|
||||
// post to facebook if it's a public post and we've ticked the 'post to Facebook' box,
|
||||
// or it's a private message with facebook participants
|
||||
// or it's a reply or likes action to an existing facebook post
|
||||
|
||||
if($fb_post && $fb_token && ($fb_enable || $b['private'] || $reply)) {
|
||||
logger('facebook: able to post');
|
||||
require_once('library/facebook.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
$msg = $b['body'];
|
||||
|
||||
logger('Facebook post: original msg=' . $msg, LOGGER_DATA);
|
||||
|
||||
// make links readable before we strip the code
|
||||
|
||||
if(preg_match("/\[url=(.+?)\](.+?)\[\/url\]/is",$msg,$matches)) {
|
||||
|
||||
$link = $matches[1];
|
||||
if(substr($matches[2],0,5) != '[img]' )
|
||||
$linkname = $matches[2];
|
||||
}
|
||||
|
||||
$msg = preg_replace("/\[url=(.+?)\](.+?)\[\/url\]/is",'$2 $1',$msg);
|
||||
|
||||
if(preg_match("/\[img\](.+?)\[\/img\]/is",$msg,$matches))
|
||||
$image = $matches[1];
|
||||
|
||||
$msg = preg_replace("/\[img\](.+?)\[\/img\]/is", t('Image: ') . '$1', $msg);
|
||||
|
||||
|
||||
|
||||
$msg = trim(strip_tags(bbcode($msg)));
|
||||
$msg = html_entity_decode($msg,ENT_QUOTES,'UTF-8');
|
||||
|
||||
if (strlen($msg) > FACEBOOK_MAXPOSTLEN) {
|
||||
$shortlink = "";
|
||||
require_once('library/slinky.php');
|
||||
|
||||
$display_url = $a->get_baseurl() . '/display/' . $a->user['nickname'] . '/' . $b['id'];
|
||||
$slinky = new Slinky( $display_url );
|
||||
// setup a cascade of shortening services
|
||||
// try to get a short link from these services
|
||||
// in the order ur1.ca, trim, id.gd, tinyurl
|
||||
$slinky->set_cascade( array( new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
|
||||
$shortlink = $slinky->short();
|
||||
// the new message will be shortened such that "... $shortlink"
|
||||
// will fit into the character limit
|
||||
$msg = substr($msg, 0, FACEBOOK_MAXPOSTLEN - strlen($shortlink) - 4);
|
||||
$msg .= '... ' . $shortlink;
|
||||
}
|
||||
if(! strlen($msg))
|
||||
return;
|
||||
|
||||
logger('Facebook post: msg=' . $msg, LOGGER_DATA);
|
||||
|
||||
if($likes) {
|
||||
$postvars = array('access_token' => $fb_token);
|
||||
}
|
||||
else {
|
||||
$postvars = array(
|
||||
'access_token' => $fb_token,
|
||||
'message' => $msg
|
||||
);
|
||||
if(isset($image))
|
||||
$postvars['picture'] = $image;
|
||||
if(isset($link))
|
||||
$postvars['link'] = $link;
|
||||
if(isset($linkname))
|
||||
$postvars['name'] = $linkname;
|
||||
}
|
||||
|
||||
if(($b['private']) && (! $b['parent'])) {
|
||||
$postvars['privacy'] = '{"value": "CUSTOM", "friends": "SOME_FRIENDS"';
|
||||
if(count($allow_arr))
|
||||
$postvars['privacy'] .= ',"allow": "' . implode(',',$allow_arr) . '"';
|
||||
if(count($deny_arr))
|
||||
$postvars['privacy'] .= ',"deny": "' . implode(',',$deny_arr) . '"';
|
||||
$postvars['privacy'] .= '}';
|
||||
|
||||
}
|
||||
|
||||
if($reply) {
|
||||
$url = 'https://graph.facebook.com/' . $reply . '/' . (($likes) ? 'likes' : 'comments');
|
||||
}
|
||||
else {
|
||||
$url = 'https://graph.facebook.com/me/feed';
|
||||
if($b['plink'])
|
||||
$postvars['actions'] = '{"name": "' . t('View on Friendika') . '", "link": "' . $b['plink'] . '"}';
|
||||
}
|
||||
|
||||
logger('facebook: post to ' . $url);
|
||||
logger('facebook: postvars: ' . print_r($postvars,true));
|
||||
|
||||
// "test_mode" prevents anything from actually being posted.
|
||||
// Otherwise, let's do it.
|
||||
|
||||
if(! get_config('facebook','test_mode'))
|
||||
$x = post_url($url, $postvars);
|
||||
|
||||
$retj = json_decode($x);
|
||||
if($retj->id) {
|
||||
q("UPDATE `item` SET `extid` = '%s' WHERE `id` = %d LIMIT 1",
|
||||
dbesc('fb::' . $retj->id),
|
||||
intval($b['id'])
|
||||
);
|
||||
}
|
||||
|
||||
logger('Facebook post returns: ' . $x, LOGGER_DEBUG);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function fb_consume_all($uid) {
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
$access_token = get_pconfig($uid,'facebook','access_token');
|
||||
if(! $access_token)
|
||||
return;
|
||||
$s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token);
|
||||
if($s) {
|
||||
$j = json_decode($s);
|
||||
logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA);
|
||||
fb_consume_stream($uid,$j,true);
|
||||
}
|
||||
$s = fetch_url('https://graph.facebook.com/me/home?access_token=' . $access_token);
|
||||
if($s) {
|
||||
$j = json_decode($s);
|
||||
logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA);
|
||||
fb_consume_stream($uid,$j,false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function fb_consume_stream($uid,$j,$wall = false) {
|
||||
$a = get_app();
|
||||
|
||||
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
$user = q("SELECT `nickname` FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if(count($user))
|
||||
$my_local_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
|
||||
|
||||
|
||||
$self_id = get_pconfig($uid,'facebook','self_id');
|
||||
if(! count($j->data) || (! strlen($self_id)))
|
||||
return;
|
||||
|
||||
foreach($j->data as $entry) {
|
||||
logger('fb_consume: entry: ' . print_r($entry,true), LOGGER_DATA);
|
||||
$datarray = array();
|
||||
$we_posted = false;
|
||||
$app = $entry->application;
|
||||
if($app->id == get_config('facebook','appid') && $wall)
|
||||
$we_posted = true;
|
||||
|
||||
$r = q("SELECT * FROM `item` WHERE ( `uri` = '%s' OR `extid` = '%s') AND `uid` = %d LIMIT 1",
|
||||
dbesc('fb::' . $entry->id),
|
||||
dbesc('fb::' . $entry->id),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r)) {
|
||||
$post_exists = true;
|
||||
$orig_post = $r[0];
|
||||
$top_item = $r[0]['id'];
|
||||
}
|
||||
else {
|
||||
$post_exists = false;
|
||||
$orig_post = null;
|
||||
}
|
||||
|
||||
if(! $orig_post) {
|
||||
$datarray['gravity'] = 0;
|
||||
$datarray['uid'] = $uid;
|
||||
$datarray['wall'] = (($wall) ? 1 : 0);
|
||||
$datarray['uri'] = $datarray['parent-uri'] = 'fb::' . $entry->id;
|
||||
$from = $entry->from;
|
||||
if($from->id == $self_id)
|
||||
$datarray['contact-id'] = $self[0]['id'];
|
||||
else {
|
||||
$r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
|
||||
dbesc($from->id),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r))
|
||||
$datarray['contact-id'] = $r[0]['id'];
|
||||
}
|
||||
|
||||
// don't store post if we don't have a contact
|
||||
|
||||
if(! x($datarray,'contact-id'))
|
||||
continue;
|
||||
|
||||
$datarray['verb'] = ACTIVITY_POST;
|
||||
if($wall) {
|
||||
$datarray['owner-name'] = $self[0]['name'];
|
||||
$datarray['owner-link'] = $self[0]['url'];
|
||||
$datarray['owner-avatar'] = $self[0]['thumb'];
|
||||
}
|
||||
$datarray['author-name'] = $from->name;
|
||||
$datarray['author-link'] = 'http://facebook.com/profile.php?id=' . $from->id;
|
||||
$datarray['author-avatar'] = 'https://graph.facebook.com/' . $from->id . '/picture';
|
||||
$datarray['plink'] = $datarray['author-link'] . '&v=wall&story_fbid=' . substr($entry->id,strpos($entry->id,'_') + 1);
|
||||
|
||||
$datarray['body'] = $entry->message;
|
||||
if($entry->picture)
|
||||
$datarray['body'] .= "\n\n" . '[img]' . $entry->picture . '[/img]';
|
||||
if($entry->link)
|
||||
$datarray['body'] .= "\n" . linkify($entry->link);
|
||||
if($entry->name)
|
||||
$datarray['body'] .= "\n" . $entry->name;
|
||||
if($entry->caption)
|
||||
$datarray['body'] .= "\n" . $entry->caption;
|
||||
if($entry->description)
|
||||
$datarray['body'] .= "\n" . $entry->description;
|
||||
$datarray['created'] = datetime_convert('UTC','UTC',$entry->created_time);
|
||||
$datarray['edited'] = datetime_convert('UTC','UTC',$entry->updated_time);
|
||||
if($entry->privacy && $entry->privacy->value !== 'EVERYONE')
|
||||
$datarray['private'] = 1;
|
||||
$top_item = item_store($datarray);
|
||||
$r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($top_item),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r))
|
||||
$orig_post = $r[0];
|
||||
|
||||
}
|
||||
$likers = $entry->likes->data;
|
||||
$comments = $entry->comments->data;
|
||||
|
||||
if(is_array($likers)) {
|
||||
foreach($likers as $likes) {
|
||||
|
||||
if(! $orig_post)
|
||||
continue;
|
||||
|
||||
$r = q("SELECT * FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `verb` = '%s' AND `author-link` = '%s' LIMIT 1",
|
||||
dbesc($orig_post['uri']),
|
||||
intval($uid),
|
||||
dbesc(ACTIVITY_LIKE),
|
||||
dbesc('http://facebook.com/profile.php?id=' . $likes->id)
|
||||
);
|
||||
|
||||
if(count($r))
|
||||
continue;
|
||||
|
||||
$likedata = array();
|
||||
$likedata['parent'] = $top_item;
|
||||
$likedata['verb'] = ACTIVITY_LIKE;
|
||||
$likedata['gravity'] = 3;
|
||||
$likedata['uid'] = $uid;
|
||||
$likedata['wall'] = (($wall) ? 1 : 0);
|
||||
$likedata['uri'] = item_new_uri($a->get_baseurl(), $uid);
|
||||
$likedata['parent-uri'] = $orig_post['uri'];
|
||||
if($likes->id == $self_id)
|
||||
$likedata['contact-id'] = $self[0]['id'];
|
||||
else {
|
||||
$r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
|
||||
dbesc($likes->id),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r))
|
||||
$likedata['contact-id'] = $r[0]['id'];
|
||||
}
|
||||
if(! x($likedata,'contact-id'))
|
||||
$likedata['contact-id'] = $orig_post['contact-id'];
|
||||
|
||||
$likedata['verb'] = ACTIVITY_LIKE;
|
||||
$likedata['author-name'] = $likes->name;
|
||||
$likedata['author-link'] = 'http://facebook.com/profile.php?id=' . $likes->id;
|
||||
$likedata['author-avatar'] = 'https://graph.facebook.com/' . $likes->id . '/picture';
|
||||
|
||||
$author = '[url=' . $likedata['author-link'] . ']' . $likedata['author-name'] . '[/url]';
|
||||
$objauthor = '[url=' . $orig_post['author-link'] . ']' . $orig_post['author-name'] . '[/url]';
|
||||
$post_type = t('status');
|
||||
$plink = '[url=' . $orig_post['plink'] . ']' . $post_type . '[/url]';
|
||||
$likedata['object-type'] = ACTIVITY_OBJ_NOTE;
|
||||
|
||||
$likedata['body'] = sprintf( t('%1$s likes %2$s\'s %3$s'), $author, $objauthor, $plink);
|
||||
$likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' .
|
||||
'<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . $orig_post['plink'] . '">') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';
|
||||
|
||||
$item = item_store($likedata);
|
||||
}
|
||||
}
|
||||
if(is_array($comments)) {
|
||||
foreach($comments as $cmnt) {
|
||||
|
||||
if(! $orig_post)
|
||||
continue;
|
||||
|
||||
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND ( `uri` = '%s' OR `extid` = '%s' ) LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc('fb::' . $cmnt->id),
|
||||
dbesc('fb::' . $cmnt->id)
|
||||
);
|
||||
if(count($r))
|
||||
continue;
|
||||
|
||||
$cmntdata = array();
|
||||
$cmntdata['parent'] = $top_item;
|
||||
$cmntdata['verb'] = ACTIVITY_POST;
|
||||
$cmntdata['gravity'] = 6;
|
||||
$cmntdata['uid'] = $uid;
|
||||
$cmntdata['wall'] = (($wall) ? 1 : 0);
|
||||
$cmntdata['uri'] = 'fb::' . $cmnt->id;
|
||||
$cmntdata['parent-uri'] = $orig_post['uri'];
|
||||
if($cmnt->from->id == $self_id) {
|
||||
$cmntdata['contact-id'] = $self[0]['id'];
|
||||
}
|
||||
else {
|
||||
$r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
|
||||
dbesc($cmnt->from->id),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r))
|
||||
$cmntdata['contact-id'] = $r[0]['id'];
|
||||
}
|
||||
if(! x($cmntdata,'contact-id'))
|
||||
$cmntdata['contact-id'] = $orig_post['contact-id'];
|
||||
|
||||
$cmntdata['created'] = datetime_convert('UTC','UTC',$cmnt->created_time);
|
||||
$cmntdata['edited'] = datetime_convert('UTC','UTC',$cmnt->created_time);
|
||||
$cmntdata['verb'] = ACTIVITY_POST;
|
||||
$cmntdata['author-name'] = $cmnt->from->name;
|
||||
$cmntdata['author-link'] = 'http://facebook.com/profile.php?id=' . $cmnt->from->id;
|
||||
$cmntdata['author-avatar'] = 'https://graph.facebook.com/' . $cmnt->from->id . '/picture';
|
||||
$cmntdata['body'] = $cmnt->message;
|
||||
$item = item_store($cmntdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
.fortunate {
|
||||
margin-top: 25px;
|
||||
margin-left: 100px;
|
||||
margin-bottom: 25px;
|
||||
color: #000088;
|
||||
font-size: 14px;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function fortunate_install() {
|
||||
register_hook('page_end', 'addon/fortunate/fortunate.php', 'fortunate_fetch');
|
||||
}
|
||||
|
||||
function fortunate_uninstall() {
|
||||
unregister_hook('page_end', 'addon/fortunate/fortunate.php', 'fortunate_fetch');
|
||||
}
|
||||
|
||||
|
||||
function fortunate_fetch($a,&$b) {
|
||||
|
||||
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="'
|
||||
. $a->get_baseurl() . '/addon/fortunate/fortunate.css' . '" media="all" />' . "\r\n";
|
||||
|
||||
$s = fetch_url('http://fortunemod.com/cookie.php?numlines=2&equal=1&rand=' . mt_rand());
|
||||
$b .= '<div class="fortunate">' . $s . '</div>';
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Java photo uploader, uses Jumploader
|
||||
*
|
||||
* WARNING: This module currently has privacy issues.
|
||||
* The java package does not pass the permissions array intact and could lead to
|
||||
* photos being seen by people that were excluded from seeing them.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function java_upload_install() {
|
||||
register_hook('photo_upload_form', 'addon/java_upload/java_upload.php', 'java_upload_form');
|
||||
register_hook('photo_post_init', 'addon/java_upload/java_upload.php', 'java_upload_post_init');
|
||||
register_hook('photo_post_end', 'addon/java_upload/java_upload.php', 'java_upload_post_end');
|
||||
}
|
||||
|
||||
|
||||
function java_upload_uninstall() {
|
||||
unregister_hook('photo_upload_form', 'addon/java_upload/java_upload.php', 'java_upload_form');
|
||||
unregister_hook('photo_post_init', 'addon/java_upload/java_upload.php', 'java_upload_post_init');
|
||||
unregister_hook('photo_post_end', 'addon/java_upload/java_upload.php', 'java_upload_post_end');
|
||||
}
|
||||
|
||||
|
||||
function java_upload_form(&$a,&$b) {
|
||||
|
||||
$uploadurl = $b['post_url'];
|
||||
$sessid = session_id();
|
||||
$archive = $a->get_baseurl() . '/addon/java_upload/jumploader_z.jar';
|
||||
$filestext = t('Select files to upload: ');
|
||||
|
||||
$nojava = t('Use the following controls only if the Java uploader [above] fails to launch.');
|
||||
|
||||
$b['default_upload'] = true;
|
||||
|
||||
|
||||
$b['addon_text'] .= <<< EOT
|
||||
|
||||
<div id="photos-upload-select-files-text">$filestext</div>
|
||||
|
||||
<div id="photos_upload_applet_wrapper">
|
||||
<applet name="jumpLoaderApplet"
|
||||
code="jmaster.jumploader.app.JumpLoaderApplet.class"
|
||||
archive="$archive"
|
||||
width="700"
|
||||
height="600"
|
||||
mayscript >
|
||||
<param name="uc_uploadUrl" value="$uploadurl" />
|
||||
<param name="uc_uploadFormName" value="photos-upload-form" />
|
||||
<param name="gc_loggingLeveL" value="FATAL" />
|
||||
<param name="uc_fileParameterName" value="userfile" />
|
||||
<param name="uc_cookie" value="PHPSESSID=$sessid; path=/;" />
|
||||
<param name="vc_disableLocalFileSystem" value="false" />
|
||||
<param name="vc_uploadViewMenuBarVisible" value="false" />
|
||||
<param name="vc_mainViewFileListViewVisible" value="true" />
|
||||
<param name="vc_mainViewFileListViewHeightPercent" value="50" />
|
||||
<param name="vc_mainViewFileTreeViewVisible" value="true" />
|
||||
<param name="vc_mainViewFileTreeViewWidthPercent" value="35" />
|
||||
<param name="vc_lookAndFeel" value="system" />
|
||||
|
||||
</applet>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="photos-upload-no-java-message" >
|
||||
$nojava
|
||||
</div>
|
||||
|
||||
EOT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function java_upload_photo_post_init(&$a,&$b) {
|
||||
|
||||
if($_POST['partitionCount'])
|
||||
$a->data['java_upload'] = true;
|
||||
else
|
||||
$a->data['java_upload'] = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function java_upload_photo_post_end(&$a,&$b) {
|
||||
|
||||
if(x($a->data,'java_upload') && $a->data['java_upload'])
|
||||
killme();
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link href="fileuploader.css" rel="stylesheet" type="text/css">
|
||||
<style>
|
||||
body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><a href="http://github.com/valums/file-uploader">Back to project page</a></p>
|
||||
|
||||
<p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>
|
||||
<p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>
|
||||
|
||||
<div id="file-uploader-demo1">
|
||||
<noscript>
|
||||
<p>Please enable JavaScript to use file uploader.</p>
|
||||
<!-- or put a simple form for upload here -->
|
||||
</noscript>
|
||||
</div>
|
||||
|
||||
<script src="fileuploader.js" type="text/javascript"></script>
|
||||
<script>
|
||||
function createUploader(){
|
||||
var uploader = new qq.FileUploader({
|
||||
element: document.getElementById('file-uploader-demo1'),
|
||||
action: 'do-nothing.htm',
|
||||
debug: true
|
||||
});
|
||||
}
|
||||
|
||||
// in your app create uploader as soon as the DOM is ready
|
||||
// don't wait for the window to load
|
||||
window.onload = createUploader;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1 +0,0 @@
|
|||
{success:true}
|
|
@ -1,31 +0,0 @@
|
|||
.qq-uploader { position:relative; width: 100%;}
|
||||
|
||||
.qq-upload-button {
|
||||
display:block; /* or inline-block */
|
||||
width: 105px; padding: 7px 0; text-align:center;
|
||||
background:#880000; border-bottom:1px solid #ddd;color:#fff;
|
||||
}
|
||||
.qq-upload-button-hover {background:#cc0000;}
|
||||
.qq-upload-button-focus {outline:1px dotted black;}
|
||||
|
||||
.qq-upload-drop-area {
|
||||
position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
|
||||
background:#FF9797; text-align:center;
|
||||
}
|
||||
.qq-upload-drop-area span {
|
||||
display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
|
||||
}
|
||||
.qq-upload-drop-area-active {background:#FF7171;}
|
||||
|
||||
.qq-upload-list {margin:15px 35px; padding:0; list-style:disc;}
|
||||
.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px;}
|
||||
.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.qq-upload-file {}
|
||||
.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
|
||||
.qq-upload-size,.qq-upload-cancel {font-size:11px;}
|
||||
|
||||
.qq-upload-failed-text {display:none;}
|
||||
.qq-upload-fail .qq-upload-failed-text {display:inline;}
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,339 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -1,24 +0,0 @@
|
|||
File uploader component is licensed under GNU GPL 2 or later, see gpl-2.0.txt.
|
||||
© 2010 Andrew Valums
|
||||
|
||||
This distribution also includes:
|
||||
|
||||
server/OctetStreamReader.java
|
||||
Dual Licensed under the MIT and GPL v.2
|
||||
|
||||
jQuery JavaScript Library
|
||||
http://jquery.com/
|
||||
Copyright 2010, John Resig
|
||||
Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
http://jquery.org/license
|
||||
|
||||
Sizzle.js - CSS selector engine used by jQuery
|
||||
http://sizzlejs.com/
|
||||
Copyright 2010, The Dojo Foundation
|
||||
Released under the MIT, BSD, and GPL Licenses.
|
||||
|
||||
QUnit - A JavaScript Unit Testing Framework
|
||||
http://docs.jquery.com/QUnit
|
||||
Copyright (c) 2009 John Resig, Jörn Zaefferer
|
||||
Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
and GPL (GPL-LICENSE.txt) licenses.
|
|
@ -1,152 +0,0 @@
|
|||
[donation_link]: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=3PMY37SL9L888&lc=US&item_name=JavaScript%20file%20uploader¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
|
||||
|
||||
This plugin uses XHR for uploading multiple files with progress-bar in FF3.6+, Safari4+,
|
||||
Chrome and falls back to hidden iframe based upload in other browsers,
|
||||
providing good user experience everywhere.
|
||||
|
||||
### <a href="http://valums.com/files/2010/file-uploader/demo.htm">Demo</a> [Donate][donation_link] ###
|
||||
|
||||
### Features ###
|
||||
* multiple file select, progress-bar in FF, Chrome, Safari
|
||||
* drag-and-drop file select in FF, Chrome
|
||||
* uploads are cancellable
|
||||
* no external dependencies
|
||||
* doesn't use Flash
|
||||
* fully working with https
|
||||
* keyboard support in FF, Chrome, Safari
|
||||
* tested in IE7,8; Firefox 3,3.6,4; Safari4,5; Chrome; Opera10.60;
|
||||
|
||||
### License ###
|
||||
This plugin is open sourced under <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPL 2</a> or later.
|
||||
If this license doesn't suit you mail me at andrew (at) valums.com.
|
||||
|
||||
Please [donate][donation_link] if you are willing to support the further development of file upload plugin.
|
||||
|
||||
### Known Issues ###
|
||||
Plugin breaks back button functionality in Opera.
|
||||
|
||||
### Getting started ###
|
||||
The fileuploader.js contains two classes that are meant to be used directly.
|
||||
If you need a complete upload widget (from demo) to quickly drop
|
||||
into your current design, use qq.FileUploader.
|
||||
|
||||
If you want to customize uploader, by using a different looking file list
|
||||
or change the behaviour or functionality use qq.FileUploaderBasic.
|
||||
|
||||
The difference between them is that qq.FileUploader provides a list of files,
|
||||
drag-and-drop, but qq.FileUploaderBasic only creates button and handles validation.
|
||||
Basic uploader is easier extendable, and doesn't limit possible customization.
|
||||
|
||||
qq.FileUploader extends qq.FileUploaderBasic, so that all the options present
|
||||
in the basic uploader also exist in the full widget.
|
||||
|
||||
### qq.FileUploader - Setting up full upload widget ###
|
||||
|
||||
Include fileuploader.js and fileuploader.css into your page.
|
||||
Create container element.
|
||||
|
||||
<div id="file-uploader">
|
||||
<noscript>
|
||||
<p>Please enable JavaScript to use file uploader.</p>
|
||||
<!-- or put a simple form for upload here -->
|
||||
</noscript>
|
||||
</div>
|
||||
|
||||
Initialize uploader when the DOM is ready. Change the action option.
|
||||
For example ../server/php.php for the default folder structure.
|
||||
In the server folder you will find examples for different platforms.
|
||||
If you can't find the one you need, check the readme.txt in the same folder.
|
||||
|
||||
var uploader = new qq.FileUploader({
|
||||
// pass the dom node (ex. $(selector)[0] for jQuery users)
|
||||
element: document.getElementById('file-uploader'),
|
||||
// path to server-side upload script
|
||||
action: '/server/upload'
|
||||
});
|
||||
|
||||
### Options of both classes ###
|
||||
|
||||
// url of the server-side upload script, should be on the same domain
|
||||
action: '/server/upload',
|
||||
// additional data to send, name-value pairs
|
||||
params: {},
|
||||
|
||||
// validation
|
||||
// ex. ['jpg', 'jpeg', 'png', 'gif'] or []
|
||||
allowedExtensions: [],
|
||||
// each file size limit in bytes
|
||||
// this option isn't supported in all browsers
|
||||
sizeLimit: 0, // max size
|
||||
minSizeLimit: 0, // min size
|
||||
|
||||
// set to true to output server response to console
|
||||
debug: false,
|
||||
|
||||
// events
|
||||
// you can return false to abort submit
|
||||
onSubmit: function(id, fileName){},
|
||||
onProgress: function(id, fileName, loaded, total){},
|
||||
onComplete: function(id, fileName, responseJSON){},
|
||||
onCancel: function(id, fileName){},
|
||||
|
||||
messages: {
|
||||
// error messages, see qq.FileUploaderBasic for content
|
||||
},
|
||||
showMessage: function(message){ alert(message); }
|
||||
|
||||
Instance methods
|
||||
|
||||
* setParams(newParams)
|
||||
|
||||
#### Changing alert/messages to something more user friendly ####
|
||||
|
||||
If you limited file types and max size, you will probably want to change the default alert and
|
||||
messages as you see fit, this is possible using showMessage callback and messages option.
|
||||
|
||||
#### Sending additional params ####
|
||||
|
||||
To add a parameter that will be passed as a query string with each upload use params option.
|
||||
|
||||
var uploader = new qq.FileUploader({
|
||||
element: document.getElementById('file-uploader'),
|
||||
action: '/server-side.upload',
|
||||
// additional data to send, name-value pairs
|
||||
params: {
|
||||
param1: 'value1',
|
||||
param2: 'value2'
|
||||
}
|
||||
});
|
||||
|
||||
To change params based on the state of your app, use
|
||||
|
||||
uploader.setParams({
|
||||
anotherParam: 'value'
|
||||
});
|
||||
|
||||
It can be nicely used in onSubmit callback.
|
||||
|
||||
#### Troubleshooting ####
|
||||
|
||||
If you can't get the uploader to work, please try the following steps
|
||||
before asking for help.
|
||||
|
||||
If the upload doesn't complete, saying failed.
|
||||
|
||||
* Set the debug option of the FileUploader to true.
|
||||
* Open the page where you have a FileUploader.
|
||||
* Open developer console in your browser.
|
||||
* Try to upload the file. You should see a server serponse.
|
||||
|
||||
It should be {success:true} for completed requests. If it's not,
|
||||
then you have a problem with your server-side script.
|
||||
|
||||
#### Contributors ####
|
||||
|
||||
Thanks to everybody who contributed, either by sending bug reports or donating. And special thanks to:
|
||||
|
||||
John Yeary
|
||||
Sidney Maestre
|
||||
Patrick Pfeiffer
|
||||
Sean Sandy (SeanJA)
|
||||
Andy Newby
|
||||
Ivan Valles
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 Blue Lotus Software, LLC.
|
||||
* Copyright 2010 John Yeary <jyeary@bluelotussoftware.com>.
|
||||
* Copyright 2010 Allan O'Driscoll
|
||||
*
|
||||
* Dual Licensed MIT and GPL v.2
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* The GNU General Public License (GPL) Version 2, June 1991
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.bluelotussoftware.apache.commons.fileupload.example;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* Reads an <code>application/octet-stream</code> and writes it to a file.
|
||||
* @author John Yeary <jyeary@bluelotussoftware.com>
|
||||
* @author Allan O'Driscoll
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OctetStreamReader extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 6748857432950840322L;
|
||||
private static final String DESTINATION_DIR_PATH = "files";
|
||||
private static String realPath;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @param config
|
||||
* @throws ServletException
|
||||
*/
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH) + "/";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the HTTP <code>POST</code> method.
|
||||
* @param request servlet request
|
||||
* @param response servlet response
|
||||
* @throws ServletException if a servlet-specific error occurs
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException {
|
||||
|
||||
PrintWriter writer = null;
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
|
||||
try {
|
||||
writer = response.getWriter();
|
||||
} catch (IOException ex) {
|
||||
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
|
||||
}
|
||||
|
||||
String filename = request.getHeader("X-File-Name");
|
||||
try {
|
||||
is = request.getInputStream();
|
||||
fos = new FileOutputStream(new File(realPath + filename));
|
||||
IOUtils.copy(is, fos);
|
||||
response.setStatus(response.SC_OK);
|
||||
writer.print("{success: true}");
|
||||
} catch (FileNotFoundException ex) {
|
||||
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
|
||||
writer.print("{success: false}");
|
||||
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
|
||||
} catch (IOException ex) {
|
||||
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
|
||||
writer.print("{success: false}");
|
||||
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
fos.close();
|
||||
is.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<!---
AJAX FileUploader for ColdFusion
version: 1.1.1
feedback: sid.maestre@designovermatter.com
-----------update history----------------
1.1.1 on 9/30/2010 by Martin Webb <martin[at]cubicstate.com>
- Change function for Upload to returnformat equals JSON
- local var scoping.
1.1 on 9/9/2010 by Sid Maestre
- Split Upload function to handle fallback uploads for browsers that don't support XHR data transfer
--->
<cfcomponent hint="I handle AJAX File Uploads from Valum's AJAX file uploader library">
<cffunction name="Upload" access="remote" output="false" returntype="any" returnformat="JSON">
<cfargument name="qqfile" type="string" required="true">
<cfset var local = structNew()>
<cfset local.response = structNew()>
<cfset local.requestData = GetHttpRequestData()>
<!--- check if XHR data exists --->
<cfif len(local.requestData.content) GT 0>
<cfset local.response = UploadFileXhr(arguments.qqfile, local.requestData.content)>
<cfelse>
<!--- no XHR data process as standard form submission --->
<cffile action="upload" fileField="arguments.qqfile" destination="#ExpandPath('.')#" nameConflict="makeunique">
<cfset local.response['success'] = true>
<cfset local.response['type'] = 'form'>
</cfif>
<cfreturn local.response>
</cffunction>
<cffunction name="UploadFileXhr" access="private" output="false" returntype="struct">
<cfargument name="qqfile" type="string" required="true">
<cfargument name="content" type="any" required="true">
<cfset var local = structNew()>
<cfset local.response = structNew()>
<!--- write the contents of the http request to a file.
The filename is passed with the qqfile variable --->
<cffile action="write" file="#ExpandPath('.')#/#arguments.qqfile#" output="#arguments.content#">
<!--- if you want to return some JSON you can do it here.
I'm just passing a success message --->
<cfset local.response['success'] = true>
<cfset local.response['type'] = 'xhr'>
<cfreturn local.response>
</cffunction>
</cfcomponent>
|
|
@ -1 +0,0 @@
|
|||
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="fileuploader.css" rel="stylesheet" type="text/css">
<style>
body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}
</style>
</head>
<body >
<h1>ColdFusion File Uploader Demo</h1>
<p><a href="http://github.com/valums/file-uploader">Back to project page</a></p>
<p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>
<p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>
<div id="file-uploader-demo1">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
<!-- or put a simple form for upload here -->
</noscript>
</div>
<script src="fileuploader.js" type="text/javascript"></script>
<script>
function createUploader(){
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader-demo1'),
action: '/valums/server/coldfusion.cfc',
params: {method: 'Upload'}
});
}
// in your app create uploader as soon as the DOM is ready
// don't wait for the window to load
window.onload = createUploader;
</script>
</body>
</html>
|
|
@ -1,9 +0,0 @@
|
|||
Coldfusion example by Sidney Maestre
|
||||
http://www.designovermatter.com/post.cfm/ajax-file-uploader-for-coldfusion
|
||||
|
||||
1. Unzip Andrew's AJAX Uploader into your web root.
|
||||
2. Replace the demo.htm with demo.cfm in the "client" folder
|
||||
3. Place coldfusion.cfc in the "server" folder
|
||||
4. Browse to the demo.cfm file and try it out. The file should be written to the "server" folder.
|
||||
|
||||
Questions? You can contact Sidney Maestreme by mail (sid.maestre(at)designovermatter.com) or Twitter @SidneyAllen
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
|
||||
use Digest::MD5;
|
||||
|
||||
my $uploaddir = '/folder/to/save/in/ajax_upload/tmp_uploads';
|
||||
|
||||
my $maxFileSize = 0.5 * 1024 * 1024; # 1/2mb max file size...
|
||||
|
||||
use CGI;
|
||||
my $IN = new CGI;
|
||||
|
||||
my $file = $IN->param('POSTDATA');
|
||||
my $temp_id = $IN->param('temp_id');
|
||||
|
||||
# make a random filename, and we guess the file type later on...
|
||||
my $name = Digest::MD5::md5_base64( rand );
|
||||
$name =~ s/\+/_/g;
|
||||
$name =~ s/\//_/g;
|
||||
|
||||
my $type;
|
||||
if ($file =~ /^GIF/) {
|
||||
$type = "gif";
|
||||
} elsif ($file =~ /PNG/) {
|
||||
$type = "png";
|
||||
} elsif ($file =~ /JFIF/) {
|
||||
$type = "jpg";
|
||||
}
|
||||
|
||||
if (!$type) {
|
||||
print qq|{ "success": false, "error": "Invalid file type..." }|;
|
||||
print STDERR "file has been NOT been uploaded... \n";
|
||||
}
|
||||
|
||||
print STDERR "Making dir: $uploaddir/$temp_id \n";
|
||||
|
||||
mkdir("$uploaddir/$temp_id");
|
||||
|
||||
open(WRITEIT, ">$uploaddir/$name.$type") or die "Cant write to $uploaddir/$name.$type. Reason: $!";
|
||||
print WRITEIT $file;
|
||||
close(WRITEIT);
|
||||
|
||||
my $check_size = -s "$uploaddir/$name.$type";
|
||||
|
||||
print STDERR qq|Main filesize: $check_size Max Filesize: $maxFileSize \n\n|;
|
||||
|
||||
print $IN->header();
|
||||
if ($check_size < 1) {
|
||||
print STDERR "ooops, its empty - gonna get rid of it!\n";
|
||||
print qq|{ "success": false, "error": "File is empty..." }|;
|
||||
print STDERR "file has been NOT been uploaded... \n";
|
||||
} elsif ($check_size > $maxFileSize) {
|
||||
print STDERR "ooops, its too large - gonna get rid of it!\n";
|
||||
print qq|{ "success": false, "error": "File is too large..." }|;
|
||||
print STDERR "file has been NOT been uploaded... \n";
|
||||
} else {
|
||||
print qq|{ "success": true }|;
|
||||
|
||||
print STDERR "file has been successfully uploaded... thank you.\n";
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Handle file uploads via XMLHttpRequest
|
||||
*/
|
||||
class qqUploadedFileXhr {
|
||||
/**
|
||||
* Save the file to the specified path
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
function save($path) {
|
||||
$input = fopen("php://input", "r");
|
||||
$temp = tmpfile();
|
||||
$realSize = stream_copy_to_stream($input, $temp);
|
||||
fclose($input);
|
||||
|
||||
if ($realSize != $this->getSize()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$target = fopen($path, "w");
|
||||
fseek($temp, 0, SEEK_SET);
|
||||
stream_copy_to_stream($temp, $target);
|
||||
fclose($target);
|
||||
|
||||
return true;
|
||||
}
|
||||
function getName() {
|
||||
return $_GET['qqfile'];
|
||||
}
|
||||
function getSize() {
|
||||
if (isset($_SERVER["CONTENT_LENGTH"])){
|
||||
return (int)$_SERVER["CONTENT_LENGTH"];
|
||||
} else {
|
||||
throw new Exception('Getting content length is not supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file uploads via regular form post (uses the $_FILES array)
|
||||
*/
|
||||
class qqUploadedFileForm {
|
||||
/**
|
||||
* Save the file to the specified path
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
function save($path) {
|
||||
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function getName() {
|
||||
return $_FILES['qqfile']['name'];
|
||||
}
|
||||
function getSize() {
|
||||
return $_FILES['qqfile']['size'];
|
||||
}
|
||||
}
|
||||
|
||||
class qqFileUploader {
|
||||
private $allowedExtensions = array();
|
||||
private $sizeLimit = 10485760;
|
||||
private $file;
|
||||
|
||||
function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
|
||||
$allowedExtensions = array_map("strtolower", $allowedExtensions);
|
||||
|
||||
$this->allowedExtensions = $allowedExtensions;
|
||||
$this->sizeLimit = $sizeLimit;
|
||||
|
||||
$this->checkServerSettings();
|
||||
|
||||
if (isset($_GET['qqfile'])) {
|
||||
$this->file = new qqUploadedFileXhr();
|
||||
} elseif (isset($_FILES['qqfile'])) {
|
||||
$this->file = new qqUploadedFileForm();
|
||||
} else {
|
||||
$this->file = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function checkServerSettings(){
|
||||
$postSize = $this->toBytes(ini_get('post_max_size'));
|
||||
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
|
||||
|
||||
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
|
||||
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
|
||||
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
|
||||
}
|
||||
}
|
||||
|
||||
private function toBytes($str){
|
||||
$val = trim($str);
|
||||
$last = strtolower($str[strlen($str)-1]);
|
||||
switch($last) {
|
||||
case 'g': $val *= 1024;
|
||||
case 'm': $val *= 1024;
|
||||
case 'k': $val *= 1024;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array('success'=>true) or array('error'=>'error message')
|
||||
*/
|
||||
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
|
||||
if (!is_writable($uploadDirectory)){
|
||||
return array('error' => "Server error. Upload directory isn't writable.");
|
||||
}
|
||||
|
||||
if (!$this->file){
|
||||
return array('error' => 'No files were uploaded.');
|
||||
}
|
||||
|
||||
$size = $this->file->getSize();
|
||||
|
||||
if ($size == 0) {
|
||||
return array('error' => 'File is empty');
|
||||
}
|
||||
|
||||
if ($size > $this->sizeLimit) {
|
||||
return array('error' => 'File is too large');
|
||||
}
|
||||
|
||||
$pathinfo = pathinfo($this->file->getName());
|
||||
$filename = $pathinfo['filename'];
|
||||
//$filename = md5(uniqid());
|
||||
$ext = $pathinfo['extension'];
|
||||
|
||||
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
|
||||
$these = implode(', ', $this->allowedExtensions);
|
||||
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
|
||||
}
|
||||
|
||||
if(!$replaceOldFile){
|
||||
/// don't overwrite previous files that were uploaded
|
||||
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
|
||||
$filename .= rand(10, 99);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
|
||||
return array('success'=>true);
|
||||
} else {
|
||||
return array('error'=> 'Could not save uploaded file.' .
|
||||
'The upload was cancelled, or server error encountered');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
|
||||
$allowedExtensions = array();
|
||||
// max file size in bytes
|
||||
$sizeLimit = 10 * 1024 * 1024;
|
||||
|
||||
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
|
||||
$result = $uploader->handleUpload('uploads/');
|
||||
// to pass data through iframe you will need to encode all html tags
|
||||
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
|
|
@ -1,18 +0,0 @@
|
|||
The server-side code should consist of two parts.
|
||||
|
||||
1. For IE6-8, Opera, older versions of other browsers you get the file as
|
||||
you normally do with regular form-base uploads.
|
||||
|
||||
2. For browsers which upload file with progress bar, you will need to get the raw
|
||||
post data and write it to the file.
|
||||
|
||||
## Return values ##
|
||||
|
||||
You should return json as a text/html, and escape all
|
||||
'<' as '<', '>' as '>', and '&' as '&'.
|
||||
|
||||
Return
|
||||
{"success":true} when upload was successful
|
||||
{"error":"error message to display"} in case of error
|
||||
|
||||
Send me a mail to andrew (at) valums.com, if you will have any questions.
|
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!.gitignore
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$fileName;
|
||||
$fileSize;
|
||||
|
||||
if (isset($_GET['qqfile'])){
|
||||
$fileName = $_GET['qqfile'];
|
||||
|
||||
// xhr request
|
||||
$headers = apache_request_headers();
|
||||
$fileSize = (int)$headers['Content-Length'];
|
||||
} elseif (isset($_FILES['qqfile'])){
|
||||
$fileName = basename($_FILES['qqfile']['name']);
|
||||
$fileSize = $_FILES['qqfile']['size'];
|
||||
} else {
|
||||
die ('{error: "server-error file not passed"}');
|
||||
}
|
||||
|
||||
if ($fileName == '4text.txt'){
|
||||
die ('jsgkdfgu4eyij');
|
||||
}
|
||||
|
||||
if ($fileSize == 0){
|
||||
die ('{error: "server-error file size is zero"}');
|
||||
}
|
||||
|
||||
if ($fileSize < 10){
|
||||
die ('{error: "server-error file size is smaller than 10 bytes"}');
|
||||
}
|
||||
|
||||
if ($fileSize > 9 * 1024){
|
||||
die ('{error: "server-error file size is bigger than 9kB"}');
|
||||
}
|
||||
|
||||
if (count($_GET)){
|
||||
array_merge($_GET, array('fileName'=>$fileName));
|
||||
|
||||
$response = array_merge($_GET, array('success'=>true, 'fileName'=>$fileName));
|
||||
|
||||
// to pass data through iframe you will need to encode all html tags
|
||||
echo htmlspecialchars(json_encode($response), ENT_NOQUOTES);
|
||||
} else {
|
||||
die ('{error: "server-error query params not passed"}');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
sleep(4);
|
||||
|
||||
$fileName;
|
||||
|
||||
if (isset($_GET['qqfile'])){
|
||||
$fileName = $_GET['qqfile'];
|
||||
|
||||
// xhr request
|
||||
$headers = apache_request_headers();
|
||||
if ((int)$headers['Content-Length'] == 0){
|
||||
die ('{error: "content length is zero"}');
|
||||
}
|
||||
} elseif (isset($_FILES['qqfile'])){
|
||||
$fileName = basename($_FILES['qqfile']['name']);
|
||||
|
||||
// form request
|
||||
if ($_FILES['qqfile']['size'] == 0){
|
||||
die ('{error: "file size is zero"}');
|
||||
}
|
||||
} else {
|
||||
die ('{error: "file not passed"}');
|
||||
}
|
||||
|
||||
if (count($_GET)){
|
||||
$_GET['success'] = true;
|
||||
echo json_encode(array_merge($_GET));
|
||||
} else {
|
||||
die ('{error: "query params not passed"}');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
usleep(300);
|
||||
|
||||
$fileName;
|
||||
|
||||
if (isset($_GET['qqfile'])){
|
||||
$fileName = $_GET['qqfile'];
|
||||
|
||||
// xhr request
|
||||
$headers = apache_request_headers();
|
||||
if ((int)$headers['Content-Length'] == 0){
|
||||
die ('{error: "content length is zero"}');
|
||||
}
|
||||
} elseif (isset($_FILES['qqfile'])){
|
||||
$fileName = basename($_FILES['qqfile']['name']);
|
||||
|
||||
// form request
|
||||
if ($_FILES['qqfile']['size'] == 0){
|
||||
die ('{error: "file size is zero"}');
|
||||
}
|
||||
} else {
|
||||
die ('{error: "file not passed"}');
|
||||
}
|
||||
|
||||
if (count($_GET)){
|
||||
//return query params
|
||||
echo json_encode(array_merge($_GET, array('fileName'=>$fileName)));
|
||||
} else {
|
||||
die ('{error: "query params not passed"}');
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
<?php
|
||||
sleep(9);
|
|
@ -1,9 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<p>Drag multiple files into input field. (Win7)</p>
|
||||
<p>Result: One file is selected multiple times. Expected: Multiple files are selected.</p>
|
||||
<input type="file" multiple></body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', function(){
|
||||
document.addEventListener('dragenter', function(e){
|
||||
e.preventDefault();
|
||||
},false);
|
||||
document.addEventListener('dragover', function(e){
|
||||
e.preventDefault();
|
||||
// e.dataTransfer.effectAllowed is none
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
},false);
|
||||
},false);
|
||||
</script>
|
||||
</html>
|
|
@ -1 +0,0 @@
|
|||
<?php header('Content-type: application/javascript'); ?>
|
|
@ -1 +0,0 @@
|
|||
<?php header('Content-type: application/json'); ?>
|
|
@ -1,2 +0,0 @@
|
|||
<?php header("HTTP/1.0 404 Not Found"); ?>
|
||||
Not found!
|
|
@ -1 +0,0 @@
|
|||
I'm a page.
|
|
@ -1,6 +0,0 @@
|
|||
<?php
|
||||
header('Content-type: text/html');
|
||||
|
||||
$data = str_repeat("a", 5000);
|
||||
|
||||
echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
header('Content-type: text/html');
|
||||
$data = array(
|
||||
'example' => "&a<computer networks>, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
|
||||
'sub' => array('arr'=>array(10,20,30), 'boo'=>false)
|
||||
);
|
||||
echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);
|
|
@ -1 +0,0 @@
|
|||
<?php header('Content-type: text/javascript'); ?>
|
|
@ -1,2 +0,0 @@
|
|||
<?php header('Content-type: text/plain'); ?>
|
||||
text<p>P tag</p>
|
|
@ -1,154 +0,0 @@
|
|||
/*!
|
||||
* jQuery JavaScript Library v1.4.2
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Sat Feb 13 22:33:48 2010 -0500
|
||||
*/
|
||||
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
|
||||
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
|
||||
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
|
||||
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
|
||||
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
|
||||
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
|
||||
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
|
||||
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
|
||||
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
|
||||
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
|
||||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
|
||||
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
|
||||
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
|
||||
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
|
||||
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
|
||||
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
|
||||
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
|
||||
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
||||
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
|
||||
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
|
||||
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
|
||||
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
|
||||
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
|
||||
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
|
||||
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
|
||||
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
|
||||
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
|
||||
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
|
||||
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
|
||||
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
|
||||
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
|
||||
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
|
||||
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
|
||||
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
|
||||
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
|
||||
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
|
||||
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
|
||||
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
|
||||
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
|
||||
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
|
||||
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
|
||||
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
|
||||
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
|
||||
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
|
||||
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
|
||||
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
|
||||
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
|
||||
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
|
||||
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
|
||||
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
|
||||
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
|
||||
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
|
||||
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
|
||||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
|
||||
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
|
||||
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
||||
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
|
||||
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
|
||||
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
|
||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
|
||||
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
|
||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
||||
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
|
||||
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
|
||||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
|
||||
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
|
||||
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
|
||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
|
||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
|
||||
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
|
||||
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
||||
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
|
||||
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
|
||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
|
||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
|
||||
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
|
||||
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
||||
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
|
||||
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
|
||||
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
|
||||
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
|
||||
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
||||
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
|
||||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
|
||||
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
|
||||
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
|
||||
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
|
||||
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
|
||||
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
|
||||
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
|
||||
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
|
||||
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
|
||||
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
|
||||
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
|
||||
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
|
||||
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
|
||||
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
|
||||
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
|
||||
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
|
||||
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
|
||||
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
|
||||
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
|
||||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
|
||||
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
|
||||
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
|
||||
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
|
||||
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
|
||||
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
|
||||
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
|
||||
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
|
||||
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
|
||||
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
|
||||
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
|
||||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
|
||||
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
|
||||
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
|
||||
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
|
||||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
|
||||
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
|
||||
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
|
||||
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
|
||||
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
|
||||
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
|
||||
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
|
||||
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
|
||||
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
|
||||
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
|
||||
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
|
@ -1,200 +0,0 @@
|
|||
/*!
|
||||
* jQuery UI 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI
|
||||
*/
|
||||
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.4",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,
|
||||
b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,
|
||||
CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable",
|
||||
"off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
|
||||
"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=
|
||||
parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+
|
||||
b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==
|
||||
b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
|
||||
;/*!
|
||||
* jQuery UI Widget 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Widget
|
||||
*/
|
||||
(function(b,j){var k=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return k.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);
|
||||
b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):
|
||||
this.each(function(){var g=b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});
|
||||
this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}b.each(d,function(f,
|
||||
h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=
|
||||
b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
|
||||
;/*!
|
||||
* jQuery UI Mouse 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Mouse
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
|
||||
this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
|
||||
return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
|
||||
this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
|
||||
a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
|
||||
;/*
|
||||
* jQuery UI Position 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Position
|
||||
*/
|
||||
(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h=
|
||||
0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+=
|
||||
g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k,
|
||||
elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"?
|
||||
-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position=
|
||||
"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);
|
||||
;/*
|
||||
* jQuery UI Draggable 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Draggables
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.mouse.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
|
||||
"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
|
||||
this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
|
||||
this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
|
||||
d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
|
||||
this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,
|
||||
b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
|
||||
a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
|
||||
0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
|
||||
this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
|
||||
(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
|
||||
"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&
|
||||
a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),
|
||||
10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
|
||||
this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():
|
||||
f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+
|
||||
this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+
|
||||
Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-
|
||||
this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=
|
||||
this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.4"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");
|
||||
if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;
|
||||
c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=
|
||||
1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;
|
||||
this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=
|
||||
this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=
|
||||
d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;
|
||||
if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!=
|
||||
"HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-
|
||||
b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
|
||||
c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
|
||||
width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&
|
||||
o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=
|
||||
p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&
|
||||
(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
|
||||
10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
|
||||
;/*
|
||||
* jQuery UI Resizable 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Resizables
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.mouse.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
|
||||
_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
|
||||
top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
|
||||
this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
|
||||
nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
|
||||
String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
|
||||
this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
|
||||
if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
|
||||
d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
|
||||
this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
|
||||
this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
|
||||
b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
|
||||
f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
|
||||
b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
|
||||
a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
|
||||
k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
|
||||
c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
|
||||
this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
|
||||
a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
|
||||
arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
|
||||
{version:"1.8.4"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
|
||||
function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
|
||||
(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
|
||||
false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
|
||||
a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
|
||||
b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
|
||||
"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
|
||||
f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
|
||||
a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
|
||||
a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
|
||||
e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
|
||||
height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
|
||||
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
|
||||
;/*
|
||||
* jQuery UI Dialog 1.8.4
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Dialog
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.button.js
|
||||
* jquery.ui.draggable.js
|
||||
* jquery.ui.mouse.js
|
||||
* jquery.ui.position.js
|
||||
* jquery.ui.resizable.js
|
||||
*/
|
||||
(function(c,j){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");
|
||||
if(typeof this.originalTitle!=="string")this.originalTitle="";var a=this,b=a.options,d=b.title||a.originalTitle||" ",f=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(i){a.moveToTop(false,
|
||||
i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var e=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);
|
||||
return false}).appendTo(e);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",f).html(d).prependTo(e);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;e.find("*").add(e).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&
|
||||
g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");
|
||||
b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,f=d.options;if(f.modal&&!a||!f.stack&&!f.modal)return d._trigger("focus",b);if(f.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=
|
||||
f.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);
|
||||
a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(f){if(f.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),e=g.filter(":first");g=g.filter(":last");if(f.target===g[0]&&!f.shiftKey){e.focus(1);return false}else if(f.target===e[0]&&f.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,
|
||||
f=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(e,h){e=c('<button type="button"></button>').text(e).click(function(){h.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&e.button()});f.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(e){return{position:e.position,
|
||||
offset:e.offset}}var b=this,d=b.options,f=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(e,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",e,a(h))},drag:function(e,h){b._trigger("drag",e,a(h))},stop:function(e,h){d.position=[h.position.left-f.scrollLeft(),h.position.top-f.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);
|
||||
b._trigger("dragStop",e,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}a=a===j?this.options.resizable:a;var d=this,f=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:d._minHeight(),
|
||||
handles:a,start:function(e,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",e,b(h))},resize:function(e,h){d._trigger("resize",e,b(h))},stop:function(e,h){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();d._trigger("resizeStop",e,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,
|
||||
a.height)},_position:function(a){var b=[],d=[0,0],f;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,e){if(+b[g]===b[g]){d[g]=b[g];b[g]=e}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a);
|
||||
f||this.uiDialog.hide()},_setOption:function(a,b){var d=this,f=d.uiDialog,g=f.is(":data(resizable)"),e=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);e=true;break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":f.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case "draggable":b?
|
||||
d._makeDraggable():f.draggable("destroy");break;case "height":e=true;break;case "maxHeight":g&&f.resizable("option","maxHeight",b);e=true;break;case "maxWidth":g&&f.resizable("option","maxWidth",b);e=true;break;case "minHeight":g&&f.resizable("option","minHeight",b);e=true;break;case "minWidth":g&&f.resizable("option","minWidth",b);e=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&f.resizable("destroy");g&&typeof b==="string"&&f.resizable("option","handles",b);!g&&b!==false&&
|
||||
d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break;case "width":e=true;break}c.Widget.prototype._setOption.apply(d,arguments);e&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-
|
||||
b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.4",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
|
||||
create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
|
||||
height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
|
||||
b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,
|
||||
function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
|
||||
;
|
Before Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 251 B |
Before Width: | Height: | Size: 178 B |
Before Width: | Height: | Size: 104 B |
Before Width: | Height: | Size: 125 B |
Before Width: | Height: | Size: 105 B |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 129 B |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB |
|
@ -1,334 +0,0 @@
|
|||
/*
|
||||
* jQuery UI CSS Framework @VERSION
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
.ui-helper-clearfix { display: inline-block; }
|
||||
/* required comment for clearfix to work in Opera \*/
|
||||
* html .ui-helper-clearfix { height:1%; }
|
||||
.ui-helper-clearfix { display:block; }
|
||||
/* end clearfix */
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
|
||||
/*
|
||||
* jQuery UI CSS Framework @VERSION
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
|
||||
.ui-widget .ui-widget { font-size: 1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
|
||||
.ui-widget-content a { color: #333333; }
|
||||
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
|
||||
.ui-widget-header a { color: #ffffff; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
|
||||
.ui-widget :active { outline: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
|
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
|
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
|
||||
.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
|
||||
.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
|
||||
* jQuery UI Resizable @VERSION
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Resizable#theming
|
||||
*/
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
|
||||
* jQuery UI Dialog @VERSION
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Dialog#theming
|
||||
*/
|
||||
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"name": "qunit",
|
||||
"author": {
|
||||
"name": "John Resig",
|
||||
"email": "jeresig@gmail.com",
|
||||
"url": "http://ejohn.org/"
|
||||
},
|
||||
"maintainer": {
|
||||
"name": "Jörn Zaefferer",
|
||||
"email": "joern.zaefferer@googlemail.com",
|
||||
"url": "http://bassistance.de/"
|
||||
},
|
||||
"url": "http://docs.jquery.com/QUnit",
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
"url": "http://www.opensource.org/licenses/mit-license.php"
|
||||
},
|
||||
"description": "An easy-to-use JavaScript Unit Testing framework.",
|
||||
"keywords": [ "testing", "unit", "jquery" ],
|
||||
"lib": "qunit"
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
|
||||
ol#qunit-tests {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
margin:0;
|
||||
padding:0;
|
||||
list-style-position:inside;
|
||||
|
||||
font-size: smaller;
|
||||
}
|
||||
ol#qunit-tests li{
|
||||
padding:0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom:1px solid #fff;
|
||||
font-size:small;
|
||||
list-style-position:inside;
|
||||
}
|
||||
ol#qunit-tests li ol{
|
||||
box-shadow: inset 0px 2px 13px #999;
|
||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
||||
margin-top:0.5em;
|
||||
margin-left:0;
|
||||
padding:0.5em;
|
||||
background-color:#fff;
|
||||
border-radius:15px;
|
||||
-moz-border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
}
|
||||
ol#qunit-tests li li{
|
||||
border-bottom:none;
|
||||
margin:0.5em;
|
||||
background-color:#fff;
|
||||
list-style-position: inside;
|
||||
padding:0.4em 0.5em 0.4em 0.5em;
|
||||
}
|
||||
|
||||
ol#qunit-tests li li.pass{
|
||||
border-left:26px solid #C6E746;
|
||||
background-color:#fff;
|
||||
color:#5E740B;
|
||||
}
|
||||
ol#qunit-tests li li.fail{
|
||||
border-left:26px solid #EE5757;
|
||||
background-color:#fff;
|
||||
color:#710909;
|
||||
}
|
||||
ol#qunit-tests li.pass{
|
||||
background-color:#D2E0E6;
|
||||
color:#528CE0;
|
||||
}
|
||||
ol#qunit-tests li.fail{
|
||||
background-color:#EE5757;
|
||||
color:#000;
|
||||
}
|
||||
ol#qunit-tests li strong {
|
||||
cursor:pointer;
|
||||
}
|
||||
h1#qunit-header{
|
||||
background-color:#0d3349;
|
||||
margin:0;
|
||||
padding:0.5em 0 0.5em 1em;
|
||||
color:#fff;
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
border-top-right-radius:15px;
|
||||
border-top-left-radius:15px;
|
||||
-moz-border-radius-topright:15px;
|
||||
-moz-border-radius-topleft:15px;
|
||||
-webkit-border-top-right-radius:15px;
|
||||
-webkit-border-top-left-radius:15px;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
|
||||
}
|
||||
h2#qunit-banner{
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
height:5px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
h2#qunit-banner.qunit-pass{
|
||||
background-color:#C6E746;
|
||||
}
|
||||
h2#qunit-banner.qunit-fail, #qunit-testrunner-toolbar {
|
||||
background-color:#EE5757;
|
||||
}
|
||||
#qunit-testrunner-toolbar {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
padding:0;
|
||||
/*width:80%;*/
|
||||
padding:0em 0 0.5em 2em;
|
||||
font-size: small;
|
||||
}
|
||||
h2#qunit-userAgent {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
background-color:#2b81af;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:#fff;
|
||||
font-size: small;
|
||||
padding:0.5em 0 0.5em 2.5em;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
p#qunit-testresult{
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
margin:0;
|
||||
font-size: small;
|
||||
color:#2b81af;
|
||||
border-bottom-right-radius:15px;
|
||||
border-bottom-left-radius:15px;
|
||||
-moz-border-radius-bottomright:15px;
|
||||
-moz-border-radius-bottomleft:15px;
|
||||
-webkit-border-bottom-right-radius:15px;
|
||||
-webkit-border-bottom-left-radius:15px;
|
||||
background-color:#D2E0E6;
|
||||
padding:0.5em 0.5em 0.5em 2.5em;
|
||||
}
|
||||
strong b.fail{
|
||||
color:#710909;
|
||||
}
|
||||
strong b.pass{
|
||||
color:#5E740B;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>QUnit Test Suite</title>
|
||||
<link rel="stylesheet" href="../qunit/qunit.css" type="text/css" media="screen">
|
||||
<script type="text/javascript" src="../qunit/qunit.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript" src="same.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">QUnit Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
</body>
|
||||
</html>
|
|
@ -1,171 +0,0 @@
|
|||
test("module without setup/teardown (default)", function() {
|
||||
expect(1);
|
||||
ok(true);
|
||||
});
|
||||
|
||||
test("expect in test", 3, function() {
|
||||
ok(true);
|
||||
ok(true);
|
||||
ok(true);
|
||||
});
|
||||
|
||||
test("expect in test", 1, function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
module("setup test", {
|
||||
setup: function() {
|
||||
ok(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("module with setup", function() {
|
||||
expect(2);
|
||||
ok(true);
|
||||
});
|
||||
|
||||
var state;
|
||||
|
||||
module("setup/teardown test", {
|
||||
setup: function() {
|
||||
state = true;
|
||||
ok(true);
|
||||
},
|
||||
teardown: function() {
|
||||
ok(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("module with setup/teardown", function() {
|
||||
expect(3);
|
||||
ok(true);
|
||||
});
|
||||
|
||||
module("setup/teardown test 2");
|
||||
|
||||
test("module without setup/teardown", function() {
|
||||
expect(1);
|
||||
ok(true);
|
||||
});
|
||||
|
||||
if (typeof setTimeout !== 'undefined') {
|
||||
state = 'fail';
|
||||
|
||||
module("teardown and stop", {
|
||||
teardown: function() {
|
||||
equals(state, "done", "Test teardown.");
|
||||
}
|
||||
});
|
||||
|
||||
test("teardown must be called after test ended", function() {
|
||||
expect(1);
|
||||
stop();
|
||||
setTimeout(function() {
|
||||
state = "done";
|
||||
start();
|
||||
}, 13);
|
||||
});
|
||||
} // end setTimeout tests
|
||||
|
||||
if (typeof asyncTest !== 'undefined') {
|
||||
module("asyncTest");
|
||||
|
||||
asyncTest("asyncTest", function() {
|
||||
expect(2);
|
||||
ok(true);
|
||||
setTimeout(function() {
|
||||
state = "done";
|
||||
ok(true);
|
||||
start();
|
||||
}, 13);
|
||||
});
|
||||
|
||||
asyncTest("asyncTest", 2, function() {
|
||||
ok(true);
|
||||
setTimeout(function() {
|
||||
state = "done";
|
||||
ok(true);
|
||||
start();
|
||||
}, 13);
|
||||
});
|
||||
} // end asyncTest tests
|
||||
|
||||
module("save scope", {
|
||||
setup: function() {
|
||||
this.foo = "bar";
|
||||
},
|
||||
teardown: function() {
|
||||
same(this.foo, "bar");
|
||||
}
|
||||
});
|
||||
test("scope check", function() {
|
||||
expect(2);
|
||||
same(this.foo, "bar");
|
||||
});
|
||||
|
||||
module("simple testEnvironment setup", {
|
||||
foo: "bar",
|
||||
bugid: "#5311" // example of meta-data
|
||||
});
|
||||
test("scope check", function() {
|
||||
same(this.foo, "bar");
|
||||
});
|
||||
test("modify testEnvironment",function() {
|
||||
this.foo="hamster";
|
||||
});
|
||||
test("testEnvironment reset for next test",function() {
|
||||
same(this.foo, "bar");
|
||||
});
|
||||
|
||||
module("testEnvironment with object", {
|
||||
options:{
|
||||
recipe:"soup",
|
||||
ingredients:["hamster","onions"]
|
||||
}
|
||||
});
|
||||
test("scope check", function() {
|
||||
same(this.options, {recipe:"soup",ingredients:["hamster","onions"]}) ;
|
||||
});
|
||||
test("modify testEnvironment",function() {
|
||||
// since we do a shallow copy, the testEnvironment can be modified
|
||||
this.options.ingredients.push("carrots");
|
||||
});
|
||||
test("testEnvironment reset for next test",function() {
|
||||
same(this.options, {recipe:"soup",ingredients:["hamster","onions","carrots"]}, "Is this a bug or a feature? Could do a deep copy") ;
|
||||
});
|
||||
|
||||
|
||||
module("testEnvironment tests");
|
||||
|
||||
function makeurl() {
|
||||
var testEnv = QUnit.current_testEnvironment;
|
||||
var url = testEnv.url || 'http://example.com/search';
|
||||
var q = testEnv.q || 'a search test';
|
||||
return url + '?q='+encodeURIComponent(q);
|
||||
}
|
||||
|
||||
test("makeurl working",function() {
|
||||
equals( QUnit.current_testEnvironment, this, 'The current testEnvironment is global');
|
||||
equals( makeurl(), 'http://example.com/search?q=a%20search%20test', 'makeurl returns a default url if nothing specified in the testEnvironment');
|
||||
});
|
||||
|
||||
module("testEnvironment with makeurl settings",{
|
||||
url:'http://google.com/',
|
||||
q:'another_search_test'
|
||||
});
|
||||
test("makeurl working with settings from testEnvironment",function() {
|
||||
equals( makeurl(), 'http://google.com/?q=another_search_test', 'rather than passing arguments, we use test metadata to form the url');
|
||||
});
|
||||
test("each test can extend the module testEnvironment", {
|
||||
q:'hamstersoup'
|
||||
}, function() {
|
||||
equals( makeurl(), 'http://google.com/?q=hamstersoup', 'url from module, q from test');
|
||||
});
|
||||
|
||||
module("jsDump");
|
||||
test("jsDump output", function() {
|
||||
equals( QUnit.jsDump.parse([1, 2]), "[ 1, 2 ]" );
|
||||
equals( QUnit.jsDump.parse({top: 5, left: 0}), "{ \"top\": 5, \"left\": 0 }" );
|
||||
equals( QUnit.jsDump.parse(document.getElementById("qunit-header")), "<h1 id=\"qunit-header\"></h1>" );
|
||||
equals( QUnit.jsDump.parse(document.getElementsByTagName("h1")), "[ <h1 id=\"qunit-header\"></h1> ]" );
|
||||
})
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1 +0,0 @@
|
|||
satastastast
|
|
@ -1 +0,0 @@
|
|||
satastastast
|
|
@ -1 +0,0 @@
|
|||
satastastast
|
|
@ -1 +0,0 @@
|
|||
s
|
|
@ -1 +0,0 @@
|
|||
satastastast
|
|
@ -1,24 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link href="../client/fileuploader.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="demo"></div>
|
||||
<ul id="separate-list"></ul>
|
||||
|
||||
<script src="../client/fileuploader.js" type="text/javascript"></script>
|
||||
<script>
|
||||
function createUploader(){
|
||||
var uploader = new qq.FileUploader({
|
||||
element: document.getElementById('demo'),
|
||||
listElement: document.getElementById('separate-list'),
|
||||
action: '../client/do-nothing.htm'
|
||||
});
|
||||
}
|
||||
window.onload = createUploader;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,106 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
|
||||
|
||||
<!-- test iwth jquery ui dialog -->
|
||||
<link href="jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css" rel="stylesheet" type="text/css" media="screen" />
|
||||
<script src="jquery-ui/jquery-ui-1.8.4.custom.min.js" type="text/javascript"></script>
|
||||
|
||||
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
|
||||
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
|
||||
|
||||
<link href="../client/fileuploader.css" rel="stylesheet" type="text/css">
|
||||
<script src="../client/fileuploader.js" type="text/javascript" ></script>
|
||||
<script>
|
||||
|
||||
jQuery(function(){
|
||||
$("#dialog").dialog();
|
||||
|
||||
asyncTest("qq.FileUploader", function() {
|
||||
expect(10);
|
||||
|
||||
var submitFileName, submitId;
|
||||
|
||||
var uploader = new qq.FileUploader({
|
||||
element: document.getElementById('file-uploader'),
|
||||
action: 'action-acceptance.php',
|
||||
params: {
|
||||
one: 'value1',
|
||||
two: 'value2'
|
||||
},
|
||||
allowedExtensions: ['txt', 'val', 'webm'],
|
||||
sizeLimit: 9 * 1024,
|
||||
minSizeLimit: 10,
|
||||
onSubmit: function(id, fileName){
|
||||
if (fileName == '5text.txt'){
|
||||
submitId = id;
|
||||
submitFileName = fileName;
|
||||
} else if (fileName == '6text.txt'){
|
||||
uploader.setParams({'new':'newvalue'});
|
||||
|
||||
same(uploader.getInProgress(), 0, 'getFilesInProgress');
|
||||
|
||||
setTimeout(function(){
|
||||
same(uploader.getInProgress(), 1, 'getFilesInProgress');
|
||||
}, 1);
|
||||
} else if (fileName == '8text.txt'){
|
||||
|
||||
setTimeout(function(){
|
||||
same(uploader.getInProgress(), 0, 'all uploads should have finished');
|
||||
start(); // check test results
|
||||
}, 1000);
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onComplete: function(id, fileName, responseJSON){
|
||||
|
||||
if (fileName == '4text.txt'){
|
||||
same(responseJSON, {}, 'should be empty if server returned malformed json');
|
||||
} else if (fileName == '5text.txt'){
|
||||
same(submitId, id, "id in both callbacks match");
|
||||
same(submitFileName, fileName, "filename in both callbacks match");
|
||||
ok(responseJSON.one === 'value1' && responseJSON.two === 'value2', "server received default params");
|
||||
same(responseJSON.fileName, fileName, "filename in onComplete correct");
|
||||
} else if (fileName == '6text.txt'){
|
||||
ok(responseJSON['new'] === 'newvalue' && responseJSON.one == null, "server received new params");
|
||||
same(uploader.getInProgress(), 0, 'upload should have finished');
|
||||
} else if (fileName == '8text.txt'){
|
||||
ok(false, "upload should be cancelled by returning false in onSubmit");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">File uploader tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<p>select files in sample-files dir, following order</p>
|
||||
<ol>
|
||||
<li>select 1imagelong...long.gif, invalid ext error should appear</li>
|
||||
<li>select 2larger.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
|
||||
<li>select 3empty.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
|
||||
<li>select 4text.txt, uploaded file should be marked as failed (server returns jsgkdfgu4eyij)</li>
|
||||
<li>select 5text.txt, callback argument tests</li>
|
||||
<li>select 6text.txt, setParams, isUploading</li>
|
||||
<li>select 7small.txt, too small size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
|
||||
<li>select 8text.txt, returning false in onSubmit cancells upload, file should not be added to list</li>
|
||||
<li>
|
||||
In FF,Chrome, select all files using drag-and-drop, only 1 error should appear.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div id="dialog" title="Basic dialog">
|
||||
File uploader inside a dialog
|
||||
<div id="file-uploader"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.drop-zone {height:100px; width:256px; background:gray; margin:20px;}
|
||||
</style>
|
||||
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
|
||||
<script src="../client/fileuploader.js" type="text/javascript" ></script>
|
||||
<script>
|
||||
|
||||
function createDropZone(selector){
|
||||
var element = $(selector)[0];
|
||||
|
||||
new qq.UploadDropZone({
|
||||
element: element,
|
||||
onEnter: function(){
|
||||
console.log('enter')
|
||||
$(element).css('background', 'green');
|
||||
},
|
||||
onLeave: function(){
|
||||
console.log('leave')
|
||||
},
|
||||
onLeaveNotDescendants: function(){
|
||||
console.log('onLeaveNotDescendants')
|
||||
$(element).css('background', 'gray');
|
||||
},
|
||||
onDrop: function(e){
|
||||
$(element).css('background', 'gray');
|
||||
console.log('drop');
|
||||
console.log(e.dataTransfer.files);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
jQuery(function(){
|
||||
createDropZone('#drop-zone1');
|
||||
createDropZone('#drop-zone2');
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="drop-zone1" class="drop-zone"><p>drop-zone1</p></div>
|
||||
<div id="drop-zone2" class="drop-zone"><p>drop-zone2</p></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
|
||||
|
||||
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
|
||||
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
|
||||
|
||||
<script src="../client/fileuploader.js" type="text/javascript" ></script>
|
||||
<script>
|
||||
jQuery(function(){
|
||||
|
||||
function getHandler(){
|
||||
if(qq.UploadHandlerXhr.isSupported()){
|
||||
return qq.UploadHandlerXhr;
|
||||
} else {
|
||||
return qq.UploadHandlerForm;
|
||||
}
|
||||
}
|
||||
|
||||
asyncTest("upload", function() {
|
||||
expect(2);
|
||||
|
||||
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
|
||||
var savedId;
|
||||
|
||||
var uploadHandler = new (getHandler())({
|
||||
action: 'action-handler-queue-test.php',
|
||||
maxConnections: 1,
|
||||
onComplete: function(id, fileName, response){
|
||||
if (!response.success){
|
||||
ok(false, 'server did not receive file')
|
||||
return;
|
||||
}
|
||||
|
||||
delete response.success;
|
||||
delete response.qqfile;
|
||||
|
||||
same(response, data, 'server received file and data');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#testinput1, #testinput2').change(upload);
|
||||
|
||||
function upload(){
|
||||
setTimeout(start, 9000);
|
||||
|
||||
var file = this;
|
||||
if (uploadHandler instanceof qq.UploadHandlerXhr){
|
||||
file = this.files[0];
|
||||
}
|
||||
var id = uploadHandler.add(file);
|
||||
uploadHandler.upload(id, data);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">File uploader tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
|
||||
<p>
|
||||
Please select a file for each input below,
|
||||
should be less than 4 sec, between selection.
|
||||
</p>
|
||||
|
||||
|
||||
<input id="testinput1" type="file">
|
||||
<input id="testinput2" type="file">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,382 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
|
||||
|
||||
<link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
|
||||
<script src="qunit/qunit/qunit.js" type="text/javascript"></script>
|
||||
|
||||
<script src="../client/fileuploader.js" type="text/javascript" ></script>
|
||||
<script>
|
||||
|
||||
jQuery(function(){
|
||||
|
||||
module('qq');
|
||||
|
||||
test("contains", function(){
|
||||
var el1 = document.createElement('div');
|
||||
var el2 = document.createElement('div');
|
||||
var el3 = document.createElement('div');
|
||||
el1.appendChild(el2);
|
||||
el2.appendChild(el3);
|
||||
|
||||
var el4 = document.createElement('div');
|
||||
|
||||
ok(qq.contains(el1,el1));
|
||||
ok(qq.contains(el1,el2));
|
||||
ok(qq.contains(el1,el3));
|
||||
ok(!qq.contains(el1,el4));
|
||||
ok(!qq.contains(el3,el2));
|
||||
});
|
||||
|
||||
test("hasClass, addClass, removeClass", function(){
|
||||
var element = document.createElement('div');
|
||||
qq.addClass(element, 'some-class');
|
||||
ok(!qq.hasClass(element, 'some'), 'dash in class name');
|
||||
});
|
||||
|
||||
test("children", function(){
|
||||
same(qq.children(document.createElement('div')), [], 'empty');
|
||||
var element = document.createElement('div');
|
||||
element.innerHTML = 'asdasd<div>text</div><span>asdas</span>asdasd';
|
||||
same(qq.children(element).length, 2);
|
||||
});
|
||||
|
||||
test("getByClass", function(){
|
||||
var element = document.createElement('div');
|
||||
element.style.display = 'none';
|
||||
element.innerHTML = '<div class="class"><div class="someclass class"></div></div><span></span><div class="test"></div><div class="class"></div>';
|
||||
document.body.appendChild(element);
|
||||
|
||||
var outside = document.createElement('div');
|
||||
outside.className = 'outside class';
|
||||
document.body.appendChild(outside);
|
||||
|
||||
same(qq.getByClass(document, 'class').length, 4, 'in document');
|
||||
same(qq.getByClass(element, 'class').length, 3, 'in test div');
|
||||
|
||||
qq.remove(element);
|
||||
qq.remove(outside);
|
||||
});
|
||||
|
||||
test("obj2url", function(){
|
||||
var tests = [
|
||||
{title:'empty', obj:{}, expect:''},
|
||||
{title:'general json', obj:{a:'b',c:'d',e:'f'}, expect:'a=b&c=d&e=f'},
|
||||
{title:'general json', obj:{a:1,b:2,c:3,d:4}, expect:'a=1&b=2&c=3&d=4'},
|
||||
{title:'general json array', obj:{a:[1,2,3,4]}, expect:'a[0]=1&a[1]=2&a[2]=3&a[3]=4'},
|
||||
{title:'complex json', obj:{a:'b',c:'d',e:['f',{g:'h',i:['j',{k:'l',m:'n'}],
|
||||
o:undefined,p:true,q:false}]},
|
||||
expect:'a=b&c=d&'
|
||||
+'e[0]=f&'
|
||||
+'e[1][g]=h&'
|
||||
+'e[1][i][0]=j&'
|
||||
+'e[1][i][1][k]=l&'
|
||||
+'e[1][i][1][m]=n&'
|
||||
+'e[1][o]=undefined&'
|
||||
+'e[1][p]=true&'
|
||||
+'e[1][q]=false'},
|
||||
{title:'function', obj:{a:function(){return 'b';}}, expect:'a=b'},
|
||||
{title:'function no return', obj:{a:function(){},undefined:'b'}, expect:'a=undefined'},
|
||||
{title:'null', obj:{a:null}, expect:'a=null'},
|
||||
{title:'prevent double encoding', obj:{a:[1,2,3],'b[]':[4,5,6],'c[d]':[7,8,9]},
|
||||
expect:'a[0]=1&a[1]=2&a[2]=3&'
|
||||
+'b[]=4&b[]=5&b[]=6&'
|
||||
+'c[d][0]=7&c[d][1]=8&c[d][2]=9'},
|
||||
{title:'spaces', obj:{a:'All your base are belong to us'},
|
||||
expect:'a=All+your+base+are+belong+to+us'},
|
||||
{title:'undefined simple', obj:{undefined:undefined}, expect:''},
|
||||
{title:'undefined complex', obj:{undefined:undefined,
|
||||
a:{undefined:undefined},
|
||||
b:[{undefined:'c'},undefined,{d:'e'}]},
|
||||
expect:'b[1]=undefined&b[2][d]=e'},
|
||||
{title:'prefix url no params', obj:{a:'b'},
|
||||
prefix:'http://any.url',
|
||||
expect:'http://any.url?a=b'},
|
||||
{title:'prefix url trailing ?', obj:{a:'b'},
|
||||
prefix:'http://any.url?',
|
||||
expect:'http://any.url?a=b'},
|
||||
{title:'prefix url param', obj:{a:'b'}, prefix:'http://any.url?foo',
|
||||
expect:'http://any.url?foo&a=b'},
|
||||
{title:'prefix url param=value', obj:{a:'b'},
|
||||
prefix:'http://any.url?foo=bar',
|
||||
expect:'http://any.url?foo=bar&a=b'},
|
||||
{title:'prefix url multi param', obj:{a:'b'},
|
||||
prefix:'http://any.url?foo=bar&bla=blub',
|
||||
expect:'http://any.url?foo=bar&bla=blub&a=b'},
|
||||
{title:'prefix url array param', obj:{a:'b',c:'d'},
|
||||
prefix:'http://any.url?foo[0]=bla&foo[1]=blub',
|
||||
expect:'http://any.url?foo[0]=bla&foo[1]=blub&a=b&c=d'}
|
||||
];
|
||||
|
||||
for (var i = 0, l = tests.length; i<l; i++) {
|
||||
//console.log('------------------ obj2url-test'+(i+1)+': '+tests[i].title);
|
||||
//console.log('object: '+tests[i].obj);
|
||||
//console.log('prefix: '+tests[i].prefix);
|
||||
var result = '';
|
||||
if (tests[i].prefix) {
|
||||
result = qq.obj2url(tests[i].obj, tests[i].prefix);
|
||||
} else {
|
||||
result = qq.obj2url(tests[i].obj);
|
||||
}
|
||||
//console.log('result: '+result);
|
||||
same(decodeURIComponent(result), tests[i].expect, tests[i].title);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var uploadTimeout = 700,
|
||||
loadTimeout = 300;
|
||||
|
||||
if (qq.UploadHandlerXhr.isSupported()){
|
||||
$('.handlerform').remove();
|
||||
} else {
|
||||
//
|
||||
module('qq.UploadHandlerForm');
|
||||
//
|
||||
|
||||
asyncTest("_getIframeContentJSON", function() {
|
||||
expect(3);
|
||||
setTimeout(start, loadTimeout);
|
||||
|
||||
var exampleObject = {
|
||||
"example" : "&a<computer networks>, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
|
||||
"sub" : {
|
||||
"arr": [10,20,30],
|
||||
"boo": false
|
||||
}
|
||||
};
|
||||
|
||||
var testedFn = qq.UploadHandlerForm.prototype._getIframeContentJSON;
|
||||
|
||||
// IE 7,8 doesn't support application-javascript, application-json, text-javascript, text-plain
|
||||
// as a response type, it also doesn't file load event when iframe loads page with 404 header
|
||||
createIframe('iframe-content-tests/somepage.php', function(iframe){
|
||||
same(testedFn(iframe), {}, "Server didn't return valid JSON object");
|
||||
});
|
||||
createIframe('iframe-content-tests/text-html.php', function(iframe){
|
||||
same(testedFn(iframe), exampleObject, "text-html");
|
||||
});
|
||||
|
||||
// test larger response (>4k)
|
||||
//http://www.coderholic.com/firefox-4k-xml-node-limit/
|
||||
createIframe('iframe-content-tests/text-html-large.php', function(iframe){
|
||||
same(testedFn(iframe).length, 5000, ">4k");
|
||||
});
|
||||
|
||||
|
||||
function createIframe(src, onLoad){
|
||||
var iframe = document.createElement('iframe');
|
||||
qq.attach(iframe, 'load', function(){
|
||||
onLoad(iframe);
|
||||
|
||||
setTimeout(function(){
|
||||
qq.remove(iframe);
|
||||
}, 1);
|
||||
});
|
||||
iframe.src = src;
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
});
|
||||
|
||||
test("upload, cancel with empty input", function(){
|
||||
expect(1);
|
||||
|
||||
var uploadHandlerForm = new qq.UploadHandlerForm({
|
||||
action: 'action-slow-response.php',
|
||||
onComplete: function(id, fileName, response){
|
||||
ok(false, 'onComplete should not run, the request should be cancelled');
|
||||
}
|
||||
});
|
||||
|
||||
var input = document.createElement('input');
|
||||
var id = uploadHandlerForm.add(input);
|
||||
uploadHandlerForm.cancel(id);
|
||||
|
||||
try {
|
||||
// should fail
|
||||
uploadHandlerForm.upload(id);
|
||||
} catch (err){
|
||||
ok(true, "wasn't uploaded after cancelling")
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
asyncTest("upload", function() {
|
||||
expect(4);
|
||||
|
||||
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
|
||||
var savedId;
|
||||
|
||||
var uploadHandler = new qq.UploadHandlerForm({
|
||||
action: 'action-handler-test.php',
|
||||
onComplete: function(id, fileName, response){
|
||||
ok(savedId == id, 'proper id in callback');
|
||||
same(fileName, uploadHandler.getName(id), 'getName method');
|
||||
|
||||
data.fileName = fileName;
|
||||
same(response, data, 'server received file and correct params, filenames match');
|
||||
}
|
||||
});
|
||||
|
||||
var input = document.getElementById('testinput1');
|
||||
qq.attach(input, 'change', function(){
|
||||
setTimeout(start, uploadTimeout);
|
||||
|
||||
savedId = uploadHandler.add(input);
|
||||
ok(savedId != null, 'id returned by add');
|
||||
|
||||
uploadHandler.upload(savedId, data);
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("cancel", function() {
|
||||
var uploadHandlerForm = new qq.UploadHandlerForm({
|
||||
action: 'action-slow-response.php',
|
||||
onComplete: function(id, fileName, response){
|
||||
ok(false, 'onComplete should not run, the request should be cancelled');
|
||||
}
|
||||
});
|
||||
|
||||
var input = document.getElementById('testinput2');
|
||||
qq.attach(input, 'change', function(){
|
||||
var id = uploadHandlerForm.add(input);
|
||||
uploadHandlerForm.upload(id);
|
||||
uploadHandlerForm.cancel(id);
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
test("check that forms and iframes were removed after use", function(){
|
||||
same($('form,iframe').length, 0, 'check that forms and iframes were removed after use');
|
||||
});
|
||||
|
||||
asyncTest('going back', function(){
|
||||
setTimeout(function(){
|
||||
var goBack = confirm("checking that the history wasn't changed, the page will go back to previous now");
|
||||
if (goBack){
|
||||
window.history.back();
|
||||
|
||||
start();
|
||||
ok(false, "the page didn't change (fails in Opera)");
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (!qq.UploadHandlerXhr.isSupported()){
|
||||
$('.handlerxhr').remove();
|
||||
} else {
|
||||
//
|
||||
module('qq.UploadHandlerXhr');
|
||||
//
|
||||
|
||||
asyncTest("upload", function() {
|
||||
expect(9);
|
||||
|
||||
var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
|
||||
var onProgressCalled = false;
|
||||
var expectedId, expectedName;
|
||||
|
||||
var uploadHandler = new qq.UploadHandlerXhr({
|
||||
action: 'action-handler-test.php',
|
||||
onProgress: function(id, fileName, loaded, total){
|
||||
if (!onProgressCalled) {
|
||||
onProgressCalled = true;
|
||||
|
||||
same(id, expectedId, 'progress event fired with correct id param');
|
||||
same(fileName, expectedName, 'progress event fired with correct fileName param')
|
||||
ok(loaded <= total && total > 0, 'progress event fired with possible loaded and total');
|
||||
|
||||
same(total, uploadHandler.getSize(id), 'getSize method');
|
||||
}
|
||||
},
|
||||
onComplete: function(id, fileName, response){
|
||||
same(id, expectedId, 'progress event fired with correct id param');
|
||||
same(fileName, expectedName, 'progress event fired with correct fileName param')
|
||||
|
||||
data.fileName = fileName;
|
||||
data.qqfile = fileName;
|
||||
|
||||
same(response, data, 'server received passed params, filenames match');
|
||||
|
||||
same(fileName, uploadHandler.getName(id), 'getName method');
|
||||
}
|
||||
});
|
||||
|
||||
var input = document.getElementById('handlerxhr1');
|
||||
|
||||
qq.attach(input, 'change', function(){
|
||||
setTimeout(start, uploadTimeout);
|
||||
|
||||
var id = uploadHandler.add(input.files[0]);
|
||||
ok(id != null, 'id returned by add');
|
||||
|
||||
expectedId = id;
|
||||
expectedName = input.files[0].name || input.files[0].fileName;
|
||||
if (!expectedName){
|
||||
ok(false, 'false value as a file name used');
|
||||
}
|
||||
|
||||
uploadHandler.upload(id, data);
|
||||
|
||||
qq.remove(input);
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("cancel", function() {
|
||||
var uploadHandler = new qq.UploadHandlerXhr({
|
||||
action: 'action-slow-response.php',
|
||||
onComplete: function(id, fileName, response){
|
||||
ok(false, 'onComplete should not run, the request should be cancelled');
|
||||
}
|
||||
});
|
||||
|
||||
var input = document.getElementById('handlerxhr2');
|
||||
if (!input){
|
||||
// input removed because uploading via XHR is not supported
|
||||
return;
|
||||
}
|
||||
|
||||
qq.attach(input, 'change', function(){
|
||||
var id = uploadHandler.add(input.files[0]);
|
||||
uploadHandler.upload(id);
|
||||
uploadHandler.cancel(id);
|
||||
|
||||
start();
|
||||
qq.remove(input);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">File uploader tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<p>
|
||||
Open this page via https connection, and make sure that loading bar is not acting strange after all tests are run.
|
||||
Back button test fails in Opera.
|
||||
</p>
|
||||
|
||||
<p>Please select a file for each input below (in order)</p>
|
||||
|
||||
<p>qq.FileUploader</p>
|
||||
<div id="fileuploader1"></div>
|
||||
|
||||
<p>qq.UploadHandlerForm</p>
|
||||
<input class="handlerform" id="testinput1" type="file">
|
||||
<input class="handlerform" id="testinput2" type="file">
|
||||
|
||||
<p>qq.UploadHandlerXhr</p>
|
||||
<input class="handlerxhr" id="handlerxhr1" type="file">
|
||||
<input class="handlerxhr" id="handlerxhr2" type="file">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* JavaScript Photo/Image Uploader
|
||||
*
|
||||
* Uses Valum 'qq' Uploader.
|
||||
* Module Author: Chris Case
|
||||
*
|
||||
* Prior to enabling, ensure that you have a directory 'uploads'
|
||||
* which is writable by the web server.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function js_upload_install() {
|
||||
register_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
|
||||
register_hook('photo_post_init', 'addon/js_upload/js_upload.php', 'js_upload_post_init');
|
||||
register_hook('photo_post_file', 'addon/js_upload/js_upload.php', 'js_upload_post_file');
|
||||
register_hook('photo_post_end', 'addon/js_upload/js_upload.php', 'js_upload_post_end');
|
||||
}
|
||||
|
||||
|
||||
function js_upload_uninstall() {
|
||||
unregister_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
|
||||
unregister_hook('photo_post_init', 'addon/js_upload/js_upload.php', 'js_upload_post_init');
|
||||
unregister_hook('photo_post_file', 'addon/js_upload/js_upload.php', 'js_upload_post_file');
|
||||
unregister_hook('photo_post_end', 'addon/js_upload/js_upload.php', 'js_upload_post_end');
|
||||
}
|
||||
|
||||
|
||||
function js_upload_form(&$a,&$b) {
|
||||
|
||||
$b['default_upload'] = false;
|
||||
|
||||
$b['addon_text'] .= '<link href="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.css" rel="stylesheet" type="text/css">';
|
||||
$b['addon_text'] .= '<script src="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.js" type="text/javascript"></script>';
|
||||
|
||||
$upload_msg = t('Upload a file');
|
||||
$drop_msg = t('Drop files here to upload');
|
||||
$cancel = t('Cancel');
|
||||
$failed = t('Failed');
|
||||
|
||||
$b['addon_text'] .= <<< EOT
|
||||
|
||||
<div id="file-uploader-demo1">
|
||||
<noscript>
|
||||
<p>Please enable JavaScript to use file uploader.</p>
|
||||
<!-- or put a simple form for upload here -->
|
||||
</noscript>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var uploader = null;
|
||||
function getSelected(opt) {
|
||||
var selected = new Array();
|
||||
var index = 0;
|
||||
for (var intLoop = 0; intLoop < opt.length; intLoop++) {
|
||||
if ((opt[intLoop].selected) ||
|
||||
(opt[intLoop].checked)) {
|
||||
index = selected.length;
|
||||
//selected[index] = new Object;
|
||||
selected[index] = opt[intLoop].value;
|
||||
//selected[index] = intLoop;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
function createUploader() {
|
||||
uploader = new qq.FileUploader({
|
||||
element: document.getElementById('file-uploader-demo1'),
|
||||
action: '{$b['post_url']}',
|
||||
|
||||
template: '<div class="qq-uploader">' +
|
||||
'<div class="qq-upload-drop-area"><span>$drop_msg</span></div>' +
|
||||
'<div class="qq-upload-button">$upload_msg</div>' +
|
||||
'<ul class="qq-upload-list"></ul>' +
|
||||
'</div>',
|
||||
|
||||
// template for one item in file list
|
||||
fileTemplate: '<li>' +
|
||||
'<span class="qq-upload-file"></span>' +
|
||||
'<span class="qq-upload-spinner"></span>' +
|
||||
'<span class="qq-upload-size"></span>' +
|
||||
'<a class="qq-upload-cancel" href="#">$cancel</a>' +
|
||||
'<span class="qq-upload-failed-text">$failed</span>' +
|
||||
'</li>',
|
||||
|
||||
debug: true,
|
||||
onSubmit: function(id,filename) {
|
||||
|
||||
uploader.setParams( {
|
||||
newalbum : document.getElementById('photos-upload-newalbum').value,
|
||||
album : document.getElementById('photos-upload-album-select').value,
|
||||
group_allow : getSelected(document.getElementById('group_allow')).join(','),
|
||||
contact_allow : getSelected(document.getElementById('contact_allow')).join(','),
|
||||
group_deny : getSelected(document.getElementById('group_deny')).join(','),
|
||||
contact_deny : getSelected(document.getElementById('contact_deny')).join(',')
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// in your app create uploader as soon as the DOM is ready
|
||||
// don't wait for the window to load
|
||||
window.onload = createUploader;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
EOT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function js_upload_post_init(&$a,&$b) {
|
||||
|
||||
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
|
||||
|
||||
$allowedExtensions = array("jpeg","gif","png","jpg");
|
||||
|
||||
// max file size in bytes
|
||||
|
||||
$sizeLimit = 6 * 1024 * 1024;
|
||||
|
||||
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
|
||||
|
||||
$result = $uploader->handleUpload();
|
||||
|
||||
|
||||
// to pass data through iframe you will need to encode all html tags
|
||||
$a->data['upload_jsonresponse'] = htmlspecialchars(json_encode($result), ENT_NOQUOTES);
|
||||
|
||||
if(isset($result['error'])) {
|
||||
logger('mod/photos.php: photos_post(): error uploading photo: ' . $result['error'] , 'LOGGER_DEBUG');
|
||||
killme();
|
||||
}
|
||||
|
||||
$a->data['upload_result'] = $result;
|
||||
|
||||
}
|
||||
|
||||
function js_upload_post_file(&$a,&$b) {
|
||||
|
||||
$result = $a->data['upload_result'];
|
||||
|
||||
$b['src'] = $result['path'];
|
||||
$b['filename'] = $result['filename'];
|
||||
$b['filesize'] = filesize($b['src']);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function js_upload_post_end(&$a,&$b) {
|
||||
|
||||
logger('upload_post_end');
|
||||
if(x($a->data,'upload_jsonresponse')) {
|
||||
echo $a->data['upload_jsonresponse'];
|
||||
killme();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle file uploads via XMLHttpRequest
|
||||
*/
|
||||
class qqUploadedFileXhr {
|
||||
|
||||
private $pathnm = '';
|
||||
|
||||
/**
|
||||
* Save the file in the temp dir.
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
function save() {
|
||||
$input = fopen("php://input", "r");
|
||||
$this->pathnm = tempnam(sys_get_temp_dir(),'frn');
|
||||
$temp = fopen($this->pathnm,"w");
|
||||
$realSize = stream_copy_to_stream($input, $temp);
|
||||
|
||||
fclose($input);
|
||||
fclose($temp);
|
||||
|
||||
if ($realSize != $this->getSize()){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getPath() {
|
||||
return $this->pathnm;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $_GET['qqfile'];
|
||||
}
|
||||
|
||||
function getSize() {
|
||||
if (isset($_SERVER["CONTENT_LENGTH"])){
|
||||
return (int)$_SERVER["CONTENT_LENGTH"];
|
||||
} else {
|
||||
throw new Exception('Getting content length is not supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file uploads via regular form post (uses the $_FILES array)
|
||||
*/
|
||||
|
||||
class qqUploadedFileForm {
|
||||
|
||||
|
||||
/**
|
||||
* Save the file to the specified path
|
||||
* @return boolean TRUE on success
|
||||
*/
|
||||
|
||||
|
||||
function save() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getPath() {
|
||||
return $_FILES['qqfile']['tmp_name'];
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $_FILES['qqfile']['name'];
|
||||
}
|
||||
function getSize() {
|
||||
return $_FILES['qqfile']['size'];
|
||||
}
|
||||
}
|
||||
|
||||
class qqFileUploader {
|
||||
private $allowedExtensions = array();
|
||||
private $sizeLimit = 10485760;
|
||||
private $file;
|
||||
|
||||
function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
|
||||
$allowedExtensions = array_map("strtolower", $allowedExtensions);
|
||||
|
||||
$this->allowedExtensions = $allowedExtensions;
|
||||
$this->sizeLimit = $sizeLimit;
|
||||
|
||||
$this->checkServerSettings();
|
||||
|
||||
if (isset($_GET['qqfile'])) {
|
||||
$this->file = new qqUploadedFileXhr();
|
||||
} elseif (isset($_FILES['qqfile'])) {
|
||||
$this->file = new qqUploadedFileForm();
|
||||
} else {
|
||||
$this->file = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkServerSettings(){
|
||||
$postSize = $this->toBytes(ini_get('post_max_size'));
|
||||
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
|
||||
logger('mod/photos.php: qqFileUploader(): upload_max_filesize=' . $uploadSize , 'LOGGER_DEBUG');
|
||||
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
|
||||
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
|
||||
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
|
||||
}
|
||||
}
|
||||
|
||||
private function toBytes($str){
|
||||
$val = trim($str);
|
||||
$last = strtolower($str[strlen($str)-1]);
|
||||
switch($last) {
|
||||
case 'g': $val *= 1024;
|
||||
case 'm': $val *= 1024;
|
||||
case 'k': $val *= 1024;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array('success'=>true) or array('error'=>'error message')
|
||||
*/
|
||||
function handleUpload(){
|
||||
|
||||
if (!$this->file){
|
||||
return array('error' => t('No files were uploaded.'));
|
||||
}
|
||||
|
||||
$size = $this->file->getSize();
|
||||
|
||||
if ($size == 0) {
|
||||
return array('error' => t('Uploaded file is empty'));
|
||||
}
|
||||
|
||||
if ($size > $this->sizeLimit) {
|
||||
|
||||
return array('error' => t('Uploaded file is too large'));
|
||||
}
|
||||
|
||||
|
||||
$maximagesize = get_config('system','maximagesize');
|
||||
|
||||
if(($maximagesize) && ($size > $maximagesize)) {
|
||||
return array('error' => t('Image exceeds size limit of ') . $maximagesize );
|
||||
|
||||
}
|
||||
|
||||
$pathinfo = pathinfo($this->file->getName());
|
||||
$filename = $pathinfo['filename'];
|
||||
|
||||
$ext = $pathinfo['extension'];
|
||||
|
||||
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
|
||||
$these = implode(', ', $this->allowedExtensions);
|
||||
return array('error' => t('File has an invalid extension, it should be one of ') . $these . '.');
|
||||
}
|
||||
|
||||
if ($this->file->save()){
|
||||
return array(
|
||||
'success'=>true,
|
||||
'path' => $this->file->getPath(),
|
||||
'filename' => $filename . '.' . $ext
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'error'=> t('Upload was cancelled, or server error encountered'),
|
||||
'path' => $this->file->getPath(),
|
||||
'filename' => $filename . '.' . $ext
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Friendika addon
|
||||
*
|
||||
* Module: LDAP Authenticate
|
||||
*
|
||||
* Authenticate a user against an LDAP directory
|
||||
* Useful for Windows Active Directory and other LDAP-based organisations
|
||||
* to maintain a single password across the organisation.
|
||||
*
|
||||
* Optionally authenticates only if a member of a given group in the directory.
|
||||
*
|
||||
* The person must have registered with Friendika using the normal registration
|
||||
* procedures in order to have a Friendika user record, contact, and profile.
|
||||
*
|
||||
* Note when using with Windows Active Directory: you may need to set TLS_CACERT in your site
|
||||
* ldap.conf file to the signing cert for your LDAP server.
|
||||
*
|
||||
* The required configuration options for this module may be set in the .htconfig.php file
|
||||
* e.g.:
|
||||
*
|
||||
* $a->config['ldapauth']['ldap_server'] = 'host.example.com';
|
||||
* ...etc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function ldapauth_install() {
|
||||
register_hook('authenticate', 'addon/ldapauth/ldapauth.php', 'ldapauth_hook_authenticate');
|
||||
}
|
||||
|
||||
|
||||
function ldapauth_uninstall() {
|
||||
unregister_hook('authenticate', 'addon/ldapauth/ldapauth.php', 'ldapauth_hook_authenticate');
|
||||
}
|
||||
|
||||
|
||||
function ldapauth_hook_authenticate($a,&$b) {
|
||||
if(ldapauth_authenticate($b['username'],$b['password'])) {
|
||||
$results = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 AND `verified` = 1 LIMIT 1",
|
||||
dbesc($b['username'])
|
||||
);
|
||||
if(count($results)) {
|
||||
$b['user_record'] = $results[0];
|
||||
$b['authenticated'] = 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
function ldapauth_authenticate($username,$password) {
|
||||
|
||||
$ldap_server = get_config('ldapauth','ldap_server');
|
||||
$ldap_binddn = get_config('ldapauth','ldap_binddn');
|
||||
$ldap_bindpw = get_config('ldapauth','ldap_bindpw');
|
||||
$ldap_searchdn = get_config('ldapauth','ldap_searchdn');
|
||||
$ldap_userattr = get_config('ldapauth','ldap_userattr');
|
||||
$ldap_group = get_config('ldapauth','ldap_group');
|
||||
|
||||
if(! ((strlen($password))
|
||||
&& (function_exists('ldap_connect'))
|
||||
&& (strlen($ldap_server))))
|
||||
return false;
|
||||
|
||||
$connect = @ldap_connect($ldap_server);
|
||||
|
||||
if(! $connect)
|
||||
return false;
|
||||
|
||||
@ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION,3);
|
||||
@ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
|
||||
if((@ldap_bind($connect,$ldap_binddn,$ldap_bindpw)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = @ldap_search($connect,$ldap_searchdn, $ldap_userattr . '=' . $username);
|
||||
|
||||
if(! $res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = @ldap_first_entry($connect,$res);
|
||||
|
||||
if(! $id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dn = @ldap_get_dn($connect,$id);
|
||||
|
||||
if(! @ldap_bind($connect,$dn,$password))
|
||||
return false;
|
||||
|
||||
if(! strlen($ldap_group))
|
||||
return true;
|
||||
|
||||
$r = @ldap_compare($connect,$ldap_group,'member',$dn);
|
||||
if ($r === -1) {
|
||||
$err = @ldap_error($connect);
|
||||
$eno = @ldap_errno($connect);
|
||||
@ldap_close($connect);
|
||||
|
||||
if ($eno === 32) {
|
||||
logger("ldapauth: access control group Does Not Exist");
|
||||
return false;
|
||||
}
|
||||
elseif ($eno === 16) {
|
||||
logger('ldapauth: membership attribute does not exist in access control group');
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
logger('ldapauth: error: ' . $err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif ($r === false) {
|
||||
@ldap_close($connect);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
function oembed(){
|
||||
$("#oembed").toggleClass('hide');
|
||||
}
|
||||
|
||||
function oembed_do(){
|
||||
embed = "[embed]"+$('#oembed_url').attr('value')+"[/embed]";
|
||||
|
||||
tinyMCE.execCommand('mceInsertRawHTML',false,embed);
|
||||
oembed();
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* oembed plugin
|
||||
*
|
||||
* oEmbed is a format for allowing an embedded representation of a URL on third party sites
|
||||
* http://www.oembed.com/
|
||||
*
|
||||
*/
|
||||
|
||||
function oembed_install() {
|
||||
register_hook('jot_tool', 'addon/oembed/oembed.php', 'oembed_hook_jot_tool');
|
||||
register_hook('page_header', 'addon/oembed/oembed.php', 'oembed_hook_page_header');
|
||||
}
|
||||
|
||||
function oembed_uninstall() {
|
||||
unregister_hook('jot_tool', 'addon/oembed/oembed.php', 'oembed_hook_jot_tool');
|
||||
unregister_hook('page_header', 'addon/oembed/oembed.php', 'oembed_hook_page_header');
|
||||
}
|
||||
|
||||
function oembed_hook_page_header($a, &$b){
|
||||
|
||||
if(($a->module !== 'network') && ($a->module !== 'profile'))
|
||||
return;
|
||||
|
||||
$b .= '<script src="addon/oembed/oembed.js"></script>
|
||||
<style>#oembed.hide { display: none }
|
||||
#oembed {
|
||||
display:block; position: absolute; width: 300px; height:200px;
|
||||
background-color:#fff; color: #000;
|
||||
border:2px solid #8888FF; padding: 1em;
|
||||
top: 200px; left: 400px; z-index:2000;
|
||||
}
|
||||
#oembed_url { width: 100%; margin-bottom:3px;}
|
||||
</style>';
|
||||
|
||||
$b .= '
|
||||
<div id="oembed" class="hide"><input id="oembed_url">
|
||||
<input type="button" value="Embed" onclick="oembed_do()" style="float:left;">
|
||||
<a onclick="oembed(); return false;" style="float:right;"><img onmouseout="imgdull(this);" onmouseover="imgbright(this);" class="wall-item-delete-icon" src="images/b_drophide.gif" style="width: 16px; height: 16px;"></a>
|
||||
<div style="clear:both">Paste a link from 5min.com, Amazon Product Image, blip.tv, Clikthrough, CollegeHumor Video,
|
||||
Daily Show with Jon Stewart, Dailymotion, dotSUB.com, Flickr Photos, Funny or Die Video,
|
||||
Google Video, Hulu, Kinomap, LiveJournal UserPic, Metacafe, National Film Board of Canada,
|
||||
Phodroid Photos, Photobucket, Qik Video, Revision3, Scribd, SlideShare, TwitPic, Twitter Status,
|
||||
Viddler Video, Vimeo, Wikipedia, Wordpress.com, XKCD Comic, YFrog, YouTube</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
|
||||
function oembed_hook_jot_tool($a, &$b) {
|
||||
$b .= '
|
||||
<div class="tool-wrapper" style="display: $visitor;" >
|
||||
<img class="tool-link" src="addon/oembed/oembed.png" alt="Embed" title="Embed" onclick="oembed();" />
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
Before Width: | Height: | Size: 417 B |
|
@ -1,43 +0,0 @@
|
|||
____ Piwik Plugin ____
|
||||
by Tobias Diekershoff
|
||||
tobias.diekershoff(at)gmx.net
|
||||
|
||||
This addon allows you to embed the code necessary for the FLOSS webanalytics
|
||||
tool piwik into the Friendika pages.
|
||||
|
||||
Online version of this Document: http://ur1.ca/35m2x
|
||||
|
||||
___ Requirements ___
|
||||
|
||||
To use this plugin you need a "piwik":http://piwik.org installation.
|
||||
|
||||
___ Where to find ___
|
||||
|
||||
In the Friendika git repository @/addon/piwik/piwik.php@ and a CSS file for
|
||||
styling the opt-out notice.
|
||||
|
||||
___ Configuration ___
|
||||
|
||||
Open the .htconfig.php file and add "piwik" to the list of activated addons.
|
||||
$a->config['system']['addon'] = "piwik, ..."
|
||||
You have to add 3 more configuration variables for the addon:
|
||||
|
||||
$a->config['piwik']['baseurl'] = 'example.com/piwik/';
|
||||
$a->config['piwik']['sideid'] = '1';
|
||||
$a->config['piwik']['optout'] = true;
|
||||
|
||||
The *baseurl* points to your piwik installation. Use the absolute path,
|
||||
remember trailing slashes but ignore the protocol (http/s) part of the URL.
|
||||
Change the *sideid* parameter to whatever ID you want to use for tracking your
|
||||
Friendika installation. The *optout* parameter (true|false) defines whether or
|
||||
not a short notice about the utilization of piwik will be displayed on every
|
||||
page of your Friendika site (at the bottom of the page with some spacing to the
|
||||
other content). Part of the note is a link that allows the visitor to set an
|
||||
_opt-out_ cookie which will prevent visits from that user be tracked by piwik.
|
||||
|
||||
Currently the optional notice states the following:
|
||||
|
||||
This website is tracked using the Piwik analytics tool. If you do not want
|
||||
that your visits are logged this way you can set a cookie to prevent Piwik
|
||||
from tracking further visits of the site (opt-out).
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#piwik-optout-link {
|
||||
padding: 100px 50px;
|
||||
text-align: justify;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
#piwik-code-block {
|
||||
display: none;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Piwik Analytics Plugin for Friendika
|
||||
*
|
||||
* Author: Tobias Diekershoff
|
||||
* tobias.diekershoff@gmx.net
|
||||
*
|
||||
* License: 3-clause BSD license (same as Friendika)
|
||||
*
|
||||
* Configuration:
|
||||
* Add the following two lines to your .htconfig.php file:
|
||||
*
|
||||
* $a->config['piwik']['baseurl'] = 'www.example.com/piwik/';
|
||||
* $a->config['piwik']['sideid'] = '1';
|
||||
* $a->config['piwik']['optout'] = true; // set to false to disable
|
||||
*
|
||||
* Change the sideid to the ID that the Piwik tracker for your Friendika
|
||||
* installation has. Alter the baseurl to fit your needs, don't care
|
||||
* about http/https but beware to put the trailing / at the end of your
|
||||
* setting.
|
||||
*
|
||||
* Documentation see http://diekershoff.homeunix.net/redmine/wiki/friendikaplugin/Piwik_Plugin
|
||||
*/
|
||||
|
||||
function piwik_install() {
|
||||
register_hook('page_end', 'addon/piwik/piwik.php', 'piwik_analytics');
|
||||
|
||||
logger("installed piwik plugin");
|
||||
}
|
||||
|
||||
function piwik_uninstall() {
|
||||
unregister_hook('page_end', 'addon/piwik/piwik.php', 'piwik_analytics');
|
||||
|
||||
logger("uninstalled piwik plugin");
|
||||
}
|
||||
|
||||
function piwik_analytics($a,&$b) {
|
||||
|
||||
/*
|
||||
* styling of every HTML block added by this plugin is done in the
|
||||
* associated CSS file. We just have to tell Friendika to get it
|
||||
* into the page header.
|
||||
*/
|
||||
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->get_baseurl() . '/addon/piwik/piwik.css' . '" media="all" />' . "\r\n";
|
||||
|
||||
/*
|
||||
* Get the configuration variables from the .htconfig file.
|
||||
*/
|
||||
$baseurl = get_config('piwik','baseurl');
|
||||
$sideod = get_config('piwik','sideid');
|
||||
$optout = get_config('piwik','optout');
|
||||
|
||||
/*
|
||||
* Add the Piwik code for the side.
|
||||
*/
|
||||
$b .= "<div id='piwik-code-block'> <!-- Piwik -->\r\n <script type=\"text/javascript\">\r\n var pkBaseURL = ((\"https:\" == document.location.protocol) ? \"https://".$baseurl."\" : \"http://".$baseurl."\");\r\n document.write(unescape(\"%3Cscript src='\" + pkBaseURL + \"piwik.js' type='text/javascript'%3E%3C/script%3E\"));\r\n </script>\r\n<script type=\"text/javascript\">\r\n try {\r\n var piwikTracker = Piwik.getTracker(pkBaseURL + \"piwik.php\", 8);\r\n piwikTracker.trackPageView();\r\n piwikTracker.enableLinkTracking();\r\n }\r\n catch( err ) {}\r\n </script>\r\n<noscript><p><img src=\"http://".$baseurl."/piwik.php?idsite=8\" style=\"border:0\" alt=\"\" /></p></noscript>\r\n <!-- End Piwik Tracking Tag --> </div>";
|
||||
/*
|
||||
* If the optout variable is set to true then display the notice
|
||||
* otherwise just include the above code into the page.
|
||||
*/
|
||||
if ($optout) {
|
||||
$b .= "<div id='piwik-optout-link'>This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> analytics tool. If you do not want that your visits are logged this way you <a href='http://". $baseurl ."index.php?module=CoreAdminHome&action=optOut'>can set a cookie to prevent Piwik from tracking further visits of the site</a> (opt-out).</div>";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Poor Man Cron. Execute updates on pageviews
|
||||
*
|
||||
* Addon Name: poormancron
|
||||
*
|
||||
*/
|
||||
|
||||
function poormancron_install() {
|
||||
register_hook('page_end', 'addon/poormancron/poormancron.php', 'poormancron_hook');
|
||||
register_hook('proc_run', 'addon/poormancron/poormancron.php','poormancron_procrun');
|
||||
logger("installed poormancron");
|
||||
}
|
||||
|
||||
function poormancron_uninstall() {
|
||||
unregister_hook('page_end', 'addon/poormancron/poormancron.php', 'poormancron_hook');
|
||||
unregister_hook('proc_run', 'addon/poormancron/poormancron.php','poormancron_procrun');
|
||||
logger("removed poormancron");
|
||||
}
|
||||
|
||||
|
||||
|
||||
function poormancron_hook($a,&$b) {
|
||||
$now = time();
|
||||
$lastupdate = get_config('poormancron', 'lastupdate');
|
||||
|
||||
// 300 secs, 5 mins
|
||||
if (!$lastupdate || ($now-$lastupdate)>300) {
|
||||
set_config('poormancron','lastupdate', $now);
|
||||
proc_run('php',"include/poller.php");
|
||||
}
|
||||
}
|
||||
|
||||
function poormancron_procrun($a, $argv) {
|
||||
logger("poormancron procrun ".implode(", ",$argv));
|
||||
array_shift($argv);
|
||||
$argc = count($argv);
|
||||
logger("poormancron procrun require_once ".basename($argv[0]));
|
||||
require_once(basename($argv[0]));
|
||||
$funcname=str_replace(".php", "", basename($argv[0]))."_run";
|
||||
|
||||
$funcname($argv, $argc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
|
||||
|
||||
#randplace-enable-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
#randplace-checkbox {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sample Friendika plugin/addon
|
||||
*
|
||||
* Addon Name: randplace
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Addons are registered with the system in the
|
||||
* .htconfig.php file.
|
||||
*
|
||||
* $a->config['system']['addon'] = 'plugin1,plugin2,etc.';
|
||||
*
|
||||
* When registration is detected, the system calls the plugin
|
||||
* name_install() function, located in 'addon/name/name.php',
|
||||
* where 'name' is the name of the addon.
|
||||
* If the addon is removed from the configuration list, the
|
||||
* system will call the name_uninstall() function.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function randplace_install() {
|
||||
|
||||
/**
|
||||
*
|
||||
* Our demo plugin will attach in three places.
|
||||
* The first is just prior to storing a local post.
|
||||
*
|
||||
*/
|
||||
|
||||
register_hook('post_local', 'addon/randplace/randplace.php', 'randplace_post_hook');
|
||||
|
||||
/**
|
||||
*
|
||||
* Then we'll attach into the plugin settings page, and also the
|
||||
* settings post hook so that we can create and update
|
||||
* user preferences.
|
||||
*
|
||||
*/
|
||||
|
||||
register_hook('plugin_settings', 'addon/randplace/randplace.php', 'randplace_settings');
|
||||
register_hook('plugin_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post');
|
||||
|
||||
logger("installed randplace");
|
||||
}
|
||||
|
||||
|
||||
function randplace_uninstall() {
|
||||
|
||||
/**
|
||||
*
|
||||
* uninstall unregisters any hooks created with register_hook
|
||||
* during install. It may also delete configuration settings
|
||||
* and any other cleanup.
|
||||
*
|
||||
*/
|
||||
|
||||
unregister_hook('post_local', 'addon/randplace/randplace.php', 'randplace_post_hook');
|
||||
unregister_hook('plugin_settings', 'addon/randplace/randplace.php', 'randplace_settings');
|
||||
unregister_hook('plugin_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post');
|
||||
|
||||
|
||||
logger("removed randplace");
|
||||
}
|
||||
|
||||
|
||||
|
||||
function randplace_post_hook($a, &$item) {
|
||||
|
||||
/**
|
||||
*
|
||||
* An item was posted on the local system.
|
||||
* We are going to look for specific items:
|
||||
* - A status post by a profile owner
|
||||
* - The profile owner must have allowed our plugin
|
||||
*
|
||||
*/
|
||||
|
||||
logger('randplace invoked');
|
||||
|
||||
if(! local_user()) /* non-zero if this is a logged in user of this system */
|
||||
return;
|
||||
|
||||
if(local_user() != $item['uid']) /* Does this person own the post? */
|
||||
return;
|
||||
|
||||
if($item['parent']) /* If the item has a parent, this is a comment or something else, not a status post. */
|
||||
return;
|
||||
|
||||
/* Retrieve our personal config setting */
|
||||
|
||||
$active = get_pconfig(local_user(), 'randplace', 'enable');
|
||||
|
||||
if(! $active)
|
||||
return;
|
||||
|
||||
/**
|
||||
*
|
||||
* OK, we're allowed to do our stuff.
|
||||
* Here's what we are going to do:
|
||||
* load the list of timezone names, and use that to generate a list of world cities.
|
||||
* Then we'll pick one of those at random and put it in the "location" field for the post.
|
||||
*
|
||||
*/
|
||||
|
||||
$cities = array();
|
||||
$zones = timezone_identifiers_list();
|
||||
foreach($zones as $zone) {
|
||||
if((strpos($zone,'/')) && (! stristr($zone,'US/')) && (! stristr($zone,'Etc/')))
|
||||
$cities[] = str_replace('_', ' ',substr($zone,strpos($zone,'/') + 1));
|
||||
}
|
||||
|
||||
if(! count($cities))
|
||||
return;
|
||||
$city = array_rand($cities,1);
|
||||
$item['location'] = $cities[$city];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Callback from the settings post function.
|
||||
* $post contains the $_POST array.
|
||||
* We will make sure we've got a valid user account
|
||||
* and if so set our configuration setting for this person.
|
||||
*
|
||||
*/
|
||||
|
||||
function randplace_settings_post($a,$post) {
|
||||
if(! local_user())
|
||||
return;
|
||||
set_pconfig(local_user(),'randplace','enable',intval($_POST['randplace']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Called from the Plugin Setting form.
|
||||
* Add our own settings info to the page.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function randplace_settings(&$a,&$s) {
|
||||
|
||||
if(! local_user())
|
||||
return;
|
||||
|
||||
/* Add our stylesheet to the page so we can make our settings look nice */
|
||||
|
||||
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->get_baseurl() . '/addon/randplace/randplace.css' . '" media="all" />' . "\r\n";
|
||||
|
||||
/* Get the current state of our config variable */
|
||||
|
||||
$enabled = get_pconfig(local_user(),'randplace','enable');
|
||||
|
||||
$checked = (($enabled) ? ' checked="checked" ' : '');
|
||||
|
||||
/* Add some HTML to the existing form */
|
||||
|
||||
$s .= '<div class="settings-block">';
|
||||
$s .= '<h3>' . t('Randplace Settings') . '</h3>';
|
||||
$s .= '<div id="randplace-enable-wrapper">';
|
||||
$s .= '<label id="randplace-enable-label" for="randplace-checkbox">' . t('Enable Randplace Plugin') . '</label>';
|
||||
$s .= '<input id="randplace-checkbox" type="checkbox" name="randplace" value="1" ' . $checked . '/>';
|
||||
$s .= '</div><div class="clear"></div>';
|
||||
|
||||
/* provide a submit button */
|
||||
|
||||
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="submit" class="settings-submit" value="' . t('Submit') . '" /></div></div>';
|
||||
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
____ StatusNet Plugin ____
|
||||
by Tobias Diekershoff
|
||||
tobias.diekershoff(at)gmx.net
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This addon is currently in under development. If you have any problem !!
|
||||
!! with it, please contact the Author. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
With this addon to Friendika you can give your user the possibility to post
|
||||
their public messages to any StatusNet instance like identi.ca for example. The
|
||||
messages will be strapped their rich context and shortened to to the character
|
||||
limit of the StatusNet instance in question if necessary. If shortening of the
|
||||
message was performed a link will be added to the notice pointing to the
|
||||
original message on your server.
|
||||
|
||||
There is a similar plugin to forward public messages to Twitter Twitter Plugin.
|
||||
|
||||
Online version of this document: http://ur1.ca/35mpb
|
||||
|
||||
___ Requirements ___
|
||||
|
||||
Due to the distributed nature of the StatusNet network, each user who wishes to
|
||||
forward public messages to a StatusNet account has get the OAuth credentials
|
||||
for themselves, which makes this addon a little bit more user unfriendly then
|
||||
the Twitter Plugin is. Nothing to geeky though!
|
||||
|
||||
The inclusion of a shorturl for the original posting in cases when the message
|
||||
was longer then the maximal allowed notice length requires it, that you have
|
||||
PHP5+ and curl on your server.
|
||||
Where to find
|
||||
|
||||
In the Friendika git repository /addon/statusnet/, this directory contains all
|
||||
required PHP files (including the Twitter OAuth library [1] by Abraham Williams,
|
||||
MIT licensed and the Slinky library [2] by Beau Lebens, BSD license), a CSS file
|
||||
for styling of the user configuration and an image to Sign in with StatusNet.
|
||||
|
||||
[1] https://github.com/abraham/twitteroauth
|
||||
[2] http://dentedreality.com.au/projects/slinky
|
||||
|
||||
___ Configuration ___
|
||||
|
||||
__ Global Configuration __
|
||||
|
||||
To activate this addon add statusnet to the list of active addons in your
|
||||
.htconfig.php file
|
||||
$a->config['system']['addon'] = "statusnet, ...".
|
||||
|
||||
__ User Configuration __
|
||||
|
||||
When the addon is activated the user has to aquire three things in order to
|
||||
connect to the StatusNet account of choice.
|
||||
* the base URL for the StatusNet API, for identi.ca this is
|
||||
https://identi.ca/api/
|
||||
* OAuth Consumer key & secret
|
||||
|
||||
To get the OAuth Consumer key pair the user has to (a) ask her Friendika admin
|
||||
if a pair already exists or (b) has to register the Friendika server as a
|
||||
client application on the StatusNet server. This can be done from the account
|
||||
settings under "Connect -> Connections -> Register an OAuth client application
|
||||
-> Register new application".
|
||||
|
||||
During the registration of the OAuth client remember the following:
|
||||
* there is no callback url
|
||||
* register a desktop client
|
||||
* with read & write access
|
||||
* the Source URL should be the URL of your Friendika server
|
||||
|
||||
After the required credentials for the application are stored in the
|
||||
configuration you have to actually connect your Friendika account with
|
||||
StatusNet. To do so follow the Sign in with StatusNet button, allow the access
|
||||
and copy the security code into the addon configuration. Friendika will then
|
||||
try to acquire the final OAuth credentials from the API, if successful the
|
||||
addon settings will allow you to select to post your public messages to your
|
||||
StatusNet account.
|
Before Width: | Height: | Size: 5.7 KiB |
|
@ -1,67 +0,0 @@
|
|||
|
||||
|
||||
#statusnet-avatar {
|
||||
float: left;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 2px;
|
||||
}
|
||||
#statusnet-info-block {
|
||||
height: 52px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#statusnet-disconnect-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
#statusnet-disconnect {
|
||||
float: left;
|
||||
}
|
||||
#statusnet-enable-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#statusnet-checkbox {
|
||||
float: left;
|
||||
}
|
||||
#statusnet-pin-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
#statusnet-pin {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
#statusnet-consumerkey-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#statusnet-consumerkey {
|
||||
float: left;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#statusnet-consumersecret-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#statusnet-consumersecret {
|
||||
float: left;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#statusnet-baseapi-label {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
#statusnet-baseapi {
|
||||
float: left;
|
||||
margin-bottom: 8px;
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* StatusNet Plugin for Friendika
|
||||
*
|
||||
* Author: Tobias Diekershoff
|
||||
* tobias.diekershoff@gmx.net
|
||||
*
|
||||
* License:3-clause BSD license (same as Friendika)
|
||||
*
|
||||
* Configuration:
|
||||
* To activate the plugin itself add it to the $a->config['system']['addon']
|
||||
* setting. After this, your user can configure their Twitter account settings
|
||||
* from "Settings -> Plugin Settings".
|
||||
*
|
||||
* Requirements: PHP5, curl [Slinky library]
|
||||
*
|
||||
* Documentation: http://diekershoff.homeunix.net/redmine/wiki/friendikaplugin/StatusNet_Plugin
|
||||
*/
|
||||
|
||||
/* __TODO__
|
||||
*
|
||||
* - what about multimedia content?
|
||||
* so far we just strip HTML tags from the message
|
||||
*/
|
||||
|
||||
|
||||
/***
|
||||
* We have to alter the TwitterOAuth class a little bit to work with any StatusNet
|
||||
* installation abroad. Basically it's only make the API path variable and be happy.
|
||||
*
|
||||
* Thank you guys for the Twitter compatible API!
|
||||
*/
|
||||
|
||||
require_once('library/twitteroauth.php');
|
||||
|
||||
class StatusNetOAuth extends TwitterOAuth {
|
||||
function get_maxlength() {
|
||||
$config = $this->get($this->host . 'statusnet/config.json');
|
||||
return $config->site->textlimit;
|
||||
}
|
||||
function accessTokenURL() { return $this->host.'oauth/access_token'; }
|
||||
function authenticateURL() { return $this->host.'oauth/authenticate'; }
|
||||
function authorizeURL() { return $this->host.'oauth/authorize'; }
|
||||
function requestTokenURL() { return $this->host.'oauth/request_token'; }
|
||||
function __construct($apipath, $consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
|
||||
parent::__construct($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret);
|
||||
$this->host = $apipath;
|
||||
}
|
||||
}
|
||||
|
||||
function statusnet_install() {
|
||||
// we need some hooks, for the configuration and for sending tweets
|
||||
register_hook('plugin_settings', 'addon/statusnet/statusnet.php', 'statusnet_settings');
|
||||
register_hook('plugin_settings_post', 'addon/statusnet/statusnet.php', 'statusnet_settings_post');
|
||||
register_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook');
|
||||
register_hook('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets');
|
||||
|
||||
logger("installed statusnet");
|
||||
}
|
||||
|
||||
|
||||
function statusnet_uninstall() {
|
||||
unregister_hook('plugin_settings', 'addon/statusnet/statusnet.php', 'statusnet_settings');
|
||||
unregister_hook('plugin_settings_post', 'addon/statusnet/statusnet.php', 'statusnet_settings_post');
|
||||
unregister_hook('post_local_end', 'addon/statusnet/statusnet.php', 'statusnet_post_hook');
|
||||
unregister_hook('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets');
|
||||
}
|
||||
|
||||
function statusnet_jot_nets(&$a,&$b) {
|
||||
if(! local_user())
|
||||
return;
|
||||
|
||||
$statusnet_post = get_pconfig(local_user(),'statusnet','post');
|
||||
if(intval($statusnet_post) == 1) {
|
||||
$statusnet_defpost = get_pconfig(local_user(),'statusnet','post_by_default');
|
||||
$selected = ((intval($statusnet_defpost) == 1) ? ' checked="checked" ' : '');
|
||||
$b .= '<div class="profile-jot-net"><input type="checkbox" name="statusnet_enable"' . $selected . 'value="1" /> '
|
||||
. t('Post to StatusNet') . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function statusnet_settings_post ($a,$post) {
|
||||
if(! local_user())
|
||||
return;
|
||||
if (isset($_POST['statusnet-disconnect'])) {
|
||||
/***
|
||||
* if the statusnet-disconnect checkbox is set, clear the statusnet configuration
|
||||
* TODO can we revoke the access tokens at Twitter and do we need to do so?
|
||||
*/
|
||||
del_pconfig( local_user(), 'statusnet', 'consumerkey' );
|
||||
del_pconfig( local_user(), 'statusnet', 'consumersecret' );
|
||||
del_pconfig( local_user(), 'statusnet', 'post' );
|
||||
del_pconfig( local_user(), 'statusnet', 'oauthtoken' );
|
||||
del_pconfig( local_user(), 'statusnet', 'oauthsecret' );
|
||||
del_pconfig( local_user(), 'statusnet', 'baseapi' );
|
||||
} else {
|
||||
if (isset($_POST['statusnet-consumersecret'])) {
|
||||
set_pconfig(local_user(), 'statusnet', 'consumerkey', $_POST['statusnet-consumerkey']);
|
||||
set_pconfig(local_user(), 'statusnet', 'consumersecret', $_POST['statusnet-consumersecret']);
|
||||
set_pconfig(local_user(), 'statusnet', 'baseapi', $_POST['statusnet-baseapi']);
|
||||
header('Location: '.$a->get_baseurl().'/settings/addon');
|
||||
} else {
|
||||
if (isset($_POST['statusnet-pin'])) {
|
||||
// if the user supplied us with a PIN from Twitter, let the magic of OAuth happen
|
||||
logger('got a StatusNet security code');
|
||||
$api = get_pconfig(local_user(), 'statusnet', 'baseapi');
|
||||
$ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' );
|
||||
$csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' );
|
||||
// the token and secret for which the PIN was generated were hidden in the settings
|
||||
// form as token and token2, we need a new connection to Twitter using these token
|
||||
// and secret to request a Access Token with the PIN
|
||||
$connection = new StatusNetOAuth($api, $ckey, $csecret, $_POST['statusnet-token'], $_POST['statusnet-token2']);
|
||||
$token = $connection->getAccessToken( $_POST['statusnet-pin'] );
|
||||
// ok, now that we have the Access Token, save them in the user config
|
||||
set_pconfig(local_user(),'statusnet', 'oauthtoken', $token['oauth_token']);
|
||||
set_pconfig(local_user(),'statusnet', 'oauthsecret', $token['oauth_token_secret']);
|
||||
set_pconfig(local_user(),'statusnet', 'post', 1);
|
||||
// reload the Addon Settings page, if we don't do it see Bug #42
|
||||
header('Location: '.$a->get_baseurl().'/settings/addon');
|
||||
} else {
|
||||
// if no PIN is supplied in the POST variables, the user has changed the setting
|
||||
// to post a tweet for every new __public__ posting to the wall
|
||||
set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable']));
|
||||
}}}
|
||||
}
|
||||
function statusnet_settings(&$a,&$s) {
|
||||
if(! local_user())
|
||||
return;
|
||||
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->get_baseurl() . '/addon/statusnet/statusnet.css' . '" media="all" />' . "\r\n";
|
||||
/***
|
||||
* 1) Check that we have a base api url and a consumer key & secret
|
||||
* 2) If no OAuthtoken & stuff is present, generate button to get some
|
||||
* 3) Checkbox for "Send public notices (respect size limitation)
|
||||
*/
|
||||
$api = get_pconfig(local_user(), 'statusnet', 'baseapi');
|
||||
$ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' );
|
||||
$csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' );
|
||||
$otoken = get_pconfig(local_user(), 'statusnet', 'oauthtoken' );
|
||||
$osecret = get_pconfig(local_user(), 'statusnet', 'oauthsecret' );
|
||||
$enabled = get_pconfig(local_user(), 'statusnet', 'post');
|
||||
$checked = (($enabled) ? ' checked="checked" ' : '');
|
||||
$s .= '<div class="settings-block">';
|
||||
$s .= '<h3>'. t('StatusNet Posting Settings').'</h3>';
|
||||
|
||||
if ( (!$ckey) && (!$csecret) ) {
|
||||
/***
|
||||
* no consumer keys
|
||||
*/
|
||||
$s .= '<p>'. t('No consumer key pair for StatusNet found. Register your Friendika Account as an desktop client on your StatusNet account, copy the consumer key pair here and enter the API base root.<br />Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Friendika installation at your favorited StatusNet installation.') .'</p>';
|
||||
$s .= '<div id="statusnet-consumer-wrapper">';
|
||||
$s .= '<label id="statusnet-consumerkey-label" for="statusnet-consumerkey">'. t('OAuth Consumer Key') .'</label>';
|
||||
$s .= '<input id="statusnet-consumerkey" type="text" name="statusnet-consumerkey" size="35" />';
|
||||
$s .= '<div class="clear"></div>';
|
||||
$s .= '<label id="statusnet-consumersecret-label" for="statusnet-consumersecret">'. t('OAuth Consumer Secret') .'</label>';
|
||||
$s .= '<input id="statusnet-consumersecret" type="text" name="statusnet-consumersecret" size="35" />';
|
||||
$s .= '<div class="clear"></div>';
|
||||
$s .= '<label id="statusnet-baseapi-label" for="statusnet-baseapi">'. t("Base API Path \x28remember the trailing /\x29") .'</label>';
|
||||
$s .= '<input id="statusnet-baseapi" type="text" name="statusnet-baseapi" size="35" />';
|
||||
$s .= '<div class="clear"></div></div>';
|
||||
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="submit" class="settings-submit" value="' . t('Submit') . '" /></div>';
|
||||
} else {
|
||||
/***
|
||||
* ok we have a consumer key pair now look into the OAuth stuff
|
||||
*/
|
||||
if ( (!$otoken) && (!$osecret) ) {
|
||||
/***
|
||||
* the user has not yet connected the account to statusnet
|
||||
* get a temporary OAuth key/secret pair and display a button with
|
||||
* which the user can request a PIN to connect the account to a
|
||||
* account at statusnet
|
||||
*/
|
||||
$connection = new StatusNetOAuth($api, $ckey, $csecret);
|
||||
$request_token = $connection->getRequestToken('oob');
|
||||
$token = $request_token['oauth_token'];
|
||||
/***
|
||||
* make some nice form
|
||||
*/
|
||||
$s .= '<p>'. t('To connect to your StatusNet account click the button below to get a security code from StatusNet which you have to copy into the input box below and submit the form. Only your <strong>public</strong> posts will be posted to StatusNet.') .'</p>';
|
||||
$s .= '<a href="'.$connection->getAuthorizeURL($token,False).'" target="_statusnet"><img src="addon/statusnet/signinwithstatusnet.png" alt="'. t('Log in with StatusNet') .'"></a>';
|
||||
$s .= '<div id="statusnet-pin-wrapper">';
|
||||
$s .= '<label id="statusnet-pin-label" for="statusnet-pin">'. t('Copy the security code from StatusNet here') .'</label>';
|
||||
$s .= '<input id="statusnet-pin" type="text" name="statusnet-pin" />';
|
||||
$s .= '<input id="statusnet-token" type="hidden" name="statusnet-token" value="'.$token.'" />';
|
||||
$s .= '<input id="statusnet-token2" type="hidden" name="statusnet-token2" value="'.$request_token['oauth_token_secret'].'" />';
|
||||
$s .= '</div><div class="clear"></div>';
|
||||
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="submit" class="settings-submit" value="' . t('Submit') . '" /></div>';
|
||||
} else {
|
||||
/***
|
||||
* we have an OAuth key / secret pair for the user
|
||||
* so let's give a chance to disable the postings to statusnet
|
||||
*/
|
||||
$connection = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret);
|
||||
$details = $connection->get('account/verify_credentials');
|
||||
$s .= '<div id="statusnet-info" ><img id="statusnet-avatar" src="'.$details->profile_image_url.'" /><p id="statusnet-info-block">'. t('Currently connected to: ') .'<a href="'.$details->statusnet_profile_url.'" target="_statusnet">'.$details->screen_name.'</a><br /><em>'.$details->description.'</em></p></div>';
|
||||
$s .= '<p>'. t('If enabled all your <strong>public</strong> postings will be posted to the associated StatusNet account as well.') .'</p>';
|
||||
$s .= '<div id="statusnet-enable-wrapper">';
|
||||
$s .= '<label id="statusnet-enable-label" for="statusnet-checkbox">'. t('Send public postings to StatusNet') .'</label>';
|
||||
$s .= '<input id="statusnet-checkbox" type="checkbox" name="statusnet-enable" value="1" ' . $checked . '/>';
|
||||
$s .= '</div><div class="clear"></div>';
|
||||
$s .= '<div id="statusnet-disconnect-wrapper">';
|
||||
$s .= '<label id="statusnet-disconnect-label" for="statusnet-disconnect">'. t('Clear OAuth configuration') .'</label>';
|
||||
$s .= '<input id="statusnet-disconnect" type="checkbox" name="statusnet-disconnect" value="1" />';
|
||||
$s .= '</div><div class="clear"></div>';
|
||||
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="submit" class="settings-submit" value="' . t('Submit') . '" /></div>';
|
||||
}
|
||||
}
|
||||
$s .= '</div><div class="clear"></div></div>';
|
||||
}
|
||||
|
||||
|
||||
function statusnet_post_hook(&$a,&$b) {
|
||||
|
||||
/**
|
||||
* Post to statusnet
|
||||
*/
|
||||
|
||||
logger('StatusNet post invoked');
|
||||
|
||||
if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (!$b['parent']) ) {
|
||||
|
||||
load_pconfig(local_user(), 'statusnet');
|
||||
|
||||
$api = get_pconfig(local_user(), 'statusnet', 'baseapi');
|
||||
$ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' );
|
||||
$csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' );
|
||||
$otoken = get_pconfig(local_user(), 'statusnet', 'oauthtoken' );
|
||||
$osecret = get_pconfig(local_user(), 'statusnet', 'oauthsecret' );
|
||||
|
||||
if($ckey && $csecret && $otoken && $osecret) {
|
||||
|
||||
$statusnet_post = get_pconfig(local_user(),'statusnet','post');
|
||||
$statusnet_enable = (($statusnet_post && x($_POST,'statusnet_enable')) ? intval($_POST['statusnet_enable']) : 0);
|
||||
|
||||
if($statusnet_enable && $statusnet_post) {
|
||||
require_once('include/bbcode.php');
|
||||
$dent = new StatusNetOAuth($api,$ckey,$csecret,$otoken,$osecret);
|
||||
$max_char = $dent->get_maxlength(); // max. length for a dent
|
||||
$msg = strip_tags(bbcode($b['body']));
|
||||
if ( strlen($msg) > $max_char) {
|
||||
$shortlink = "";
|
||||
require_once('library/slinky.php');
|
||||
// post url = base url + /display/ + owner + post id
|
||||
// we construct this from the Owner link and replace
|
||||
// profile by display - this will cause an error when
|
||||
// /profile/ is in the owner url twice but I don't
|
||||
// think this will be very common...
|
||||
$posturl = str_replace('/profile/','/display/',$b['owner-link']).'/'.$b['id'];
|
||||
$slinky = new Slinky( $posturl );
|
||||
// setup a cascade of shortening services
|
||||
// try to get a short link from these services
|
||||
// in the order ur1.ca, trim, id.gd, tinyurl
|
||||
$slinky->set_cascade( array( new Slinky_UR1ca(), new Slinky_Trim(), new Slinky_IsGd(), new Slinky_TinyURL() ) );
|
||||
$shortlink = $slinky->short();
|
||||
// the new message will be shortened such that "... $shortlink"
|
||||
// will fit into the character limit
|
||||
$msg = substr($msg, 0, $max_char-strlen($shortlink)-4);
|
||||
$msg .= '... ' . $shortlink;
|
||||
}
|
||||
// and now tweet it :-)
|
||||
if(strlen($msg))
|
||||
$dent->post('statuses/update', array('status' => $msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|