Drop simpleid
diff --git a/.gitignore b/.gitignore
index 343857e..99deb89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,6 @@
 /logs/mail/
 /logs/mail-supervisor/
 /logs/nginx/
-/logs/simpleid/
 /mail/config/
 /mail/data/
 /mail/rspamd-override.d/
diff --git a/docker-compose.yml b/docker-compose.yml
index 60e2230..2dc0db7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -14,12 +14,9 @@
       - "443:443"
     networks:
       - kcnet
-      - simpleidnet
       - gerritnet
     volumes:
       - ./certbot/www/:/var/www/certbot/:ro
-      - ./simpleid/identities/:/var/db/simpleid-templates/:ro
-      - ./simpleid/www/:/var/www/simpleid/:ro
       - ./certs/:/etc/nginx/certs/:rw
       - ./nginx/sa.conf:/etc/nginx/conf.d/sa.conf.template:ro
       - ./nginx/empty.conf:/etc/nginx/conf.d/default.conf:ro
@@ -75,18 +72,6 @@
       - kcnet
     secrets:
       - seed
-  simpleid:
-    build:
-      context: ./simpleid/
-    env_file: environment
-    networks:
-      - simpleidnet
-    volumes:
-      - ./simpleid/cache/:/var/cache/simpleid/:rw
-      - ./simpleid/identities/:/var/db/simpleid-templates/:ro
-      - ./simpleid/store/:/var/lib/simpleid/:rw
-      - ./simpleid/www/:/var/www/simpleid/:ro
-      - ./logs/simpleid/:/var/log/:rw
   gerrit:
     build:
       context: .
@@ -153,11 +138,6 @@
       timeout: 3s
       retries: 0
 networks:
-  simpleidnet:
-    driver: bridge
-    ipam:
-      config:
-        - subnet: 10.12.14.16/29
   gerritnet:
     driver: bridge
     ipam:
diff --git a/nginx/Dockerfile.entrypoint b/nginx/Dockerfile.entrypoint
index 05e17b4..34e10f1 100644
--- a/nginx/Dockerfile.entrypoint
+++ b/nginx/Dockerfile.entrypoint
@@ -5,7 +5,6 @@
 {
     domain=${SA_PUBLIC_DOMAIN_NAME:-miau.local}
     live=/etc/nginx/certs/live
-    html=/var/www/html
 
     if [ ! -f ${live}/${domain}/privkey.pem ]; then
         mkdir -p ${live}/${domain}
@@ -15,22 +14,11 @@
         cp /etc/ssl/certs/sa-selfsigned.crt ${live}/${domain}/cert.pem
     fi
 
-    rm -rf ${html}
-    cp -a /var/www/simpleid ${html}
-
-    for tmpl in /var/db/simpleid-templates/*.identity; do
-        ref=$(dirname ${tmpl})/$(basename ${tmpl} .identity)
-        name=$(basename ${ref})
-        sed "s/miau.local/${domain}/" ${ref} >${html}/${name}
-    done
-
     for f in /etc/nginx/conf.d/sa.conf; do
         sed "s/miau.local/${domain}/" ${f}.template >${f}
     done
 }
 
-chown -R root:root /var/www/html/
-
-chmod -R a-w /etc/nginx/certs/ /etc/nginx/conf.d/sa.conf /var/www/html/
+chmod -R a-w /etc/nginx/certs/ /etc/nginx/conf.d/sa.conf
 
 exec /docker-entrypoint.sh "$@"
diff --git a/nginx/sa.conf b/nginx/sa.conf
index 4022254..1978248 100644
--- a/nginx/sa.conf
+++ b/nginx/sa.conf
@@ -19,18 +19,6 @@
 
     server_name id.miau.local;
 
-    location /id/ {
-        alias /var/www/html/;
-        index index.php index.html;
-    }
-    location ~ ^/id/.*\.php$ {
-	fastcgi_split_path_info ^/id(.+\.php)(.*)$;
-        include fastcgi_params;
-        fastcgi_pass simpleid:9000;
-        fastcgi_index index.php;
-        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
-    }
-
     location /auth/ {   # Gerrit adds this prefix for Keycloak...
         rewrite ^/auth(.*)$ $1 last;
     }
diff --git a/simpleid/.devcontainer/devcontainer.json b/simpleid/.devcontainer/devcontainer.json
deleted file mode 100644
index ed14f03..0000000
--- a/simpleid/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,24 +0,0 @@
-// For format details, see https://aka.ms/devcontainer.json. For config options, see the
-// README at: https://github.com/devcontainers/templates/tree/main/src/php
-{
-	"name": "PHP",
-	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
-	"image": "mcr.microsoft.com/devcontainers/php:7.4",
-
-	// Features to add to the dev container. More info: https://containers.dev/features.
-	// "features": {},
-
-	// Configure tool-specific properties.
-	// "customizations": {},
-
-	// Use 'forwardPorts' to make a list of ports inside the container available locally.
-	//"forwardPorts": [8080]
-
-	// Use 'postCreateCommand' to run commands after the container is created.
-	// "postCreateCommand": "sudo chmod a+x \"$(pwd)\" && sudo rm -rf /var/www/html && sudo ln -s \"$(pwd)\" /var/www/html"
-	"postCreateCommand": "sudo curl -sSLf -o /usr/local/bin/install-php-extensions https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions && sudo chmod +x /usr/local/bin/install-php-extensions && sudo PHP_INI_DIR=/usr/local/etc/php install-php-extensions bcmath"
-
-
-	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
-	// "remoteUser": "root"
-}
diff --git a/simpleid/.gitignore b/simpleid/.gitignore
deleted file mode 100644
index a55cf42..0000000
--- a/simpleid/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-composer.lock
-vendor/
-www/vendor/
-dist/
-version.txt
diff --git a/simpleid/CHANGELOG.txt b/simpleid/CHANGELOG.txt
deleted file mode 100644
index 3df9fe9..0000000
--- a/simpleid/CHANGELOG.txt
+++ /dev/null
@@ -1,344 +0,0 @@
-SimpleID 1.0.6
---------------
-
-- Enhancements:
-    * Update autocomplete setting for one time password fields
-- Bug fixes:
-    * #86 Further fix to compatibility with PHP 8.2
-
-SimpleID 1.0.5
---------------
-
-- Bug fixes:
-    * #85 Fix compatibility with PHP 8.2
-
-SimpleID 1.0.4
---------------
-
-- Bug fixes:
-    * #81 Cache cleanup does not cover subdirectories
-
-
-SimpleID 1.0.3
---------------
-
-- Security enhancements:
-    * #23 Configuration can now be in a separate conf directory
-- Bug fixes:
-    * #35 Fix undefined index error in discovery.inc.php
-
-SimpleID 1.0.2
---------------
-
-- Bug fixes:
-    * #158 Incorrect handling of fsock-based HTTP requests
-
-SimpleID 1.0.1
---------------
-
-- Bug fixes:
-    * #154 Duplicate random_bytes() function as it is now also a native
-      function in PHP7
-    * #155 Infinite loop in cache.inc if a particular cache type has not been
-      created
-
-
-SimpleID 1.0
-------------
-
-- Security enhancements:
-    * #149 Add PBKDF2 to available password hashing algorithms to improve
-      hashing security
-    * #150 Changed hash string comparison function to mitigate against
-      timing attacks
-
-
-SimpleID 0.9.1
---------------
-
-- Bug fixes:
-    * #147 Incorrect update_access_check warning when upgrading
-    * #148 Identity files with certlogin can now be symlinked from the
-      identities directory
-
-
-SimpleID 0.9
-------------
-
-- Security enhancements:
-    * #9 Changed file extensions from .inc to .php
-    * #69 #71 Require HTTPS for login pages
-    * #100 Restricted path and added http_only flag for session cookies
-    * #101 Implemented HTTP strict transport security header
-    * #130 Added support for TOTP one-time passwords
-- Improvements to identity files:
-    * #21 Allow non-MD5 hash algorithms and salted passwords
-    * #137 Identity files can now be symlinked from the identities
-      directory
-- Improvements to user interface:
-    * #93 #106 Localization support
-    * #103 Enhanced simpleweb error pages
-    * #138 Refactored style sheets for better mobile device support
-- New extension:
-    * #85 certauth extension for authentication using client SSL
-      certificates
-- Improvements to SimpleID internals:
-    * #58 #72 Dropped support for PHP 4 and fixed up PHP syntax
-      warnings
-    * #110 Refactored authentication system to allow for custom authentication
-      extensions
-    * #131 Refactored cache system to improve performance
-    * #132 Refactored "remember me" cookies
-
-SimpleID 0.8.5
---------------
-
-- Bug fixes:
-    * #129 Fixed bug introduced in 0.8.4 regarding Warning if
-      suhosin.get.max_value_length configuration setting is too low
-    * #134 PHP syntax warnings under PHP 5.3
-
-SimpleID 0.8.4
---------------
-
-- Bug fixes:
-    * #123 Updated user interface to reflect change in SimpleID web site URL
-    * #125 Fixed line ending (CRLF vs LF) bug introduced when migrating from
-      SVN to Git
-    * #122 Fixed PEAR package not loading PEAR_Config
-    * #133 Fixed bug in bignum.inc where bignum_new() was returning $false
-      instead of false
-- Improvements to SimpleID internals:
-    * #129 Warning if suhosin.get.max_value_length configuration setting
-      is too low
-
-SimpleID 0.8.3
---------------
-
-- Bug fixes:
-    * #119 Remove XRDS-Simple Type element from template.xtpl for Blogger
-      interoperability
-
-SimpleID 0.8.2
---------------
-
-- Bug fixes:
-    * #104 Detect missing PHP extensions
-    * #105 Incorrect CSS property in simpleid.css
-    * #108 Incorrect footer links
-    * #109 Incorrect processing of HTTP requests and responses when used with
-      SAPI CGI
-    * #112 Incorrect reference to html/consent.js in page.inc
-- Improvements to user interface:      
-    * #111 Replaced packaged version of jQuery with CDN version
-
-SimpleID 0.8.1
---------------
-
-- Bug fixes:
-    * #77 Incorrect detection of register_globals PHP configuration variable
-    * #86 PHP syntax warnings in filesystem.store.inc
-    * #88 Updated URL to Simple Registration Extension specification in
-      example.identity.dist
-    * #91 Missing parameters in simpleid_checkid_error()
-    * #92 Corrected path handling in simpleweb
-    * #98 Missing global variable in simpleid_openid_consent()
-- Improvements to user interface:
-    * #94 Switch redirects from form-based to HTTP header-based
-- Improvements to the PAPE extension
-    * #95 Added private personal identifiers
-    
-
-SimpleID 0.8
-------------
-
-- Improved OpenID specification compliance:
-    * Added read-only support for attribute exchange extension
-    * Addes support for provider authentication policy extension 
-- Improvements to user interfaces:
-    * #14 Added support for clean URLs
-    * #18 Improved comformance to HTML specifications in user interface
-    * #19 For OpenID immediate requests, assertion will not fail simply because
-      return_to has not been verified
-    * #23 Optional support for browsers to save SimpleID passwords
-- Improvements to SimpleID internals:
-    * Refactored function names
-    * Refactored function layout in discovery.inc and openid.inc
-    * Opened up identity store code to allow support for non filesystem based
-      identity files
-    * Improved source code documentation
-    
-SimpleID 0.7.6
---------------
-
-- Fixed directory traversal vulnerability SA-2011-1
-  (http://simpleid.sourceforge.net/advisories/sa-2011-1)
-
-SimpleID 0.7.5
---------------
-
-- Bug fixes:
-    * #61 PHP safe mode causing curl configuration issues
-    * #64 Issue with URL parsing under Simpleweb framework
-
-
-SimpleID 0.7.4
---------------
-
-- Fixed incorrect implementation of fix for PHP's handling of HTTP parameters.
-
-
-SimpleID 0.7.3
---------------
-
-- Bug fixes:
-    * #47 PHP syntax warnings in discovery.inc.
-    * #48 PHP syntax warnings in user.inc.
-    * #50 Fix for PHP's handling of HTTP parameters.
-
-
-SimpleID 0.7.2
---------------
-
-- Bug fixes:
-    * #40 PHP syntax warnings in simpleweb.inc.
-    * #42 PHP syntax warnings in index.php.
-
-
-SimpleID 0.7.1
---------------
-
-- Bug fixes:
-    * Incorrect specification for expiry time for auto login.
-    * Fixed verification of credentials under legacy authentication.
-    * Fixed incorrect signing of Simple Registration Extension response.
-    * Fixed Javascript for digest authentication.
-    * Used Javascript instead of forms for page redirection for better HTTPS
-      user experience.
-
-
-SimpleID 0.7
-------------
-
-- Improved OpenID specification compliance:
-    * Added additional return_to verification using discovery.
-    * Fixed support for SHA256.
-    * Fixed indirect message URL encoding.
-    * Fixed filtering of extension-specific parameters.
-    * Fixed XRDS document for SimpleID.
-- Preliminary implementation of the OpenID User Interface extension.
-- Added support for GMP for improved performance for arbitary precision
-  arithmetic operations.
-- Improved user interface:
-    * Separated Dashboard, My Profile and My Sites pages.
-    * Added "log in as different user" functionality.
-    * CSS improvements.
-    * Added framekiller code.
-    * Support for nicer URLs via mod_rewrite.
-- Enhanced detection of SSL/TLS for user login page.
-- Implemented flexible persistent storage system to store user data.
-- Improved extension framework: major refactoring of hooks available to be
-  utilised by extensions.
-- Improved URL routing framework: included simpleweb.inc.
-- Added upgrade script.
-- Enhanced logging of status and errors.
-- Enhanced code documentation.
-
-
-SimpleID 0.6.5
---------------
-
-- Bug fixes:
-    * Fixed XSS vulnerability in user login page.
-    * Fixed XRDS-Location HTTP header.
-
-
-SimpleID 0.6.4
---------------
-
-- Fixed user interface bug on trusted sites page (disable Submit button when
-  there are no trusted sites).
-
-
-SimpleID 0.6.3
---------------
-
-- Fixed session_type verification response when using OpenID 1.1 associations.
-
-
-SimpleID 0.6.2
---------------
-
-- Fixed session_type verification issue when using OpenID 1.1 associations.
-
-
-SimpleID 0.6.1
---------------
-  
-- Fixed return_to verification issue when using OpenID 1.1 (legacy handling of
-  nonce parameter).
-
-SimpleID 0.6
-------------
-
-- Bug fixes:
-    * Fixed syntax errors in openid.inc.
-    * Fixed incorrect error authentication response.
-- Implemented digest authentication for user login (security enhancements).
-- Implemented persistent login
-- Enhanced form security:
-    * Added form token verification.
-    * Enhanced encoding of HTML special characters.
-- Improved compliance against OpenID specifications:
-    * Added return_to verification.
-- Changed extension of extensions from .inc to .extension.inc.
-- Enhanced code documentation.
-
-
-SimpleID 0.5.1
---------------
-
-- Bug fixes:
-    * Removed remnants of maths question (removed in SimpleID 0.5) from user.inc
-- Included Simple Registration Extension by default
-
-
-SimpleID 0.5
-------------
-
-- Bug fixes:
-    * Removed XSS vulnerabilities
-    * Fixed incorrect processing of Simple Registration Extension parameters
-    * Fixed URL for identifier selection.
-- The identifier variable is now optional in identity files.  SimpleID automatically
-  assigns an identifier to all identities where this is not specified.
-- Log in security improvements:
-    * Removed requirement to complete a maths question to log in.
-    * Added nonce check into login page to detect repeat attacks.
-- Improved compliance against OpenID specifications:
-    * Enhanced support for OpenID 2.0.
-    * Enhanced checking of request parameters.
-    * Added support for discovery of SimpleID services via XRDS.
-- Support for SHA256 where this is compiled into PHP.
-- Added default profile page and XRDS document for each user.
-
-
-SimpleID 0.2.1
---------------
-
-- Bug fixes:
-    * Removed incorrect and legacy handling of nonce parameter in OpenID 1.1
-      authentication responses
-
-
-SimpleID 0.2
-------------
-
-- Bug fixes:
-    * Fixed template compile error in Simple Registration Extension.
-
-
-SimpleID 0.1
-------------
-
-- Initial release
diff --git a/simpleid/COPYING-normalizecss.txt b/simpleid/COPYING-normalizecss.txt
deleted file mode 100644
index c6bcc9b..0000000
--- a/simpleid/COPYING-normalizecss.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) Nicolas Gallagher and Jonathan Neal
-
-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.
diff --git a/simpleid/COPYING-xtemplate.txt b/simpleid/COPYING-xtemplate.txt
deleted file mode 100644
index fc2988d..0000000
--- a/simpleid/COPYING-xtemplate.txt
+++ /dev/null
@@ -1,191 +0,0 @@
-$HeadURL: https://xtpl.svn.sourceforge.net/svnroot/xtpl/branches/php4/license.txt $
-$Id$
-
-XTemplate is dual licensed using BSD and LGPL.
-
-In plain English, you do not need to distribute your application in source code form, nor do you need to distribute XTemplate source code, provided you follow the rest of terms of the BSD license.
-
-For more info about XTemplate, visit http://www.phpxtemplate.org/
-
-BSD Style-License
-=================
-
-Copyright (c) 2000-2001 Barnab�s Debreceni [cranx@users.sourceforge.net] XTemplate
-Copyright (c) 2002-2007 Jeremy Coates [cocomp@users.sourceforge.net] XTemplate & CachingXTemplate
-
-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 the XTemplate, Barnab�s Debreceni, Jeremy Coates nor the names of its contributors may be used to
-endorse or promote products derived from this software without specific prior written
-permission.
-
-DISCLAIMER:
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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
-XTemplate, Barnab�s Debreceni, Jeremy Coates OR CONTRIBUTORS 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.
-
-==========================================================
-
-Copyright (c) 2000-2001 Barnab�s Debreceni [cranx@users.sourceforge.net] XTemplate
-Copyright (c) 2002-2007 Jeremy Coates [cocomp@users.sourceforge.net] XTemplate
-
-GNU LESSER GENERAL PUBLIC LICENSE
-Version 2.1, February 1999
-
-Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-
-Preamble
-The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
-
-This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
-
-When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things.
-
-To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
-
-For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
-
-We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
-
-To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
-
-Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
-
-Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
-
-When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
-
-We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
-
-For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
-
-In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
-
-Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
-
-The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
-
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
-
-A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
-
-The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
-
-"Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library.
-
-Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
-
-1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library.
-
-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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
-b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
-c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
-d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
-(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library.
-
-In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
-
-3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
-
-Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
-
-This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
-
-4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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.
-
-If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
-
-5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
-
-However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
-
-When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
-
-If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
-
-Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
-
-6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
-
-You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
-
-
-a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
-b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
-c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
-d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
-e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
-For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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.
-
-It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
-
-7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
-
-
-a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
-b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
-8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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.
-
-9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
-
-10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License.
-
-11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library.
-
-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.
-
-12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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.
-
-13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
-
-14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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
-
-15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-
-END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/simpleid/COPYING.txt b/simpleid/COPYING.txt
deleted file mode 100644
index 5312a46..0000000
--- a/simpleid/COPYING.txt
+++ /dev/null
@@ -1,342 +0,0 @@
-// $Id$
-
-        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.
diff --git a/simpleid/Dockerfile b/simpleid/Dockerfile
deleted file mode 100644
index f4ad457..0000000
--- a/simpleid/Dockerfile
+++ /dev/null
@@ -1,17 +0,0 @@
-FROM php:8.2-fpm-alpine
-
-RUN \
-	apk add gmp gmp-dev && \
-	docker-php-ext-configure bcmath && \
-	docker-php-ext-install -j$(nproc) bcmath && \
-	docker-php-ext-configure gmp && \
-	docker-php-ext-install -j$(nproc) gmp && \
-	docker-php-ext-enable opcache && \
-	apk del gmp-dev
-
-RUN mv "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini"
-
-COPY Dockerfile.entrypoint /simpleid-entrypoint
-RUN chmod 544 /simpleid-entrypoint
-
-ENTRYPOINT ["/bin/sh", "/simpleid-entrypoint"]
diff --git a/simpleid/Dockerfile.entrypoint b/simpleid/Dockerfile.entrypoint
deleted file mode 100644
index 6678240..0000000
--- a/simpleid/Dockerfile.entrypoint
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-set -e
-
-{
-    domain=${SA_PUBLIC_DOMAIN_NAME:-miau.local}
-    ids=/var/db/simpleid
-    html=/var/www/html
-
-    mkdir -p ${ids}
-    rm -rf ${html}
-    cp -a /var/www/simpleid ${html}
-
-    for tmpl in /var/db/simpleid-templates/*.identity; do
-        id=$(basename ${tmpl})
-        sed "s/miau.local/${domain}/" ${tmpl} >${ids}/${id}
-    done
-
-    for f in /var/www/simpleid/config.php; do
-        sed "s/miau.local/${domain}/" ${f} >${html}/$(basename ${f})
-    done
-}
-
-chown -R www-data:www-data /var/cache/simpleid/
-chown -R www-data:www-data /var/lib/simpleid/
-chown -R www-data:www-data /var/log/
-
-chown -R root:root /var/db/simpleid/
-chown -R root:root /var/www/html/
-
-chmod -R a-w /var/db/simpleid/ /var/www/html/
-
-exec docker-php-entrypoint php-fpm "$@"
diff --git a/simpleid/README.txt b/simpleid/README.txt
deleted file mode 100644
index b693305..0000000
--- a/simpleid/README.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-SimpleID
-========
-
-SimpleID is a simple, personal OpenID provider written in PHP.
-
-Latest Version
---------------
-
-Version 1.0 is the final version of the original series of SimpleID.
-SimpleID 2.0 is almost a complete rewrite of SimpleID and is not
-backwards compatible this version.
-
-The latest version of SimpleID can be found in the SimpleID web page at
-<http://simpleid.org/>
-
-Upgrading
----------
-
-General upgrade instructions can be found in UPGRADE.txt.
-
-IMPORTANT: SimpleID version 0.9 introduced numerous changes and additional
-system requirements.  A manual upgrading process is required.  If you are
-upgrading from an earlier version of SimpleID, please read UPGRADE.txt for
-upgrade instructions.
-
-IMPORTANT: SimpleID version 0.7 introduced numerous changes.  A manual
-upgrading process is required.  If you are upgrading from an earlier version of
-SimpleID, please read UPGRADE.txt for upgrade instructions.
-
-IMPORTANT: SimpleID version 0.6 introduced a new log in mechanism.  If you
-are upgrading from an earlier version of SimpleID, please read
-UPGRADE.txt for upgrade instructions.
-
-
-Installation
-------------
-
-For installation instructions, please see the SimpleID Getting Started Guide at
-<http://simpleid.org/docs/1/#getting-started>.
-
-Documentation
--------------
-
-Documentation for SimpleID can be found at
-<http://simpleid.org/docs/1/>.
-
-Licensing
----------
-
-Licensing information for SimpleID can be found in the file COPYING.txt.
-
-Donate
-------
-
-If you enjoy using SimpleID, please consider making a donation to support the
-ongoing development work.  To find out more on how to donate, visit
-<http://simpleid.org/donate>.
-
-Your donation is very much appreciated.
-
-Acknowledgements
-----------------
-
-SimpleID includes code from the Drupal OpenID module
-<http://drupal.org/project/openid>, written by Rowan Kerr
-<rowan@standardinteractive.com> and James Walker <james@bryght.com>.
-
-SimpleID includes code from php-gettext <https://launchpad.net/php-gettext>,
-written by Danilo Segan <danilo@kvota.net> and Nico Kaiser <nico@siriux.net>.
-
-SimpleID uses the XTemplate PHP templating engine
-<http://www.phpxtemplate.org>, written by Barnabas Debreceni and Jeremy Coates.
-Licensing information for this library can be found in COPYING-xtemplate.txt.
-
-SimpleID uses the famfamfam Silk icon set
-<http://www.famfamfam.com/lab/icons/silk/>, designed by Mark James.  The icon
-set is licensed is licensed under a Creative Commons Attribution 2.5 License
-<http://creativecommons.org/licenses/by/2.5/>.
-
-SimpleID uses the jQuery JavaScript library <http://jquery.com>, by John
-Resig and the jQuery team.  Licensing information for this library can be found
-at <http://docs.jquery.com/Licensing>.
-
-SimpleID uses the jQuery QR code library
-<http://jeromeetienne.github.io/jquery-qrcode/>, by Jerome Etienne.  Licensing
-information for this library can be found at
-<https://github.com/jeromeetienne/jquery-qrcode/blob/master/MIT-LICENSE.txt>.
-
-SimpleID uses normalize.css style sheet
-<http://necolas.github.io/normalize.css/>, by Nicolas Gallagher and Jonathan
-Neal.  Licensing information for this library can be found at
-<https://github.com/necolas/normalize.css/blob/master/LICENSE.md>.
diff --git a/simpleid/RoboFile.php b/simpleid/RoboFile.php
deleted file mode 100644
index 748ae39..0000000
--- a/simpleid/RoboFile.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-
-use Gettext\Scanner\PhpScanner;
-use Gettext\Generator\PoGenerator;
-use Gettext\Translations;
-use Symfony\Component\Finder\Finder;
-
-/**
- * This is project's console commands configuration for Robo task runner.
- *
- * @see http://robo.li/
- */
-class RoboFile extends \Robo\Tasks {
-    public function xgettext() {
-        $domain = 'messages';
-
-        $finder = new Finder();
-        $finder->in('www')->name('*.php');
-
-        $translations[] = Translations::create($domain);
-
-        $scanner = new PhpScanner(...$translations);
-        $scanner->setDefaultDomain($domain);
-
-        $scanner->setFunctions(['t' => 'gettext']);
-
-        foreach ($finder as $file) {
-            $scanner->scanFile($file);
-        }
-
-        $generator = new PoGenerator();
-
-        foreach ($scanner->getTranslations() as $domain => $translations) {
-            $destFile = 'www/locale/messages.pot';
-
-            $translations->getHeaders()->set('Project-Id-Version', 'PACKAGE VERSION');
-            $translations->getHeaders()->set('Report-Msgid-Bugs-To', '');
-            $translations->getHeaders()->set('POT-Creation-Date', date('c'));
-            $translations->getHeaders()->set('PO-Revision-Date', 'YEAR-MO-DA HO:MI+ZONE');
-            $translations->getHeaders()->set('Last-Translator', 'FULL NAME <EMAIL@ADDRESS>');
-            $translations->getHeaders()->set('Language-Team', 'LANGUAGE <LL@li.org>');
-            $translations->getHeaders()->set('MIME-Version', '1.0');
-            $translations->getHeaders()->set('Content-Type', 'text/plain; charset=UTF-8');
-            $translations->getHeaders()->set('Content-Transfer-Encoding', '8bit');
-
-            $generator->generateFile($translations, $destFile);
-        }
-    }
-
-    public function build() {
-        $ref = getenv('GITHUB_REF_NAME');
-        if ($ref === false) {
-            $version = 'master';
-        } else {
-            $version = str_replace('release-', '', $ref);
-        }
-
-        $dist_file = 'simpleid-' . $version . '.tar.gz';
-        
-        // 1. Set up robo collections and create temp directory
-        $main_collection = $this->collectionBuilder();
-        $prepare_collection = $this->collectionBuilder();
-        $temp = $main_collection->tmpDir();
-        $working = $main_collection->workDir("dist");
-
-        // 3. Prepare step
-        // (a) Copy files to temp directory
-        $prepare_collection->taskMirrorDir([
-            '.' => "$temp/simpleid"
-        ]);
-
-        // (b) remove unnecessary directories and files
-        $prepare_collection->taskDeleteDir([
-            "$temp/simpleid/.git",
-            "$temp/simpleid/.github",
-            "$temp/simpleid/.sourceforge",
-            "$temp/simpleid/dist",
-            "$temp/simpleid/vendor",
-            "$temp/simpleid/www/vendor",
-            "$temp/simpleid/www/test",
-            "$temp/simpleid/www/test-suite"
-        ]);
-
-        $prepare_collection->taskFileSystemStack()->remove([
-            "$temp/simpleid/www/.htaccess",
-            "$temp/simpleid/www/config.inc",
-            "$temp/simpleid/www/config.php",
-            "$temp/simpleid/www/composer.lock",
-            "$temp/simpleid/composer.lock"
-        ]);
-
-        // (c) run
-        $result = $prepare_collection->run();
-        if (!$result->wasSuccessful()) {
-            return $result;
-        }
-
-        // 4. Replace variables
-        $finder = new Finder();
-        $finder->in("$temp/simpleid/www")->name('*.php')->name('*.dist');
-        foreach($finder as $file) {
-            $main_collection->taskReplaceInFile($file)
-                ->from(['@@BUILD_VERSION@@', '@@IDENTITIES_DIR@@', '@@CACHE_DIR@@', '@@STORE_DIR@@'])
-                ->to([$version, '../identities', '../cache', '../store']);
-        }
-
-        // 5. Create the release files
-        $main_collection->taskFileSystemStack()->mkdir("$working/$version")->copy('.sourceforge/frs/README.md', "$working/$version/README.md");
-        $main_collection->taskPack("$working/$version/$dist_file")->addDir('simpleid/', "$temp/simpleid");
-        $main_collection->taskWriteToFile('version.txt')->text($version);
-
-        // 6. Run everything
-        return $main_collection->run();
-    }
-}
\ No newline at end of file
diff --git a/simpleid/UPGRADE.txt b/simpleid/UPGRADE.txt
deleted file mode 100644
index 16c1856..0000000
--- a/simpleid/UPGRADE.txt
+++ /dev/null
@@ -1,171 +0,0 @@
-Upgrading SimpleID
-==================
-
-Introduction
-------------
-
-SimpleID is currently in heavy development, with the software changing rapidly.
-As a result, it is very important to upgrade SimpleID when a new version is
-released.
-
-General information on upgrading can be found at
-<http://simpleid.org/docs/1/upgrading/>.
-
-This document sets out the additional steps which may need to be performed to
-upgrade to a specific version of SimpleID.
-
-Upgrading to SimpleID 0.9
--------------------------
-
-1. System requirements
-
-The system requirements for SimpleID have changed.  The most important
-changes are:
-
-    (a) PHP
-
-        From version 0.9, the minimum version of PHP is 5.3.0.  PHP 4 is no
-        longer supported.
-
-    (b) HTTPS support
-
-        From version 0.9, HTTPS support is mandatory.  The evolving security
-        environment means that it is no longer safe to accept logins from
-        unencrypted connections.
-
-        If you run your own server, there are now many inexpensive certificate 
-        authorities from which to get certificates.  Self-signed certificates
-        are also acceptable (although not recommended).
-
-        If you are using a shared server from a web hosting provider, check
-        with them regarding SSL capabilities.  Many offer a shared SSL
-        certificate to the server at no extra cost.
-
-For further information on the revised system requirements, see the SimpleID
-web site at <http://simpleid.org/docs/1/system-requirements/>
-
-2. Enhanced password security
-
-Version 0.9 now supports storing passwords with hashing algorithms other than
-MD5 and with a salt.  You may wish to update your identity file to take
-advantage of this new feature.
-
-3. File extensions
-
-SimpleID PHP code files no longer use the .inc file extension.  Instead only
-the .php file extension is used.  This prevents misconfigured web servers to
-return SimpleID source code.
-
-You will need to perform the following manually:
-
-    (a) Rename config.inc to config.php
-
-    (b) Rename any custom extensions in the extensions directory from
-        .extension.inc to .extension.php
-
-    (c) Delete all old .inc files from the SimpleID web directory.
-
-4. upgrade.php
-
-You will need to run the upgrade script to complete the upgrade.  To run the
-script, use your web browser to go to
-
-http://www.exmaple.com/simpleid/upgrade.php
-
-where http://www.exmaple.com/simpleid/ is the URL of your SimpleID server
-(where you have moved the www directory).  You will need to be logged in as
-an administrator to proceed with the script.
-
-Upgrading to SimpleID 0.8
--------------------------
-
-SimpleID 0.8 does not require any additional steps as part of the upgrade
-process.
-
-However, you will still need to run the upgrade script to complete the
-upgrade.  To run the script, use your web browser to go to
-
-http://www.exmaple.com/simpleid/upgrade.php
-
-where http://www.exmaple.com/simpleid/ is the URL of your SimpleID server
-(where you have moved the www directory).  You will need to be logged in as
-an administrator to proceed with the script.
-
-
-Upgrading to SimpleID 0.7
--------------------------
-
-1. New storage framework
-
-SimpleID introduced a new storage framework.  The new framework allows SimpleID
-to store additional information about your identity.
-
-As a result, you will need to be aware that there is a new configuration option
-called SIMPLEID_STORE_DIR, which specifies the directory where this information
-will be stored.  This directory must exist and be readable and writable by the
-web server.
-
-If you are upgrading from SimpleID 0.6, this setting will default to the
-directory specified by SIMPLEID_CACHE_DIR in your config.inc.  However, it is
-a good idea to place this in a separate directory.  To do this, add the
-following line to your config.inc:
-
-define('SIMPLEID_STORE_DIR', '<your directory here>');
-
-2. Administrators
-
-SimpleID 0.7 introduced the concept of administrators.  Administrators
-have access to certain functions which regular users cannot.  To make a user
-an administrator, edit the user's identity file to include the following line:
-
-administrator=1
-
-3. User Interface Extension
-
-SimpleID 0.7 introduced support for the draft OpenID User Interface Extension.
-It is enabled by default for new installations of SimpleID, however if you
-are upgrading you may need to enable it manually.  To do so, edit
-your config.inc to change the SIMPLEID_EXTENSIONS configuration option to
-include ui.  For example:
-
-define('SIMPLEID_EXTENSIONS', 'sreg,ui');
-
-4. Upgrade script
-
-SimpleID introduced a new upgrade script.  This means that whenever you
-upgrade you will also need to run the script.  To run the script, use your
-web browser to go to
-
-http://www.exmaple.com/simpleid/upgrade.php
-
-where http://www.exmaple.com/simpleid/ is the URL of your SimpleID server
-(where you have moved the www directory).  You will need to be logged in as
-an administrator to proceed with the script.
-
-
-Upgrading to SimpleID 0.6
--------------------------
-
-SimpleID version 0.6 introduced a new log in system.  The new system allows
-you to log in to SimpleID without sending your password in plain text.  Your
-password is used to create a cryptographic digest, which is then sent to
-the SimpleID server and verified.
-
-As a result, you need to be aware of two things:
-
-1.  You browser must have JavaScript switched on in order to use the new
-    log in system.  If JavaScript is not switched on, SimpleID reverts to the
-    "legacy" log in system used in previous versions, subject to the important
-    point below.
-    
-2.  By default, SimpleID version 0.6 will not accept logins under the legacy
-    system.  You can override this by putting the following line in your
-    config.inc:
-    
-    define('SIMPLEID_ALLOW_LEGACY_LOGIN', true);
-    
-    It is STRONGLY RECOMMENDED that you DO NOT switch the legacy login system
-    on, as it is substantially less secure than the new login system.  Use this
-    ONLY if your browser does not support JavaScript.
-    
-
diff --git a/simpleid/cache/.gitignore b/simpleid/cache/.gitignore
deleted file mode 100644
index e4012f6..0000000
--- a/simpleid/cache/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Ignore this directory
-*
-
-# Don't ignore this file
-!.gitignore
\ No newline at end of file
diff --git a/simpleid/composer.json b/simpleid/composer.json
deleted file mode 100644
index 4eb9b0f..0000000
--- a/simpleid/composer.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-    "name": "simpleid/simpleid",
-    "description": "A simple, personal OpenID provider written in PHP",
-    "type": "project",
-    "require": {
-        "php": "^5.3 | ^7.0",
-        "ext-bcmath": "*",
-        "ext-pcre": "*",
-        "ext-session": "*",
-        "ext-xml": "*",
-        "ext-hash": "*"
-    },
-    "suggest": {
-        "ext-gmp": "Better performance"
-    },
-    "require-dev": {
-        "pear/archive_tar": "^1.4",
-        "gettext/gettext": "^5.0",
-        "gettext/php-scanner": "^1.0",
-        "consolidation/robo": "1.0"
-    },
-    "scripts": {
-        "build": [ "@composer install", "robo build" ],
-        "xgettext": [ "@composer install", "robo xgettext" ]
-    },
-    "license": "GPL-2.0+",
-    "authors": [
-        {
-            "name": "Kelvin Mo",
-            "email": "kmo@users.sourceforge.net"
-        }
-    ]
-}
diff --git a/simpleid/extensions/hooks.php b/simpleid/extensions/hooks.php
deleted file mode 100644
index 24219ce..0000000
--- a/simpleid/extensions/hooks.php
+++ /dev/null
@@ -1,337 +0,0 @@
-<?php
-
-/**
- * 
- * This page lists out all the hooks which are available to SimpleID extensions.
- *
- * When implementing these hooks in your extensions, you should replace the word
- * hook with the name of your extension.
- *
- * @package extensions
- */
-
-/**
- * Returns an array of type URIs to be included in SimpleID's XRDS document.
- *
- * For example:
- *
- * <code>
- * <?php
- * return array('http://specs.openid.net/extensions/ui/1.0/lang-pref', 'http://specs.openid.net/extensions/ui/1.0/mode/popup');
- * ?>
- * </code>
- *
- * @return array an array of URIs
- * @since 0.7
- */
-function hook_xrds_types() {
-}
-
-/**
- * Processes an authentication request that is <i>not</i> about an identifier.
- *
- * The OpenID specifications provides a mechanism for extensions to process
- * authentication requests that are not about an identifier.  Authentication requests
- * about identifiers are automatically processed by the {@link simpleid_checkid_identity()}
- * function and the {@link hook_checkid_identity()} hooks.
- *
- * Assertion results are coded within SimpleID as an integer between 127 ({@link CHECKID_OK})
- * and -127 ({@link CHECKID_PROTOCOL_ERROR}).  Positive values indicate a potential
- * positive assertion (subject to various types of user approval), while negative
- * values indicate a irrecoverable negative assertion.
- *
- * This hook should return one of these values.  If the extension is unable to
- * handle this particular type of authentication request, it should return NULL.
- *
- * @param array $request the OpenID request
- * @param bool $immediate true if openid.mode is checkid_immediate
- * @return int a return value from the list of possible values returned by
- * {@link simpleid_checkid_identity()} or NULL
- * @see simpleid_checkid()
- */
-function hook_checkid($request, $immediate) {
-}
-
-
-/**
- * Processes an authentication request where the assertion is potentially
- * positive.
- *
- * Assertion results are coded within SimpleID as an integer between 127 ({@link CHECKID_OK})
- * and -127 ({@link CHECKID_PROTOCOL_ERROR}).  Positive values indicate a potential
- * positive assertion (subject to various types of user approval), while negative
- * values indicate a irrecoverable negative assertion.
- *
- * Extensions are able to examine the authentication request to modify change
- * the assertion result from positive to negative.  As SimpleID takes the
- * minimum from the results returned by this hook, extensions are
- * not able to change the assertion result from negative to positive.
- *
- * If the extension is indifferent to the result of the current authentication
- * request (e.g. it cannot understand it), it should return NULL.
- *
- * This hook is not called at all if SimpleID determines that the assertion
- * is negative.
- *
- * @param array $request the OpenID request
- * @param string $identity the identity to be checked against
- * @param bool $immediate true if openid.mode is checkid_immediate
- * @return int a return value from the list of possible values returned by
- * {@link simpleid_checkid_identity()} or NULL
- * @see simpleid_checkid_identity()
- */
-function hook_checkid_identity($request, $identity, $immediate) {
-}
-
-/**
- * Gets fields and values to be included in the OpenID response.
- *
- * For positive assertions, this hook should assume that all user approvals
- * have been given and return a response array accordingly.  The extension has
- * the opportunity to modify the response what the user has actually approved
- * in the {@link hook_send() send hook}.
- *
- * This hook will need to provide any aliases required.
- *
- * An example:
- *
- * <code>
- * <?php
- * $alias = openid_extension_alias($my_uri);
- * return array(
- *     'openid.ns.' . $alias => $my_uri,
- *     'openid.' . $alias . '.field' => 'value'
- * );
- * ?>
- * </code>
- *
- * @param bool $assertion true if a positive assertion is made, false otherwise
- * @param array $request the OpenID request
- * @return array the fields and values to include
- */
-function hook_response($assertion, $request) {
-}
- 
-/**
- * Gets fields associated with this extension which needs to be signed
- *
- * SimpleID automatically handles signing fields required by the OpenID
- * specification, so only the fields introduced by this extension
- * needed to be returned by this function.
- *
- * The array of fields returned by this function must include any applicable
- * aliases as required.  For example
- *
- * <code>
- * <?php
- * $alias = openid_extension_alias($my_uri);
- * return array($alias . '.field1', $alias . 'field2');
- * ?>
- * </code>
- *
- * @param array $response the OpenID response to sign
- * @return array an array of fields to sign
- */
-function hook_signed_fields($response) {
-}
-
-/**
- * Determines the format in which assertions are sent, when they are sent via
- * indirect communication.
- *
- * The OpenID specification version 2.0 provides for the sending of assertions
- * via indirect communication.  The original specifications provide that the
- * response should be formatted within the query string.
- *
- * Some extensions to the OpenID specification allows the assertion to be
- * formatted in some other way, e.g. via the fragment.  This hook allows
- * extensions to specify which format the assertion should be sent.
- *
- * If the extension is indifferent regarding the format, it should return
- * null
- *
- * @param string $url the URL of the RP to which the response is to be sent
- * @param array $response the assertion to be sent
- * @return int one of OPENID_RESPONSE_QUERY or OPENID_RESPONSE_FRAGMENT or NULL
- */
-function hook_indirect_response($url, $response) {
-}
-
-/**
- * Provides additional form items when displaying the relying party consent
- * form
- * 
- *
- * @param array $request the OpenID request
- * @param array $response the proposed OpenID response
- * @param array $rp the user's preferences saved with this relying party
- * @return string HTML code to be inserted into the verification form
- * @see simpleid_consent_form()
- * @deprecated Use {@link hook_consent_form()}
- */
-function hook_rp_form($request, $response, $rp) {
-}
-
-/**
- * Provides additional form items when displaying the relying party consent
- * form
- * 
- *
- * @param array $request the OpenID request
- * @param array $response the proposed OpenID response
- * @param array $rp the user's preferences saved with this relying party
- * @return string HTML code to be inserted into the verification form
- * @see simpleid_consent_form()
- * @since 0.8
- */
-function hook_consent_form($request, $response, $rp) {
-}
-
-/**
- * Processes the relying party consent form.
- *
- * This provides the extension with the opportunity to:
- *
- * - modify the OpenID response based on the user's preferences by editing
- *   $response
- * - save the user's preferences by editing $rp
- *
- * <strong>WARNING</strong> Because this function requires parameters to be
- * passed by reference, this does not work with {@link extension_invoke_all()}.
- *
- * @param array $form_request the data submitted by the user in the relying
- * party verification form
- * @param array &$response pointer to the proposed OpenID response
- * @param array &$rp pointer to the user's preferences saved with this relying party
- * @deprecated Use {@link hook_consent()}
- *
- */
-function hook_send($form_request, &$response, &$rp) {
-}
-
-/**
- * Processes the relying party verification form.
- *
- * This provides the extension with the opportunity to:
- *
- * - modify the OpenID response based on the user's preferences by editing
- *   $response
- * - save the user's preferences by editing $rp
- *
- * <strong>WARNING</strong> Because this function requires parameters to be
- * passed by reference, this does not work with {@link extension_invoke_all()}.
- *
- * @param array $form_request the data submitted by the user in the relying
- * party verification form
- * @param array &$response pointer to the proposed OpenID response
- * @param array &$rp pointer to the user's preferences saved with this relying party
- * @since 0.8
- *
- */
-function hook_consent($form_request, &$response, &$rp) {
-}
-
-/**
- * Return any additional items provided by the extension to be appended to the
- * Simpleweb route array.
- *
- * @see simpleweb.inc.php
- * @see simpleid_start()
- * @return array the routes array
- * @since 0.7
- */
-function hook_routes() {
-}
-
-/**
- * Provides additional form items when displaying the login form
- * 
- * @param string $destination he SimpleID location to which the user is directed
- * if login is successful
- * @param string $state the current SimpleID state, if required by the location
- * @see user_login_form()
- */
-function hook_user_login_form($destination, $state) {
-}
-
-/**
- * Attempts to automatically login using credentials presented by the user agent.
- *
- * This hook is called by the {@link user_auto_login()} function.  The hook
- * should detect any credentials present in the request and return a $user array
- * (loaded using the {@link user_load()} function) if credentials identifying
- * the user is present.
- *
- * If no credentials are present, or the credentials are invalid, this hook
- * should return NULL.
- * 
- * @return array the user array, or NULL
- */
-function hook_user_auto_login() {
-}
-
-/**
- * Verifies a set of credentials for a specified user.
- *
- * A set of credentials comprises:
- *
- * - A user name
- * - Some kind of verifying information, such as a plaintext password, a hashed
- *   password (e.g. digest) or some other kind of identifying information.
- *
- * The user name is passed to this function using the $uid parameter.  The user
- * name may or may not exist.  If the user name does not exist, this function
- * <strong>must</strong> return false.
- *
- * The credentials are supplied as an array using the $credentials parameter.
- * Typically this array will be a subset of the $_POST superglobal passed to the
- * {@link user_login()} function.  Thus it will generally contain the keys 'pass' and
- * 'digest'.
- *
- * This hook must check whether the credentials supplied matches the credentials
- * for the specified user in the store.  If for any reason that credentials
- * do not match, this function <strong>must</strong> return false.
- *
- * @param string $uid the name of the user to verify
- * @param array $credentials the credentials supplied by the browser
- * @return bool whether the credentials supplied matches those for the specified
- * user
- */
-function hook_user_verify_credentials($uid, $credentials) {
-}
-
-
-
-/**
- * Returns additional blocks to be displayed in the user's dashboard.
- *
- * A block is coded as an array in accordance with the specifications set
- * out in {@link page.inc}.
- *
- * This hook should return an <i>array</i> of blocks, i.e. an array of
- * arrays.
- *
- * @see page_dashboard()
- * @return array an array of blocks to add to the user's dashboard
- * @since 0.7
- */
-function hook_page_dashboard() {
-}
-
-/**
- * Returns additional blocks to be displayed in the user's profile page.
- *
- * A block is coded as an array in accordance with the specifications set
- * out in {@link page.inc}.
- *
- * This hook should return an <i>array</i> of blocks, i.e. an array of
- * arrays.
- *
- * @see page_profile()
- * @return array an array of blocks to add to the user's profile page
- * @since 0.7
- */
-function hook_page_profile() {
-}
-
-?>
diff --git a/simpleid/identities/example.identity.dist b/simpleid/identities/example.identity.dist
deleted file mode 100644
index 7223f51..0000000
--- a/simpleid/identities/example.identity.dist
+++ /dev/null
@@ -1,233 +0,0 @@
-; :mode=ini:
-; $Id$
-;
-;
-; SimpleID identity file.
-;
-; This file contains all the data associated with an identity.  It should
-; always be named username.identity, where username is the user name to be used
-; when logging into SimpleID.
-;
-; In this file, if a value contains non-numeric characters, you will need to
-; surround it with quotation characters.
-;
-
-;
-; The OpenID Identifier associated with this identity.  This is typically a
-; URL, although the OpenID specifications allow the use of URIs and even XRIs.
-;
-; Relying parties must be able to resolve the identity to obtain the address
-; of this SimpleID installation.
-;
-; WARNING: If you change the OpenID Identifier after you have used it in
-; SimpleID, you will need to delete all files named 'identity-*.cache' in the
-; cache directory.
-;
-; Examples:
-;    http://example.com/
-;    http://example.com:8888/
-;    http://example.com/myopenid
-;    https://example.com:8080/myopenid
-;
-identity="http://example.com/"
-
-;
-; The password associated with this identity.  
-;
-; The password is encoded as follows:
-;
-;     pass="hash:algorithm:other_params"
-;
-; There are three components to the password string.  Only the first component
-; (the hash) is required, the other two are optional.
-;
-; 1. The hash of the password.  For backwards compatibility reasons, the
-;    default algorithm for hashing the password is MD5.
-;
-;    However, you are strongly encouraged to use a much stronger password
-;    hashing algorithm, such as PBKDF2 with a HMAC-SHA256 function and at least
-;    100,000 iterations.
-;
-; 2. The algorithm used to hash the password.  If this is omitted, 'md5' is assumed.
-;
-;    Allowed algorithms are:
-;
-;    - md5
-;    - sha1
-;    - if the hash module is enabled, pbkdf2 and any algorithms available from that
-;      module
-;
-; 3. Other parameters.
-;
-;    For md5 and sha1, this is an optional salt used to hash the password.  If
-;    used, the password is appended by a colon character (:) then the salt before
-;    a hash is calculated, that is:
-;
-;    hash(password:salt)
-;
-;    For pbkdf2, it is the underlying pseudorandom function, the number of
-;    iterations and the salt, separated by colons.
-;
-; Examples (these contain the same password):
-;    1a79a4d60de6718e8e5b326e338ae533                   ; MD5 hash and no salt
-;    c3499c2729730a7f807efb8676a92dcb6f8a3f8f:sha1      ; SHA1 hash and no salt
-;    f5e6ea5714945786623ad3932ccc757d::ideally-a-large-number-of-random-characters-to-use-as-salt                   ; MD5 hash with salt
-;    9bce4e6997c6f2590717686bd62f99e33d5c6e1c:sha1:ideally-a-large-number-of-random-characters-to-use-as-salt       ; SHA1 hash with salt
-;    c6e1aa5914c6e4e55fae69093afbc02e180810dcc7d3da9f863aa54f3d76e2c3:pbkdf2:sha256:100000:ideally-a-large-number-of-random-characters-to-use-as-salt ; PBKDF2
-;
-pass="906ae7ffe4d00616daf099c74dcb51b86057f51531123c8039007b53176ae0e5:pbkdf2:sha256:100000:C2WG7PRM7PICMN5R"
-
-;
-; Whether this user is given administrative privileges in SimpleID.
-;
-; This setting has no effect in the current version of SimpleID.  However,
-; more functionality may be added to SimpleID in future versions which will
-; be restricted to SimpleID administrators.
-;
-; You should grant administrative privileges to at least one user.
-;
-; If you wish this user to be given administrative privileges, uncomment the
-; line below.
-;
-;administrator=1
-
-;
-; Advanced users only: SSL client certificates associated with this identity.
-;
-; You can associate SSL client certificates to this identity, so that you can
-; log in using certificates instead of supplying a user name or password.
-;
-; The SSL certicate is identified using two parameters:
-;
-; - the certificate's serial number
-; - the distinguished name of the certificate's issuer
-;
-; You can find out these two values using OpenSSL by running the following
-; commands (replacing the file name of the certificate as required):
-; 
-;    openssl x509 -noout -serial -in certificate.crt
-;    openssl x509 -noout -issuer -in certificate.crt
-;
-; These two values are then joined together using a semicolon.
-;
-; This option is for advanced users only.  Please see the documentation at
-; http://simpleid.org/docs/1/certauth/
-; for details on how to set this up.
-;
-; Note, you must also enable the certauth extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; certauth
-
-; Example:
-;
-;[certauth]
-;cert[]="02A97C;/C=XX/O=Example CA/OU=Example CA Certificate Signing/CN=Example Client CA"
-
-
-;
-; OpenID Connect user information.
-;
-; If you want to provide personal data to OpenID Connect clients, uncomment the
-; section below and fill in your details.
-;
-; Note that you will need to supply your data in this section again even if you
-; have uncommented and filled in the Simple Registration Extension and/or
-; Attribute Exchange Extension information in the sections below.  SimpleID
-; does not pick these up automatically.
-;
-; WARNING: The address fields below are only supported by PHP 5.3 or later.
-; Earlier versions of PHP are not able to read identity files with
-; associative arrays
-;
-;[user_info]
-;name="Example"
-;given_name="Example"
-;family_name="Example"
-;middle_name="Example"
-;nickname="Example"
-;profile="http://example.com/profile/example"
-;picture="http://example.com/profile/example.jpg"
-;website="http://example.com/blog/example"
-;email="example@example.com"
-;gender="male"
-;birthday="12/31/2000"
-;zoneinfo="Australia/Sydney"
-;locale="en-AU"
-;phone_number="+61400000000"
-;address["formatted"]="1 George Street, Sydney NSW 2000, Australia"
-;address["street_address"]="1 George Street"
-;address["locality"]="Sydney"
-;address["region"]="NSW"
-;address["postal_code"]="2000"
-;address["country"]="Australia"
-
-
-;
-; Simple Registration Extension data.
-;
-; If you want to provide registration data to relying parties which support the
-; Simple Registration Extension, uncomment the section below and fill
-; in your details.
-;
-; Further information on the Simple Registration Extension can be found at
-; http://simpleid.org/docs/1/extensions-bundled/#sreg
-;
-; Note, you must also enable the Simple Registration Extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; sreg
-;
-;[sreg]
-;nickname="Example"
-;email="example@example.com"
-;fullname="Example"
-;dob="2000-00-00"
-;gender="M"
-;postcode="1234"
-;country="en"
-;language="au"
-;timezone="Australia/Sydney"
-
-
-;
-; Attribute Exchange Extension data.
-;
-; If you want to provide personal identity information data to relying parties
-; which support the Attribute Exchange Extension, uncomment the section below
-; and fill in your details.
-;
-; The format of this section is attribute type URI=attribute value.  Examples
-; are given below.
-;
-; For a full list of attributes, see http://openid.net/specs/openid-attribute-properties-list-1_0-01.html
-;
-; Note if you have already uncommented and filled out the OpenID Connect user
-; information and/or Simple Registration Extension data above, you do not need
-; to fill out the corresponding attributes again in the section below.  SimpleID
-; will pick these up automatically, including:
-;
-;    http://axschema.org/namePerson/friendly
-;    http://axschema.org/contact/email
-;    http://axschema.org/namePerson
-;    http://axschema.org/birthDate
-;    http://axschema.org/person/gender
-;    http://axschema.org/contact/postalCode/home
-;    http://axschema.org/contact/country/home
-;    http://axschema.org/pref/language
-;    http://axschema.org/pref/timezone
-;    http://openid.net/schema/namePerson/friendly
-;    http://openid.net/schema/contact/internet/email
-;    http://openid.net/schema/gender
-;    http://openid.net/schema/contact/postalCode/home
-;    http://openid.net/schema/contact/country/home
-;    http://openid.net/schema/language/pref
-;    http://openid.net/schema/timezone
-;
-; Note, you must also enable the Attribute Exchange Extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; ax
-;
-;[ax]
-;http://openid.net/schema/company/name="Example Company Limited"
-;http://openid.net/schema/company/title="Managing Director"
-;http://openid.net/schema/contact/web/blog="http://simpleid.org/"
-
diff --git a/simpleid/identities/icon b/simpleid/identities/icon
deleted file mode 100644
index 149c53d..0000000
--- a/simpleid/identities/icon
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-    <head>
-        <link rel="openid.server" href="https://id.miau.local/id/" />
-        <link rel="openid2.provider" href="https://id.miau.local/id/" />
-    </head>
-</html>
diff --git a/simpleid/identities/icon.identity b/simpleid/identities/icon.identity
deleted file mode 100644
index dd20d15..0000000
--- a/simpleid/identities/icon.identity
+++ /dev/null
@@ -1,233 +0,0 @@
-; :mode=ini:
-; $Id$
-;
-;
-; SimpleID identity file.
-;
-; This file contains all the data associated with an identity.  It should
-; always be named username.identity, where username is the user name to be used
-; when logging into SimpleID.
-;
-; In this file, if a value contains non-numeric characters, you will need to
-; surround it with quotation characters.
-;
-
-;
-; The OpenID Identifier associated with this identity.  This is typically a
-; URL, although the OpenID specifications allow the use of URIs and even XRIs.
-;
-; Relying parties must be able to resolve the identity to obtain the address
-; of this SimpleID installation.
-;
-; WARNING: If you change the OpenID Identifier after you have used it in
-; SimpleID, you will need to delete all files named 'identity-*.cache' in the
-; cache directory.
-;
-; Examples:
-;    http://example.com/
-;    http://example.com:8888/
-;    http://example.com/myopenid
-;    https://example.com:8080/myopenid
-;
-identity="https://id.miau.local/id/icon"
-
-;
-; The password associated with this identity.  
-;
-; The password is encoded as follows:
-;
-;     pass="hash:algorithm:other_params"
-;
-; There are three components to the password string.  Only the first component
-; (the hash) is required, the other two are optional.
-;
-; 1. The hash of the password.  For backwards compatibility reasons, the
-;    default algorithm for hashing the password is MD5.
-;
-;    However, you are strongly encouraged to use a much stronger password
-;    hashing algorithm, such as PBKDF2 with a HMAC-SHA256 function and at least
-;    100,000 iterations.
-;
-; 2. The algorithm used to hash the password.  If this is omitted, 'md5' is assumed.
-;
-;    Allowed algorithms are:
-;
-;    - md5
-;    - sha1
-;    - if the hash module is enabled, pbkdf2 and any algorithms available from that
-;      module
-;
-; 3. Other parameters.
-;
-;    For md5 and sha1, this is an optional salt used to hash the password.  If
-;    used, the password is appended by a colon character (:) then the salt before
-;    a hash is calculated, that is:
-;
-;    hash(password:salt)
-;
-;    For pbkdf2, it is the underlying pseudorandom function, the number of
-;    iterations and the salt, separated by colons.
-;
-; Examples (these contain the same password):
-;    1a79a4d60de6718e8e5b326e338ae533                   ; MD5 hash and no salt
-;    c3499c2729730a7f807efb8676a92dcb6f8a3f8f:sha1      ; SHA1 hash and no salt
-;    f5e6ea5714945786623ad3932ccc757d::ideally-a-large-number-of-random-characters-to-use-as-salt                   ; MD5 hash with salt
-;    9bce4e6997c6f2590717686bd62f99e33d5c6e1c:sha1:ideally-a-large-number-of-random-characters-to-use-as-salt       ; SHA1 hash with salt
-;    c6e1aa5914c6e4e55fae69093afbc02e180810dcc7d3da9f863aa54f3d76e2c3:pbkdf2:sha256:100000:ideally-a-large-number-of-random-characters-to-use-as-salt ; PBKDF2
-;
-pass="9885d0ea104f04cb8a9299b8cf597baff16673dfa6fcee7fce9d98bb6868956d:pbkdf2:sha256:100000:uiaecubklb"
-
-;
-; Whether this user is given administrative privileges in SimpleID.
-;
-; This setting has no effect in the current version of SimpleID.  However,
-; more functionality may be added to SimpleID in future versions which will
-; be restricted to SimpleID administrators.
-;
-; You should grant administrative privileges to at least one user.
-;
-; If you wish this user to be given administrative privileges, uncomment the
-; line below.
-;
-;administrator=1
-
-;
-; Advanced users only: SSL client certificates associated with this identity.
-;
-; You can associate SSL client certificates to this identity, so that you can
-; log in using certificates instead of supplying a user name or password.
-;
-; The SSL certicate is identified using two parameters:
-;
-; - the certificate's serial number
-; - the distinguished name of the certificate's issuer
-;
-; You can find out these two values using OpenSSL by running the following
-; commands (replacing the file name of the certificate as required):
-; 
-;    openssl x509 -noout -serial -in certificate.crt
-;    openssl x509 -noout -issuer -in certificate.crt
-;
-; These two values are then joined together using a semicolon.
-;
-; This option is for advanced users only.  Please see the documentation at
-; http://simpleid.org/docs/1/certauth/
-; for details on how to set this up.
-;
-; Note, you must also enable the certauth extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; certauth
-
-; Example:
-;
-;[certauth]
-;cert[]="02A97C;/C=XX/O=Example CA/OU=Example CA Certificate Signing/CN=Example Client CA"
-
-
-;
-; OpenID Connect user information.
-;
-; If you want to provide personal data to OpenID Connect clients, uncomment the
-; section below and fill in your details.
-;
-; Note that you will need to supply your data in this section again even if you
-; have uncommented and filled in the Simple Registration Extension and/or
-; Attribute Exchange Extension information in the sections below.  SimpleID
-; does not pick these up automatically.
-;
-; WARNING: The address fields below are only supported by PHP 5.3 or later.
-; Earlier versions of PHP are not able to read identity files with
-; associative arrays
-;
-;[user_info]
-;name="Example"
-;given_name="Example"
-;family_name="Example"
-;middle_name="Example"
-;nickname="Example"
-;profile="http://example.com/profile/example"
-;picture="http://example.com/profile/example.jpg"
-;website="http://example.com/blog/example"
-;email="example@example.com"
-;gender="male"
-;birthday="12/31/2000"
-;zoneinfo="Australia/Sydney"
-;locale="en-AU"
-;phone_number="+61400000000"
-;address["formatted"]="1 George Street, Sydney NSW 2000, Australia"
-;address["street_address"]="1 George Street"
-;address["locality"]="Sydney"
-;address["region"]="NSW"
-;address["postal_code"]="2000"
-;address["country"]="Australia"
-
-
-;
-; Simple Registration Extension data.
-;
-; If you want to provide registration data to relying parties which support the
-; Simple Registration Extension, uncomment the section below and fill
-; in your details.
-;
-; Further information on the Simple Registration Extension can be found at
-; http://simpleid.org/docs/1/extensions-bundled/#sreg
-;
-; Note, you must also enable the Simple Registration Extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; sreg
-;
-[sreg]
-nickname="icon"
-email="nico.h@gmx.de"
-fullname="Nico Huber"
-;dob="2000-00-00"
-;gender="M"
-;postcode="1234"
-country="de"
-;language="au"
-timezone="Europe/Berlin"
-
-
-;
-; Attribute Exchange Extension data.
-;
-; If you want to provide personal identity information data to relying parties
-; which support the Attribute Exchange Extension, uncomment the section below
-; and fill in your details.
-;
-; The format of this section is attribute type URI=attribute value.  Examples
-; are given below.
-;
-; For a full list of attributes, see http://openid.net/specs/openid-attribute-properties-list-1_0-01.html
-;
-; Note if you have already uncommented and filled out the OpenID Connect user
-; information and/or Simple Registration Extension data above, you do not need
-; to fill out the corresponding attributes again in the section below.  SimpleID
-; will pick these up automatically, including:
-;
-;    http://axschema.org/namePerson/friendly
-;    http://axschema.org/contact/email
-;    http://axschema.org/namePerson
-;    http://axschema.org/birthDate
-;    http://axschema.org/person/gender
-;    http://axschema.org/contact/postalCode/home
-;    http://axschema.org/contact/country/home
-;    http://axschema.org/pref/language
-;    http://axschema.org/pref/timezone
-;    http://openid.net/schema/namePerson/friendly
-;    http://openid.net/schema/contact/internet/email
-;    http://openid.net/schema/gender
-;    http://openid.net/schema/contact/postalCode/home
-;    http://openid.net/schema/contact/country/home
-;    http://openid.net/schema/language/pref
-;    http://openid.net/schema/timezone
-;
-; Note, you must also enable the Attribute Exchange Extension in SimpleID.  To
-; do this, make sure the SIMPLEID_EXTENSIONS option in config.php contains
-; ax
-;
-;[ax]
-;http://openid.net/schema/company/name="Example Company Limited"
-;http://openid.net/schema/company/title="Managing Director"
-;http://openid.net/schema/contact/web/blog="http://simpleid.org/"
-
diff --git a/simpleid/store/.gitignore b/simpleid/store/.gitignore
deleted file mode 100644
index e4012f6..0000000
--- a/simpleid/store/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Ignore this directory
-*
-
-# Don't ignore this file
-!.gitignore
\ No newline at end of file
diff --git a/simpleid/www/.htaccess.dist b/simpleid/www/.htaccess.dist
deleted file mode 100644
index b962c35..0000000
--- a/simpleid/www/.htaccess.dist
+++ /dev/null
@@ -1,51 +0,0 @@
-# :mode=htaccess:
-#
-# SimpleID
-#
-# Copyright (C) Kelvin Mo 2009
-#
-# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-# 
-# $Id$
-
-# Protect files and directories from prying eyes.
-<FilesMatch "(\.(inc|cache|client|identity|xtpl|inc\.php|store\.php|extension\.php)|config\.php|locale)$">
-    Order deny,allow
-    Deny from all
-</FilesMatch>
-
-# Don't show directory listings for URLs which map to a directory.
-Options -Indexes
-
-# Various rewrite rules.
-<IfModule mod_rewrite.c>
-    RewriteEngine on
-
-    # Modify the RewriteBase if you are using SimpleID in a subdirectory and
-    # the rewrite rules are not working properly.
-    #RewriteBase /simpleid
-
-    # Pass Authorization header to PHP
-    RewriteCond %{HTTP:Authorization} ^(.*)
-    RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
-
-    # Rewrite URLs
-    RewriteCond %{REQUEST_FILENAME} !-f
-    RewriteCond %{REQUEST_FILENAME} !-d
-    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
-</IfModule>
-
-# Switch register_globals to off
-php_value register_globals 0
diff --git a/simpleid/www/bignum.inc.php b/simpleid/www/bignum.inc.php
deleted file mode 100644
index 78fefd7..0000000
--- a/simpleid/www/bignum.inc.php
+++ /dev/null
@@ -1,286 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Abstraction library for multiple precision mathematics.  This file uses either
- * the GNU Multiple Precision Arithmic Libary (GMP) if it is installed, or the
- * default BCMath library if it is not installed.
- *
- * @package simpleid
- * @filesource
- */
-
- 
-if (function_exists('gmp_init')) {
-    /**
-     * Defines whether the GMP library is available.
-     */
-    define('BIGNUM_GMP', true);
-} else {
-    /** @ignore */
-    define('BIGNUM_GMP', false);
-}
-
-/**
- * Returns whether either the GMP or the BCMath library is installed.  If neither
- * of these libraries are installed, the functions in this file will not work.
- *
- * @return bool true if either GMP or BCMath is installed.
- */ 
-function bignum_loaded() {
-    return (function_exists('gmp_init') || function_exists('bcadd'));
-}
-
-/**
- * Creates a bignum.
- *
- * @param mixed $str An integer, a string in base 2 to 36, or a byte stream in base 256
- * @param int $base an integer between 2 and 36, or 256
- * @return resource a bignum
- */
-function bignum_new($str, $base = 10) {
-    switch ($base) {
-        case 10:
-            if (BIGNUM_GMP) {
-                return gmp_init($str, 10);
-            } else {
-                return $str;
-            }
-            break;
-        case 256:
-            $bytes = array_merge(unpack('C*', $str));
-
-            $num = bignum_new(0);
-      
-            foreach ($bytes as $byte) {
-                $num = bignum_mul($num, 256);
-                $num = bignum_add($num, bignum_new($byte));
-            }
-            return $num;
-            break;
-        default:
-            if (!is_integer($base) || ($base < 2) || ($base > 36)) return FALSE;
-
-            $num = bignum_new(0);
-
-            for ($i = 0; $i < strlen($str); $i++) {
-                $num = bignum_mul($num, $base);
-                $num = bignum_add($num, bignum_new(base_convert($str[$i], $base, 10)));
-            }
-            return $num;
-    }
-
-    return FALSE;
-}
-
-/**
- * Converts a bignum into a string representation (base 2 to 36) or a byte stream
- * (base 256)
- *
- * @param resource $num the bignum
- * @param int $base an integer between 2 and 36, or 256
- * @return string the converted bignum
- */
-function bignum_val($num, $base = 10) {
-    switch ($base) {
-        case 10:
-            if (BIGNUM_GMP) {
-                $base10 = gmp_strval($num, 10);
-            } else {
-                $base10 = $num;
-            }
-
-            return $base10;
-            break;
-    
-        case 256:
-            $cmp = bignum_cmp($num, 0);
-            if ($cmp < 0) {
-                return FALSE;
-            }
-    
-            if ($cmp == 0) {
-                return "\x00";
-            }
-    
-            $bytes = array();
-      
-            while (bignum_cmp($num, 0) > 0) {
-                array_unshift($bytes, bignum_mod($num, 256));
-                $num = bignum_div($num, 256);
-            }
-      
-            if ($bytes && ($bytes[0] > 127)) {
-                array_unshift($bytes, 0);
-            }
-      
-            $byte_stream = '';
-            foreach ($bytes as $byte) {
-                $byte_stream .= pack('C', $byte);
-            }
-      
-            return $byte_stream;
-            break;
-        default:
-            if (!is_integer($base) || ($base < 2) || ($base > 36)) return FALSE;
-
-            $cmp = bignum_cmp($num, 0);
-            if ($cmp < 0) {
-                return FALSE;
-            }
-    
-            if ($cmp == 0) {
-                return "0";
-            }
-
-            $str = '';
-            while (bignum_cmp($num, 0) > 0) {
-                $r = intval(bignum_val(bignum_mod($num, $base)));
-                $str = base_convert($r, 10, $base) . $str;
-                $num = bignum_div($num, $base);
-            }
- 
-            return $str;
-    }
-    
-    return FALSE;
-}
-
-/**
- * Adds two bignums
- *
- * @param resource $a
- * @param resource $b
- * @return resource a bignum representing a + b
- */
-function bignum_add($a, $b) {
-    if (BIGNUM_GMP) {
-        return gmp_add($a, $b);
-    } else {
-        return bcadd($a, $b);
-    }
-}
-
-/**
- * Multiplies two bignums
- *
- * @param resource $a
- * @param resource $b
- * @return resource a bignum representing a * b
- */
-function bignum_mul($a, $b) {
-    if (BIGNUM_GMP) {
-        return gmp_mul($a, $b);
-    } else {
-        return bcmul($a, $b);
-    }
-}
-
-/**
- * Divides two bignums
- *
- * @param resource $a
- * @param resource $b
- * @return resource a bignum representing a / b
- */
-function bignum_div($a, $b) {
-    if (BIGNUM_GMP) {
-        return gmp_div($a, $b);
-    } else {
-        return bcdiv($a, $b);
-    }
-}
-
-/**
- * Raise base to power exp
- *
- * @param resource $base the base
- * @param mixed $exp the exponent, as an integer or a bignum
- * @return resource a bignum representing base ^ exp
- */
-function bignum_pow($base, $exp) {
-    if (BIGNUM_GMP) {
-        if (is_resource($exp) && (get_resource_type($exp) == 'gmp')) $exp = gmp_intval($exp);
-        return gmp_pow($base, $exp);
-    } else {
-        return bcpow($base, $exp);
-    }
-}
-
-/**
- * Returns n modulo d
- *
- * @param resource $n
- * @param resource $d
- * @return resource a bignum representing n mod d
- */
-function bignum_mod($n, $d) {
-    if (BIGNUM_GMP) {
-        return gmp_mod($n, $d);
-    } else {
-        return bcmod($n, $d);
-    }
-}
-
-/**
- * Raise a number into power with modulo
- *
- * @param resource $base the base
- * @param resource $exp the exponent
- * @param resource $mod the modulo
- * @return resource a bignum representing base ^ exp mod mod
- */
-function bignum_powmod($base, $exp, $mod) {
-    if (BIGNUM_GMP) {
-        return gmp_powm($base, $exp, $mod);
-    } elseif (function_exists('bcpowmod')) {
-        return bcpowmod($base, $exp, $mod);
-    } else {
-        $square = bignum_mod($base, $mod);
-        $result = 1;
-        while (bignum_cmp($exp, 0) > 0) {
-            if (bignum_mod($exp, 2)) {
-                $result = bignum_mod(bignum_mul($result, $square), $mod);
-            }
-            $square = bignum_mod(bignum_mul($square, $square), $mod);
-            $exp = bignum_div($exp, 2);
-        }
-        return $result;
-    }
-}
-
-/**
- * Compares two bignum
- *
- * @param resource $a
- * @param resource $b
- * @return int positive value if a > b, zero if a = b and a negative value if a < b
- */
-function bignum_cmp($a, $b) {
-    if (BIGNUM_GMP) {
-        return gmp_cmp($a, $b);
-    } else {
-        return bccomp($a, $b);
-    }
-}
-?>
diff --git a/simpleid/www/cache.inc.php b/simpleid/www/cache.inc.php
deleted file mode 100644
index d555e73..0000000
--- a/simpleid/www/cache.inc.php
+++ /dev/null
@@ -1,232 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Functions for caching and persistence.
- *
- * @package simpleid
- * @filesource
- */
- 
-/**
- *  Stores data into the cache.
- *
- * @param string $type the type of data in the cache
- * @param string $key an identifier
- * @param mixed $data the data to store
- * @param int $time if present, sets the modification time of the cache file to this
- * time
- */ 
-function cache_set($type, $key, $data, $time = NULL) {
-    $filename = _cache_get_name($type, $key);
-    if (!file_exists(dirname($filename))) mkdir(dirname($filename), 0775, true);
-    $file = fopen($filename, 'w');
-    fwrite($file, serialize($data));
-    fclose($file);
-    
-    if ($time != NULL) {
-        touch($filename, $time);
-    }
-}
-
-/**
- * Obtains data from the cache.
- *
- * @param string $type the type of data in the cache
- * @param string $key an identifier
- * @return mixed the data associated with the type and key, or NULL if the cache
- * does not contain the requested data.
- */
-function cache_get($type, $key) {
-    $filename = _cache_get_name($type, $key);
-    
-    if (!file_exists($filename)) return NULL;
-    
-    return unserialize(file_get_contents($filename));
-}
-
-/**
- * Obtains all data of a particular type from the cache.
- *
- * @param string $type the type of data in the cache
- * @return mixed an array of data associated with the type, or NULL if the cache
- * does not contain the requested data.
- */
-function cache_get_all($type) {
-    $r = array();
-    
-    if (!is_dir(CACHE_DIR . '/' . $type)) return $r;
-    $dir = opendir(CACHE_DIR . '/' . $type);
-    
-    while (($file = readdir($dir)) !== false) {
-        $filename = CACHE_DIR . '/' . $type . '/' . $file;
-        
-        if (filetype($filename) != "file") continue;
-        
-        $r[] = unserialize(file_get_contents($filename));
-    }
-    
-    closedir($dir);
-    
-    return $r;
-}
-
-/**
- * Deletes data from the cache.
- *
- * @param string $type the type of data in the cache
- * @param string $key an identifier
- */
-function cache_delete($type, $key) {
-    $filename = _cache_get_name($type, $key);
-    if (file_exists($filename)) unlink($filename);
-}
-
-/**
- * Garbage collects data stored the cache.  Data is deleted if it was stored
- * for longer than the specified expiry.
- *
- * This function is deprecated, use {@link cache_expire()}.
- *
- * @param int $expiry the expiry time, in seconds, after which data will be deleted
- * @param string $type the type of data in the cache
- * @deprecated
- */
-function cache_gc($expiry, $type = NULL) {
-    if ($type == NULL) {
-        $dir = opendir(CACHE_DIR);
-
-        while (($file = readdir($dir)) !== false) {
-            $filename = CACHE_DIR . '/' . $file;
-            if (in_array(filetype($filename), array('dir', 'link')))
-                cache_gc($expiry, $file);
-        }
-    } else {
-        if (!is_dir(CACHE_DIR . '/' . $type)) return;
-        $dir = opendir(CACHE_DIR . '/' . $type);
-        while (($file = readdir($dir)) !== false) {
-            $filename = CACHE_DIR . '/' . $type . '/' . $file;
-        
-            if ((filetype($filename) == "file") && (filectime($filename) < time() - $expiry))
-                unlink($filename);
-        }
-    }
-    
-    closedir($dir);
-}
-
-/**
- * Garbage collects data stored the cache.  Data is deleted if it was stored
- * for longer than the specified expiry.
- *
- * The parameter to this function takes either an integer or an array.  If the
- * parameter is an integer, everything in the cache older than the specified
- * time (in seconds) will be deleted.  If the parameter is an array, 
- * cache items of the type specified in the key to the array, older than the
- * corresponding value will be deleted.
- *
- * This function is deprecated, use {@link cache_expire()}.
- *
- * @param int|array $params the expiry time, in seconds, after which data will be deleted,
- * or an array specifiying the expiry time for each type
- */
-function cache_expire($params) {
-
-    $dirs = array();
-    array_push($dirs, CACHE_DIR);
-    while (sizeof($dirs)) {
-        $dirname = array_pop($dirs);
-        if (($dir = opendir($dirname)) === false) {
-            continue;
-        }
-
-        while (($file = readdir($dir)) !== false) {
-            $expiry = NULL;
-            if ($file == '.' || $file == '..') {
-                continue;
-            }
-            $filename = $dirname . '/' . $file;
-
-            if (is_dir($filename)) {
-                array_push($dirs, $filename);
-                continue;
-            }
-
-            if (is_int($params)) {
-                $expiry = $params;
-            } elseif (is_array($params)) {
-                foreach ($params as $type => $param) {
-                    if (strpos($filename, $type) !== false) {
-                        $expiry = $param;
-                        break;
-                    }
-                }
-            }
-
-            if (!is_null($expiry) && (filetype($filename) == "file") && (filectime($filename) < time() - $expiry)) {
-                unlink($filename);
-            }
-        }
-
-        closedir($dir);
-    }
-}
-
-/**
- * Returns the time remaining, in seconds, before the data associated with the
- * type and key become subject to garbage collection by {@link cache_gc()}.
- *
- * @param string $type the type of data in the cache
- * @param string $key an identifier
- * @param int $expiry the expiry time, in seconds, which would be passed onto the
- * {@link cache_gc()} function
- * @return int the time remaining before expiry, rounded downwards,
- * or zero if the cache does not contain the requested data
- * @since 0.8
- */
-function cache_ttl($type, $key, $expiry) {
-    $filename = _cache_get_name($type, $key);
-    
-    if (!file_exists($filename)) return 0;
-    
-    return filectime($filename) - (time() - $expiry) - 1;
-}
-
-/**
- * Returns the name of the cache data file, given a type and an identifier.
- *
- * @param string $type the type of data in the cache
- * @param string $key an identifier
- * @return string a file name
- */
-function _cache_get_name($type, $key) {
-    return CACHE_DIR . '/' . $type . '/' . md5($key) . '.cache';
-}
-
-?>
diff --git a/simpleid/www/common.inc.php b/simpleid/www/common.inc.php
deleted file mode 100644
index b0f3fd6..0000000
--- a/simpleid/www/common.inc.php
+++ /dev/null
@@ -1,664 +0,0 @@
-<?php 
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Common functions used by SimpleID, and the implementation of extensions.
- *
- * @package simpleid
- * @filesource
- */
- 
-/**
- * Sets a message to display to the user on the rendered SimpleID page.
- *
- * @param string $msg the message to set
- */
-function set_message($msg) {
-    global $xtpl;
-    
-    $xtpl->assign('message', $msg);
-    $xtpl->parse('main.message');
-}
-
-/**
- * Displays a fatal error message and exits.
- *
- * @param string $error the message to set
- */
-function indirect_fatal_error($error) {
-    global $xtpl;
-    
-    set_message($error);
-    
-    $xtpl->parse('main');
-    $xtpl->out('main');
-    exit;
-}
-
-/**
- * Send a HTTP response code to the user agent.
- *
- * The format of the HTTP response code depends on the way PHP is run.
- * When run as an Apache module, a properly formatted HTTP response
- * string is sent.  When run via CGI, the response code is sent via the
- * Status response header.
- *
- * @param string $code the response code along
- */
-function header_response_code($code) {
-    if (substr(PHP_SAPI, 0,3) === 'cgi') {
-        header('Status: ' . $code);
-    } else {
-        header($_SERVER['SERVER_PROTOCOL'] . ' ' . $code);
-    }
-}
-
-/**
- * Determines whether the current connection with the user agent is via
- * HTTPS.
- *
- * HTTPS is detected if one of the following occurs:
- *
- * - $_SERVER['HTTPS'] is set to 'on' (Apache installations)
- * - $_SERVER['HTTP_X_FORWARDED_PROTO'] is set to 'https' (reverse proxies)
- * - $_SERVER['HTTP_FRONT_END_HTTPS'] is set to 'on'
- *
- * @return bool true if the connection is via HTTPS
- */
-function is_https() {
-    return (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
-        || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https'))
-        || (isset($_SERVER['HTTP_FRONT_END_HTTPS']) && ($_SERVER['HTTP_FRONT_END_HTTPS'] == 'on'));
-}
-
-
-/**
- * Ensure the current connection with the user agent is secure with HTTPS.
- *
- * This function uses {@link is_https()} to determine whether the connection
- * is via HTTPS.  If it is, this function will return successfully.
- *
- * If it is not, what happens next is determined by the following steps.
- *
- * 1. If $allow_override is true and {@link SIMPLEID_ALLOW_PLAINTEXT} is also true,
- * then the function will return successfully
- * 2. Otherwise, then it will either redirect (if $action is
- * redirect) or return an error (if $action is error)
- *
- * @param string $action what to do if connection is not secure - either
- * 'redirect' or 'error'
- * @param boolean $allow_override whether SIMPLEID_ALLOW_PLAINTEXT is checked
- * to see if an unencrypted connection is allowed
- * @param string $redirect_url if $action is redirect, what URL to redirect to.
- * If null, this will redirect to the same page (albeit with an HTTPS connection)
- * @param boolean $strict whether HTTP Strict Transport Security is active
- * @see SIMPLEID_ALLOW_PLAINTEXT
- */
-function check_https($action = 'redirect', $allow_override = false, $redirect_url = null, $strict = true) {
-    if (is_https()) {
-        if ($strict) header('Strict-Transport-Security: max-age=3600');
-        return;
-    }
-    
-    if ($allow_override && SIMPLEID_ALLOW_PLAINTEXT) return;
-    
-    if ($action == 'error') {
-        if (substr(PHP_SAPI, 0,3) === 'cgi') {
-            header('Status: 426 Upgrade Required');
-        } else {
-            header($_SERVER['SERVER_PROTOCOL'] . ' 426 Upgrade Required');
-        }
-
-        header('Upgrade: TLS/1.2, HTTP/1.1');
-        header('Connection: Upgrade');
-        indirect_fatal_error(t('An encrypted connection (HTTPS) is required for this page.'));
-        return;
-    }
-    
-    if ($redirect_url == null) $redirect_url = simpleid_url('', $_SERVER['QUERY_STRING'], false, 'https');
-    
-    if (substr(PHP_SAPI, 0,3) === 'cgi') {
-        header('Status: 301 Moved Permanently');
-    } else {
-        header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
-    }
-        
-    header('Location: ' . $redirect_url);
-}
-
-/**
- * Fix PHP's handling of request data.  PHP changes dots in all request parameters
- * to underscores when creating the $_GET, $_POST and $_REQUEST arrays.
- *
- * This function scans the original query string and POST parameters and fixes
- * them.
- */
-function fix_http_request() {
-    // Fix GET parameters
-    if (isset($_SERVER['QUERY_STRING'])) {
-        $get = parse_http_query($_SERVER['QUERY_STRING']);
-        
-        foreach ($get as $key => $value) {
-            // We strip out array-like identifiers - PHP uses special processing for these
-            if ((strpos($key, '[') !== FALSE) && (strpos($key, ']') !== FALSE)) $key = substr($key, 0, strpos($key, '['));
-            
-            // Replace special characters with underscore as per PHP processing
-            $php_key = preg_replace('/[ .[\x80-\x9F]/', '_', $key);
-            
-            // See if the PHP key is present; if so, copy and delete
-            if (($key != $php_key) && isset($_GET[$php_key])) {
-                $_GET[$key] = $_GET[$php_key];
-                $_REQUEST[$key] = $_REQUEST[$php_key];
-                unset($_GET[$php_key]);
-                unset($_REQUEST[$php_key]);
-            }
-        }
-    }
-    
-    // Fix POST parameters
-    $input = file_get_contents('php://input');
-    if ($input !== FALSE) {
-        $post = parse_http_query($input);
-        
-        foreach ($post as $key => $value) {
-            // We strip out array-like identifiers - PHP uses special processing for these
-            if ((strpos($key, '[') !== FALSE) && (strpos($key, ']') !== FALSE)) $key = substr($key, 0, strpos($key, '['));
-            
-            // Replace special characters with underscore as per PHP processing
-            $php_key = preg_replace('/[ .[\x80-\x9F]/', '_', $key);
-            
-            // See if the PHP key is present; if so, copy and delete
-            if (($key != $php_key) && isset($_POST[$php_key])) {
-                $_POST[$key] = $_POST[$php_key];
-                $_REQUEST[$key] = $_REQUEST[$php_key];
-                unset($_POST[$php_key]);
-                unset($_REQUEST[$php_key]);
-            }
-        }
-    }
-}
-
-/**
- * Parses a query string.
- *
- * @param string $query the query string to parse
- * @return array an array containing the parsed key-value pairs
- *
- * @since 0.7
- */
-function parse_http_query($query) {
-    $data = array();
-    
-    if ($query === NULL) return array();
-    if ($query === '') return array();
-    
-    $pairs = explode('&', $query);
-    
-    foreach ($pairs as $pair) {
-        list ($key, $value) = explode('=', $pair, 2);
-        $data[$key] = urldecode($value);
-    }
-
-    return $data;
-}
-
-/**
- * Assigns and returns a unique ID for the user agent (UAID).
- *
- * A UAID uniquely identifies the user agent (e.g. browser) used to
- * make the HTTP request.  The UAID is stored in a long-dated
- * cookie.  Therefore, the UAID may be useful for security purposes.
- *
- * This function will look for a cookie sent by the user agent with
- * the name returned by {@link simpleid_cookie_name()} with a suffix
- * of uaid.  If the cookie does not exist, it will generate a
- * random UAID and return it to the user agent with a Set-Cookie
- * response header.
- *
- * @return string the UAID
- */
-function get_user_agent_id() {
-    if (isset($_COOKIE[simpleid_cookie_name('uaid')])) return $_COOKIE[simpleid_cookie_name('uaid')];
-
-    $uaid = bin2hex(pack('LLLL', mt_rand(), mt_rand(), mt_rand(), mt_rand()));
-    setcookie(simpleid_cookie_name('uaid'), $uaid, time() + 315360000, get_base_path(), '', false, true);
-    return $uaid;
-}
-
-/**
- * Content type negotiation using the Accept Header.
- *
- * Under HTTP, the user agent is able to negoatiate the content type returned with
- * the server using HTTP Accept header.  This header contains a comma-delimited
- * list of items (e.g. content types) which the user agent is able to
- * accept, ranked by a quality parameter.
- *
- * This function takes the header from the user agent, compares it against the
- * content types which the server can provide, then returns the item which the highest
- * quality which the server can provide.
- *
- * @param array $content_types an array of content types which the server can
- * provide
- * @param string $accept_header the header string provided by the user agent.
- * If NULL, this defaults to $_SERVER['HTTP_ACCEPT'] if available
- * @return string the negotiated content type, FALSE if $accept_header is NULL and
- * the user agent did not provide an Accept header, or NULL if the negotiation is
- * unsuccessful
- *
- * @since 0.8
- *
- */
-function negotiate_content_type($content_types, $accept_header = NULL) {
-    $content_types = array_map("strtolower", $content_types);
-    if (($accept_header == NULL) && isset($_SERVER['HTTP_ACCEPT'])) $accept_header = $_SERVER['HTTP_ACCEPT'];
-    
-    if ($accept_header) {
-        $acceptible = preg_split('/\s*,\s*/', strtolower(trim($accept_header)));
-        for ($i = 0; $i < count($acceptible); $i++) {
-            $split = preg_split('/\s*;\s*q\s*=\s*/', $acceptible[$i], 2);
-            $item = strtolower($split[0]);
-            
-            if (count($split) == 1) {
-                $q = 1.0;
-            } else {
-                $q = doubleval($split[1]);
-            }
-            
-            if ($q > 0.0) {
-                if (in_array($item, $content_types)) {
-                    if ($q == 1.0) {
-                        return $item;
-                    }
-                    $candidates[$item] = $q;
-                } else {
-                    $item = preg_quote($item, '/');
-                    $item = strtr($item, array('\*' => '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'));
-                    
-                    foreach ($content_types as $value) {
-                        if (preg_match("/^$item$/", $value)) {
-                            if ($q == 1.0) {
-                                return $value;
-                            }
-                            $candidates[$value] = $q;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-        if (isset($candidates)) {
-            arsort($candidates);
-            reset($candidates);
-            return key($candidates);
-        }
-        return NULL;
-    } else {
-        // No headers
-        return FALSE;
-    }
-}
-
-/**
- * Serialises a variable for inclusion as a URL parameter.
- *
- * @param mixed $data the data to serialise
- * @return string serialised data
- * @see unpickle()
- */
-function pickle($data) {
-    return base64_encode(gzcompress(serialize($data)));
-}
-
-/**
- * Deserialises data specified in a URL parameter as a variable.
- *
- * @param string $pickle the serialised data
- * @return mixed the deserialised data
- * @see pickle()
- */
-function unpickle($pickle) {
-    return unserialize(gzuncompress(base64_decode($pickle)));
-}
-
-/**
- * Compares two strings using the same time whether they're equal or not.
- * This function should be used to mitigate timing attacks when, for
- * example, comparing password hashes
- *
- * @param string $str1
- * @param string $str2
- * @return bool true if the two strings are equal
- */
-function secure_compare($str1, $str2) {
-    if (function_exists('hash_equals')) return hash_equals($str1, $str2);
-
-    $xor = $str1 ^ $str2;
-    $result = strlen($str1) ^ strlen($str2); //not the same length, then fail ($result != 0)
-    for ($i = strlen($xor) - 1; $i >= 0; $i--) $result += ord($xor[$i]);
-    return !$result;
-}
-
-/**
- * Obtains the URI of the current request, given a base URI.
- *
- * @param string $base the base URI
- * @return string the request URI
- */
-function get_request_uri($base) {
-    $i = strpos($base, '//');
-    $i = strpos($base, '/', $i + 2);
-    
-    if ($i === false) {
-        return $base . $_SERVER['REQUEST_URI'];
-    } else {
-        return substr($base, 0, $i) . $_SERVER['REQUEST_URI'];
-    }
-}
-
-/**
- * Returns the base URL path, relative to the current host, of the SimpleID
- * installation.
- *
- * This is worked out from {@link SIMPLEID_BASE_URL}.  It will always contain
- * a trailing slash.
- *
- * @return string the base URL path
- * @since 0.8
- * @see SIMPLEID_BASE_URL
- */
-function get_base_path() {
-    static $base_path;
-    
-    if (!$base_path) {
-        if ((substr(SIMPLEID_BASE_URL, -1) == '/') || (substr(SIMPLEID_BASE_URL, -9) == 'index.php')) {
-            $url = SIMPLEID_BASE_URL;
-        } else {
-            $url = SIMPLEID_BASE_URL . '/';
-        }
-        
-        $parts = parse_url($url);
-        $base_path = $parts['path'];
-    }
-    
-    return $base_path;
-}
-
-/**
- * Determines whether the {@link SIMPLEID_BASE_URL} configuration option is a
- * HTTPS URL.
- *
- * @return true if SIMPLEID_BASE_URL is a HTTPS URL
- */
-function is_base_https() {
-    return (stripos(SIMPLEID_BASE_URL, 'https:') === 0);
-}
-
-/**
- * Obtains a SimpleID URL.  URLs produced by SimpleID should use this function.
- *
- * @param string $q the q parameter
- * @param string $params a properly encoded query string
- * @param bool $relative whether a relative URL should be returned
- * @param string $secure if $relative is false, either 'https' to force an HTTPS connection, 'http' to force
- * an unencrypted HTTP connection, 'detect' to base on the current connection, or NULL to vary based on SIMPLEID_BASE_URL
- * @return string the url
- *
- * @since 0.7
- */
-function simpleid_url($q = '', $params = '', $relative = false, $secure = null) {
-    if ($relative) {
-        $url = get_base_path();
-    } else {
-        // Make sure that the base has a trailing slash
-        if ((substr(SIMPLEID_BASE_URL, -1) == '/') || (substr(SIMPLEID_BASE_URL, -9) == 'index.php')) {
-            $url = SIMPLEID_BASE_URL;
-        } else {
-            $url = SIMPLEID_BASE_URL . '/';
-        }
-        
-        if (($secure == 'https') && (stripos($url, 'http:') === 0)) {
-            $url = 'https:' . substr($url, 5);
-        }
-        if (($secure == 'http') && (stripos($url, 'https:') === 0)) {
-            $url = 'http:' . substr($url, 6);
-        }
-        if (($secure == 'detect') && (is_https()) && (stripos($url, 'http:') === 0)) {
-            $url = 'https:' . substr($url, 5);
-        }
-        if (($secure == 'detect') && (!is_https()) && (stripos($url, 'https:') === 0)) {
-            $url = 'http:' . substr($url, 6);
-        }
-    }
-    
-    if (SIMPLEID_CLEAN_URL) {
-        $url .= $q . (($params == '') ? '' : '?' . $params);
-    } elseif (($q == '') && ($params == '')) {
-        $url .= '';
-    } elseif ($q == '') {
-        $url .= 'index.php?' . $params;
-    } else {
-        $url .= 'index.php?q=' . $q . (($params == '') ? '' : '&' . $params);
-    }
-    return $url;
-}
-
-/**
- * Obtains the URL of the host of the SimpleID's installation.  The host is worked
- * out based on SIMPLEID_BASE_URL
- *
- * @param string $secure if $relative is false, either 'https' to force an HTTPS connection, 'http' to force
- * an unencrypted HTTP connection, or NULL to vary based on SIMPLEID_BASE_URL
- * @return string the url
- */
-function simpleid_host_url($secure = null) {
-    $parts = parse_url(SIMPLEID_BASE_URL);
-    
-    if ($secure == 'https') {
-        $scheme = 'https';
-    } elseif ($secure == 'http') {
-        $scheme = 'http';
-    } else {
-        $scheme = $parts['scheme'];
-    }
-    
-    $url = $scheme . '://';
-    if (isset($parts['user'])) {
-        $url .= $parts['user'];
-        if (isset($parts['pass'])) $url .= ':' . $parts['pass'];
-        $url .= '@';
-    }
-    $url .= $parts['host'];
-    if (isset($parts['port'])) $url .= ':' . $parts['port'];
-
-    return $url;
-}
-
-/**
- * Returns a relatively unique cookie name based on a specified suffix and
- * SIMPLEID_BASE_URL.
- *
- * @param string $suffix the cookie name suffix
- * @return string the cookie name
- */
-function simpleid_cookie_name($suffix) {
-    static $prefix = NULL;
-
-    if ($prefix == NULL) {
-        $prefix = substr(get_form_token('cookie', FALSE), 0, 7) . '_';
-    }
-    return $prefix . $suffix;
-}
-
-/**
- * Obtains a form token given a form ID.
- *
- * Form tokens are used in SimpleID forms to guard against cross-site forgery
- * attacks.
- *
- * @param string $id the form ID
- * @param bool $bind_session whether to bind the form token to the current session
- * @return string a form token
- */
-function get_form_token($id, $bind_session = TRUE) {
-    global $user;
-
-    if (store_get('site-token') == NULL) {
-        $site_token = pack('LLLL', mt_rand(), mt_rand(), mt_rand(), mt_rand());
-        store_set('site-token', $site_token);
-    } else {
-        $site_token = store_get('site-token');
-    }
-    
-    return _get_form_token($site_token, $id, $bind_session);
-}
-
-/**
- * Checks whether a form token is valid
- *
- * @param string $token the token returned by the user agent
- * @param string $id the form ID
- * @param bool $bind_session whether the token has been bound to the current session
- * @return bool true if the form token is valid
- */
-function validate_form_token($token, $id, $bind_session = TRUE) {
-    global $user;
-    
-    $site_token = store_get('site-token');
-    
-    return ($token == _get_form_token($site_token, $id, $bind_session));
-}
-
-function _get_form_token($site_token, $id, $bind_session = TRUE) {
-    global $user;
-
-    if (($user == NULL) || (!$bind_session)) {
-        $key = $site_token;
-    } else {
-        $key = session_id() . $site_token;
-    }
-
-    if (function_exists('hash_hmac') && function_exists('hash_algos') && (in_array('sha1', hash_algos()))) {
-        return hash_hmac('sha1', $id, $key);
-    } else {
-        if (strlen($site_token) > 64) {
-            $site_token = sha1($site_token, TRUE);
-        }
-    
-        $site_token = str_pad($site_token, 64, chr(0x00));
-        $ipad = str_repeat(chr(0x36), 64);
-        $opad = str_repeat(chr(0x5c), 64);
-        return bin2hex(sha1(($key ^ $opad) . sha1(($key ^ $ipad) . $text, TRUE), TRUE));
-    }
-}
-
-/* ------- SimpleID extension support ---------------------------------------- */
-
-
-/**
- * This variable holds an array of extensions specified by the user
- *
- * @global array $simpleid_extensions
- * @see SIMPLEID_EXTENSIONS
- */
-$simpleid_extensions = array();
-
-/**
- * Initialises the extension mechanism.  This function looks up the extensions
- * to load in the {@link SIMPLEID_EXTENSIONS} constants, loads them, then
- * calls the ns hook.
- */
-function extension_init() {
-    global $simpleid_extensions;
-    
-    $simpleid_extensions = preg_split('/,\s*/', SIMPLEID_EXTENSIONS);
-    
-    foreach ($simpleid_extensions as $extension) {
-        include_once 'extensions/' . $extension . '/' . $extension . '.extension.php';
-    }
-}
-
-/**
- * Invokes a hook in all the loaded extensions.
- *
- * @param string $function the name of the hook to call
- * @param mixed $args the arguments to the hook
- * @return array the return values from the hook
- */
-function extension_invoke_all() {
-    global $simpleid_extensions;
-    
-    $args = func_get_args();
-    $function = array_shift($args);
-    $return = array();
-    
-    foreach ($simpleid_extensions as $extension) {
-        if (function_exists($extension . '_' . $function)) {
-            log_debug('extension_invoke_all: ' . $extension . '_' . $function);
-            $result = call_user_func_array($extension . '_' . $function, $args);
-            if (isset($result) && is_array($result)) {
-                $return = array_merge($return, $result);
-            } elseif (isset($result)) {
-                $return[] = $result;
-            } 
-        }
-    }
-    
-    return $return;
-}
-
-/**
- * Invokes a hook in a specified extension.
- *
- * @param string $extension the extension to call
- * @param string $function the name of the hook to call
- * @param mixed $args the arguments to the hook
- * @return mixed the return value from the hook
- */
-function extension_invoke() {
-    $args = func_get_args();
-    $extension = array_shift($args);
-    $function = array_shift($args);
-    
-    if (function_exists($extension . '_' . $function)) {
-        log_debug('extension_invoke: ' . $extension . '_' . $function);
-        return call_user_func_array($extension . '_' . $function, $args);
-    }
-}
-
-/**
- * Returns an array of currently loaded extensions.
- *
- * @return array a list of the names of the currently loaded extensions.
- */
-function get_extensions() {
-    global $simpleid_extensions;
-    
-    return $simpleid_extensions;
-}
-?>
diff --git a/simpleid/www/config.default.php b/simpleid/www/config.default.php
deleted file mode 100644
index a64e832..0000000
--- a/simpleid/www/config.default.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-/**
- * Default configuration settings
- *
- * @package simpleid
- * @filesource
- */
-
-/**
- * Define a constant if it has not been defined already.
- *
- * @param $name string the name of the constant
- * @param $value mixed the value of the constant - only scalar and null values
- * are allowed
- */
-function define_default($name, $value) {
-    if (!defined($name)) {
-        define($name, $value);
-    }
-}
-
-define_default('SIMPLEID_CLEAN_URL', false);
-define_default('SIMPLEID_ALLOW_PLAINTEXT', false);
-define_default('SIMPLEID_ALLOW_AUTOCOMPLETE', false);
-define_default('SIMPLEID_EXTENSIONS', 'sreg');
-define_default('SIMPLEID_VERIFY_RETURN_URL_USING_REALM', true);
-define_default('SIMPLEID_STORE', 'filesystem');
-define_default('SIMPLEID_STORE_DIR', SIMPLEID_CACHE_DIR);
-define_default('SIMPLEID_LOCALE', 'en');
-define_default('SIMPLEID_LOGFILE', '');
-define_default('SIMPLEID_LOGLEVEL', 4);
-
-if (function_exists('date_default_timezone_set')) date_default_timezone_set(@date_default_timezone_get());
-?>
diff --git a/simpleid/www/config.pear.php b/simpleid/www/config.pear.php
deleted file mode 100644
index 0d797a8..0000000
--- a/simpleid/www/config.pear.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2012
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Proxy for {@link config.php} for PEAR installations.
- *
- * @package pear
- */
- 
-include_once 'PEAR/Config.php';
- 
-$pear_cfg_dir = PEAR_Config::singleton()->get('cfg_dir');
-include_once $pear_cfg_dir . '/simpleid/config.php';
-?>
diff --git a/simpleid/www/config.php b/simpleid/www/config.php
deleted file mode 100644
index 2bca86d..0000000
--- a/simpleid/www/config.php
+++ /dev/null
@@ -1,220 +0,0 @@
-<?php
-/**
- * SimpleID configuration file.
- *
- * @package simpleid
- *
- */
-/*
- * $Id$
- *
- */
-
-
-/**
- * Base URL.
- *
- * This is the URL of the location you want to place your SimpleID
- * distribution.  It becomes the URL of the SimpleID server.
- *
- * It is not allowed to have a trailing slash; SimpleID will add it
- * for you.
- *
- * Examples:
- * <code>
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com');
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com:8888');
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com/simpleid');
- *   define('SIMPLEID_BASE_URL', 'https://www.example.com:8888/simpleid');
- * </code>
- *
- */
-define('SIMPLEID_BASE_URL', 'https://id.miau.local/id');
-
-/**
- * Allow clean URLs.
- *
- * URLs used in SimpleID are normally in the form
- * http://www.example.com/index.php?q=foo.  Enabling clean URLs will allow for
- * SimpleID URLs to be in the form http://www.example.com/foo
- *
- * In order to support clean URLs, you must be using Apache with mod_rewrite
- * enabled.  You will need to rename .htaccess.dist in the SimpleID web directory
- * to .htaccess
- *
- * @since 0.8
- *
- */
-define('SIMPLEID_CLEAN_URL', false);
-
-/**
- * Directory to store identity information.
- *
- * This directory must exist and be readable by the web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_IDENTITIES_DIR', '/var/db/simpleid');
-
-/**
- * Directory to store cache data.
- *
- * This directory must exist and be readable and writable by the
- * web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_CACHE_DIR', '/var/cache/simpleid');
-
-/**
- * Persistent data storage mechanism.
- *
- * SimpleID provides flexible methods to store and retrieve persistent data.
- * By default, SimpleID uses the file system to store this data, implemented
- * in filesystem.store.inc.  Users can implement other methods by creating
- * a file with extension .store.inc and specifying the file through this
- * setting.
- * 
- * Generally you do not need to change this setting.
- *
- */
-define('SIMPLEID_STORE', 'filesystem');
-
-/**
- * Directory to store persistent data.
- *
- * This directory must exist and be readable and writable by the
- * web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_STORE_DIR', '/var/lib/simpleid');
-
-/**
- * Allows use of unencrypted connections.
- *
- * Between versions 0.6 and 0.8 (inclusive), SimpleID uses either HTTPS or 
- * a form of digest authentication for its login system.  This allows passwords
- * and other secure information not to be sent to the server as plaintext.
- *
- * From version 0.9, SimpleID mandates the use of HTTPS for all connections
- * (other than direct connections between SimpleID and an OpenID relying
- * party).  However, for debug purposes, it may be necessary to allow
- * unencrypted connections to SimpleID.
- *
- * It is strongly recommended that this is set to false.  Setting this to true
- * will allow passwords to be sent as plaintext.  You should not change this
- * value unless it is absolutely necessary.
- *
- * @since 0.9
- */
-define('SIMPLEID_ALLOW_PLAINTEXT', false);
-
-/**
- * Allows web browsers to save passwords.
- *
- * SimpleID prevents web browsers from saving user passwords entered in a user
- * logs into SimpleID.  Setting this value to true will allow browsers to
- * ask the user whether the password should be saved in the browser's password
- * store.
- *
- * The default is set to false for security reasons.  You should not change
- * this value unless you are certain regarding the security of your browser's
- * password store.
- *
- * @since 0.8
- */
-define('SIMPLEID_ALLOW_AUTOCOMPLETE', false);
-
-/**
- * Performs additional verification of relying party return URLs.
- *
- * When authenticating using OpenID version 2, SimpleID version 0.7 or later
- * can perform additional verification of the relying party's return URLs under
- * section 9.2.1 of the OpenID specification.
- *
- * The default is set to true for security reasons.  However, if your web server
- * is blocked by your web hosting provider's firewall from accessing outside
- * servers, then set this to false.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_VERIFY_RETURN_URL_USING_REALM', true);
-
-
-/**
- * The locale for the SimpleID user interface.
- *
- * @since 0.9
- */
-define('SIMPLEID_LOCALE', 'en');
-
-/**
- * Date and time format.
- *
- * The date and time format specified using the strftime() syntax.
- *
- * See http://www.php.net/strftime for details.
- * 
- */
-define('SIMPLEID_DATE_TIME_FORMAT', '%Y-%m-%d %H:%M:%S %Z');
-
-/**
- * The number of seconds before associations expire.  This is an advanced
- * option, for which the default setting should work fine.
- *
- * Note that for ICAM compliance, this number must be less than 86400.
- */
-define('SIMPLEID_ASSOC_EXPIRES_IN', 3600);
-
-/**
- * SimpleID extensions.
- *
- * The SimpleID extensions you wish to load.  You should separate the
- * extensions you wish to load with a comma.
- *
- */
-define('SIMPLEID_EXTENSIONS', 'sreg,ui');
-
-/**
- * Log file.
- *
- * You can specify a file into which SimpleID will log various diagnostic
- * messages.
- *
- * The log file's directory must exist and must be writable by the web server.
- *
- * To disable logging, set this as an empty string.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_LOGFILE', '/var/log/simpleid.log');
-
-/**
- * The level of detail for log messages.
- *
- * You can determine which messages are captured in the log file by specifying
- * a number between 0 and 5. The higher the number, the more messages are
- * logged.
- *
- * WARNING: Setting the log level to 5 will result in security sensitive
- * information also being logged.
- *
- * This has effect only if logging is enabled.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_LOGLEVEL', 4);
-?>
diff --git a/simpleid/www/config.php.dist b/simpleid/www/config.php.dist
deleted file mode 100644
index 4601ae8..0000000
--- a/simpleid/www/config.php.dist
+++ /dev/null
@@ -1,220 +0,0 @@
-<?php
-/**
- * SimpleID configuration file.
- *
- * @package simpleid
- *
- */
-/*
- * $Id$
- *
- */
-
-
-/**
- * Base URL.
- *
- * This is the URL of the location you want to place your SimpleID
- * distribution.  It becomes the URL of the SimpleID server.
- *
- * It is not allowed to have a trailing slash; SimpleID will add it
- * for you.
- *
- * Examples:
- * <code>
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com');
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com:8888');
- *   define('SIMPLEID_BASE_URL', 'http://www.example.com/simpleid');
- *   define('SIMPLEID_BASE_URL', 'https://www.example.com:8888/simpleid');
- * </code>
- *
- */
-define('SIMPLEID_BASE_URL', 'http://www.example.com');
-
-/**
- * Allow clean URLs.
- *
- * URLs used in SimpleID are normally in the form
- * http://www.example.com/index.php?q=foo.  Enabling clean URLs will allow for
- * SimpleID URLs to be in the form http://www.example.com/foo
- *
- * In order to support clean URLs, you must be using Apache with mod_rewrite
- * enabled.  You will need to rename .htaccess.dist in the SimpleID web directory
- * to .htaccess
- *
- * @since 0.8
- *
- */
-define('SIMPLEID_CLEAN_URL', false);
-
-/**
- * Directory to store identity information.
- *
- * This directory must exist and be readable by the web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_IDENTITIES_DIR', '../identities');
-
-/**
- * Directory to store cache data.
- *
- * This directory must exist and be readable and writable by the
- * web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_CACHE_DIR', '../cache');
-
-/**
- * Persistent data storage mechanism.
- *
- * SimpleID provides flexible methods to store and retrieve persistent data.
- * By default, SimpleID uses the file system to store this data, implemented
- * in filesystem.store.inc.  Users can implement other methods by creating
- * a file with extension .store.inc and specifying the file through this
- * setting.
- * 
- * Generally you do not need to change this setting.
- *
- */
-define('SIMPLEID_STORE', 'filesystem');
-
-/**
- * Directory to store persistent data.
- *
- * This directory must exist and be readable and writable by the
- * web server.
- *
- * For maximum security, it is highly recommended to place this
- * directory outside your web browser's document root directory, so
- * that it is not visible to user agents.
- *
- */
-define('SIMPLEID_STORE_DIR', '../store');
-
-/**
- * Allows use of unencrypted connections.
- *
- * Between versions 0.6 and 0.8 (inclusive), SimpleID uses either HTTPS or 
- * a form of digest authentication for its login system.  This allows passwords
- * and other secure information not to be sent to the server as plaintext.
- *
- * From version 0.9, SimpleID mandates the use of HTTPS for all connections
- * (other than direct connections between SimpleID and an OpenID relying
- * party).  However, for debug purposes, it may be necessary to allow
- * unencrypted connections to SimpleID.
- *
- * It is strongly recommended that this is set to false.  Setting this to true
- * will allow passwords to be sent as plaintext.  You should not change this
- * value unless it is absolutely necessary.
- *
- * @since 0.9
- */
-define('SIMPLEID_ALLOW_PLAINTEXT', false);
-
-/**
- * Allows web browsers to save passwords.
- *
- * SimpleID prevents web browsers from saving user passwords entered in a user
- * logs into SimpleID.  Setting this value to true will allow browsers to
- * ask the user whether the password should be saved in the browser's password
- * store.
- *
- * The default is set to false for security reasons.  You should not change
- * this value unless you are certain regarding the security of your browser's
- * password store.
- *
- * @since 0.8
- */
-define('SIMPLEID_ALLOW_AUTOCOMPLETE', false);
-
-/**
- * Performs additional verification of relying party return URLs.
- *
- * When authenticating using OpenID version 2, SimpleID version 0.7 or later
- * can perform additional verification of the relying party's return URLs under
- * section 9.2.1 of the OpenID specification.
- *
- * The default is set to true for security reasons.  However, if your web server
- * is blocked by your web hosting provider's firewall from accessing outside
- * servers, then set this to false.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_VERIFY_RETURN_URL_USING_REALM', true);
-
-
-/**
- * The locale for the SimpleID user interface.
- *
- * @since 0.9
- */
-define('SIMPLEID_LOCALE', 'en');
-
-/**
- * Date and time format.
- *
- * The date and time format specified using the strftime() syntax.
- *
- * See http://www.php.net/strftime for details.
- * 
- */
-define('SIMPLEID_DATE_TIME_FORMAT', '%Y-%m-%d %H:%M:%S %Z');
-
-/**
- * The number of seconds before associations expire.  This is an advanced
- * option, for which the default setting should work fine.
- *
- * Note that for ICAM compliance, this number must be less than 86400.
- */
-define('SIMPLEID_ASSOC_EXPIRES_IN', 3600);
-
-/**
- * SimpleID extensions.
- *
- * The SimpleID extensions you wish to load.  You should separate the
- * extensions you wish to load with a comma.
- *
- */
-define('SIMPLEID_EXTENSIONS', 'sreg,ui');
-
-/**
- * Log file.
- *
- * You can specify a file into which SimpleID will log various diagnostic
- * messages.
- *
- * The log file's directory must exist and must be writable by the web server.
- *
- * To disable logging, set this as an empty string.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_LOGFILE', '');
-
-/**
- * The level of detail for log messages.
- *
- * You can determine which messages are captured in the log file by specifying
- * a number between 0 and 5. The higher the number, the more messages are
- * logged.
- *
- * WARNING: Setting the log level to 5 will result in security sensitive
- * information also being logged.
- *
- * This has effect only if logging is enabled.
- *
- * @since 0.7
- *
- */
-define('SIMPLEID_LOGLEVEL', 4);
-?>
diff --git a/simpleid/www/discovery.inc.php b/simpleid/www/discovery.inc.php
deleted file mode 100644
index 17939f8..0000000
--- a/simpleid/www/discovery.inc.php
+++ /dev/null
@@ -1,649 +0,0 @@
-<?php 
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Support for XRDS based discovery.
- *
- * The functions for this file supports HTTP-based identifiers.  For XRIs, the
- * resolution service xri.net is used to resolve to HTTP-based URLs.
- *
- * @package simpleid
- * @since 0.7
- * @filesource
- */
- 
-include_once "http.inc.php";
-
-/**
- * The namespace identifier for an XRDS document.
- */
-define('XRDS_NS', 'xri://$xrds');
-
-/**
- * The namespace identifier for XRDS version 2.
- */
-define('XRD2_NS', 'xri://$xrd*($v*2.0)');
-
-/**
- * The namespace identifier for XRDS Simple.
- */
-define('XRDS_SIMPLE_NS', 'http://xrds-simple.net/core/1.0');
-
-/**
- * The type identifier for XRDS Simple.
- */
-define('XRDS_SIMPLE_TYPE', 'xri://$xrds*simple');
-
-/**
- * The namespace identifier for OpenID services.
- */
-define('XRD_OPENID_NS', 'http://openid.net/xmlns/1.0');
-
-/**
- * Obtains the services for particular identifier.
- *
- * This function attempts to discover and obtain the XRDS document associated
- * with the identifier, parses the XRDS document and returns an array of
- * services.
- *
- * If an XRDS document is not found, and $openid is set to true, this function
- * will also attempt to discover OpenID services by looking for link elements
- * with rel of openid.server or openid2.provider in the discovered HTML document.
- *
- * @param string $identifier the identifier
- * @param bool $openid if true, performs additional discovery of OpenID services
- * by looking for link elements within the discovered document
- * @return array an array of discovered services, or an empty array if no services
- * are found
- */
-function discovery_xrds_discover($identifier, $openid = FALSE) {
-    $identifier = discovery_xrds_normalize($identifier);
-    $url = discovery_xrds_url($identifier);
-    
-    $xrds = discovery_xrds_get($url);
-
-    if ($xrds) {
-        return discovery_xrds_parse($xrds);
-    } else {
-        if ($openid) return discovery_html_get_services($url);
-        return array();
-    }
-}
-
-/**
- * Given an array of discovered services, obtains information on services of
- * a particular type.
- *
- * @param array $services the discovered services
- * @param string $type the URI of the type of service to obtain
- * @return array an array of matching services, or an empty array of no services
- * match
- */
-function discovery_xrds_services_by_type($services, $type) {
-    $matches = array();
-    
-    foreach ($services as $service) {
-        foreach ($service['type'] as $service_type) {
-            if ($service_type == $type) $matches[] = $service;
-        }
-    }
-    return $matches;
-}
-
-/**
- * Given an array of discovered services, obtains information on the service of
- * a specified ID.
- *
- * @param array $services the discovered services
- * @param string $id the XML ID of the service in the XRDS document
- * @return array the matching service, or NULL of no services
- * are found
- */
-function discovery_xrds_service_by_id($services, $id) {
-    foreach ($services as $service) {
-        if ($service['#id'] == $id) return $service;
-    }
-    return NULL;
-}
-
-/**
- * Obtains a XRDS document at a particular URL.  Performs Yadis discovery if
- * the URL does not produce a XRDS document.
- *
- * @param string $url the URL
- * @param bool $check whether to check the content type of the response is
- * application/xrds+xml
- * @param int $retries the number of tries to make
- * @return string the contents of the XRDS document
- */
-function discovery_xrds_get($url, $check = TRUE, $retries = 5) {
-    if ($retries == 0) return NULL;
-    
-    $response = http_make_request($url, array('Accept' => 'application/xrds+xml'));
-
-    if (isset($response['http-error'])) return NULL;
-    if (($response['content-type'] == 'application/xrds+xml') || ($check == FALSE)) {
-        return $response['data'];
-    } elseif (isset($response['headers']['x-xrds-location'])) {
-        return discovery_xrds_get($response['headers']['x-xrds-location'], false, $retries - 1);
-    } elseif (isset($response['data'])) {
-        $location = _discovery_meta_httpequiv('X-XRDS-Location', $response['data']);
-        if ($location) {
-            return discovery_xrds_get($location, false, $retries - 1);
-        }
-        return NULL;
-    } else {
-        return NULL;
-    }
-}
-
-/**
- * Normalises an identifier for discovery.
- *
- * If the identifier begins with xri://, acct: or mailto:, this is stripped out.  If the identifier
- * does not begin with a valid URI scheme, http:// is assumed and added to the
- * identifier.
- *
- * @param string $identifier the identifier to normalise
- * @return string the normalised identifier
- */
-function discovery_xrds_normalize($identifier) {
-    $normalized = $identifier;
-    
-    if (discovery_is_xri($identifier)) {
-        if (stristr($identifier, 'xri://') !== false) $normalized = substr($identifier, 6);
-    } elseif (discovery_is_email($identifier)) {
-        if (stristr($identifier, 'acct:') !== false) $normalized = substr($identifier, 5);
-        if (stristr($identifier, 'mailto:') !== false) $normalized = substr($identifier, 7);
-    } else {
-        if (stristr($identifier, '://') === false) $normalized = 'http://'. $identifier;
-        if (substr_count($normalized, '/') < 3) $normalized .= '/';
-    }
-    
-    return $normalized;
-}
-
-/**
- * Obtains a URL for an identifier.  If the identifier is a XRI, the XRI resolution
- * service is used to convert the identifier to a URL.
- *
- * @param string $identifier the identifier
- * @return string the URL
- */
-function discovery_xrds_url($identifier) {
-    if (discovery_is_xri($identifier)) {
-        return 'http://xri.net/' . $identifier;
-    } elseif (discovery_is_email($identifier)) {
-        //list($user, $host) = explode('@', $identifier, 2);
-        //$host_meta = 'http://' . $host . '/.well-known/host-meta';
-    } else {
-        return $identifier;
-    }
-
-}
-
-/**
- * Determines whether an identifier is an XRI.
- *
- * XRI identifiers either start with xri:// or with @, =, +, $ or !.
- *
- * @param string $identifier the parameter to test
- * @return bool true if the identifier is an XRI
- */
-function discovery_is_xri($identifier) {
-    $firstchar = substr($identifier, 0, 1);
-    if ($firstchar == "@" || $firstchar == "=" || $firstchar == "+" || $firstchar == "\$" || $firstchar == "!") return true;
-    if (stristr($identifier, 'xri://') !== FALSE) return true;
-    return false;
-}
-
-/**
- * Determines whether an identifier is an e-mail address.
- *
- * An identifier is an e-mail address if it:
- *
- * - has a single @ character
- * - does not have a slash character
- *
- * @param string $identifier the parameter to test
- * @return bool true if the identifier is an e-mail address
- */
-function discovery_is_email($identifier) {
-    // If it begins with acct: or mailto:, strip it out
-    if (stristr($identifier, 'acct:') !== false) $identifier = substr($identifier, 5);
-    if (stristr($identifier, 'mailto:') !== false) $identifier = substr($identifier, 7);
-    
-    // If it contains a slash, it is not an e-mail address
-    if (strpos($identifier, "/") !== false) return false;
-    
-    $at = strpos($identifier, "@");
-    
-    // If it does not contain a @, it is not an e-mail address
-    if ($at === false) return false;
-    
-    // If it contains more than one @, it is not an e-mail
-    if (strrpos($identifier, "@") != $at) return false;
-    
-    return true;
-}
-
-
-/**
- * Callback function to sort service and URI elements based on priorities
- * specified in the XRDS document.
- *
- * The XRDS specification allows multiple instances of certain elements, such
- * as Service and URI.  The specification allows an attribute called priority
- * so that the document creator can specify the order the elements should be used.
- *
- * @param array $a
- * @param array $b
- * @return int
- */
-function discovery_xrds_priority_sort($a, $b) {
-    if (!isset($a['#priority']) && !isset($b['#priority'])) return 0;
-    
-    // if #priority is missing, #priority is assumed to be infinity
-    if (!isset($a['#priority'])) return 1;
-    if (!isset($b['#priority'])) return -1;
-    
-    if ($a['#priority'] == $b['#priority']) return 0;
-    return ($a['#priority'] < $b['#priority']) ? -1 : 1;
-}
-
-/**
- * Parses an XRDS document to return services available.
- *
- * @param string $xrds the XRDS document
- * @return array the parsed structure
- *
- * @see XRDSParser
- */
-function discovery_xrds_parse($xrds) {
-    $parser = new XRDSParser();
-    $parser->parse($xrds);
-    $parser->free();
-    $services = $parser->services();
-    uasort($services, 'discovery_xrds_priority_sort');
-
-    return $services;
-}
-
-/**
- * Obtains the OpenID services for particular identifier by scanning for link
- * elements in the returned document.
- *
- * Note that this function does not use the YADIS protocol to scan for services.
- * To use the YADIS protocol, use {@link discovery_get_services()}.
- *
- * @param string $url the URL
- * @return array an array of discovered services, or an empty array if no services
- * are found
- */
-function discovery_html_get_services($url) {
-    $services = array();
-        
-    $response = http_make_request($url);
-    $html = $response['data'];
-        
-    $uri = _discovery_link_rel('openid2.provider', $html);
-    $delegate = _discovery_link_rel('openid2.local_id', $html);
-    
-    if ($uri) {
-        $service = array(
-            'type' => 'http://specs.openid.net/auth/2.0/signon',
-            'uri' => $uri
-            );
-        if ($delegate) $service['localid'] = $delegate;
-        $services[] = $service;
-    }
-
-    $uri = _discovery_link_rel('openid.server', $html);
-    $delegate = _discovery_link_rel('openid.delegate', $html);
-        
-    if ($uri) {
-        $service = array(
-            'type' => 'http://openid.net/signon/1.0',
-            'uri' => $uri
-            );
-        if ($delegate) $service['localid'] = $delegate;
-        $services[] = $service;
-    }
-    
-    return $services;
-}
-
-/**
- * Searches through an HTML document to obtain the value of a meta
- * element with a specified http-equiv attribute.
- *
- * @param string $equiv the http-equiv attribute for which to search
- * @param string $html the HTML document to search
- * @return mixed the value of the meta element, or FALSE if the element is not
- * found
- */
-function _discovery_meta_httpequiv($equiv, $html) {
-    $html = preg_replace('/<!(?:--(?:[^-]*|-[^-]+)*--\s*)>/', '', $html); // Strip html comments
-    
-    $equiv = preg_quote($equiv);
-    preg_match('|<meta\s+http-equiv=["\']'. $equiv .'["\'](.*)/?>|iUs', $html, $matches);
-    if (isset($matches[1])) {
-        preg_match('|content=["\']([^"]+)["\']|iUs', $matches[1], $content);
-        if (isset($content[1])) {
-            return $content[1];
-        }
-    }
-    return FALSE;
-}
-
-/**
- * Searches through an HTML document to obtain the value of a link
- * element with a specified rel attribute.
- *
- * @param string $rel the rel attribute for which to search
- * @param string $html the HTML document to search
- * @return mixed the href of the link element, or FALSE if the element is not
- * found
- */
-function _discovery_link_rel($rel, $html) {
-    $html = preg_replace('/<!(?:--(?:[^-]*|-[^-]+)*--\s*)>/s', '', $html); // Strip html comments
-    
-    $rel = preg_quote($rel);
-    preg_match('|<link\s+rel=["\'](.*)'. $rel .'(.*)["\'](.*)/?>|iUs', $html, $matches);
-    if (isset($matches[3])) {
-        preg_match('|href=["\']([^"]+)["\']|iU', $matches[3], $href);
-        return trim($href[1]);
-    }
-    return FALSE;
-}
-
-/**
- * A simple XRDS parser.
- *
- * This parser uses the classic expat functions available in PHP to parse the
- * XRDS Simple XML document.
- *
- * The result is an array of discovered services.
- *
- * @link http://xrds-simple.net/
- */
-class XRDSParser {
-    /**
-     * XML parser
-     * @var resource
-     * @access private
-     */
-    var $parser;
-    
-    /**
-     * Discovered services
-     * @var array
-     * @access private
-     */
-    var $services = array();
-    
-    /**
-     * State: are we parsing a service element?
-     * @var bool
-     * @access private
-     */
-    var $in_service = FALSE;
-    
-    /**
-     * CDATA buffer
-     * @var string
-     * @access private
-     */
-    var $_buffer;
-    /**
-     * Attributes buffer
-     * @var array
-     * @access private
-     */
-    var $_attribs = array();
-    
-    /**
-     * priority attribute buffer
-     * @var string
-     * @access private
-     */
-    var $priority = NULL;
-    
-    /**
-     * Currently parsed service buffer
-     * @var array
-     * @access private
-     */
-    var $service = array();
-    
-    /**
-     * Creates an instance of the XRDS parser.
-     *
-     * This constructor also initialises the underlying XML parser.
-     */
-    function __construct() {
-        $this->parser = xml_parser_create_ns();
-        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING,0);
-        xml_set_object($this->parser, $this);
-        xml_set_element_handler($this->parser, 'element_start', 'element_end');
-        xml_set_character_data_handler($this->parser, 'cdata');
-    }
-    
-    /**
-     * Frees memory associated with the underlying XML parser.
-     *
-     * Note that only the memory associated with the underlying XML parser is
-     * freed.  Memory associated with the class itself is not freed.
-     *
-     * @access public
-     */
-    function free() {
-        xml_parser_free($this->parser);
-    }
-    
-    /**
-     * Parses an XRDS document.
-     *
-     * Once the parsing is complete, use {@link XRDSParser::services()} to obtain
-     * the services extracted from the document.
-     *
-     * @param string $xml the XML document to parse
-     * @access public
-     */
-    function parse($xml) {
-        xml_parse($this->parser, $xml);
-    }
-    
-    /**
-     * Gets an array of discovered services.
-     *
-     * @return array an array of discovered services, or an empty array
-     * @access public
-     * @see XRDSParser::parse()
-     */
-    function services() {
-        return $this->services;
-    }
-    
-    /**
-     * XML parser callback
-     *
-     * @access private
-     */
-    function element_start(&$parser, $qualified, $attribs) {
-        list($ns, $name) = $this->parse_namespace($qualified);
-
-        // Strictly speaking, XML namespace URIs are semi-case sensitive
-        // (i.e. the scheme and host are not case sensitive, but other elements
-        // are).  However, the XRDS-Simple specifications defines a
-        // namespace URI for XRD (xri://$XRD*($v*2.0) rather than xri://$xrd*($v*2.0))
-        // with an unusual case.
-        if ((strtolower($ns) == strtolower(XRD2_NS)) && ($name == 'Service')) {
-            $this->in_service = TRUE;
-            $this->service = array();
-            
-            if (in_array('priority', $attribs)) {
-                $this->service['#priority'] = $attribs['priority'];
-            }
-            if (in_array('id', $attribs)) {
-                $this->service['#id'] = $attribs['id'];
-            }
-        }
-        
-        if ((strtolower($ns) == strtolower(XRD2_NS)) && ($this->in_service)) {
-            switch ($name) {
-                case 'Type':
-                case 'LocalID':
-                case 'URI':
-                    if (in_array('priority', $attribs)) {
-                        $this->priority = $attribs['priority'];
-                    } else {
-                        $this->priority = NULL;
-                    }
-            }
-        }
-        
-        $this->_buffer = '';
-        $this->_attribs = $attribs;
-    }
-
-    /**
-     * XML parser callback
-     *
-     * @access private
-     */
-    function element_end(&$parser, $qualified) {
-        list($ns, $name) = $this->parse_namespace($qualified);
-        
-        if ((strtolower($ns) == strtolower(XRD2_NS)) && ($this->in_service)) {
-            switch ($name) {
-                case 'Service':
-                    foreach (array('type', 'localid', 'uri') as $key) {
-                        if (!isset($this->service[$key])) continue;
-                        $this->service[$key] = $this->flatten_uris($this->service[$key]);
-                    }
-                
-                    $this->services[] = $this->service;
-                    $this->in_service = FALSE;
-                    break;
-
-                case 'Type':
-                case 'LocalID':
-                case 'URI':
-                    $key = strtolower($name);
-                    if (!isset($this->service[$key])) {
-                        $this->service[$key] = array();
-                    }
-                    if ($this->priority != NULL) {
-                        $this->service[$key][] = array('#uri' => trim($this->_buffer), '#priority' => $this->priority);
-                    } else {
-                        $this->service[$key][] = array('#uri' => trim($this->_buffer));
-                    }
-                    $this->priority = NULL;
-                    break;
-            }
-        }
-        
-        if ((strtolower($ns) == strtolower(XRD_OPENID_NS)) && ($this->in_service)) {
-            switch ($name) {
-                case 'Delegate':
-                    $this->service['delegate'] = trim($this->_buffer);
-            }
-        }
-
-        $this->_attribs = array();
-    }
-
-    /**
-     * XML parser callback
-     *
-     * @access private
-     */
-    function cdata(&$parser, $data) {
-        $this->_buffer .= $data;
-    }
-    
-    /**
-     * Parses a namespace-qualified element name.
-     *
-     * @param string $qualified the qualified name
-     * @return array an array with two elements - the first element contains
-     * the namespace qualifier (or an empty string), the second element contains
-     * the element name
-     * @access protected
-     */
-    function parse_namespace($qualified) {
-        $pos = strrpos($qualified, ':');
-        if ($pos !== FALSE) return array(substr($qualified, 0, $pos), substr($qualified, $pos + 1, strlen($qualified)));
-        return array('', $qualified);
-    }
-    
-    /**
-     * Flattens the service array.
-     *
-     * In an XRDS document, child elements of the service element often contains
-     * a list of URIs, with the priority specified in the priority attribute.
-     *
-     * When the document is parsed in this class, the URI and the priority are first
-     * extracted into the #uri and the #priority keys respectively.  This function
-     * takes this array, sorts the elements using the #priority keys (if $sort is
-     * true), then collapses the array using the value associated with the #uri key.
-     *
-     * @param array $array the service array, with URIs and priorities
-     * @param bool $sort whether to sort the service array using the #priority
-     * keys
-     * @return array the services array with URIs sorted by priority
-     * @access protected
-     */
-    function flatten_uris($array, $sort = TRUE) {
-        $result = array();
-        
-        if ($sort) uasort($array, 'discovery_xrds_priority_sort');
-        
-        for ($i = 0; $i < count($array); $i++) {
-            $result[] = $array[$i]['#uri'];
-        }
-        
-        return $result;
-    }
-}
-
-if (!function_exists('rfc3986_urlencode')) {
-    /**
-     * Encodes a URL using RFC 3986.
-     *
-     * PHP's rawurlencode function encodes a URL using RFC 1738.  RFC 1738 has been
-     * updated by RFC 3986, which change the list of characters which needs to be
-     * encoded.
-     *
-     * Strictly correct encoding is required for various purposes, such as OAuth
-     * signature base strings.
-     *
-     * @param string $s the URL to encode
-     * @return string the encoded URL
-     */
-    function rfc3986_urlencode($s) {
-        return str_replace('%7E', '~', rawurlencode($s));
-    }
-}
-?>
diff --git a/simpleid/www/extensions/ax/ax.extension.php b/simpleid/www/extensions/ax/ax.extension.php
deleted file mode 100644
index 1286c52..0000000
--- a/simpleid/www/extensions/ax/ax.extension.php
+++ /dev/null
@@ -1,327 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Implements the Attribute Exchange extension.
- * 
- *
- * @package simpleid
- * @subpackage extensions
- * @filesource
- */
-
-/** Namespace for the AX extension */
-define('OPENID_NS_AX', 'http://openid.net/srv/ax/1.0');
-
-/** @ignore */
-global $ax_sreg_map;
-
-/**
- * A mapping between Type URIs defined for Attribute Exchange and the corresponding
- * property for the Simple Registration Extension
- *
- * @link http://www.axschema.org/types/#sreg
- * @global array
- */
-$ax_sreg_map = array(
-    'http://axschema.org/namePerson/friendly' => 'nickname',
-    'http://axschema.org/contact/email' => 'email',
-    'http://axschema.org/namePerson' => 'fullname',
-    'http://axschema.org/birthDate' => 'dob',
-    'http://axschema.org/person/gender' => 'gender',
-    'http://axschema.org/contact/postalCode/home' => 'postcode',
-    'http://axschema.org/contact/country/home' => 'country',
-    'http://axschema.org/pref/language' => 'language',
-    'http://axschema.org/pref/timezone' => 'timezone',
-    'http://openid.net/schema/namePerson/friendly' => 'nickname',
-    'http://openid.net/schema/contact/internet/email' => 'email',
-    'http://openid.net/schema/gender' => 'gender',
-    'http://openid.net/schema/contact/postalCode/home' => 'postcode',
-    'http://openid.net/schema/contact/country/home' => 'country',
-    'http://openid.net/schema/language/pref' => 'language',
-    'http://openid.net/schema/timezone' => 'timezone'
-);
-
-/**
- * Returns the support for AX in SimpleID XRDS document
- *
- * @return array
- * @see hook_xrds_types()
- */
-function ax_xrds_types() {
-    return array(OPENID_NS_AX);
-}
-
-/**
- * @see hook_response()
- */
-function ax_response($assertion, $request) {
-    global $user;
-    global $version;
-    global $ax_sreg_map;
-    
-    // We only deal with positive assertions
-    if (!$assertion) return array();
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_AX, $request)) return array();
-    
-    $request = openid_extension_filter_request(OPENID_NS_AX, $request);
-    if (!isset($request['mode'])) return array();
-    $mode = $request['mode'];
-    
-    $response = array();
-    $alias = openid_extension_alias(OPENID_NS_AX);
-    $response['openid.ns.' . $alias] = OPENID_NS_AX;
-    
-    if ($mode == 'fetch_request') {
-        $response['openid.' . $alias . '.mode'] = 'fetch_response';
-        
-        $required = (isset($request['required'])) ? explode(',', $request['required']) : array();
-        $optional = (isset($request['if_available'])) ? explode(',', $request['if_available']) : array();
-        $fields = array_merge($required, $optional);
-        
-        foreach ($fields as $field) {
-            $type = $request['type.' . $field];
-            $response['openid.' . $alias . '.type.' . $field] = $type;
-            $value = _ax_get_value($type);
-            
-            if ($value == NULL) {
-                $response['openid.' . $alias . '.count.' .  $field] = 0;
-            } elseif (is_array($value)) {
-                $response['openid.' . $alias . '.count.' .  $field] = count($value);
-                for ($i = 0; $i < count($value); $i++) {
-                    $response['openid.' . $alias . '.value.' .  $field . '.' . ($i + 1)] = $value[$i];
-                }
-            } else {
-                $response['openid.' . $alias . '.value.' .  $field] = $value;
-            }
-        }
-    } elseif ($mode == 'store_request') {
-        // Sadly, we don't support storage at this stage
-        $response['openid.' . $alias . '.mode'] = 'store_response_failure';
-        $response['openid.' . $alias . '.error'] = 'OpenID provider does not support storage of attributes';
-    }
-    
-    return $response;
-}
-
-/**
- * Returns an array of fields that need signing.
- *
- * @see hook_signed_fields()
- */
-function ax_signed_fields($response) {
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_AX, $response)) return array();
-    
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_AX, $response));
-    $alias = openid_extension_alias(OPENID_NS_AX);
-    $signed_fields = array();
-
-    if (isset($response['openid.ns.' . $alias])) $signed_fields[] = 'ns.' . $alias;
-    foreach ($fields as $field) {
-        if (isset($response['openid.' . $alias . '.' . $field])) $signed_fields[] = $alias . '.' . $field;
-    }
-    
-    return $signed_fields;
-}
-
-/**
- * @see hook_consent_form()
- */
-function ax_consent_form($request, $response, $rp) {
-    global $user;
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_AX, $request)) return '';
-    
-    $request = openid_extension_filter_request(OPENID_NS_AX, $request);
-    if (!isset($request['mode'])) return '';
-    $mode = $request['mode'];
-    
-    $xtpl2 = new XTemplate('extensions/ax/ax.xtpl');
-    
-    if ($mode == 'fetch_request') {
-        $xtpl2->assign('alias', openid_extension_alias(OPENID_NS_AX));
-        
-        $required = (isset($request['required'])) ? explode(',', $request['required']) : array();
-        $optional = (isset($request['if_available'])) ? explode(',', $request['if_available']) : array();
-        $fields = array_merge($required, $optional);
-        $i = 1;
-        
-        foreach ($fields as $field) {
-            $type = $request['type.' . $field];
-            $value = _ax_get_value($type);
-            
-            $xtpl2->assign('name', htmlspecialchars($type, ENT_QUOTES, 'UTF-8'));
-            $xtpl2->assign('id', $i);
-            
-            if (is_array($value)) {
-                $xtpl2->assign('value', htmlspecialchars(implode(',', $value), ENT_QUOTES, 'UTF-8'));
-            } elseif ($value != NULL) {
-                $xtpl2->assign('value', htmlspecialchars($value, ENT_QUOTES, 'UTF-8'));
-            }
-            
-            $xtpl2->assign('checked', (in_array($field, $required) || !isset($rp['ax_consents']) || in_array($field, $rp['ax_consents'])) ? 'checked="checked"' : '');
-            $xtpl2->assign('disabled', (in_array($field, $required)) ? 'disabled="disabled"' : '');
-            if (in_array($field, $required)) $xtpl2->parse('fetch_request.ax.required');
-            
-            $xtpl2->parse('fetch_request.ax');
-            
-            $i++;
-        }
-
-        $xtpl2->assign('ax_data', t('SimpleID will also be sending the following information to the site.'));
-        $xtpl2->assign('name_label', t('Type URL'));
-        $xtpl2->assign('value_label', t('Value'));
-        
-        $xtpl2->parse('fetch_request');
-        return $xtpl2->text('fetch_request');
-    } elseif ($mode == 'store_request') {
-        // Sadly, we don't support storage at this stage
-        $xtpl2->assign('store_request_message', t('This web site requested to store information about you on SimpleID. Sadly, SimpleID does not support this feature.'));
-        $xtpl2->parse('store_request');
-        return $xtpl2->text('store_request');
-    }
-}
-
-/**
- * @see hook_consent()
- */
-function ax_consent($form_request, &$response, &$rp) {
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_AX, $response)) return array();
-    
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_AX, $response));
-    $alias = openid_extension_alias(OPENID_NS_AX);
-    
-    foreach ($fields as $field) {
-        if ((strpos($field, 'value.') !== 0) && (strpos($field, 'count.') !== 0)) continue;
-        
-        $type_alias = (strpos($field, '.', 6) === FALSE) ? substr($field, 6) : substr($field, strpos($field, '.', 6) - 6);
-        $type = $response['openid.' . $alias . '.type.' . $type_alias];
-        
-        if (isset($response['openid.' . $alias . '.' . $field])) {
-            if (!in_array($type, $form_request['ax_consents'])) {
-                unset($response['openid.' . $alias . '.' . $field]);
-            }
-        }
-    }
-    foreach ($fields as $field) {
-        if (strpos($field, 'type.') !== 0) continue;
-        $type = $response['openid.' . $alias . '.' . $field];
-        
-        if (isset($response['openid.' . $alias . '.' . $field])) {
-            if (!in_array($type, $form_request['ax_consents'])) {
-                unset($response['openid.' . $alias . '.' . $field]);
-            }
-        }
-    }
-    
-    if (count(array_keys(openid_extension_filter_request(OPENID_NS_AX, $response))) == 0) {
-        // We have removed all the responses, so we remove the namespace as well
-        unset($response['openid.ns.' . $alias]);
-    }
-    
-    $rp['ax_consents'] = $form_request['ax_consents'];
-}
-
-/**
- * @see hook_page_profile()
- */
-function ax_page_profile() {
-    global $user;
-    $xtpl2 = new XTemplate('extensions/ax/ax.xtpl');
-    
-    if (isset($user['ax'])) {
-        foreach ($user['ax'] as $name => $value) {
-            $xtpl2->assign('name', htmlspecialchars($name, ENT_QUOTES, 'UTF-8'));
-            $xtpl2->assign('value', htmlspecialchars($value, ENT_QUOTES, 'UTF-8'));
-            $xtpl2->parse('user_page.ax');
-        }
-    }
-    
-    $xtpl2->assign('ax_data', t('SimpleID will send the following information to sites which supports the Attribute Exchange Extension.  If you have also supplied OpenID Connect user information in your identity, or have the Simple Registration Extension installed, these may also be sent as part of this Extension.'));
-    $xtpl2->assign('edit_identity_file', t('To change these, <a href="!url">edit your identity file</a>.', array('!url' => 'http://simpleid.org/docs/1/identity-files/')));
-    $xtpl2->assign('name_label', t('Type URL'));
-    $xtpl2->assign('value_label', t('Value'));
-    
-    $xtpl2->parse('user_page');
-    
-    return array(array(
-        'id' => 'ax',
-        'title' => t('Attribute Exchange Extension'),
-        'content' => $xtpl2->text('user_page')
-    ));
-}
-
-/**
- * Looks up the value of a specified Attribute Exchange Extension type URI.
- *
- * This function looks up the ax section of the user's identity file.  If the
- * specified type cannot be found, it looks up the corresponding field in the
- * OpenID Connect user information (user_info section) and the Simple Registration
- * Extension (sreg section).
- *
- * @param string $type the type URI to look up
- * @return string the value or NULL if not found
- */
-function _ax_get_value($type) {
-    global $user;
-    global $ax_sreg_map;
-    
-    if (isset($user['ax'][$type])) {
-        return $user['ax'][$type];
-    } else {
-        // Look up OpenID Connect
-        switch ($type) {
-            case 'http://axschema.org/namePerson/friendly':
-                if (isset($user['user_info']['nickname'])) return $user['user_info']['nickname'];
-                break;
-            case 'http://axschema.org/contact/email':
-                if (isset($user['user_info']['email'])) return $user['user_info']['email'];
-                break;
-            case 'http://axschema.org/namePerson':
-                if (isset($user['user_info']['name'])) return $user['user_info']['name'];
-                break;
-            case 'http://axschema.org/pref/timezone':
-                if (isset($user['user_info']['zoneinfo'])) return $user['user_info']['zoneinfo'];
-                break;
-            case 'http://axschema.org/person/gender':
-                if (isset($user['user_info']['gender'])) return strtoupper(substr($user['user_info']['gender'], 0, 1));
-                break;
-            case 'http://axschema.org/contact/postalCode/home':
-                if (isset($user['user_info']['address']['postal_code'])) return $user['user_info']['address']['postcal_code'];
-                break;
-        } 
-        
-        // Look up sreg
-        if (isset($ax_sreg_map[$type]) && isset($user['sreg'][$ax_sreg_map[$type]])) {
-            return $user['sreg'][$ax_sreg_map[$type]];
-        } else {
-            return NULL;
-        }
-    }
-}
-?>
diff --git a/simpleid/www/extensions/ax/ax.xtpl b/simpleid/www/extensions/ax/ax.xtpl
deleted file mode 100644
index bf9edbe..0000000
--- a/simpleid/www/extensions/ax/ax.xtpl
+++ /dev/null
@@ -1,44 +0,0 @@
-<!-- BEGIN: user_page -->
-<!-- :mode=html: $Id$ -->
-    <p>{ax_data}</p>
-    
-    <p>{edit_identity_file}</p>
-    
-    <table>
-        <tr>
-            <th>{name_label}</th>
-            <th>{value_label}</th>
-        </tr>
-        <!-- BEGIN: ax -->
-        <tr>
-            <td>{name}</td>
-            <td>{value}</td>
-        </tr>
-        <!-- END: ax -->
-    </table>
-<!-- END: user_page -->
-            
-<!-- BEGIN: fetch_request -->
-    <p>{ax_data}</p>
-    
-    <table>
-        <tr>
-            <th></th>
-            <th>{name_label}</th>
-            <th>{value_label}</th>
-        </tr>
-        <!-- BEGIN: ax -->
-        <tr>
-            <td><input name="ax_consents[]" type="checkbox" value="{name}" id="ax-consents-{id}" {checked} {disabled} /><!-- BEGIN: required --><input name="ax_consents[]" type="hidden" value="{name}" /><!-- END: required --></td>
-            <td><label for="ax-consents-{id}">{name}</label></td>
-            <td>{value}</td>
-        </tr>
-        <!-- END: ax -->
-    </table>
-<!-- END: fetch_request -->
-
-<!-- BEGIN: store_request -->
-<div class="message">
-    <p>{store_request_message}</p>
-</div>
-<!-- END: store_request -->
diff --git a/simpleid/www/extensions/certauth/certauth.extension.php b/simpleid/www/extensions/certauth/certauth.extension.php
deleted file mode 100644
index b442d93..0000000
--- a/simpleid/www/extensions/certauth/certauth.extension.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2012
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Authentication using a SSL client certificate.
- *
- * @package simpleid
- * @subpackage extensions
- * @filesource
- */
- 
-
-/**
- * Attempt to login using a SSL client certificate.
- *
- * Note that the web server must be set up to request a SSL client certificate
- * and pass the certificate's details to PHP.
- */
-function certauth_user_auto_login() {
-    if (!_certauth_has_client_cert()) return NULL;
-    
-    $cert = trim($_SERVER['SSL_CLIENT_M_SERIAL']) . ';' . trim($_SERVER['SSL_CLIENT_I_DN']);
-    log_debug('Client SSL certificate: ' . $cert);
-
-    $uid = store_get_uid_from_cert($cert);
-    if ($uid != NULL) {
-        log_debug('Client SSL certificate accepted for ' . $uid);
-        return user_load($uid);
-    } else {
-        log_warn('Client SSL certificate presented, but no user with that certificate exists.');
-        return NULL;
-    }
-}
-
-/**
- * Determines whether the user agent supplied valid a certificate identifying the
- * user.
- *
- * A valid certificate is supplied if all of the following occurs:
- *
- * - the connection is done using HTTPS (i.e. {@link is_https()} is true)
- * - the web server has been set up to request a certificate from the user agent
- * - the web server has been set up to pass the certificate details to PHP
- * - the certificate has not been revoked
- * - the certificate contains a serial number and a valid issuer
- *
- * @return true if the user agent has supplied a valid SSL certificate
- */
-function _certauth_has_client_cert() {
-    // False if we are not in HTTP
-    if (!is_https()) return false;
-    
-    // False if certificate is not valid
-    if (!isset($_SERVER['SSL_CLIENT_VERIFY']) || ($_SERVER['SSL_CLIENT_VERIFY'] !== 'SUCCESS')) return false;
-    
-    // False if certificate is expired or has no expiry date
-    if (!isset($_SERVER['SSL_CLIENT_V_REMAIN']) || ($_SERVER['SSL_CLIENT_V_REMAIN'] < 0)) return false;
-    if (!isset($_SERVER['SSL_CLIENT_V_END'])) return false;
-    
-    // False if no serial number
-    if (!isset($_SERVER['SSL_CLIENT_M_SERIAL'])) return false;
-    
-    // False if no issuer
-    if (!isset($_SERVER['SSL_CLIENT_I_DN'])) return false;
-    
-    return true;
-}
-?>
diff --git a/simpleid/www/extensions/pape/pape.extension.php b/simpleid/www/extensions/pape/pape.extension.php
deleted file mode 100644
index e189f2e..0000000
--- a/simpleid/www/extensions/pape/pape.extension.php
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Implements the Provider Authentication Policy Extension extension.
- * 
- *
- * @package simpleid
- * @subpackage extensions
- * @filesource
- */
-
-/** Namespace for the PAPE extension */
-define('OPENID_NS_PAPE', 'http://specs.openid.net/extensions/pape/1.0');
-
-/** Namespaces for PAPE policies */
-define('PAPE_POLICY_NONE', 'http://schemas.openid.net/pape/policies/2007/06/none');
-define('PAPE_POLICY_PPID', 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier');
-
-/** Namespaces for PAPE levels */
-define('PAPE_LEVEL_NIST800_63', 'http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf');
-
-/**
- * Returns the support for PAPE in SimpleID XRDS document
- *
- * @return array
- * @see hook_xrds_types()
- */
-function pape_xrds_types() {
-    return array(
-        OPENID_NS_PAPE,
-        PAPE_POLICY_PPID,
-        PAPE_LEVEL_NIST800_63
-    );
-}
-
-/**
- * @see hook_checkid_identity()
- */
-function pape_checkid_identity($request, $identity, $immediate) {
-    global $user;
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_PAPE, $request)) return null;
-    
-    // See if we are choosing an identity and save for later
-    // This may be used by pape_response() to produce a private identifier
-    if ($request['openid.identity'] == OPENID_IDENTIFIER_SELECT) _pape_identifier_select(true);
-    
-    $pape_request = openid_extension_filter_request(OPENID_NS_PAPE, $request);
-    
-    // If the relying party provides a max_auth_age
-    if (isset($pape_request['max_auth_age'])) {
-        // If we are not logged in then we don't need to do anything
-        if ($user == NULL) return NULL;
-        
-        // If the last time we logged on actively (i.e. using a password) is greater than
-        // max_auth_age, we then require the user to log in again
-        if ((!isset($user['auth_active']) || !$user['auth_active']) 
-            && ((time() - $user['auth_time']) > $pape_request['max_auth_age'])) {
-            set_message(t('This web site\'s policy requires you to log in again to confirm your identity.'));
-            
-            _user_logout();
-            return CHECKID_LOGIN_REQUIRED;
-        }
-    }
-}
-
-/**
- * @see hook_response()
- */
-function pape_response($assertion, $request) {
-    global $user, $version;
-    
-    // We only deal with positive assertions
-    if (!$assertion) return array();
-    
-    // We only respond if we are using OpenID 2 or later
-    if ($version < OPENID_VERSION_2) return array();
-    
-    // Get what is requested
-    $pape_request = openid_extension_filter_request(OPENID_NS_PAPE, $request);
-        
-    // If the extension is requested, we use the same alias, otherwise, we
-    // make one up
-    $alias = openid_extension_alias(OPENID_NS_PAPE, 'pape');
-    $response = array();
-    
-    // The PAPE specification recommends us to respond even when the extension
-    // is not present in the request.
-    $response['openid.ns.' . $alias] = OPENID_NS_PAPE;
-    
-    // We return the last time the user logged in using the login form
-    $response['openid.' . $alias . '.auth_time'] = gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user['auth_time']);
-    
-    // We don't comply with NIST_SP800-63
-    $response['openid.' . $alias . '.auth_level.ns.nist'] = PAPE_LEVEL_NIST800_63;
-    $response['openid.' . $alias . '.auth_level.nist'] = 0;
-    
-    // The default is that we don't apply any authentication policies. This can be changed later in the
-    // function
-    $response['openid.' . $alias . '.auth_policies'] = PAPE_POLICY_NONE;
-
-    // Now we go through the authentication policies
-    if (isset($pape_request['preferred_auth_policies'])) {
-        $policies = preg_split('/\s+/', $pape_request['preferred_auth_policies']);
-        
-        if (in_array(PAPE_POLICY_PPID, $policies)) {
-            // We want a ppid.  Check that the authentication request is correct
-            if (_pape_identifier_select()) {
-                $realm = openid_get_realm($request, $version);
-                $identity = $request['openid.identity'];
-                
-                $ppid = _pape_ppid($identity, $realm);                
-                $response['openid.claimed_id'] = $ppid;
-                $response['openid.identity'] = $ppid;
-            }
-        }
-    }
-    
-    return $response;
-}
-
-/**
- * Returns an array of fields that need signing.
- *
- * @see hook_signed_fields()
- */
-function pape_signed_fields($response) {
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_PAPE, $response));
-    $alias = openid_extension_alias(OPENID_NS_PAPE);
-    $signed_fields = array();
-
-    if (isset($response['openid.ns.' . $alias])) $signed_fields[] = 'ns.' . $alias;
-    foreach ($fields as $field) {
-        if (isset($response['openid.' . $alias . '.' . $field])) $signed_fields[] = $alias . '.' . $field;
-    }
-    
-    return $signed_fields;
-}
-
-/**
- * Sets and returns whether the current OpenID request is requesting an identity.
- *
- * @param bool $identifier_select
- * @return bool whether the current OpenID request is requesting an identity
- */
-function _pape_identifier_select($identifier_select = NULL) {
-    static $static_identifier_select = false;
-    
-    if (!is_null($identifier_select)) $static_identifier_select = $identifier_select;
-    
-    return $static_identifier_select;
-}
-
-/**
- * Generates a private personal identifier (PPID).  The PPID is an opaque identifier
- * for a particular user-RP pair
- *
- * @param string $identity the identity of the user
- * @param string $realm the URL of the relying party
- * @return string the PPID
- */
-function _pape_ppid($identity, $realm) {
-    // We are reusing the site-token from get_form_token() in common.inc
-    if (store_get('site-token') == NULL) {
-        $site_token = mt_rand();
-        store_set('site-token', $site_token);
-    } else {
-        $site_token = store_get('site-token');
-    }
-    
-    $parts = parse_url($realm);
-    $host = $parts['host'];
-    if (strstr($host, 'www.') === 0) $host = substr($host, 4);
-    
-    return simpleid_url('ppid/' . md5($site_token . $identity . $host));
-}
-
-?>
diff --git a/simpleid/www/extensions/sreg/sreg.extension.php b/simpleid/www/extensions/sreg/sreg.extension.php
deleted file mode 100644
index 955d6f6..0000000
--- a/simpleid/www/extensions/sreg/sreg.extension.php
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Implements the Simple Registration extension.
- * 
- *
- * @package simpleid
- * @subpackage extensions
- * @filesource
- */
- 
-/** Namespace for the Simple Registration extension */
-define('OPENID_NS_SREG', 'http://openid.net/extensions/sreg/1.1');
-
-/**
- * @see hook_response()
- */
-function sreg_response($assertion, $request) {
-    global $user;
-    global $version;
-    
-    // We only deal with positive assertions
-    if (!$assertion) return array();
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_SREG, $request)) return array();
-    
-    $request = openid_extension_filter_request(OPENID_NS_SREG, $request);
-    $required = (isset($request['required'])) ? explode(',', $request['required']) : array();
-    $optional = (isset($request['optional'])) ? explode(',', $request['optional']) : array();
-    $fields = array_merge($required, $optional);
-    $alias = openid_extension_alias(OPENID_NS_SREG);
-    $response = array();
-    
-    if ($version == OPENID_VERSION_2) $response['openid.ns.' . $alias] = OPENID_NS_SREG;
-    
-    foreach ($fields as $field) {
-        $value = _sreg_get_value($field);
-        
-        if ($value != NULL) $response['openid.' . $alias . '.' .  $field] = $value;
-    }
-    
-    return $response;
-}
-
-/**
- * Returns an array of fields that need signing.
- *
- * @see hook_signed_fields()
- */
-function sreg_signed_fields($response) {
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_SREG, $response)) return array();
-    
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_SREG, $response));
-    $alias = openid_extension_alias(OPENID_NS_SREG);
-    $signed_fields = array();
-
-    if (isset($response['openid.ns.' . $alias])) $signed_fields[] = 'ns.' . $alias;
-    foreach ($fields as $field) {
-        if (isset($response['openid.' . $alias . '.' . $field])) $signed_fields[] = $alias . '.' . $field;
-    }
-    
-    return $signed_fields;
-}
-
-/**
- * @see hook_consent_form()
- */
-function sreg_consent_form($request, $response, $rp) {
-    global $user;
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_SREG, $request)) return '';
-    
-    $request = openid_extension_filter_request(OPENID_NS_SREG, $request);
-    $required = (isset($request['required'])) ? explode(',', $request['required']) : array();
-    $optional = (isset($request['optional'])) ? explode(',', $request['optional']) : array();
-    $fields = array_merge($required, $optional);
-    
-    if ((count($request)) && isset($user['sreg'])) {
-        $xtpl2 = new XTemplate('extensions/sreg/sreg.xtpl');
-        
-        $xtpl2->assign('alias', openid_extension_alias(OPENID_NS_SREG));
-        
-        if (isset($request['policy_url'])) {            
-            $xtpl2->assign('policy', t('You can view the site\'s policy in relation to the use of this information at this URL: <a href="@url">@url</a>.', array('@url' => $request['policy_url'])));            
-        }
-        
-        foreach ($fields as $field) {
-            $value = _sreg_get_value($field);
-        
-            if ($value != NULL) {
-                $xtpl2->assign('name', htmlspecialchars($field, ENT_QUOTES, 'UTF-8'));
-                $xtpl2->assign('value', htmlspecialchars($value, ENT_QUOTES, 'UTF-8'));
-                
-                $xtpl2->assign('checked', (in_array($field, $required) || !isset($rp['sreg_consents']) || in_array($field, $rp['sreg_consents'])) ? 'checked="checked"' : '');
-                $xtpl2->assign('disabled', (in_array($field, $required)) ? 'disabled="disabled"' : '');
-                if (in_array($field, $required)) $xtpl2->parse('form.sreg.required');
-                
-                $xtpl2->parse('form.sreg');
-            }
-        }
-        
-        $xtpl2->assign('sreg_data', t('SimpleID will also be sending the following registration information to the site.'));
-        $xtpl2->assign('name_label', t('Name'));
-        $xtpl2->assign('value_label', t('Value'));
-        
-        $xtpl2->parse('form');
-        return $xtpl2->text('form');
-    }
-}
-
-/**
- * @see hook_consent()
- */
-function sreg_consent($form_request, &$response, &$rp) {
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_SREG, $response)) return;
-    
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_SREG, $response));
-    $alias = openid_extension_alias(OPENID_NS_SREG);
-    
-    foreach ($fields as $field) {
-        if (isset($response['openid.' . $alias . '.' . $field])) {
-            if (!in_array($field, $form_request['sreg_consents'])) {
-                unset($response['openid.' . $alias . '.' . $field]);
-            }
-        }
-    }
-    
-    if (count(array_keys(openid_extension_filter_request(OPENID_NS_SREG, $response))) == 0) {
-        // We have removed all the responses, so we remove the namespace as well
-        unset($response['openid.ns.' . $alias]);
-    }
-    
-    $rp['sreg_consents'] = $form_request['sreg_consents'];
-}
-
-/**
- * @see hook_page_profile()
- */
-function sreg_page_profile() {
-    global $user;
-    $xtpl2 = new XTemplate('extensions/sreg/sreg.xtpl');
-    
-    if (isset($user['sreg'])) {
-        foreach ($user['sreg'] as $name => $value) {
-            $xtpl2->assign('name', htmlspecialchars($name, ENT_QUOTES, 'UTF-8'));
-            $xtpl2->assign('value', htmlspecialchars($value, ENT_QUOTES, 'UTF-8'));
-            $xtpl2->parse('user_page.sreg');
-        }
-    }
-    
-    $xtpl2->assign('sreg_data', t('SimpleID will send the following information to sites which supports the Simple Registration Extension.'));
-    $xtpl2->assign('connect_data', t('If you have also supplied OpenID Connect user information in your identity file, these may also be sent as part of this Extension.'));
-    $xtpl2->assign('edit_identity_file', t('To change these, <a href="!url">edit your identity file</a>.', array('!url' => 'http://simpleid.org/docs/1/identity-files/')));
-    $xtpl2->assign('name_label', t('Name'));
-    $xtpl2->assign('value_label', t('Value'));
-    
-    $xtpl2->parse('user_page');
-    
-    return array(array(
-        'id' => 'sreg',
-        'title' => t('Simple Registration Extension'),
-        'content' => $xtpl2->text('user_page')
-    ));
-}
-
-
-/**
- * Looks up the value of a specified Simple Registration Extension field.
- *
- * This function looks up the sreg section of the user's identity file.  If the
- * specified field cannot be found, it looks up the corresponding field in the
- * OpenID Connect user information (user_info section).
- *
- * @param string $field the field to look up
- * @return string the value or NULL if not found
- */
-function _sreg_get_value($field) {
-    global $user;
-    
-    if (isset($user['sreg'][$field])) {
-        return $user['sreg'][$field];
-    } else {
-        switch ($field) {
-            case 'nickname':
-            case 'email':
-                if (isset($user['user_info'][$field])) return $user['user_info'][$field];
-                break;
-            case 'fullname':
-                if (isset($user['user_info']['name'])) return $user['user_info']['name'];
-                break;
-            case 'timezone':
-                if (isset($user['user_info']['zoneinfo'])) return $user['user_info']['zoneinfo'];
-                break;
-            case 'gender':
-                if (isset($user['user_info']['gender'])) return strtoupper(substr($user['user_info']['gender'], 0, 1));
-                break;
-            case 'postcode':
-                if (isset($user['user_info']['address']['postal_code'])) return $user['user_info']['address']['postcal_code'];
-                break;
-            default:
-                return NULL;
-        } 
-        return NULL;
-    }
-}
-
-
-
-?>
diff --git a/simpleid/www/extensions/sreg/sreg.xtpl b/simpleid/www/extensions/sreg/sreg.xtpl
deleted file mode 100644
index 07550bb..0000000
--- a/simpleid/www/extensions/sreg/sreg.xtpl
+++ /dev/null
@@ -1,40 +0,0 @@
-<!-- BEGIN: user_page -->
-<!-- :mode=html: $Id$ -->
-    <p>{sreg_data}</p>
-    
-    <p>{connect_data}</p>
-    
-    <p>{edit_identity_file}</p>
-    
-    <table>
-        <tr>
-            <th>{name_label}</th>
-            <th>{value_label}</th>
-        </tr>
-        <!-- BEGIN: sreg -->
-        <tr>
-            <td>{name}</td>
-            <td>{value}</td>
-        </tr>
-        <!-- END: sreg -->
-    </table>
-<!-- END: user_page -->
-            
-<!-- BEGIN: form -->
-    <p>{sreg_data} {policy}</p>
-    
-    <table>
-        <tr>
-            <th></th>
-            <th>{name_label}</th>
-            <th>{value_label}</th>
-        </tr>
-        <!-- BEGIN: sreg -->
-        <tr>
-            <td><input name="sreg_consents[]" type="checkbox" value="{name}" id="sreg-consents-{name}" {checked} {disabled} /><!-- BEGIN: required --><input name="sreg_consents[]" type="hidden" value="{name}" /><!-- END: required --></td>
-            <td><input type="hidden" name="openid.{alias}.{name}" value="{value}" /><label for="sreg-consents-{name}">{name}</label></td>
-            <td>{value}</td>
-        </tr>
-        <!-- END: sreg -->
-    </table>
-<!-- END: form -->
diff --git a/simpleid/www/extensions/ui/ui.css b/simpleid/www/extensions/ui/ui.css
deleted file mode 100644
index a6b9cfd..0000000
--- a/simpleid/www/extensions/ui/ui.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-.dialog-page {
-    background: #FFFFFF;
-}
-
-.dialog-page #content {
-    margin: 10px auto;
-    padding: 0;
-    border: 0;
-}
diff --git a/simpleid/www/extensions/ui/ui.extension.php b/simpleid/www/extensions/ui/ui.extension.php
deleted file mode 100644
index 3982be0..0000000
--- a/simpleid/www/extensions/ui/ui.extension.php
+++ /dev/null
@@ -1,260 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Implements the popup and icon modes from the User Interface extension
- *
- * @package simpleid
- * @subpackage extensions
- * @filesource
- */
-
-/** Namespace for the User Interface extension */
-define('OPENID_NS_UI', 'http://specs.openid.net/extensions/ui/1.0');
-
-/**
- * Returns the popup mode in SimpleID XRDS document
- *
- * @return array
- * @see hook_xrds_types()
- */
-function ui_xrds_types() {
-    return array(
-        'http://specs.openid.net/extensions/ui/1.0/mode/popup',
-        'http://specs.openid.net/extensions/ui/1.0/icon'
-    );
-}
-
-/**
- * Detects the openid.ui.x-has-session parameter and processes it accordingly.
- *
- * @return array
- * @see hook_response()
- */
-function ui_response($assertion, $request) {
-    global $user;
-    global $version;
-    
-    // We only deal with negative assertions
-    if ($assertion) return array();
-    
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_UI, $request)) return array();
-    
-    // We only deal with openid.ui.x-has-session requests
-    $filtered_request = openid_extension_filter_request(OPENID_NS_UI, $request);
-    if (!isset($filtered_request['mode']) || ($filtered_request['mode'] != 'x-has-session')) return array();
-    
-    // If user is null, there is no active session
-    if ($user == NULL) return array();
-    
-    // There is an active session
-    $alias = openid_extension_alias(OPENID_NS_UI);
-    $response = array();
-    
-    $response['openid.ns.' . $alias] = OPENID_NS_UI;
-    $response['openid.' . $alias . '.mode'] = 'x-has-session';
-    
-    return $response;
-}
-
-/**
- * Returns an array of fields that need signing.
- *
- * @see hook_signed_fields()
- */
-function ui_signed_fields($response) {
-    // We only respond if the extension is requested
-    if (!openid_extension_requested(OPENID_NS_UI, $response)) return array();
-    
-    $fields = array_keys(openid_extension_filter_request(OPENID_NS_UI, $response));
-    $alias = openid_extension_alias(OPENID_NS_UI);
-    $signed_fields = array();
-
-    if (isset($response['openid.ns.' . $alias])) $signed_fields[] = 'ns.' . $alias;
-    foreach ($fields as $field) {
-        if (isset($response['openid.' . $alias . '.' . $field])) $signed_fields[] = $alias . '.' . $field;
-    }
-    
-    return $signed_fields;
-}
-
-/**
- * Detects the presence of the UI extension and modifies the login form
- * accordingly.
- *
- * @param string $destination
- * @param string $state
- * @see hook_user_login_form()
- */
-function ui_user_login_form($destination, $state) {
-    if (($destination != 'continue') || (!$state)) return;
-    
-    $request = unpickle($state);
-    openid_parse_request($request);
-    
-    // Skip if popup does not exist
-    if (!openid_extension_requested(OPENID_NS_UI, $request)) return;
-    
-    $filtered_request = openid_extension_filter_request(OPENID_NS_UI, $request);
-    
-    if (isset($filtered_request['mode']) && ($filtered_request['mode'] == 'popup')) _ui_insert_css_js();
-    
-    return;
-}
-
-/**
- * Detects the presence of the UI extension and modifies the relying party
- * verification form accordingly.
- *
- * @param array $request
- * @param array $response
- * @param array $rp
- * @return string
- * @see hook_consent_form()
- */
-function ui_consent_form($request, $response, $rp) {
-    // Skip if popup does not exist
-    if (!openid_extension_requested(OPENID_NS_UI, $request)) return '';
-    
-    $filtered_request = openid_extension_filter_request(OPENID_NS_UI, $request);
-    
-    if (isset($filtered_request['mode']) && ($filtered_request['mode'] == 'popup')) _ui_insert_css_js();
-    
-    if (isset($filtered_request['icon']) && ($filtered_request['icon'] == 'true')) {
-        global $xtpl;
-        
-        $realm = $request['openid.realm'];
-        $icon_url = simpleid_url('ui/icon', 'realm=' . rawurlencode($realm) . '&tk=' . _ui_icon_token($realm));
-        
-        $xtpl->assign('icon_url', htmlspecialchars($icon_url, ENT_QUOTES, 'UTF-8'));
-        $xtpl->parse('main.openid_consent.icon');
-    }
-    
-    return '';
-}
-
-/**
- * Specifies that the OpenID response should be sent via the fragment
- *
- */
-function ui_indirect_response($url, $response) {
-    global $openid_ns_to_alias;
-    if (!array_key_exists(OPENID_NS_UI, $openid_ns_to_alias)) return NULL;
-    
-    // Cheat - if we run this, then the redirect page will also be themed!
-    _ui_insert_css_js();
-    
-    if (strstr($url, '#')) {
-        return OPENID_RESPONSE_FRAGMENT;
-    } else {
-        return NULL;
-    }
-}
-
-/**
- * Adds an extra route to the SimpleWeb framework.
- */
-function ui_routes() {
-    return array('ui/icon' => 'ui_icon');
-}
-
-/**
- * Returns an icon.
- */
-function ui_icon() {
-    if (!isset($_GET['realm']) || !isset($_GET['tk']) || ($_GET['tk'] != _ui_icon_token($_GET['realm']))) {
-        header_response_code('404 Not Found');
-        indirect_fatal_error(t('Invalid UI icon parameters.'));
-    }
-    
-    $realm = $_GET['realm'];
-    $icon_res = _ui_get_icon($realm);
-    
-    if ($icon_res === NULL) {
-        header_response_code('404 Not Found');
-        indirect_fatal_error(t('Unable to get icon.'));
-    }
-    
-    header('Via: ' . $icon_res['protocol'] . ' simpleid-ui-icon-' . md5($realm));
-    header('Cache-Control: max-age=86400');
-    header('Content-Type: ' . $icon_res['headers']['content-type']);
-    if (isset($icon_res['headers']['content-encoding'])) header('Content-Encoding: ' . $icon_res['headers']['content-encoding']);
-    print $icon_res['data'];
-}
-
-/**
- * Inserts the necessary CSS and JavaScript code to implement the popup mode
- * from the User Interface extension.
- */
-function _ui_insert_css_js() {
-    global $xtpl;
-    
-    $css = (isset($xtpl->vars['css'])) ? $xtpl->vars['css'] : '';
-    $js = (isset($xtpl->vars['javascript'])) ? $xtpl->vars['javascript'] : '';
-    
-    $xtpl->assign('css', $css . '@import url(' . get_base_path() . 'extensions/ui/ui.css);');
-    $xtpl->assign('javascript', $js . '<script src="' . get_base_path() . 'extensions/ui/ui.js" type="text/javascript"></script>');
-}
-
-/**
- * Attempts to obtain an icon from a RP
- *
- * @param string $realm the openid.realm parameter
- * @return array the response from {@link http_make_request()} with the discovered URL of the
- * RP's icon
- */
-function _ui_get_icon($realm) {
-    $rp_info = simpleid_get_rp_info($realm);
-    
-    if (isset($rp_info['ui_icon'])) return $rp_info['ui_icon'];
-    
-    $services = discovery_xrds_services_by_type($rp_info['services'], 'http://specs.openid.net/extensions/ui/icon');
-        
-    if ($services) {
-        $icon_url = $services[0]['uri'];
-        
-        $icon_res = http_make_request($icon_url);
-        if (isset($icon_res['http-error'])) {
-            return NULL;
-        }
-        
-        $rp_info['ui_icon'] = $icon_res;
-        simpleid_set_rp_info($realm, $rp_info);
-    } else {
-        return NULL;
-    }
-}
-
-/**
- * Returns a token to be used when requesting the icon.
- *
- * The token is used to prevent flooding SimpleID with external requests.
- *
- * @param string $realm the openid.realm parameter
- * @return string the token
- */
-function _ui_icon_token($realm) {
-    return get_form_token('q=ui/icon&realm=' . rawurlencode($realm));
-}
-?>
diff --git a/simpleid/www/extensions/ui/ui.js b/simpleid/www/extensions/ui/ui.js
deleted file mode 100644
index 1711d13..0000000
--- a/simpleid/www/extensions/ui/ui.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * This program is licensed under the GPL.
- * 
- * $Id$
- */
-
-$(document).ready(function() {
-    $('input#edit-cancel').click(function() {
-        window.close();
-        return false;
-    });
-    $(document).keydown(function(e) {
-        if (e.which == 27) { // Close the window if user presses Esc
-            window.close();
-            return false;
-        }
-    });
-});
diff --git a/simpleid/www/filesystem.store.php b/simpleid/www/filesystem.store.php
deleted file mode 100644
index 7d99a8d..0000000
--- a/simpleid/www/filesystem.store.php
+++ /dev/null
@@ -1,334 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Functions for persistent storage via the file system.
- *
- * In general, there are three different sets of data which SimpleID needs
- * to store:
- *
- * - transient data (e.g. OpenID associations, sessions, auto-login)
- * - application data (e.g. salt for form tokens)
- * - user data (e.g. user names, passwords and settings)
- *
- * Prior to version 0.7, both transient data and application data are stored
- * using {@link cache.inc}.  From version 0.7, application data are now
- * stored separately from the cache.
- *
- * Prior to version 0.7, user data is only stored in the identity file, to which
- * SimpleID cannot write.  This means that if the user wishes to change a setting,
- * he or she will need to edit the identity file manually.  Other user settings
- * (e.g. RP preferences) are stored using {@link cache.inc}
- *
- * From version 0.7, user data is stored in two files, one is the identity
- * file, the other is the user store file, which SimpleID can write.
- *
- * @package simpleid
- * @filesource
- */
-
-/**
- * This variable is a cache of SimpleID's application settings.  It is populated
- * progressively as {@link store_get()} is called.
- *
- * @global array $simpleid_settings
- */
-$simpleid_settings = array();
-
-/**
- * Returns whether the user name exists in the user store.
- *
- * @param string $uid the name of the user to check
- * @return bool whether the user name exists
- */
-function store_user_exists($uid) {
-    if (_store_is_valid_name($uid)) {
-        $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
-        return (file_exists($identity_file));
-    } else {
-        return false;
-    }
-}
-
-/**
- * Loads user data for a specified user name.
- *
- * The user name must exist.  You should check whether the user name exists with
- * the {@link store_user_exists()} function
- *
- * @param string $uid the name of the user to load
- * @return mixed data for the specified user
- */
-function store_user_load($uid) {
-    if (!_store_is_valid_name($uid)) return array();
-    $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
-    
-    if (file_exists($store_file)) {
-        $data = unserialize(file_get_contents($store_file));
-    } else {
-        $data = array();
-    }
-    
-    $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
-    $data = array_merge($data, parse_ini_file($identity_file, TRUE));
-    
-    return $data;
-}
-
-/**
- * Returns the time which a user's data has been updated.
- *
- * The user name must exist.  You should check whether the user name exists with
- * the {@link store_user_exists()} function.
- *
- * The time returned can be based on the identity file,
- * the user store file, or the latter of the two.
- *
- * @param string $uid the name of the user to obtain the update time
- * @param string $type one of: 'identity' (identity file), 'usrstore' (user store
- * file) or NULL (latter of the two)
- * @return int the updated time
- */ 
-function store_user_updated_time($uid, $type = NULL) {
-    if (!_store_is_valid_name($uid)) return NULL;
-    
-    $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
-    $identity_time = filemtime($identity_file);
-    
-    $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
-    if (file_exists($store_file)) {
-        $store_time = filemtime($store_file);
-    } else {
-        $store_time = NULL;
-    }
-    
-    if ($type == 'identity') {
-        return $identity_time;
-    } elseif ($type == 'usrstore') {
-        return $store_time;
-    } elseif ($type == NULL) {
-        return ($identity_time > $store_time) ? $identity_time : $store_time;
-    } else {
-        return NULL;
-    }
-}
-
-
-/**
- * Finds the user name from a specified OpenID Identity URI.
- *
- * @param string $identity the Identity URI of the user to load
- * @return string the user name for the Identity URI, or NULL if no user has
- * the specified Identity URI
- */
-function store_get_uid($identity) {
-    $uid = cache_get('identity', $identity);
-    if ($uid !== NULL) return $uid;
-    
-    $r = NULL;
-    
-    $dir = opendir(SIMPLEID_IDENTITIES_DIR);
-    
-    while (($file = readdir($dir)) !== false) {
-        $filename = SIMPLEID_IDENTITIES_DIR . '/' . $file;
-        
-        if (is_link($filename)) $filename = readlink($filename);
-        if ((filetype($filename) != "file") || (!preg_match('/^(.+)\.identity$/', $file, $matches))) continue;
-        
-        $uid = $matches[1];
-        $test_user = store_user_load($uid);
-        
-        cache_set('identity', $test_user['identity'], $uid);
-    
-        if ($test_user['identity'] == $identity) {
-            $r = $uid;
-        }
-    }
-        
-    closedir($dir);
-    
-    return $r;
-}
-
-/**
- * Finds the user name from a specified client SSL certificate string.
- *
- * The client SSL certificate string comprises the certificate's serial number
- * (in capitals hex notation) and the distinguished name of the certificate's issuer
- * (with components joined using slashes), joined using a semi-colon.
- *
- *
- * @param string $cert the client SSL certificate string of the user to load
- * @return string the user name matching the client SSL certificate string, or NULL if no user has
- * client SSL certificate string
- */
-function store_get_uid_from_cert($cert) {
-    $uid = cache_get('cert', $cert);
-    if ($uid !== NULL) return $uid;
-    
-    $r = NULL;
-    
-    $dir = opendir(SIMPLEID_IDENTITIES_DIR);
-    
-    while (($file = readdir($dir)) !== false) {
-        $filename = SIMPLEID_IDENTITIES_DIR . '/' . $file;
-        
-        if (is_link($filename)) $filename = readlink($filename);
-        if ((filetype($filename) != "file") || (!preg_match('/^(.+)\.identity$/', $file, $matches))) continue;
-        
-        $uid = $matches[1];
-        $test_user = store_user_load($uid);
-        
-        if (isset($test_user['certauth']['cert'])) {
-            if (is_array($test_user['certauth']['cert'])) {
-                foreach ($test_user['certauth']['cert'] as $test_cert) {
-                    if (trim($test_cert) != '') cache_set('cert', $test_cert, $uid);
-                }
-                foreach ($test_user['certauth']['cert'] as $test_cert) {
-                    if ((trim($test_cert) != '') && ($test_cert == $cert))  $r = $uid;
-                }
-            } else {
-                if (trim($test_cert) != '') {
-                    cache_set('cert', $test_user['certauth']['cert'], $uid);
-                    if ($test_user['certauth']['cert'] == $cert) $r = $uid;
-                }
-            }
-        }
-    }
-        
-    closedir($dir);
-    
-    return $r;
-}
-
-/**
- * Saves user data for a specific user name.
- *
- * This data is stored in the user store file.
- *
- * @param string $uid the name of the user
- * @param array $data the data to save
- * @param array $exclude an array of keys to exclude from the user store file.
- * These are generally keys which are stored in the identity file.
- *
- * @since 0.7
- */
-function store_user_save($uid, $data, $exclude = array()) {
-    foreach ($exclude as $key) {
-        if (isset($data[$key])) unset($data[$key]);
-    }
-    
-    if (!_store_is_valid_name($uid)) {
-        trigger_error("Invalid user name for filesystem store", E_USER_ERROR);
-        return;
-    }
-    
-    $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
-    $file = fopen($store_file, 'w');
-    fwrite($file, serialize($data));
-    fclose($file);
-}
-
-/**
- * Loads an application setting.
- *
- * @param string $name the name of the setting to return
- * @param mixed $default the default value to use if this variable has never been set
- * @return mixed the value of the setting
- *
- */
-function store_get($name, $default = NULL) {
-    global $simpleid_settings;
-    
-    if (!_store_is_valid_name($name)) return $default;
-    
-    if (!isset($simpleid_settings[$name])) {
-        $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
-        
-        if (file_exists($setting_file)) {
-            $simpleid_settings[$name] = unserialize(file_get_contents($setting_file));
-        } else {
-            return $default;
-        }
-    }
-    
-    return $simpleid_settings[$name];
-}
-
-/**
- * Saves an application setting.
- *
- * @param string $name the name of the setting to save
- * @param mixed $value the value of the setting
- *
- */
-function store_set($name, $value) {
-    global $simpleid_settings;
-    
-    if (!_store_is_valid_name($name)) {
-        trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
-        return;
-    }
-    
-    $simpleid_settings[$name] = $value;
-    
-    $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
-    $file = fopen($setting_file, 'w');
-    fwrite($file, serialize($value));
-    fclose($file);
-}
-
-/**
- * Deletes an application setting.
- *
- * @param string $name the name of the setting to delete
- *
- */
-function store_del($name) {
-    global $simpleid_settings;
-    
-    if (!_store_is_valid_name($name)) {
-        trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
-        return;
-    }
-    
-    if (isset($simpleid_settings[$name])) unset($simpleid_settings[$name]);
-    
-    $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
-    if (file_exists($setting_file)) unlink($setting_file);
-}
-
-/**
- * Determines whether a name is a valid name for use with this store.
- *
- * For file system storage, a name is not valid if it contains either a
- * directory separator (i.e. / or \).
- *
- * @param string $name the name to check
- * @return boolean whether the name is valid for use with this store 
- *
- */
-function _store_is_valid_name($name) {
-    return preg_match('!\A[^/\\\\]*\z!', $name);
-}
-?>
diff --git a/simpleid/www/html/application.png b/simpleid/www/html/application.png
deleted file mode 100644
index 1dee9e3..0000000
--- a/simpleid/www/html/application.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/block.xtpl b/simpleid/www/html/block.xtpl
deleted file mode 100644
index c70ff41..0000000
--- a/simpleid/www/html/block.xtpl
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- :mode=html: $Id$ -->
-<!-- BEGIN: block -->
-<div class="block" id="{id}">
-    <div class="block-header">
-        <!-- BEGIN: links -->
-        <div class="block-header-links">
-            {links}
-        </div>
-        <!-- END: links -->
-        <h2>{title}</h2>
-    </div>
-    <div class="block-content">
-    {content}
-    </div>
-</div>
-<!-- END: block -->
diff --git a/simpleid/www/html/drive.png b/simpleid/www/html/drive.png
deleted file mode 100644
index 37b7c9b..0000000
--- a/simpleid/www/html/drive.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/jquery.js b/simpleid/www/html/jquery.js
deleted file mode 100644
index da41706..0000000
--- a/simpleid/www/html/jquery.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
-//@ sourceMappingURL=jquery-1.10.2.min.map
-*/
-(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
-}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
-u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
diff --git a/simpleid/www/html/jquery.qrcode.js b/simpleid/www/html/jquery.qrcode.js
deleted file mode 100644
index fe9680e..0000000
--- a/simpleid/www/html/jquery.qrcode.js
+++ /dev/null
@@ -1,28 +0,0 @@
-(function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function p(a,c){this.totalCount=a;this.dataCount=c}function t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return this.data.length},
-write:function(a){for(var c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
-for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
-0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var d=1*c,b=0;b<this.modules[c].length;b++){var e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return a},
-setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var f=-2;2>=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
-j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
-b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var g=0;2>g;g++)if(null==this.modules[b][i-g]){var n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
-c),b=new t,e=0;e<d.length;e++){var f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
-0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
-(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return d};s=4;for(var j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
-78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var c=a<<12;0<=j.getBCHDigit(c)-
-j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
-a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
-a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
-2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
-LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return new q(c,0)},mod:function(a){if(0>
-this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
-[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
-116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
-43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
-3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
-55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
-45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
-(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
-correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
-j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
-d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);
diff --git a/simpleid/www/html/lock-open.png b/simpleid/www/html/lock-open.png
deleted file mode 100644
index a471765..0000000
--- a/simpleid/www/html/lock-open.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/lock.png b/simpleid/www/html/lock.png
deleted file mode 100644
index 2ebc4f6..0000000
--- a/simpleid/www/html/lock.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/nav-toggle.png b/simpleid/www/html/nav-toggle.png
deleted file mode 100644
index 063079e..0000000
--- a/simpleid/www/html/nav-toggle.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/normalize.css b/simpleid/www/html/normalize.css
deleted file mode 100644
index c2de8df..0000000
--- a/simpleid/www/html/normalize.css
+++ /dev/null
@@ -1,406 +0,0 @@
-/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
-
-/* ==========================================================================
-   HTML5 display definitions
-   ========================================================================== */
-
-/**
- * Correct `block` display not defined in IE 8/9.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
-    display: block;
-}
-
-/**
- * Correct `inline-block` display not defined in IE 8/9.
- */
-
-audio,
-canvas,
-video {
-    display: inline-block;
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
-    display: none;
-    height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9.
- * Hide the `template` element in IE, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
-    display: none;
-}
-
-/* ==========================================================================
-   Base
-   ========================================================================== */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- *    user zoom.
- */
-
-html {
-    font-family: sans-serif; /* 1 */
-    -ms-text-size-adjust: 100%; /* 2 */
-    -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
-    margin: 0;
-}
-
-/* ==========================================================================
-   Links
-   ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
-    background: transparent;
-}
-
-/**
- * Address `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
-    outline: thin dotted;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
-    outline: 0;
-}
-
-/* ==========================================================================
-   Typography
-   ========================================================================== */
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari 5, and Chrome.
- */
-
-h1 {
-    font-size: 2em;
-    margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
-    border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
- */
-
-b,
-strong {
-    font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari 5 and Chrome.
- */
-
-dfn {
-    font-style: italic;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
-    -moz-box-sizing: content-box;
-    box-sizing: content-box;
-    height: 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
-    background: #ff0;
-    color: #000;
-}
-
-/**
- * Correct font family set oddly in Safari 5 and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
-    font-family: monospace, serif;
-    font-size: 1em;
-}
-
-/**
- * Improve readability of pre-formatted text in all browsers.
- */
-
-pre {
-    white-space: pre-wrap;
-}
-
-/**
- * Set consistent quote types.
- */
-
-q {
-    quotes: "\201C" "\201D" "\2018" "\2019";
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
-    font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
-    font-size: 75%;
-    line-height: 0;
-    position: relative;
-    vertical-align: baseline;
-}
-
-sup {
-    top: -0.5em;
-}
-
-sub {
-    bottom: -0.25em;
-}
-
-/* ==========================================================================
-   Embedded content
-   ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9.
- */
-
-img {
-    border: 0;
-}
-
-/**
- * Correct overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
-    overflow: hidden;
-}
-
-/* ==========================================================================
-   Figures
-   ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari 5.
- */
-
-figure {
-    margin: 0;
-}
-
-/* ==========================================================================
-   Forms
-   ========================================================================== */
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
-    border: 1px solid #c0c0c0;
-    margin: 0 2px;
-    padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
-    border: 0; /* 1 */
-    padding: 0; /* 2 */
-}
-
-/**
- * 1. Correct font family not being inherited in all browsers.
- * 2. Correct font size not being inherited in all browsers.
- * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
- */
-
-button,
-input,
-select,
-textarea {
-    font-family: inherit; /* 1 */
-    font-size: 100%; /* 2 */
-    margin: 0; /* 3 */
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
-    line-height: normal;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
- * Correct `select` style inheritance in Firefox 4+ and Opera.
- */
-
-button,
-select {
-    text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- *    and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- *    `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
-    -webkit-appearance: button; /* 2 */
-    cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
-    cursor: default;
-}
-
-/**
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
-    box-sizing: border-box; /* 1 */
-    padding: 0; /* 2 */
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
- *    (include `-moz` to future-proof).
- */
-
-input[type="search"] {
-    -webkit-appearance: textfield; /* 1 */
-    -moz-box-sizing: content-box;
-    -webkit-box-sizing: content-box; /* 2 */
-    box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-    -webkit-appearance: none;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-    border: 0;
-    padding: 0;
-}
-
-/**
- * 1. Remove default vertical scrollbar in IE 8/9.
- * 2. Improve readability and alignment in all browsers.
- */
-
-textarea {
-    overflow: auto; /* 1 */
-    vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
-   Tables
-   ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
-    border-collapse: collapse;
-    border-spacing: 0;
-}
diff --git a/simpleid/www/html/openid-consent.js b/simpleid/www/html/openid-consent.js
deleted file mode 100644
index 52bd63c..0000000
--- a/simpleid/www/html/openid-consent.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(document).ready(function() {
-    $('.return-to-suspect').click(function() {
-        if ($(this).attr('checked') == false) return true;
-        
-        return confirm(l.openid_suspect);
-    });
-});
diff --git a/simpleid/www/html/page-profile.js b/simpleid/www/html/page-profile.js
deleted file mode 100644
index a64da93..0000000
--- a/simpleid/www/html/page-profile.js
+++ /dev/null
@@ -1,21 +0,0 @@
-var discovery_refresh = function() {
-    var code = '';
-    
-    if ($('#discovery-openid1')[0].checked) {
-        code += $('#discovery-templates .openid1').html() + '\n';
-        if ($('#discovery-local-id')[0].checked) code += $('.openid1-local-id').html() + '\n';
-    }
-    if ($('#discovery-openid2')[0].checked) {
-        code += $('#discovery-templates .openid2').html() + '\n';
-        if ($('#discovery-local-id')[0].checked) code += $('.openid2-local-id').html() + '\n';
-    }
-    
-    if (code == '') code = l.code;
-    
-    $('#discovery-link-tags').html(code);
-}
-
-$(document).ready(function() {
-    $('.discovery-checkbox').click(discovery_refresh);
-    discovery_refresh();
-});
diff --git a/simpleid/www/html/simpleid.css b/simpleid/www/html/simpleid.css
deleted file mode 100644
index 02dc644..0000000
--- a/simpleid/www/html/simpleid.css
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-@import url(normalize.css);
-
-/* General elements -------------------------------------------------------- */
-html {
-    font: 12px/19px Helvetica, Arial, sans-serif;
-}
-
-h1 {
-    font-weight: normal;
-    color: #666666;
-}
-
-a {
-    border-bottom: 1px solid #CCCCCC;
-    color: #1144AA;
-    text-decoration: none !important;
-    font-weight: bold;
-}
-a:visited {
-    border-color: #CCCCCC;
-    color: #114499;
-}
-a:focus, a:hover {
-    border-color: #4488EE;
-    color: #4488EE;
-}
-
-table {
-    border-collapse: collapse;
-    margin: 0 0 1em 0;
-    width: 100%;
-}
-
-td, th {
-    border-bottom: 1px solid #CCCCCC;
-    text-align: left;
-    vertical-align: top;
-    padding: 5px 5px;
-}
-th {
-    border-bottom: 0px;
-    background-color: #666666;
-    color: #FFFFFF;
-    white-space: nowrap;
-    font-weight: bold;
-}
-
-pre {
-    border:1px solid #CCCCCC;
-    padding: 5px;
-    font-family:"Bitstream Vera Sans Mono","Courier New",monospace;
-    font-size: 0.9em;
-    white-space: nowrap;
-    overflow: scroll;
-}
-
-/* Page layout ------------------------------------------------------------- */
-#header {
-    background-color: #666666;
-    color: #CCCCCC;
-    padding: 0px 10px;
-    line-height: 1;
-}
-#header-inner { margin: 0px auto; max-width: 1140px; }
-
-#header h1 {
-    font-weight: bold;
-    font-size: 14px;
-    text-transform: uppercase;
-    margin: 0.5em 0;
-    color: #CCCCCC;
-    letter-spacing: 0;
-}
-
-#header h1 a {
-    color: #FFFFFF;
-    text-decoration: none;
-    border-bottom: none;
-}
-
-#nav-toggle, #logo { float: left; padding: 5px 0px; }
-#nav-toggle {
-    padding: 5px;
-    border-right: 1px solid #FFFFFF;
-    margin-right: 0.5em;
-    cursor: pointer;
-    display: none;
-}
-#nav-toggle img { padding: 0.5em; }
-
-#nav {
-    background-color: #666666;
-    color: #CCCCCC;
-    padding: 5px 10px;
-}
-#nav-inner { margin: 0px auto; max-width: 1140px; }
-#nav ul {
-    margin: 0;
-    padding: 0;
-    text-align: left;
-}
-#nav li {
-    display: inline;
-    list-style-type: none;
-}
-#nav a {
-    background-color: #888888;
-    padding: 6px 8px;
-    border-width: 0;
-    color: #FFFFFF;
-}
-#nav ul#nav-left { float: left; }
-#nav ul#nav-right { float: right; }
-
-#user {
-    float: right;
-    margin: 0.5em 0;
-    padding: 5px 0;
-}
-.logged-in-as .identity {
-    padding-left: 20px;
-    background: transparent url(user.png) no-repeat top left;
-    color: #FFFFFF;
-}
-.logged-in-as a {
-    color: #FFFFFF;
-    border-bottom-color: #FFFFFF;
-    font-weight: normal;
-}
-#logout:before { content: " · "; }
-
-#user-toggle {
-    float: right;
-    padding: 5px;
-    margin-left: 0.5em;
-    border-left: 1px solid #FFFFFF;
-    cursor: pointer;
-    display: none;
-}
-#user-toggle img { padding: 0.5em; }
-
-#footer {
-    margin: 2em 0;
-    padding: 0px 10px;
-    text-align: right;
-    font-size: 0.9em;
-    color: #999999;
-}
-#footer address { font-style: normal }
-#footer a { color: #999999; }
-
-#content {
-    margin: auto;
-    padding: 1em 10px;
-    max-width: 1140px;
-    clear: both;
-}
-
-
-/* Specific elements ------------------------------------------------------- */
-.realm, .site {
-    padding-left: 20px;
-    background: transparent url(world.png) no-repeat top left;
-}
-.app {
-    padding-left: 20px;
-    background: transparent url(application.png) no-repeat top left;
-}
-.device {
-    padding-left: 20px;
-    background: transparent url(drive.png) no-repeat top left;
-}
-.url-elide { color: #999999; }
-
-span.last-time { display: none; }
-
-.message, .login-security {
-    border: 1px solid #666666;
-    border-radius: 4px;
-    padding: 0 10px;
-    background: #DDDDDD;
-    margin-bottom: 10px;
-}
-.message p { line-height: 1; }
-
-.unsecure {
-    border: 1px solid #AAAA11;
-    background: #FFFFDD;
-}
-.unsecure p { padding-left: 20px; background: transparent url(lock-open.png) no-repeat top left; }
-.secure {
-    border: 1px solid #44AA11;
-    background: #EEFFDD;
-}
-.secure p { padding-left: 20px; background: transparent url(lock.png) no-repeat top left; }
-
-.block {
-    background-color: #EEEEEE;
-    margin-bottom: 20px;
-}
-.block-header {
-    background-color: #666666;
-    margin:0 0 5px;
-    padding: 5px 10px;
-}
-.block-header h2 {
-    font-size: 1.2em;
-    font-weight: bold;
-    color: #FFFFFF;
-    margin: 0;
-    padding: 0;
-    border-top-width: 0;
-}
-.block-header-links {
-    float: right;
-    font-size: 0.9em;
-    text-align: right;
-    white-space: nowrap;
-}
-.block-header-links a {
-    color: #FFFFFF;
-    border-bottom-color: #FFFFFF;
-    font-weight: normal;
-}
-.block-content {
-    padding: 5px 10px;
-}
-.block-content p {
-    margin: 0 0 5px 0;
-    padding: 0;
-}
-.block-content h3 {
-    font-size: 1em;
-    font-weight: bold;
-    margin: 0;
-    padding: 5px 0 0 0;
-}
-
-#discovery label { display: inline; }
-#discovery-templates { display: none; }
-
-.otp-key {
-    font-size: 18px;
-    font-family: "Bitstream Vera Sans Mono","Courier New",monospace;
-    margin: 5px;
-}
-.otp-letters { padding: 0 2px; }
-#otp-key-qr { padding: 16px 0; }
-
-/* Forms */
-.form-item { margin: 1em 0; }
-
-label {
-    display: block;
-    font-weight: bold;
-    padding: 2px 0;
-}
-label.option { font-weight: normal; }
-
-select, textarea, input[type="text"], input[type="password"], input[type="number"] {
-    display: inline-block;
-    padding: 0.5em;    
-    border: 1px solid #AAAAAA;
-    border-radius: 2px;
-}
-select:focus, textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {
-    border-color: #1144AA;
-}
-
-input[type="submit"], input[type="button"] {
-    padding: 0.5em 1em;
-    background-color: #EEEEEE;
-    border: 1px solid #999999;
-    border-radius: 2px;
-    zoom: 1;
-    vertical-align: middle;
-    font-weight: bold;
-}
-input[type="submit"]:active, input[type="button"]:active {
-    box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
-}
-input[type="submit"][disabled], input[type="button"][disabled] {
-    color: #999999 !important;
-    background-color: #EEEEEE !important;
-    border-color: #999999 !important;
-}
-input[type="submit"].form-default, input[type="button"].form-default {
-    color: #FFFFFF;
-    background-color: #1144AA;
-    border-color: #114499;
-}
-
-input[type="radio"], input[type="checkbox"] { margin: 0.5em 0; }
-input[type="radio"]:focus, input[type="checkbox"]:focus {
-    outline: 1px auto #1144AA;
-}
-
-/* Dialogs and dialog pages */
-.dialog-page { background: #EEEEEE; }
-.dialog-page #content {
-    padding-top: 50px;
-    max-width: 400px;
-}
-.dialog-page #content-inner {
-    padding: 20px;
-    border: 10px solid #DDDDDD;
-    background: #FFFFFF;
-}
-
-.dialog-page form { padding-right: 2px; } /* Used to adjust the padding in text boxes */
-.dialog-page .form-item { padding-right: 1em; } /* Used to adjust the padding in text boxes */
-.dialog-page select, .dialog-page textarea, .dialog-page input[type="text"], .dialog-page input[type="password"], .dialog-page input[type="number"] {
-    width: 100%;
-}
-
-/* Mobile devices ---------------------------------------------------------- */
-@media only screen and (max-width: 767px) {
-    html { font-size: 14px; }
-
-    #logo .version { display: none; }
-
-    #nav-toggle, #user-toggle { display: block; }
-    #nav-toggle.expand, #user-toggle.expand { background-color: #888888; }
-
-    #nav {
-        display: none;
-        position: absolute;
-        float: none;
-        left: 10px;
-        top: 40px;
-        padding: 0;
-    }
-    #nav.expand { display: block; }
-    #nav li { display: block; }
-    #nav a { display: block; }
-
-    #user {
-        display: none;
-        position: absolute;
-        float: none;
-        right: 10px;
-        top: 40px;
-        background-color: #888888;
-        margin: 0;
-        padding: 0 8px;
-    }
-    #user.expand { display: block; }
-    #user span {
-        display: block;
-        padding: 6px 0;
-    }
-    #logout:before { content: ""; }
-    
-    .dialog-page { background: #FFFFFF; }
-    .dialog-page #content { padding-top: 10px; }
-    .dialog-page #content-inner {
-        padding: 0px;
-        border-width: 0px;
-    }
-}
-
diff --git a/simpleid/www/html/simpleid.ico b/simpleid/www/html/simpleid.ico
deleted file mode 100644
index b35053e..0000000
--- a/simpleid/www/html/simpleid.ico
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/simpleid.png b/simpleid/www/html/simpleid.png
deleted file mode 100644
index 25bde22..0000000
--- a/simpleid/www/html/simpleid.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/template.xtpl b/simpleid/www/html/template.xtpl
deleted file mode 100644
index c51924b..0000000
--- a/simpleid/www/html/template.xtpl
+++ /dev/null
@@ -1,419 +0,0 @@
-<!-- BEGIN: main --><!DOCTYPE html>
-<html lang="en">
-    <!-- :mode=html: $Id$ -->
-    <head>
-        <title>{title} - SimpleID</title>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-        <meta name="SimpleID-Version" content="{version}" />
-        <meta name="robots" content="noindex,nofollow" />
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
-        <link rel="shortcut icon" href="{base_path}html/simpleid.ico" type="image/x-icon" />
-        
-        <!-- BEGIN: provider -->
-            <link rel="openid.server" href="{provider}" />
-            <link rel="openid2.provider" href="{provider}" />
-            <meta content="{xrds}" http-equiv="X-XRDS-Location" />
-        <!-- END: provider -->
-        <!-- BEGIN: local_id -->
-            <link rel="openid.delegate" href="{local_id}" />
-            <link rel="openid2.local_id" href="{local_id}" />
-        <!-- END: local_id -->
-        
-        <link rel="stylesheet" href="{base_path}html/simpleid.css" />
-        <style type="text/css" media="screen">
-            {css}
-        </style>
-        
-        <script src="{base_path}html/jquery.js" type="text/javascript"></script>
-        <script type="text/javascript">
-        var l = {
-            <!-- BEGIN: js_locale -->"{js_locale_label}": "{js_locale_text}",<!-- END: js_locale -->
-        };
-        </script>
-        <!-- BEGIN: framekiller -->
-        <script type="text/javascript">
-            $(document).ready(function() {
-                if (top !== self) top.location.replace(self.location.href);
-            });
-        </script>
-        <!-- END: framekiller -->
-        {javascript}
-    </head>
-    <body class="{page_class}">
-        <div id="header"><div id="header-inner">
-            <!-- BEGIN: nav_toggle --><div id="nav-toggle"><img src="{base_path}html/nav-toggle.png" /></div><!-- END: nav_toggle -->
-            <div id="logo">
-                <h1><a href="http://simpleid.org/">SimpleID</a> <span class="version">{version}</span></h1>
-            </div>
-            <!-- BEGIN: user -->
-            <div id="user-toggle"><img src="{base_path}html/user-toggle.png" /></div>
-            <div id="user">
-                <div class="logged-in-as">
-                    <span><strong title="{identity}" class="identity">{uid}</strong></span>
-                <!-- BEGIN: logout --><span id="logout"><a href="{url}">{logout}</a></span><!-- END: logout -->
-                </div>
-            </div>
-            <!-- END: user -->
-            <div style="clear: both;"></div>
-        </div></div>
-        <!-- BEGIN: nav -->
-        <div id="nav"><div id="nav-inner">
-            <ul id="nav-left">
-                <li><a href="{nav_base}">{nav_dashboard_label}</a></li>
-                <li><a href="{nav_base}my/profile">{nav_profile_label}</a></li>
-                <li><a href="{nav_base}my/sites">{nav_sites_label}</a></li>
-            </ul>
-            <div style="clear: both"></div>
-        </div></div>
-        <!-- END: nav -->
-        <div id="content"><div id="content-inner">
-            <h1>{title}</h1>
-            
-            <!-- BEGIN: message -->
-            <div class="message">
-                <p>{message}</p>
-            </div>
-            <!-- END: message -->
-            
-            <!-- BEGIN: login -->
-            <!-- BEGIN: login_security -->
-            <div class="login-security {security_class}">
-                <p>{security_message}</p>
-            </div>
-            <!-- END: login_security -->
-            
-            <form action="{base_path}index.php" method="post" enctype="application/x-www-form-urlencoded" id="login-form">
-                <input type="hidden" name="q" value="login"/><input name="destination" type="hidden" value="{destination}"/>
-                <input type="hidden" name="mode" value="{mode}"/><input type="hidden" name="nonce" value="{nonce}" />
-
-                <!-- BEGIN: credentials -->
-                <input type="hidden" name="digest" id="edit-digest" value="" />
-                
-                <div class="form-item">
-                    <label for="edit-name">{name_label}</label>
-                    <!-- BEGIN: input_uid --><input type="text" maxlength="60" name="name" id="edit-name" value="" autocapitalize="off" autocorrect="off" class="form-text required" {security_disabled} /><!-- END: input_uid -->
-                    <!-- BEGIN: fixed_uid --><input type="hidden" name="name" value="{uid}"/><input type="hidden" name="fixed_uid" value="1"/><div id="edit-name">{uid}</div><!-- END: fixed_uid -->
-                </div>
-                <div class="form-item">
-                    <label for="edit-pass">{pass_label}</label>
-                    <input type="password" name="pass" id="edit-pass" size="60" class="form-text required" {security_disabled} />
-                </div>                
-                <div class="form-item">
-                    <label class="option">
-                        <input type="checkbox" name="autologin" value="1" />
-                        {autologin_label}
-                    </label>
-                </div>
-                <!-- END: credentials -->
-
-                <!-- BEGIN: otp -->
-                <input type="hidden" name="autologin" value="{autologin}" />
-                
-                <p>{otp_instructions_label}</p>
-
-                <p>{otp_recovery_label}</p>
-                
-                <div class="form-item">
-                    <label for="edit-otp">{otp_label}</label>
-                    <input type="number" maxlength="6" name="otp" id="edit-otp" size="10" value="" autocapitalize="off" autocorrect="off" class="form-text required" />
-                </div>
-                <!--div class="form-item">
-                    <label class="option">
-                        <input type="checkbox" name="autoverify" value="1" />
-                        {autoverify_label}
-                    </label>
-                </div-->
-                <!-- END: otp -->
-
-                <input type="submit" name="op" id="edit-submit" value="{submit_button}" class="form-default" {security_disabled} />
-                <!-- BEGIN: state -->
-                    <input type="submit" name="op" id="edit-cancel" value="{cancel_button}" />
-                    <input type="hidden" name="s" value="{state}"/>
-                <!-- END: state -->
-            </form>
-            <!-- END: login -->
-            
-            <!-- BEGIN: openid_consent -->
-            <form action="{base_path}index.php" method="post" enctype="application/x-www-form-urlencoded" id="rp-form">
-                <input type="hidden" name="q" value="openid/consent" />
-                <input type="hidden" name="s" value="{state}" />
-                <input name="tk" type="hidden" value="{token}"/>
-                
-                <!-- BEGIN: icon -->
-                <div class="icon">
-                    <img src="{icon_url}" alt="" />
-                </div>
-                <!-- END: icon -->
-                
-                <!-- BEGIN: setup -->
-                <input type="hidden" name="openid.realm" value="{realm}" />
-                
-                <p>{realm_label}</p>
-                
-                <!-- BEGIN: suspect -->
-                <div class="message unsecure">
-                    <p>{suspect_label}</p>
-                </div>
-                <!-- END: suspect -->
-                
-                <div class="form-item">
-                    <label class="option">
-                        <input class="{realm_class}" type="checkbox" name="autorelease" {auto_release} value="1" />
-                        {auto_release_label}
-                    </label>
-                </div>
-
-                {extensions}
-                
-                <input type="submit" name="op" id="edit-submit" value="{ok_button}" class="form-default" />
-                <input type="submit" name="op" id="edit-cancel" value="{cancel_button}" />
-                <!-- END: setup -->
-
-                <!-- BEGIN: cancel -->
-                <input type="hidden" name="openid.return_to" value="{return_to}" />
-                
-                <p>{unable_label}</p>
-                
-                <p>{identity_not_matching_label}</p>
-                
-                <p>{switch_user_label}</p>
-                
-                <input type="submit" name="op" id="edit-cancel" value="{cancel_button}" class="form-default" />
-                <!-- END: cancel -->                
-            </form>
-            <!-- END: openid_consent -->
-            
-            <!-- BEGIN: blocks -->
-                {blocks}
-            <!-- END: blocks -->
-
-            <!-- BEGIN: sites -->
-            <form action="{base_path}index.php" method="post" enctype="application/x-www-form-urlencoded" >
-            <input name="q" type="hidden" value="my/sites" />
-            <input name="tk" type="hidden" value="{token}"/>
-            <input name="update-all" type="hidden" value="1"/>
-            <table id="sites">
-                <thead>
-                    <tr>
-                        <th>{realm_label}</th>
-                        <th>{last_time_label}</th>
-                        <th>{auto_release_label}</th>
-                        <th>{remove_label}</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <!-- BEGIN:realm -->
-                    <tr>
-                        <td><span class="realm">{realm_name}</span></td>
-                        <td><span class="last-time">{last_time}</span> {last_time_formatted}</td>
-                        <td><input class="{realm_class}" type="checkbox" value="1" name="autorelease[{realm}]" {auto_release}/></td>
-                        <td><input type="checkbox" value="1" name="remove[{realm}]"/></td>
-                    </tr>
-                    <!-- END: realm -->
-                </tbody>
-            </table>
-            <input type="submit" name="op" id="edit-submit" value="{submit_button}" class="form-default" {disabled} />
-            </form>
-            <!-- END: sites -->
-
-            <!-- BEGIN: otp -->
-            <p>{about_otp}</p>
-
-            <p>{otp_warning}</p>
-            
-            <p>{setup_otp}</p>
-
-            <ol>
-                <li>{download_app}</li>
-                <li>{add_account}
-                    <div class="otp-key"><span class="otp-letters">{secret1}</span><span class="otp-letters">{secret5}</span><span class="otp-letters">{secret9}</span><span class="otp-letters">{secret13}</span></div>
-                    <div id="otp-key-qr"></div>
-                </li>
-                <li>{verify_code}</li>
-            </ol>
-
-            <script src="{base_path}html/jquery.qrcode.js" type="text/javascript"></script><script type="text/javascript">$('#otp-key-qr').qrcode("{qr}");</script>
-
-            <form action="{base_path}index.php" method="post" enctype="application/x-www-form-urlencoded">
-                <input type="hidden" name="q" value="otp"/><input type="hidden" name="tk" value="{token}"/>
-                
-                <div class="form-item">
-                    <label for="edit-otp">{otp_label}</label>
-                    <input type="text" inputmode="numeric" maxlength="6" name="otp" id="edit-otp" size="10" value="" autocapitalize="off" autocorrect="off" class="form-text required" />
-                </div>
-                <input type="submit" name="op" id="edit-submit" value="{submit_button}" class="form-default" />
-            </form>
-
-            <!-- END: otp -->
-            
-            <!-- BEGIN: upgrade_access_denied -->
-            <p>{login_required}</p>
-            
-            <p>{edit_upgrade_php}</p>
-            
-            <ol>
-                <li>{edit_upgrade_php1}</li>
-                <li>{edit_upgrade_php2}</li>
-                <li>{edit_upgrade_php3}</li>
-                <li>{edit_upgrade_php4}</li>
-            </ol>
-            
-            <p>{simpleid_docs}</p>
-            <!-- END: upgrade_access_denied -->
-
-            <!-- BEGIN: upgrade_info -->
-            <p>{intro}</p>
-            
-            <p>{simpleid_docs}</p>
-            
-            <ol>
-                <li>{step1}</li>
-                <li>{step2}</li>
-            </ol>
-  
-            <p>{click_continue}</p>
-
-            <form method="post" action="{base_path}upgrade.php">
-                <input type="hidden" name="q" value="upgrade-selection" />
-                <input type="hidden" name="tk" value="{token}" />
-                <input type="submit" value="{continue_button}" />
-            </form>
-            <!-- END: upgrade_info -->
-            
-            <!-- BEGIN: upgrade_selection -->
-            <p>{version_detected}</p>
-            
-            <p>{original_version_label}: <strong class="upgrade-version original-version">{original_version}</strong></p>
-            
-            <p>{this_version_label}: <strong class="upgrade-version this-version">{this_version}</strong></p>
-            
-                <!-- BEGIN: selection_complete -->
-                    <p>{script_complete}</p>
-                    <!-- BEGIN: upgrade_access_check -->
-                    <div class="message unsecure">
-                        <p>{edit_upgrade_php}</p>
-                    </div>
-                    <!-- END: upgrade_access_check -->
-                <!-- END: selection_complete -->
-                
-                <!-- BEGIN: selection_continue -->
-                <p>{click_continue}</p>
-
-                <form method="post" action="{base_path}upgrade.php">
-                    <input type="hidden" name="q" value="upgrade-apply" />
-                    <input type="hidden" name="tk" value="{token}" />
-                    <input type="hidden" name="handle" value="{handle}" />
-                    <input type="submit" value="{continue_button}" />
-                </form>
-                <!-- END: selection_continue -->
-                
-            <!-- END: upgrade_selection -->
-            
-            <!-- BEGIN: upgrade_results -->
-            <p>{upgrade_complete}</p>
-            <!-- BEGIN: upgrade_access_check -->
-            <div class="message unsecure">
-                <p>{edit_upgrade_php}</p>
-            </div>
-            <!-- END: upgrade_access_check -->
-            
-            <div class="upgrade-results">
-            {results}
-            </div>
-            <!-- END: upgrade_results -->
-        </div></div>
-
-        <div id="footer">
-            <address>
-                SimpleID {version} &copy; Kelvin Mo &middot;
-                <a href="http://simpleid.org/docs/1/">{footer_doc}</a> &middot;
-                <a href="http://github.com/simpleid/simpleid/">{footer_support}</a>
-            </address>
-        </div>
-
-        <script type="text/javascript">
-        (function() {
-            var nav, nav_toggle, user, user_toggle;
-
-            nav = document.getElementById('nav');
-            nav_toggle = document.getElementById('nav-toggle');
-            user = document.getElementById('user');
-            user_toggle = document.getElementById('user-toggle');
-
-            if (nav) {
-                nav_toggle.onclick = function() {
-                    if (nav.className.indexOf('expand') !== -1) {
-                        nav.className = nav.className.replace(' expand', '');
-                        nav_toggle.className = nav_toggle.className.replace(' expand', '');
-                    } else {
-                        nav.className += ' expand';
-                        nav_toggle.className += ' expand';
-                    }
-                }
-            }
-
-            if (user) {
-                user_toggle.onclick = function() {
-                    if (user.className.indexOf('expand') !== -1) {
-                        user.className = user.className.replace(' expand', '');
-                        user_toggle.className = user_toggle.className.replace(' expand', '');
-                    } else {
-                        user.className += ' expand';
-                        user_toggle.className += ' expand';
-                    }
-                }
-            }
-        })();
-        </script>
-    </body>
-</html>
-<!-- END: main -->
-
-<!-- BEGIN: xrds --><?xml version="1.0" encoding="UTF-8"?>
-<xrds:XRDS xmlns="xri://$xrd*($v*2.0)" xmlns:xrds="xri://$xrds" xmlns:simple="http://xrds-simple.net/core/1.0">
-    <XRD version="2.0">
-        <!-- BEGIN: user_xrds -->
-        <Service priority="10">
-            <Type>http://specs.openid.net/auth/2.0/signon</Type>
-            <URI>{simpleid_base_url}</URI>
-            <!-- BEGIN: local_id2 -->
-            <LocalID>{local_id}</LocalID>            
-            <!-- END: local_id2 -->
-        </Service>
-        <Service priority="20" xmlns:openid="http://openid.net/xmlns/1.0">
-            <Type>http://openid.net/signon/1.0</Type>
-            <URI>{simpleid_base_url}</URI>
-            <!-- BEGIN: local_id -->
-            <openid:Delegate>{local_id}</openid:Delegate>
-            <!-- END: local_id -->
-        </Service>
-        <!-- END: user_xrds -->
-        <!-- BEGIN: op_xrds -->
-        <Service>
-            <Type>http://specs.openid.net/auth/2.0/server</Type>
-            <!-- Keep old domain -->
-            <Type>http://simpleid.koinic.net/type/version#{version}</Type>
-            <!-- BEGIN: type --><Type>{uri}</Type><!-- END: type -->
-            <URI>{simpleid_base_url}</URI>
-        </Service>
-        <!-- END: op_xrds -->
-    </XRD>
-</xrds:XRDS>
-<!-- END: xrds -->
-
-<!-- BEGIN: xrd --><?xml version="1.0" encoding="UTF-8"?>
-<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
-    {signature}
-    <!-- BEGIN: user_xrd -->
-    <Subject>{acct_uri}</Subject>
-    <Alias>{simpleid_user_uri}</Alias>
-    <!-- BEGIN: local_id -->
-    <Alias>{local_id}</Alias>
-    <!-- END: local_id -->
-    <Link rel="http://specs.openid.net/auth/2.0/provider" href="{simpleid_base_url}" />
-    <!-- END: user_xrd -->
-    <!-- BEGIN: xrd_link -->
-    <Link rel="{rel}" href="{href}" />
-    <!-- END: xrd_link -->
-</XRD>
-<!-- END: xrd -->
diff --git a/simpleid/www/html/upgrade.css b/simpleid/www/html/upgrade.css
deleted file mode 100644
index 780daee..0000000
--- a/simpleid/www/html/upgrade.css
+++ /dev/null
@@ -1,14 +0,0 @@
-.upgrade-version {
-    font-weight: bold;
-    font-size: 1.5em;
-}
-
-.original-version { color: #666666; }
-.this-version { color: #4A80ED; }
-
-.upgrade-results {
-    overflow: auto;
-    height: 200px;
-    border: 1px solid #666666;
-    background-color: #EEEEEE;
-}
diff --git a/simpleid/www/html/user-login.js b/simpleid/www/html/user-login.js
deleted file mode 100644
index bbcc227..0000000
--- a/simpleid/www/html/user-login.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(document).ready(function() {
-    if (!$('.login-security').is('.allow-autocomplete')) $('#edit-pass').attr('autocomplete', 'off');
-    
-    if ($('#edit-name').is('.form-text')) $('#edit-name').focus();
-    if ($('#edit-otp').is('.form-text')) $('#edit-otp').focus();
-});
-
diff --git a/simpleid/www/html/user-toggle.png b/simpleid/www/html/user-toggle.png
deleted file mode 100644
index a68304c..0000000
--- a/simpleid/www/html/user-toggle.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/user.png b/simpleid/www/html/user.png
deleted file mode 100644
index 79f35cc..0000000
--- a/simpleid/www/html/user.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/html/world.png b/simpleid/www/html/world.png
deleted file mode 100644
index 68f21d3..0000000
--- a/simpleid/www/html/world.png
+++ /dev/null
Binary files differ
diff --git a/simpleid/www/http.inc.php b/simpleid/www/http.inc.php
deleted file mode 100644
index 37c1345..0000000
--- a/simpleid/www/http.inc.php
+++ /dev/null
@@ -1,359 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
- 
-/**
- * Functions for making and processing HTTP requests.
- *
- * @package simpleid
- * @since 0.7
- * @filesource
- */
-
-/**
- * The user agent to use during HTTP requests.
- */
-define('SIMPLEHTTP_USER_AGENT', 'SimpleHTTP/' . substr('$Rev$', 6, -2));
-
-/**
- * Performs an HTTP request.
- *
- * Communication with the web server is conducted using libcurl where possible.
- * Where libcurl does not exist, then sockets will be used.
- *
- * Note that the request must be properly prepared before passing onto this function.
- * For example, for POST requests, the Content-Type and Content-Length headers must be
- * included in $headers.
- *
- * @param string $url the URL
- * @param array $headers HTTP headers containing name => value pairs
- * @param string $body the request body
- * @param string $method the HTTP request method
- * @param int $retry the maximum number of redirects allowed
- * @return array containing keys 'error-code' (for communication errors), 'error'
- * (for communication errors), 'data' (content returned), 'code' (the HTTP status code), 'http-error'
- * (if the HTTP status code is not 200 or 304), 'protocol' (the HTTP protocol in the response),
- * 'headers' (an array of return headers in lowercase),
- * 'content-type' (the HTTP content-type returned)
- */
-function http_make_request($url, $headers = array(), $body = NULL, $method = 'GET', $retry = 3) {
-    // If CURL is available, we use it
-    if (extension_loaded('curl')) {
-        $response = _http_make_request_curl($url, $headers, $body, $method, $retry);
-    } else {
-        $response = _http_make_request_fsock($url, $headers, $body, $method, $retry);
-    }
-    
-    if (!isset($response['error-code'])) {
-        $valid_codes = array(
-            100, 101,
-            200, 201, 202, 203, 204, 205, 206,
-            300, 301, 302, 303, 304, 305, 307,
-            400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417,
-            500, 501, 502, 503, 504, 505
-        );
-    
-        // RFC 2616 states that all unknown HTTP codes must be treated the same as the
-        // base code in their class.
-        if (!in_array($response['code'], $valid_codes)) {
-            $response['code'] = floor($response['code'] / 100) * 100;
-        }
-        
-        if (($response['code'] != 200) && ($response['code'] != 304)) {
-            $response['http-error'] = $response['code'];
-        }
-        
-    }
-
-    return $response;
-}
-
-/**
- * Returns the protocols currently supported for making remote requests.
- *
- * If libcurl is used, this function returns a list of protocols supported by the
- * included build of the library.  If libcurl is not used, then HTTP is the
- * only protocol supported.
- *
- * @return array an array of protocols
- */
-function http_protocols() {
-    if (extension_loaded('curl')) {
-        $curl_version = curl_version();
-        return $curl_version['protocols'];
-    } else {
-        return array('http');
-    }
-}
-
-/**
- * Performs an HTTP request using libcurl.
- *
- * @param string $url the URL
- * @param array $headers HTTP headers containing name => value pairs
- * @param string $body the request body
- * @param string $method the HTTP request method
- * @param int $retry the maximum number of redirects allowed
- * @return array containing keys 'error-code' (for communication errors), 'error'
- * (for communication errors), 'data' (content returned), 'code' (the HTTP status code), 'http-error'
- * (if the HTTP status code is not 200 or 304), 'headers' (an array of return headers),
- * 'content-type' (the HTTP content-type returned)
- */
-function _http_make_request_curl($url, $headers = array(), $body = NULL, $method = 'GET', $retry = 3) {
-    // CURLOPT_FOLLOWLOCATION only works when safe mode is off or when open_basedir is set
-    // In these instances we will need to follow redirects manually
-    $manual_redirect = ((@ini_get('safe_mode') === 1)   // safe mode
-        || (strtolower(@ini_get('safe_mode')) == 'on')  // safe mode
-        || (@ini_get('open_basedir') != false)); // open_basedir
-    
-    $version = curl_version();
-    
-    $curl = curl_init($url);
-    
-    if (version_compare($version['version'], '7.10.5', '>=')) {
-        curl_setopt($curl, CURLOPT_ENCODING, '');
-    }
-    
-    if (!$manual_redirect) curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
-    
-    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
-    curl_setopt($curl, CURLOPT_MAXREDIRS, $retry);
-    curl_setopt($curl, CURLOPT_HTTPHEADER, array(implode("\n", $headers) . "\n"));
-    curl_setopt($curl, CURLOPT_USERAGENT, SIMPLEHTTP_USER_AGENT);
-    
-    curl_setopt($curl, CURLOPT_TIMEOUT, 20);
-    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
-    
-    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-    curl_setopt($curl, CURLOPT_HEADER, true);
-    
-    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
-    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
-    
-    if ($body != NULL) curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
-    
-    $response = curl_exec($curl);
-    
-    if (($response === FALSE) && ((curl_errno($curl) == 23) || (curl_errno($curl) == 61))) {
-        curl_setopt($curl, CURLOPT_ENCODING, 'none');
-        $response = curl_exec($curl);
-    }
-    
-    if ($response === FALSE) {
-        $result = array();
-        $result['error-code'] = curl_errno($curl);
-        $result['error'] = curl_error($curl);
-    } else {
-        $result['code'] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
-        $result['url'] = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
-        $result['content-type'] = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
-        
-        // Parse response.
-        $result['raw'] = $response;
-        
-        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
-        $result['data'] = substr($response, $header_size);
-        
-        $response_headers = substr($response, 0, $header_size - 4);
-
-        // In case where redirect occurs, we want the last set of headers
-        $header_blocks = explode("\r\n\r\n", $response_headers);
-        $header_block = array_pop($header_blocks);
-
-        $result = array_merge($result, _http_parse_headers($header_block, TRUE));
-        
-        // If we are in safe mode, we need to process redirects manually
-        if ($manual_redirect && (($result['code'] == 301) || ($result['code'] == 302) || ($result['code'] == 307))) {
-            if ($retry == 0) {
-                // Too many times, return an error
-                $result['error-code'] = 47;
-                $result['error'] = 'Too many redirects';
-            } else {
-                curl_close($curl);
-                return _http_make_request_curl($result['headers']['location'], $headers, $body, $method, $retry - 1);
-            }
-        }
-    }
-    
-    curl_close($curl);
-
-    return $result;
-}
-
-/**
- * Performs an HTTP request using sockets.
- *
- * @param string $url the URL
- * @param array $headers HTTP headers containing name => value pairs
- * @param string $body the request body
- * @param string $method the HTTP request method
- * @param int $retry the maximum number of redirects allowed
- * @return array containing keys 'error-code' (for communication errors), 'error'
- * (for communication errors), 'data' (content returned), 'code' (the HTTP status code), 'http-error'
- * (if the HTTP status code is not 200 or 304), 'headers' (an array of return headers),
- * 'content-type' (the HTTP content-type returned)
- */
-function _http_make_request_fsock($url, $headers = array(), $body = NULL, $method = 'GET', $retry = 3) {
-    $result = array();
-    
-    $parts = parse_url($url);
-    
-    if (!isset($parts)) {
-        $result['error-code'] = 3;
-        $result['error'] = 'URL not properly formatted';
-        return $result;
-    }
-    
-    if ($parts['scheme'] == 'http') {
-        $port = isset($parts['port']) ? $parts['port'] : 80;
-        $host = $parts['host'];
-    } elseif ($parts['scheme'] == 'https') {
-        $port = isset($parts['port']) ? $parts['port'] : 443;
-        $host = 'ssl://' . $parts['host'];
-    } else {
-        $result['error-code'] = 1;
-        $result['error'] = 'Unsupported protocol';
-    }
-    
-    $fp = @fsockopen($host, $port, $errno, $errstr, 15);
-
-    if (!$fp) {
-        $result['error-code'] = 7;
-        $result['error'] = "Cannot connect: Error $errno:" . trim($errstr);
-        return $result;
-    }
-    
-    if (isset($parts['path'])) {
-        $path = $url_parts['path'];
-        if (isset($parts['query'])) $path .= '?' . $url_parts['query'];
-    } else {
-        $path = '/';
-    }
-
-    $headers = array_merge(
-        array(
-            'Host' => $parts['host'],
-            'User-Agent' => SIMPLEHTTP_USER_AGENT,
-            'Connection' => 'close'
-        ),
-        $headers
-    );
-
-    if (isset($parts['user']) && isset($parts['pass'])) {
-        $headers['Authorization'] = 'Basic '. base64_encode($parts['user'] . (!empty($parts['pass']) ? ":". $parts['pass'] : ''));
-    }
-    
-    $request = $method . ' '. $path ." HTTP/1.0\r\n";
-    
-    $keys = array_keys($headers);
-    for ($i = 0; $i < count($keys); $i++) {
-        $request .= $keys[$i] . ': ' . $headers[$keys[$i]] . "\r\n";
-    }
-    
-    // End of headers - separator
-    $request .= "\r\n";
-    
-    if ($body != NULL) $request .= $body;
-    
-    fwrite($fp, $request);
-
-    // Fetch response.
-    $response = '';
-    while (!feof($fp) && $chunk = fread($fp, 1024)) {
-        $response .= $chunk;
-    }
-    fclose($fp);
-
-    // Parse response.
-    list($header_block, $result['data']) = explode("\r\n\r\n", $response, 2);
-    
-    $result = array_merge($result, _http_parse_headers($header_block, FALSE));
-    
-    // Process redirects
-    if (($result['code'] == 301) || ($result['code'] == 302) || ($result['code'] == 307)) {
-        if ($retry == 0) {
-            // Too many times, return an error
-            $result['error-code'] = 47;
-            $result['error'] = 'Too many redirects';
-        } else {
-            $result = _http_make_request_fsock($result['headers']['location'], $headers, $body, $method, $retry - 1);
-        }
-    }
-
-    $result['url'] = $url;
-    return $result;
-}
-
-/**
- * Parses HTTP response headers.
- *
- * @param string $header_block the unparsed header block
- * @param bool $curl if true, use simplified parsing as libcurl already parses
- * the headers
- * @return an array containing the following keys: 'protocol' (the HTTP protocol in the response),
- * 'headers' (an array of return headers in lowercase).  If $curl is false, additional
- * parsing is done for 'code' and 'content-type'
- */
-function _http_parse_headers($header_block, $curl) {
-    $headers = array();
-    $result = array();
-    
-    // Split the status line from the rest of the message header
-    list($status, $header_block) = preg_split("/\r\n|\n|\r/", $header_block, 2);
-    
-    // RFC 2616, section 4.2: Header fields can be extended over multiple lines
-    // by preceding each extra line with at least one space or tab.  So we need
-    // to join them...
-    $header_block = preg_replace('/(\r\n|\n|\r)( |\t)+/', '', $header_block);
-    
-    // Then split them to get the fields
-    $fields = preg_split("/\r\n|\n|\r/", $header_block);
-    
-    // Parse the status line
-    list($protocol, $code, $reason) = explode(' ', trim($status), 3);
-    
-    $result['protocol'] = $protocol;    
-    if (!$curl) $result['code'] = $code;
-
-    // Parse headers.
-    while ($field = trim(array_shift($fields))) {
-        list($header, $value) = explode(':', $field, 2);
-        
-        // Headers are case insensitive
-        $header = strtolower($header);
-        
-        if (isset($headers[$header])) {
-            // RFC 2616, section 4.2: Multiple headers with the same field
-            // name is the same as a concatenating all the headers in a single
-            // header, separated by commas.
-            $headers[$header] .= ','. trim($value);
-        } else {
-            $headers[$header] = trim($value);
-        }
-        
-        if (!$curl && (strtolower($header) == 'content-type')) $result['content-type'] = $value;
-    }
-        
-    $result['headers'] = $headers;
-    return $result;
-}
-?>
diff --git a/simpleid/www/index.php b/simpleid/www/index.php
deleted file mode 100644
index 756e725..0000000
--- a/simpleid/www/index.php
+++ /dev/null
@@ -1,1206 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-/**
- * Main SimpleID file.
- *
- * @package simpleid
- * @filesource
- */
-
-include_once "version.inc.php";
-include_once "locale.inc.php";
-
-// Check if the configuration file has been defined
-if (file_exists('conf/config.php')) {
-    include_once 'conf/config.php';
-} elseif (file_exists('config.php')) {
-    include_once 'config.php';
-} else {
-    die(t('No configuration file found.  See the <a href="!url">manual</a> for instructions on how to set up a configuration file.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-}
-
-include_once "config.default.php";
-include_once "log.inc.php";
-include_once "common.inc.php";
-include_once "simpleweb.inc.php";
-include_once "openid.inc.php";
-include_once "discovery.inc.php";
-include_once "user.inc.php";
-include_once "cache.inc.php";
-include_once SIMPLEID_STORE . ".store.php";
-include_once "page.inc.php";
-include_once "lib/xtemplate.class.php";
-
-define('CACHE_DIR', SIMPLEID_CACHE_DIR);
-
-/**
- */
-define('CHECKID_OK', 127);
-define('CHECKID_RETURN_TO_SUSPECT', 3);
-define('CHECKID_APPROVAL_REQUIRED', 2);
-define('CHECKID_LOGIN_REQUIRED', -1);
-define('CHECKID_IDENTITIES_NOT_MATCHING', -2);
-define('CHECKID_IDENTITY_NOT_EXIST', -3);
-define('CHECKID_PROTOCOL_ERROR', -127);
-
-define('ASSOCIATION_PRIVATE', 2);
-define('ASSOCIATION_SHARED', 1);
-
-
-/**
- * This variable holds the version of the OpenID specification associated with
- * the current OpenID request.  This can be either {@link OPENID_VERSION_1_1}
- * or {@link OPENID_VERSION_2}.
- *
- * @global float $version
- */
-$version = OPENID_VERSION_1_1;
-
-/**
- * This variable holds an instance of the XTemplate engine.
- *
- * @global object $xtpl
- */
-$xtpl = NULL;
-
-/**
- * This variable holds the combined $_GET and $_POST superglobal arrays.
- * This is then passed through {@link fix_http_request()}.
- *
- * @global array $GETPOST
- */
-$GETPOST = array();
-
-simpleid_start();
-
-/**
- * Entry point for SimpleID.
- *
- * @see user_init()
- */
-function simpleid_start() {
-    global $xtpl, $GETPOST;
-
-    locale_init(SIMPLEID_LOCALE);
-
-    $xtpl = new XTemplate('html/template.xtpl');
-    $xtpl->assign('version', SIMPLEID_VERSION);
-    $xtpl->assign('base_path', get_base_path());
-    $xtpl->assign('footer_doc', t('Documentation'));
-    $xtpl->assign('footer_support', t('Support'));
-
-    if (!is_dir(SIMPLEID_IDENTITIES_DIR)) {
-        log_fatal('Identities directory not found.');
-        indirect_fatal_error(t('Identities directory not found.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/documentation/getting-started')));
-    }
-
-    if (!is_dir(SIMPLEID_CACHE_DIR) || !is_writeable(SIMPLEID_CACHE_DIR)) {
-        log_fatal('Cache directory not found or not writeable.');
-        indirect_fatal_error(t('Cache directory not found or not writeable.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    }
-
-
-    if (!is_dir(SIMPLEID_STORE_DIR) || !is_writeable(SIMPLEID_STORE_DIR)) {
-        log_fatal('Store directory not found or not writeable.');
-        indirect_fatal_error(t('Store directory not found or not writeable.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    }
-
-    if ((@ini_get('register_globals') === 1) || (@ini_get('register_globals') === '1') || (strtolower(@ini_get('register_globals')) == 'on')) {
-        log_fatal('register_globals is enabled in PHP configuration.');
-        indirect_fatal_error(t('register_globals is enabled in PHP configuration, which is not supported by SimpleID.  See the <a href="!url">manual</a> for further information.', array('!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-
-    if (!bignum_loaded()) {
-        log_fatal('gmp/bcmath PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'gmp/bcmath', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('preg_match')) {
-        log_fatal('pcre PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'pcre', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('session_start')) {
-        log_fatal('session PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'session', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('xml_parser_create_ns')) {
-        log_fatal('xml PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'xml', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('hash')) {
-        log_fatal('hash PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'hash', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (is_numeric(@ini_get('suhosin.get.max_value_length')) && (@ini_get('suhosin.get.max_value_length') < 1024)) {
-        log_fatal('suhosin.get.max_value_length < 1024');
-        indirect_fatal_error(t('suhosin.get.max_value_length is less than 1024, which will lead to problems. See the <a href="!url">manual</a> for further information on system requirements.', array('!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-
-    fix_http_request();
-    $GETPOST = array_merge($_GET, $_POST);
-    openid_parse_request($GETPOST);
-
-    $q = (isset($GETPOST['q'])) ? $GETPOST['q'] : '';
-
-    $uaid = get_user_agent_id();
-    extension_init();
-    user_init($q);
-    log_info('Session opened for "' . $q . '" from ' . $uaid . ' [' . $_SERVER['REMOTE_ADDR'] . ', ' . gethostbyaddr($_SERVER['REMOTE_ADDR']) . ']');
-
-    // Clean stale assocations
-    cache_expire(array(
-        'association' => SIMPLEID_ASSOC_EXPIRES_IN,
-        'stateless' => 300)
-    );
-
-    simpleid_route($q);
-}
-
-/**
- * Dispatches to the correct SimpleID function based on the request path.  The
- * request path usually comes from the q parameter in the query string (which may
- * be inserted by mod_rewrite), but can come from other functions as well.
- *
- * @param string $q the request path
- */
-function simpleid_route($q) {
-    $routes = array(
-        'continue' => 'simpleid_continue',
-        'login' => 'user_login',
-        'logout' => 'user_logout',
-        'my/dashboard' => 'page_dashboard',
-        'my/sites' => 'page_sites',
-        'my/profile' => 'page_profile',
-        'otp' => 'user_otp_page',
-        'openid/consent' => 'simpleid_openid_consent',
-        'ppid/(.*)' => 'user_ppid_page',
-        'user' => 'user_public_page',
-        'user/(.+)' => 'user_public_page',
-        'xrds/(.*)' => 'user_xrds',
-        'xrds' => 'simpleid_xrds',
-    );
-    $routes = array_merge($routes, extension_invoke_all('routes'), array('.*' => 'simpleid_index'));
-
-    simpleweb_run($routes, $q);
-}
-
-/**
- * The default route, called when the q parameter is missing or is invalid.
- *
- * This function performs the following:
- *
- * - If openid.mode is present, then the request is an OpenID request.  This
- *   is passed to {@link simpleid_process_openid()}
- * - If the Accept HTTP header contains the expression application/xrds+xml, then
- *   the request is a YADIS discovery request for SimpleID as an OpenID provider.  Thi
- *   is passed to {@link simpleid_xrds()}
- * - Otherwise, the dashboard or the login page is displayed to the user as
- *   appropriate
- *
- */
-function simpleid_index() {
-    global $GETPOST;
-
-    log_debug('simpleid_index');
-
-    $content_type = negotiate_content_type(array('text/html', 'application/xml', 'application/xhtml+xml', 'application/xrds+xml'));
-
-    header('Vary: Accept');
-    if (isset($GETPOST['openid.mode'])) {
-        simpleid_process_openid($GETPOST);
-        return;
-    } elseif ($content_type == 'application/xrds+xml') {
-        simpleid_xrds();
-    } else {
-        // Point to SimpleID's XRDS document
-        header('X-XRDS-Location: ' . simpleid_url('xrds'));
-        page_dashboard();
-    }
-}
-
-
-/**
- * Process an OpenID request.
- *
- * This function determines the version of the OpenID specification that is
- * relevant to this request, checks openid.mode and passes the
- * request on to the function required to process the request.
- *
- * The OpenID request expressed as an array contain key-value pairs corresponding
- * to the HTTP request.  This is usually contained in the <code>$_REQUEST</code>
- * variable.
- *
- * @param array $request the OpenID request
- */
-function simpleid_process_openid($request) {
-    global $version;
-
-    $version = openid_get_version($request);
-
-    switch ($request['openid.mode']) {
-        case 'associate':
-            simpleid_associate($request);
-            return;
-        case 'checkid_immediate':
-        case 'checkid_setup':
-            check_https('redirect', true, simpleid_url('continue', 's=' . rawurlencode(pickle($request)), false, 'https'));
-
-            return simpleid_checkid($request);
-        case 'check_authentication':
-            simpleid_check_authentication($request);
-            break;
-        default:
-            if (isset($request['openid.return_to'])) {
-                // Indirect communication - send error via indirect communication.
-                header_response_code('400 Bad Request');
-                set_message(t('Invalid OpenID message.'));
-                page_dashboard();
-            } else {
-                // Direct communication
-                openid_direct_error('Invalid OpenID message.');
-            }
-    }
-}
-
-/**
- * Processes an association request from a relying party.
- *
- * An association request has an openid.mode value of
- * associate.  This function checks whether the association request
- * is valid, and if so, creates an association and sends the response to
- * the relying party.
- *
- * @see _simpleid_create_association()
- * @param array $request the OpenID request
- * @link http://openid.net/specs/openid-authentication-1_1.html#mode_associate, http://openid.net/specs/openid-authentication-2_0.html#associations
- *
- */
-function simpleid_associate($request) {
-    global $version;
-
-    log_info('OpenID association request: ' . log_array($request));
-
-    $assoc_types = openid_association_types();
-    $session_types = openid_session_types(is_https(), $version);
-
-    // Common Request Parameters [8.1.1]
-    if (($version == OPENID_VERSION_1_1) && !isset($request['openid.session_type'])) $request['openid.session_type'] = '';
-    $assoc_type = $request['openid.assoc_type'];
-    $session_type = $request['openid.session_type'];
-
-    // Diffie-Hellman Request Parameters [8.1.2]
-    $dh_modulus = (isset($request['openid.dh_modulus'])) ? $request['openid.dh_modulus'] : NULL;
-    $dh_gen = (isset($request['openid.dh_gen'])) ? $request['openid.dh_gen'] : NULL;
-    $dh_consumer_public = $request['openid.dh_consumer_public'];
-
-    if (!isset($request['openid.session_type']) || !isset($request['openid.assoc_type'])) {
-        log_error('Association failed: openid.session_type or openid.assoc_type not set');
-        openid_direct_error('openid.session_type or openid.assoc_type not set');
-        return;
-    }
-
-    // Check if the assoc_type is supported
-    if (!array_key_exists($assoc_type, $assoc_types)) {
-        $error = array(
-            'error_code' => 'unsupported-type',
-            'session_type' => 'DH-SHA1',
-            'assoc_type' => 'HMAC-SHA1'
-        );
-        log_error('Association failed: The association type is not supported by SimpleID.');
-        openid_direct_error('The association type is not supported by SimpleID.', $error, $version);
-        return;
-    }
-    // Check if the session_type is supported
-    if (!array_key_exists($session_type, $session_types)) {
-        $error = array(
-            'error_code' => 'unsupported-type',
-            'session_type' => 'DH-SHA1',
-            'assoc_type' => 'HMAC-SHA1'
-        );
-        log_error('Association failed: The session type is not supported by SimpleID.');
-        openid_direct_error('The session type is not supported by SimpleID.', $error, $version);
-        return;
-    }
-
-    if ($session_type == 'DH-SHA1' || $session_type == 'DH-SHA256') {
-        if (!$dh_consumer_public) {
-            log_error('Association failed: openid.dh_consumer_public not set');
-            openid_direct_error('openid.dh_consumer_public not set');
-            return;
-        }
-    }
-
-    $response = _simpleid_create_association(ASSOCIATION_SHARED, $assoc_type, $session_type, $dh_modulus, $dh_gen, $dh_consumer_public);
-
-    openid_direct_response(openid_direct_message($response, $version));
-}
-
-
-/**
- * Creates an association.
- *
- * This function calls {@link openid_dh_server_assoc()} where required, to
- * generate the cryptographic values required for an association response.
- *
- * @param int $mode either ASSOCIATION_SHARED or ASSOCIATION_PRIVATE
- * @param string $assoc_type a valid OpenID association type
- * @param string $session_type a valid OpenID session type
- * @param string $dh_modulus for Diffie-Hellman key exchange, the modulus encoded in Base64
- * @param string $dh_gen for Diffie-Hellman key exchange, g encoded in Base64
- * @param string $dh_consumer_public for Diffie-Hellman key exchange, the public key of the relying party encoded in Base64
- * @return mixed if $mode is ASSOCIATION_SHARED, an OpenID response
- * to the association request, if $mode is ASSOCIATION_PRIVATE, the
- * association data for storage.
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor14, http://openid.net/specs/openid-authentication-2_0.html#anchor20
- */
-function _simpleid_create_association($mode = ASSOCIATION_SHARED, $assoc_type = 'HMAC-SHA1', $session_type = 'no-encryption', $dh_modulus = NULL, $dh_gen = NULL, $dh_consumer_public = NULL) {
-    global $version;
-
-    $assoc_types = openid_association_types();
-    $session_types = openid_session_types(is_https(), $version);
-
-    $mac_size = $assoc_types[$assoc_type]['mac_size'];
-    $hmac_func = $assoc_types[$assoc_type]['hmac_func'];
-
-    $assoc_handle = random_id();
-    $expires_in = SIMPLEID_ASSOC_EXPIRES_IN;
-
-    $secret = random_bytes($mac_size);
-
-    $response = array(
-        'assoc_handle' => $assoc_handle,
-        'assoc_type' => $assoc_type,
-        'expires_in' => $expires_in
-    );
-
-    // If $session_type is '', then it must be using OpenID 1.1 (blank parameter
-    // is not allowed for OpenID 2.0.  For OpenID 1.1 blank requests, we don't
-    // put a session_type in the response.
-    if ($session_type != '') $response['session_type'] = $session_type;
-
-    if (($session_type == 'no-encryption') || ($session_type == '')) {
-        $mac_key = base64_encode(call_user_func($hmac_func, $secret, $response['assoc_handle']));
-        $response['mac_key'] = $mac_key;
-    } elseif ($session_type == 'DH-SHA1' || $session_type == 'DH-SHA256') {
-        $hash_func = $session_types[$session_type]['hash_func'];
-
-        $dh_assoc = openid_dh_server_assoc($secret, $dh_consumer_public, $dh_modulus, $dh_gen, $hash_func);
-        $mac_key = base64_encode($secret);
-        $response['dh_server_public'] = $dh_assoc['dh_server_public'];
-        $response['enc_mac_key'] = $dh_assoc['enc_mac_key'];
-    }
-
-    $association = array('assoc_handle' => $assoc_handle, 'assoc_type' => $assoc_type, 'mac_key' => $mac_key, 'created' => time());
-    if ($mode == ASSOCIATION_PRIVATE) $association['private'] = 1;
-    cache_set('association', $assoc_handle, $association);
-
-    if ($mode == ASSOCIATION_SHARED) {
-        log_info('Created association: ' . log_array($response));
-        log_debug('***** MAC key: ' . $association['mac_key']);
-        return $response;
-    } else {
-        log_info('Created association: private; ' . log_array($association, array('assoc_handle', 'assoc_type')));
-        log_debug('***** MAC key: ' . $association['mac_key']);
-        return $association;
-    }
-}
-
-
-/**
- * Processes an authentication request from a relying party.
- *
- * An authentication request has an openid.mode value of
- * checkid_setup or checkid_immediate.
- *
- * If the authentication request is a standard OpenID request about an identity
- * (i.e. contains the key openid.identity), this function calls
- * {@link simpleid_checkid_identity()} to see whether the user logged on into SimpleID
- * matches the identity supplied in the OpenID request.
- *
- * If the authentication request is not about an identity, this function calls
- * the {@link hook_checkid() checkid hook} of the loaded extensions.
- *
- * Depending on the OpenID version, this function will supply an appropriate
- * assertion.
- *
- * @param array $request the OpenID request
- *
- */
-function simpleid_checkid($request) {
-    global $version;
-
-    $immediate = ($request['openid.mode'] == 'checkid_immediate');
-
-    log_info('OpenID authentication request: ' . (($immediate) ? 'immediate' : 'setup') . '; '. log_array($request));
-
-    // Check for protocol correctness
-    if ($version == OPENID_VERSION_1_1) {
-        if (!isset($request['openid.return_to'])) {
-            log_error('Protocol Error: openid.return_to not set.');
-            indirect_fatal_error(t('Protocol Error: openid.return_to not set.'));
-            return;
-        }
-        if (!isset($request['openid.identity'])) {
-            log_error('Protocol Error: openid.identity not set.');
-            indirect_fatal_error(t('Protocol Error: openid.identity not set.'));
-            return;
-        }
-    }
-
-    if ($version >= OPENID_VERSION_2) {
-        if (isset($request['openid.identity']) && !isset($request['openid.claimed_id'])) {
-            log_error('Protocol Error: openid.identity set, but not openid.claimed_id.');
-            indirect_fatal_error(t('Protocol Error: openid.identity set, but not openid.claimed_id.'));
-            return;
-        }
-
-        if (!isset($request['openid.realm']) && !isset($request['openid.return_to'])) {
-            log_error('Protocol Error: openid.return_to not set when openid.realm is not set.');
-            indirect_fatal_error(t('Protocol Error: openid.return_to not set when openid.realm is not set.'));
-            return;
-        }
-    }
-
-    if (isset($request['openid.return_to'])) {
-        $realm = openid_get_realm($request, $version);
-
-        if (!openid_url_matches_realm($request['openid.return_to'], $realm)) {
-            log_error('Protocol Error: openid.return_to does not match realm.');
-            openid_indirect_error($request['openid.return_to'], 'Protocol Error: openid.return_to does not match realm.');
-            return;
-        }
-    }
-
-    if (isset($request['openid.identity'])) {
-        // Standard request
-        log_debug('openid.identity found, use simpleid_checkid_identity');
-        $result = simpleid_checkid_identity($request, $immediate);
-    } else {
-        log_debug('openid.identity not found, trying extensions');
-        // Extension request
-        $results = extension_invoke_all('checkid', $request, $immediate);
-
-        // Filter out nulls
-        $results = array_merge(array_diff($results, array(NULL)));
-
-        // If there are still results, it is the lowest value, otherwise, it is CHECKID_PROTOCOL_ERROR
-        $result = ($results) ? min($results) : CHECKID_PROTOCOL_ERROR;
-    }
-
-    switch ($result) {
-        case CHECKID_APPROVAL_REQUIRED:
-            log_info('CHECKID_APPROVAL_REQUIRED');
-            if ($immediate) {
-                $response = simpleid_checkid_approval_required($request);
-                simpleid_assertion_response($response, $request['openid.return_to']);
-            } else {
-                $response = simpleid_checkid_ok($request);
-                simpleid_openid_consent_form($request, $response, $result);
-            }
-            break;
-        case CHECKID_RETURN_TO_SUSPECT:
-            log_info('CHECKID_RETURN_TO_SUSPECT');
-            if ($immediate) {
-                $response = simpleid_checkid_error($request, $immediate);
-                simpleid_assertion_response($response, $request['openid.return_to']);
-            } else {
-                $response = simpleid_checkid_ok($request);
-                simpleid_openid_consent_form($request, $response, $result);
-            }
-            break;
-        case CHECKID_OK:
-            log_info('CHECKID_OK');
-            $response = simpleid_checkid_ok($request);
-            $response = simpleid_sign($response, isset($request['openid.assoc_handle']) ? $request['openid.assoc_handle'] : NULL);
-            simpleid_assertion_response($response, $request['openid.return_to']);
-            break;
-        case CHECKID_LOGIN_REQUIRED:
-            log_info('CHECKID_LOGIN_REQUIRED');
-            if ($immediate) {
-                $response = simpleid_checkid_login_required($request);
-                simpleid_assertion_response($response, $request['openid.return_to']);
-            } else {
-                user_login_form('continue', pickle($request));
-                exit;
-            }
-            break;
-        case CHECKID_IDENTITIES_NOT_MATCHING:
-        case CHECKID_IDENTITY_NOT_EXIST:
-            log_info('CHECKID_IDENTITIES_NOT_MATCHING | CHECKID_IDENTITY_NOT_EXIST');
-            $response = simpleid_checkid_error($request, $immediate);
-            if ($immediate) {
-                simpleid_assertion_response($response, $request['openid.return_to']);
-            } else {
-                simpleid_openid_consent_form($request, $response, $result);
-            }
-            break;
-        case CHECKID_PROTOCOL_ERROR:
-            if (isset($request['openid.return_to'])) {
-                $response = simpleid_checkid_error($request, $immediate);
-                simpleid_assertion_response($response, $request['openid.return_to']);
-            } else {
-                indirect_fatal_error('Unrecognised request.');
-            }
-            break;
-    }
-}
-
-/**
- * Processes a standard OpenID authentication request about an identity.
- *
- * Checks whether the current user logged into SimpleID matches the identity
- * supplied in an OpenID request.
- *
- * @param array &$request the OpenID request
- * @param bool $immediate whether checkid_immediate was used
- * @return int one of CHECKID_OK, CHECKID_APPROVAL_REQUIRED, CHECKID_RETURN_TO_SUSPECT, CHECKID_IDENTITY_NOT_EXIST,
- * CHECKID_IDENTITIES_NOT_MATCHING, CHECKID_LOGIN_REQUIRED or CHECKID_PROTOCOL_ERROR
- * @global array the current logged in user
- */
-function simpleid_checkid_identity(&$request, $immediate) {
-    global $user, $version;
-
-    $realm = openid_get_realm($request, $version);
-
-    // Check 1: Is the user logged into SimpleID as any user?
-    if ($user == NULL) {
-        return CHECKID_LOGIN_REQUIRED;
-    } else {
-        $uid = $user['uid'];
-    }
-
-    // Check 2: Is the user logged in as the same identity as the identity requested?
-    // Choose the identity URL for the user automatically
-    if ($request['openid.identity'] == OPENID_IDENTIFIER_SELECT) {
-        $test_user = user_load($uid);
-        $identity = $test_user['identity'];
-
-        log_info('OpenID identifier selection: Selected ' . $uid . ' [' . $identity . ']');
-    } else {
-        $identity = $request['openid.identity'];
-        $test_user = user_load_from_identity($identity);
-    }
-    if ($test_user == NULL) return CHECKID_IDENTITY_NOT_EXIST;
-    if ($test_user['uid'] != $user['uid']) {
-        log_notice('Requested user ' . $test_user['uid'] . ' does not match logged in user ' . $user['uid']);
-        return CHECKID_IDENTITIES_NOT_MATCHING;
-    }
-
-    // Pass the assertion to extensions
-    $assertion_results = extension_invoke_all('checkid_identity', $request, $identity, $immediate);
-    $assertion_results = array_merge(array_diff($assertion_results, array(NULL)));
-
-    // Populate the request with the selected identity
-    if ($request['openid.identity'] == OPENID_IDENTIFIER_SELECT) {
-        $request['openid.claimed_id'] = $identity;
-        $request['openid.identity'] = $identity;
-    }
-
-    // Check 3: Discover the realm and match its return_to
-    $user_rp = (isset($user['rp'][$realm])) ? $user['rp'][$realm] : NULL;
-
-    if (($version >= OPENID_VERSION_2) && SIMPLEID_VERIFY_RETURN_URL_USING_REALM) {
-        $verified = FALSE;
-
-        $rp_info = simpleid_get_rp_info($realm);
-        $services = discovery_xrds_services_by_type($rp_info['services'], OPENID_RETURN_TO);
-
-        log_info('OpenID 2 discovery: ' . count($services) . ' matching services');
-
-        if ($services) {
-            $return_to_uris = array();
-
-            foreach ($services as $service) {
-                $return_to_uris = array_merge($return_to_uris, $service['uri']);
-            }
-            foreach ($return_to_uris as $return_to) {
-                if (openid_url_matches_realm($request['openid.return_to'], $return_to)) {
-                    log_info('OpenID 2 discovery: verified');
-                    $verified = TRUE;
-                    break;
-                }
-            }
-        }
-
-        $rp_info['return_to_verified'] = $verified;
-        simpleid_set_rp_info($realm, $rp_info);
-
-        if (!$verified) {
-            if (($user_rp != NULL) && ($user_rp['auto_release'] == 1)) {
-                log_notice('OpenID 2 discovery: not verified, but overridden by user preference');
-            } else {
-                log_notice('OpenID 2 discovery: not verified');
-                $assertion_results[] = CHECKID_RETURN_TO_SUSPECT;
-            }
-        }
-    }
-
-    // Check 4: For checkid_immediate, the user must already have given
-    // permission to log in automatically.
-    if (($user_rp != NULL) && ($user_rp['auto_release'] == 1)) {
-        log_info('Automatic set for realm ' . $realm);
-        $assertion_results[] = CHECKID_OK;
-        return min($assertion_results);
-    } else {
-        $assertion_results[] = CHECKID_APPROVAL_REQUIRED;
-        return min($assertion_results);
-    }
-}
-
-/**
- * Obtains information on a relying party by performing discovery on them.  Information
- * obtained includes the discovery URL, the parsed XRDS document, and any other
- * information saved by SimpleID extensions
- *
- * The results are cached for 1 hour.  For performance reasons, stale results may
- * be obtained by using the $allow_stale parameter
- *
- * @param string $realm the openid.realm parameter
- * @param bool $allow_stale allow stale results to be returned, otherwise discovery
- * will occur
- * @return array containing information on a relying party.
- * @link http://openid.net/specs/openid-authentication-2_0.html#rp_discovery
- * @since 0.8
- */
-function simpleid_get_rp_info($realm, $allow_stale = FALSE) {
-    $url = openid_realm_discovery_url($realm);
-
-    log_info('simpleid_get_rp_info');
-
-    $rp_info = cache_get('rp-info', $realm);
-
-    if (($rp_info == NULL) || (!isset($rp_info['updated'])) || (!$allow_stale && ($rp_info['updated'] < time() - 3600))) {
-        log_info('OpenID 2 RP discovery: realm: ' . $realm . '; url: ' . $url);
-
-        $rp_info = array(
-            'url' => $url,
-            'services' => discovery_xrds_discover($url),
-            'updated' => time()
-        );
-
-        cache_set('rp-info', $realm, $rp_info);
-    }
-
-    return $rp_info;
-}
-
-/**
- * Saves information on a relying party to disk.
- *
- * @param string $realm the openid.realm parameter
- * @param array $rp_info containing information on a relying party.
- *
- * @since 0.8
- */
-function simpleid_set_rp_info($realm, $rp_info) {
-    if (!isset($rp_info['updated'])) $rp_info['updated'] = time();
-    cache_set('rp-info', $realm, $rp_info, $rp_info['updated']);
-}
-
-/**
- * Returns an OpenID response indicating a positive assertion.
- *
- * @param array $request the OpenID request
- * @return array an OpenID response with a positive assertion
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor17, http://openid.net/specs/openid-authentication-1_1.html#anchor23, http://openid.net/specs/openid-authentication-2_0.html#positive_assertions
- */
-function simpleid_checkid_ok($request) {
-    global $version;
-
-    $message = array(
-        'openid.mode' => 'id_res',
-        'openid.op_endpoint' => simpleid_url(),
-        'openid.response_nonce' => openid_nonce()
-    );
-
-    if (isset($request['openid.assoc_handle'])) $message['openid.assoc_handle'] = $request['openid.assoc_handle'];
-    if (isset($request['openid.identity'])) $message['openid.identity'] = $request['openid.identity'];
-    if (isset($request['openid.return_to'])) $message['openid.return_to'] = $request['openid.return_to'];
-
-    if (($version >= OPENID_VERSION_2) && isset($request['openid.claimed_id'])) {
-        $message['openid.claimed_id'] = $request['openid.claimed_id'];
-    }
-
-    $message = array_merge($message, extension_invoke_all('response', TRUE, $request));
-
-    log_info('OpenID authentication response: ' . log_array($message));
-    return openid_indirect_message($message, $version);
-}
-
-/**
- * Returns an OpenID response indicating a negative assertion to a
- * checkid_immediate request, where an approval of the relying party by the
- * user is required
- *
- * @param mixed $request the OpenID request
- * @return mixed an OpenID response with a negative assertion
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor17, http://openid.net/specs/openid-authentication-1_1.html#anchor23, http://openid.net/specs/openid-authentication-2_0.html#negative_assertions
- */
-function simpleid_checkid_approval_required($request) {
-    global $version;
-
-    if ($version >= OPENID_VERSION_2) {
-        $message = array('openid.mode' => 'setup_needed');
-    } else {
-        $request['openid.mode'] = 'checkid_setup';
-        $message = array(
-            'openid.mode' => 'id_res',
-            'openid.user_setup_url' => simpleid_url('continue', 's=' . rawurlencode(pickle($request)))
-        );
-    }
-
-    $message = array_merge($message, extension_invoke_all('response', FALSE, $request));
-
-    log_info('OpenID authentication response: ' . log_array($message));
-    return openid_indirect_message($message, $version);
-}
-
-/**
- * Returns an OpenID response indicating a negative assertion to a
- * checkid_immediate request, where the user has not logged in.
- *
- * @param array $request the OpenID request
- * @return array an OpenID response with a negative assertion
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor17, http://openid.net/specs/openid-authentication-1_1.html#anchor23, http://openid.net/specs/openid-authentication-2_0.html#negative_assertions
- */
-function simpleid_checkid_login_required($request) {
-    global $version;
-
-    if ($version >= OPENID_VERSION_2) {
-        $message = array('openid.mode' => 'setup_needed');
-    } else {
-        $message = array(
-            'openid.mode' => 'id_res',
-            'openid.user_setup_url' => simpleid_url('login', 'destination=continue&s=' . rawurlencode(pickle($request)))
-        );
-    }
-
-    $message = array_merge($message, extension_invoke_all('response', FALSE, $request));
-
-    log_info('OpenID authentication response: ' . log_array($message));
-    return openid_indirect_message($message, $version);
-}
-
-/**
- * Returns an OpenID response indicating a generic negative assertion.
- *
- * The content of the negative version depends on the OpenID version, and whether
- * the openid.mode of the request was checkid_immediate
- *
- * @param array $request the OpenID request
- * @param bool $immediate true if openid.mode of the request was checkid_immediate
- * @return array an OpenID response with a negative assertion
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor17, http://openid.net/specs/openid-authentication-1_1.html#anchor23, http://openid.net/specs/openid-authentication-2_0.html#negative_assertions
- */
-function simpleid_checkid_error($request, $immediate = false) {
-    global $version;
-
-    $message = array();
-    if ($immediate) {
-        if ($version >= OPENID_VERSION_2) {
-            $message['openid.mode'] = 'setup_needed';
-        } else {
-            $message['openid.mode'] = 'id_res';
-        }
-    } else {
-        $message['openid.mode'] = 'cancel';
-    }
-
-    $message = array_merge($message, extension_invoke_all('response', FALSE, $request));
-
-    log_info('OpenID authentication response: ' . log_array($message));
-    return openid_indirect_message($message, $version);
-}
-
-/**
- * Signs an OpenID response, using signature information from an association
- * handle.
- *
- * @param array &$response the OpenID response
- * @param array $assoc_handle the association handle containing key information
- * for the signature.  If $assoc_handle is not specified, a private association
- * is created
- * @return array the signed OpenID response
- *
- */
-function simpleid_sign(&$response, $assoc_handle = NULL) {
-    global $version;
-
-    if (!$assoc_handle) {
-        $assoc = _simpleid_create_association(ASSOCIATION_PRIVATE);
-        $response['openid.assoc_handle'] = $assoc['assoc_handle'];
-    } else {
-        $assoc = cache_get('association', $assoc_handle);
-
-        if (!is_array($assoc) || ($assoc['created'] + SIMPLEID_ASSOC_EXPIRES_IN < time())) {
-            // Association has expired, need to create a new one
-            log_notice('Association handle ' . ($assoc['assoc_handle'] ?? '(none)') . ' expired.  Using stateless mode.');
-            $response['openid.invalidate_handle'] = $assoc_handle;
-            $assoc = _simpleid_create_association(ASSOCIATION_PRIVATE);
-            $response['openid.assoc_handle'] = $assoc['assoc_handle'];
-        }
-    }
-
-    // If we are using stateless mode, then we need to cache the response_nonce
-    // so that the RP can only verify once
-    if (isset($assoc['private']) && ($assoc['private'] == 1) && isset($response['openid.response_nonce'])) {
-        cache_set('stateless', $response['openid.response_nonce'], array(
-            'response_nonce' => $response['openid.response_nonce'],
-            'assoc_handle' => $response['openid.assoc_handle']));
-    }
-
-    // Get all the signed fields [10.1]
-    openid_parse_request($response); // Fill the namespace array
-    $signed_fields = array('op_endpoint', 'return_to', 'response_nonce', 'assoc_handle', 'identity', 'claimed_id');
-    $signed_fields = array_merge($signed_fields, extension_invoke_all('signed_fields', $response));
-
-    // Check if the signed keys are actually present
-    $to_sign = array();
-    foreach ($signed_fields as $field) {
-        if (isset($response['openid.' . $field])) $to_sign[] = $field;
-    }
-
-    $response['openid.signed'] = implode(',', $to_sign);
-
-    // Generate signature for this message
-    $mac_key = $assoc['mac_key'];
-    $assoc_types = openid_association_types();
-    $hmac_func = $assoc_types[$assoc['assoc_type']]['hmac_func'];
-
-    $response['openid.sig'] = openid_sign($response, $to_sign, $mac_key, $hmac_func, $version);
-
-    log_info('OpenID signed authentication response: ' . log_array($response));
-
-    return $response;
-}
-
-/**
- * Processes a direct verification request.  This is used in the OpenID specification
- * to verify signatures generated using stateless mode.
- *
- * @param array $request the OpenID request
- * @see http://openid.net/specs/openid-authentication-1_1.html#mode_check_authentication, http://openid.net/specs/openid-authentication-2_0.html#verifying_signatures
- */
-function simpleid_check_authentication($request) {
-    global $version;
-
-    log_info('OpenID direct verification: ' . log_array($request));
-
-    $is_valid = simpleid_verify_signatures($request);
-
-    if ($is_valid) {
-        $response = array('is_valid' => 'true');
-    } else {
-        $response = array('is_valid' => 'false');
-    }
-
-    // RP wants to check whether a handle is invalid
-    if (isset($request['openid.invalidate_handle'])) {
-        $invalid_assoc = cache_get('association', $request['openid.invalidate_handle']);
-
-        if (!$invalid_assoc || ($invalid_assoc['created'] + SIMPLEID_ASSOC_EXPIRES_IN < time())) {
-            // Yes, it's invalid
-            $response['invalidate_handle'] = $request['openid.invalidate_handle'];
-        }
-    }
-
-    log_info('OpenID direct verification response: ' . log_array($response));
-
-    openid_direct_response(openid_direct_message($response, $version));
-}
-
-/**
- * Verifies the signature of a signed OpenID request/response.
- *
- * @param array $request the OpenID request/response
- * @return bool true if the signature is verified
- * @since 0.8
- */
-function simpleid_verify_signatures($request) {
-    global $version;
-
-    log_info('simpleid_verify_signatures');
-
-    $is_valid = TRUE;
-
-    $assoc = (isset($request['openid.assoc_handle'])) ? cache_get('association', $request['openid.assoc_handle']) : NULL;
-    $stateless = (isset($request['openid.response_nonce'])) ? cache_get('stateless', $request['openid.response_nonce']) : NULL;
-
-    if (!$assoc) {
-        log_notice('simpleid_verify_signatures: Association not found.');
-        $is_valid = FALSE;
-    } elseif (!$assoc['assoc_type']) {
-        log_error('simpleid_verify_signatures: Association does not contain valid assoc_type.');
-        $is_valid = FALSE;
-    } elseif (!isset($assoc['private']) || ($assoc['private'] != 1)) {
-        log_warn('simpleid_verify_signatures: Attempting to verify an association with a shared key.');
-        $is_valid = FALSE;
-    } elseif (!$stateless || ($stateless['assoc_handle'] != $request['openid.assoc_handle'])) {
-        log_warn('simpleid_verify_signatures: Attempting to verify a response_nonce more than once, or private association expired.');
-        $is_valid = FALSE;
-    } else {
-        $mac_key = $assoc['mac_key'];
-        $assoc_types = openid_association_types();
-        $hmac_func = $assoc_types[$assoc['assoc_type']]['hmac_func'];
-
-        $signed_keys = explode(',', $request['openid.signed']);
-        $signature = openid_sign($request, $signed_keys, $mac_key, $hmac_func, $version);
-        log_debug('***** Signature: ' . $signature);
-
-        if ($signature != $request['openid.sig']) {
-            log_warn('simpleid_verify_signatures: Signature supplied in request does not match the signatured generated.');
-            $is_valid = FALSE;
-        }
-
-        cache_delete('stateless', $request['openid.response_nonce']);
-    }
-
-    return $is_valid;
-}
-
-
-/**
- * Continues an OpenID authentication request.
- *
- * This function decodes an OpenID authentication request specified in the
- * s request parameter and feeds it to the
- * {@link simpleid_process_openid} function.  This allows SimpleID to preserve
- * the state of an OpenID request.
- */
-function simpleid_continue() {
-    global $GETPOST;
-
-    $request = unpickle($GETPOST['s']);
-    openid_parse_request($request);
-    simpleid_process_openid($request);
-}
-
-/**
- * Provides a form for user consent of an OpenID relying party, where the
- * {@link simpleid_checkid_identity()} function returns a CHECKID_APPROVAL_REQUIRED
- * or CHECKID_RETURN_TO_SUSPECT.
- *
- * Alternatively, provide a form for the user to rectify the situation where
- * {@link simpleid_checkid_identity()} function returns a CHECKID_IDENTITIES_NOT_MATCHING
- * or CHECKID_IDENTITY_NOT_EXIST
- *
- * @param array $request the original OpenID request
- * @param array $response the proposed OpenID response, subject to user
- * verification
- * @param int $reason either CHECKID_APPROVAL_REQUIRED, CHECKID_RETURN_TO_SUSPECT,
- * CHECKID_IDENTITIES_NOT_MATCHING or CHECKID_IDENTITY_NOT_EXIST
- */
-function simpleid_openid_consent_form($request, $response, $reason = CHECKID_APPROVAL_REQUIRED) {
-    global $user;
-    global $xtpl;
-    global $version;
-
-    $request_state = pickle($request);
-
-    user_header($request_state);
-
-    $realm = openid_get_realm($request, $version);
-
-    $xtpl->assign('token', get_form_token('rp'));
-    $xtpl->assign('state', pickle($response));
-    $xtpl->assign('realm', htmlspecialchars($realm, ENT_QUOTES, 'UTF-8'));
-
-    $xtpl->assign('cancel_button', t('Cancel'));
-
-    if ($response['openid.mode'] == 'cancel') {
-        $xtpl->assign('return_to', htmlspecialchars($request['openid.return_to'], ENT_QUOTES, 'UTF-8'));
-
-        $xtpl->assign('unable_label', t('Unable to log into <strong class="realm">@realm</strong>.', array('@realm' => $realm)));
-        $xtpl->assign('identity_not_matching_label', t('Your current identity does not match the requested identity %identity.', array('%identity' => $request['openid.identity'])));
-        $xtpl->assign('switch_user_label', t('<a href="!url">Switch to a different user</a> and try again.', array('!url' => simpleid_url('logout', 'destination=continue&s=' . rawurlencode($request_state), true))));
-
-        $xtpl->parse('main.openid_consent.cancel');
-    } else {
-        $xtpl->assign('javascript', '<script src="' . get_base_path() . 'html/openid-consent.js" type="text/javascript"></script>');
-
-        $rp = (isset($user['rp'][$realm])) ? $user['rp'][$realm] : NULL;
-
-        $extensions = extension_invoke_all('consent_form', $request, $response, $rp);
-        $xtpl->assign('extensions', implode($extensions));
-
-        if ($reason == CHECKID_RETURN_TO_SUSPECT) {
-            $xtpl->assign('suspect_label', t('Warning: This web site has not confirmed its identity and might be fraudulent.  Do not share any personal information with this web site unless you are sure it is legitimate. See the <a href="!url" class="popup">SimpleID documentation for details</a> (OpenID version 2.0 return_to discovery failure)',
-                array('!url' => 'http://simpleid.org/docs/1/return_to/')));
-
-            $xtpl->parse('main.openid_consent.setup.suspect');
-            $xtpl->assign('realm_class', 'return-to-suspect');
-        }
-
-        $xtpl->assign('realm_label', t('You are being logged into <strong class="realm">@realm</strong>.', array('@realm' => $realm)));
-        $xtpl->assign('auto_release_label', t('Automatically send my information to this site for any future requests.'));
-        $xtpl->assign('ok_button', t('OK'));
-
-        $xtpl->parse('main.openid_consent.setup');
-    }
-
-    $xtpl->parse('main.openid_consent');
-
-    $xtpl->assign(array('js_locale_label' => 'openid_suspect', 'js_locale_text' => addslashes(t('This web site has not confirmed its identity and might be fraudulent.')) . '\n\n' . addslashes(t('Are you sure you wish to automatically send your information to this site for any future requests?'))));
-    $xtpl->parse('main.js_locale');
-
-    $xtpl->parse('main.framekiller');
-
-    header('X-Frame-Options: DENY');
-
-    $xtpl->assign('title', t('OpenID Login'));
-    $xtpl->assign('page_class', 'dialog-page');
-    $xtpl->parse('main');
-
-    $xtpl->out('main');
-}
-
-
-/**
- * Processes a user response from the {@link simpleid_openid_consent_form()} function.
- *
- * If the user verifies the relying party, an OpenID response will be sent to
- * the relying party.  Otherwise, the dashboard will be displayed to the user.
- *
- */
-function simpleid_openid_consent() {
-    global $xtpl, $user, $version, $GETPOST;
-
-    if ($user == NULL) {
-        user_login_form('');
-        return;
-    }
-
-    if (!validate_form_token($GETPOST['tk'], 'rp')) {
-        set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-        $xtpl->assign('title', t('OpenID Login'));
-        $xtpl->parse('main');
-        $xtpl->out('main');
-        return;
-    }
-
-    $uid = $user['uid'];
-
-    $response = unpickle($GETPOST['s']);
-    $version = openid_get_version($response);
-    openid_parse_request($response);
-    $return_to = $response['openid.return_to'];
-    if (!$return_to) $return_to = $GETPOST['openid.return_to'];
-
-    if ($GETPOST['op'] == t('Cancel')) {
-        $response = simpleid_checkid_error(false);
-        if (!$return_to) set_message(t('Log in cancelled.'));
-    } else {
-        $now = time();
-        $realm = $GETPOST['openid.realm'];
-
-        if (isset($user['rp'][$realm])) {
-            $rp = $user['rp'][$realm];
-        } else {
-            $rp = array('realm' => $realm, 'first_time' => $now);
-        }
-        $rp['last_time'] = $now;
-        $rp['auto_release'] = (isset($GETPOST['autorelease']) && $GETPOST['autorelease']) ? 1 : 0;
-
-        // Mimic extension_invoke_all, but allow for passing by reference {{
-        global $simpleid_extensions;
-
-        foreach ($simpleid_extensions as $extension) {
-            $consent_function = $extension . '_consent';
-            if (function_exists($consent_function)) {
-                $consent_function($GETPOST, $response, $rp);
-            }
-        }
-        // }}
-
-        $user['rp'][$realm] = $rp;
-        user_save($user);
-
-        $response = simpleid_sign($response, isset($response['openid.assoc_handle']) ? $response['openid.assoc_handle'] : NULL);
-        if (!$return_to) set_message(t('You were logged in successfully.'));
-    }
-
-    if ($return_to) {
-        simpleid_assertion_response($response, $return_to);
-    } else {
-        page_dashboard();
-    }
-}
-
-/**
- * Sends an OpenID assertion response.
- *
- * The OpenID specification version 2.0 provides for the sending of assertions
- * via indirect communication.  However, future versions of the OpenID
- * specification may provide for sending of assertions via direct communication.
- *
- * @param array $response the signed OpenID assertion response to send
- * @param string $indirect_url the URL to which the OpenID response is sent.  If
- * this is an empty string, the response is sent via direct communication
- */
-function simpleid_assertion_response($response, $indirect_url = NULL) {
-    global $xtpl, $version;
-
-    if ($indirect_url) {
-        // We want to see if the extensions want to change the way indirect responses are made
-        $results = extension_invoke_all('indirect_response', $indirect_url, $response);
-        $results = array_filter($results, 'is_null');
-        $component = ($results) ? max($results) : OPENID_RESPONSE_QUERY;
-
-        openid_indirect_response($indirect_url, $response, $component);
-    } else {
-        openid_direct_response(openid_direct_message($response, $version));
-    }
-}
-
-/**
- * Displays the XRDS document for this SimpleID installation.
- *
- */
-function simpleid_xrds() {
-    global $xtpl;
-
-    log_debug('Providing XRDS.');
-
-    header('Content-Type: application/xrds+xml');
-    header('Content-Disposition: inline; filename=yadis.xml');
-
-    $types = extension_invoke_all('xrds_types');
-    foreach ($types as $type) {
-        $xtpl->assign('uri', htmlspecialchars($type, ENT_QUOTES, 'UTF-8'));
-        $xtpl->parse('xrds.op_xrds.type');
-    }
-
-    $xtpl->assign('simpleid_base_url', htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8'), false, 'detect');
-    $xtpl->parse('xrds.op_xrds');
-    $xtpl->parse('xrds');
-    $xtpl->out('xrds');
-}
-
-
-?>
diff --git a/simpleid/www/lib/gettext/gettext.inc.php b/simpleid/www/lib/gettext/gettext.inc.php
deleted file mode 100644
index 00b9666..0000000
--- a/simpleid/www/lib/gettext/gettext.inc.php
+++ /dev/null
@@ -1,536 +0,0 @@
-<?php
-/*
-   Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
-   Copyright (c) 2009 Danilo Segan <danilo@kvota.net>
-
-   Drop in replacement for native gettext.
-
-   This file is part of PHP-gettext.
-
-   PHP-gettext 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.
-
-   PHP-gettext 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 PHP-gettext; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-/*
-LC_CTYPE        0
-LC_NUMERIC      1
-LC_TIME         2
-LC_COLLATE      3
-LC_MONETARY     4
-LC_MESSAGES     5
-LC_ALL          6
-*/
-
-// LC_MESSAGES is not available if php-gettext is not loaded
-// while the other constants are already available from session extension.
-if (!defined('LC_MESSAGES')) {
-  define('LC_MESSAGES',	5);
-}
-
-require('streams.php');
-require('gettext.php');
-
-
-// Variables
-
-global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE;
-$text_domains = array();
-$default_domain = 'messages';
-$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL');
-$EMULATEGETTEXT = 0;
-$CURRENTLOCALE = '';
-
-/* Class to hold a single domain included in $text_domains. */
-class domain {
-  var $l10n;
-  var $path;
-  var $codeset;
-}
-
-// Utility functions
-
-/**
- * Return a list of locales to try for any POSIX-style locale specification.
- */
-function get_list_of_locales($locale) {
-  /* Figure out all possible locale names and start with the most
-   * specific ones.  I.e. for sr_CS.UTF-8@latin, look through all of
-   * sr_CS.UTF-8@latin, sr_CS@latin, sr@latin, sr_CS.UTF-8, sr_CS, sr.
-   */
-  $locale_names = array();
-  $lang = NULL;
-  $country = NULL;
-  $charset = NULL;
-  $modifier = NULL;
-  if ($locale) {
-    if (preg_match("/^(?P<lang>[a-z]{2,3})"              // language code
-                   ."(?:_(?P<country>[A-Z]{2}))?"           // country code
-                   ."(?:\.(?P<charset>[-A-Za-z0-9_]+))?"    // charset
-                   ."(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/",  // @ modifier
-                   $locale, $matches)) {
-
-      if (isset($matches["lang"])) $lang = $matches["lang"];
-      if (isset($matches["country"])) $country = $matches["country"];
-      if (isset($matches["charset"])) $charset = $matches["charset"];
-      if (isset($matches["modifier"])) $modifier = $matches["modifier"];
-
-      if ($modifier) {
-        if ($country) {
-          if ($charset)
-            array_push($locale_names, "${lang}_$country.$charset@$modifier");
-          array_push($locale_names, "${lang}_$country@$modifier");
-        } elseif ($charset)
-            array_push($locale_names, "${lang}.$charset@$modifier");
-        array_push($locale_names, "$lang@$modifier");
-      }
-      if ($country) {
-        if ($charset)
-          array_push($locale_names, "${lang}_$country.$charset");
-        array_push($locale_names, "${lang}_$country");
-      } elseif ($charset)
-          array_push($locale_names, "${lang}.$charset");
-      array_push($locale_names, $lang);
-    }
-
-    // If the locale name doesn't match POSIX style, just include it as-is.
-    if (!in_array($locale, $locale_names))
-      array_push($locale_names, $locale);
-  }
-  return $locale_names;
-}
-
-/**
- * Utility function to get a StreamReader for the given text domain.
- */
-function _get_reader($domain=null, $category=5, $enable_cache=true) {
-    global $text_domains, $default_domain, $LC_CATEGORIES;
-    if (!isset($domain)) $domain = $default_domain;
-    if (!isset($text_domains[$domain]->l10n)) {
-        // get the current locale
-        $locale = _setlocale(LC_MESSAGES, 0);
-        $bound_path = isset($text_domains[$domain]->path) ?
-          $text_domains[$domain]->path : './';
-        $subpath = $LC_CATEGORIES[$category] ."/$domain.mo";
-
-        $locale_names = get_list_of_locales($locale);
-        $input = null;
-        foreach ($locale_names as $locale) {
-          $full_path = $bound_path . $locale . "/" . $subpath;
-          if (file_exists($full_path)) {
-            $input = new FileReader($full_path);
-            break;
-          }
-        }
-
-        if (!array_key_exists($domain, $text_domains)) {
-          // Initialize an empty domain object.
-          $text_domains[$domain] = new domain();
-        }
-        $text_domains[$domain]->l10n = new gettext_reader($input,
-                                                          $enable_cache);
-    }
-    return $text_domains[$domain]->l10n;
-}
-
-/**
- * Returns whether we are using our emulated gettext API or PHP built-in one.
- */
-function locale_emulation() {
-    global $EMULATEGETTEXT;
-    return $EMULATEGETTEXT;
-}
-
-/**
- * Checks if the current locale is supported on this system.
- */
-function _check_locale_and_function($function=false) {
-    global $EMULATEGETTEXT;
-    if ($function and !function_exists($function))
-        return false;
-    return !$EMULATEGETTEXT;
-}
-
-/**
- * Get the codeset for the given domain.
- */
-function _get_codeset($domain=null) {
-    global $text_domains, $default_domain, $LC_CATEGORIES;
-    if (!isset($domain)) $domain = $default_domain;
-    return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
-}
-
-/**
- * Convert the given string to the encoding set by bind_textdomain_codeset.
- */
-function _encode($text) {
-    $source_encoding = mb_detect_encoding($text);
-    $target_encoding = _get_codeset();
-    if ($source_encoding != $target_encoding) {
-        return mb_convert_encoding($text, $target_encoding, $source_encoding);
-    }
-    else {
-        return $text;
-    }
-}
-
-
-// Custom implementation of the standard gettext related functions
-
-/**
- * Returns passed in $locale, or environment variable $LANG if $locale == ''.
- */
-function _get_default_locale($locale) {
-  if ($locale == '') // emulate variable support
-    return getenv('LANG');
-  else
-    return $locale;
-}
-
-/**
- * Sets a requested locale, if needed emulates it.
- */
-function _setlocale($category, $locale) {
-    global $CURRENTLOCALE, $EMULATEGETTEXT;
-    if ($locale === 0) { // use === to differentiate between string "0"
-        if ($CURRENTLOCALE != '')
-            return $CURRENTLOCALE;
-        else
-            // obey LANG variable, maybe extend to support all of LC_* vars
-            // even if we tried to read locale without setting it first
-            return _setlocale($category, $CURRENTLOCALE);
-    } else {
-        if (function_exists('setlocale')) {
-          $ret = setlocale($category, $locale);
-          if (($locale == '' and !$ret) or // failed setting it by env
-              ($locale != '' and $ret != $locale)) { // failed setting it
-            // Failed setting it according to environment.
-            $CURRENTLOCALE = _get_default_locale($locale);
-            $EMULATEGETTEXT = 1;
-          } else {
-            $CURRENTLOCALE = $ret;
-            $EMULATEGETTEXT = 0;
-          }
-        } else {
-          // No function setlocale(), emulate it all.
-          $CURRENTLOCALE = _get_default_locale($locale);
-          $EMULATEGETTEXT = 1;
-        }
-        // Allow locale to be changed on the go for one translation domain.
-        global $text_domains, $default_domain;
-        if (array_key_exists($default_domain, $text_domains)) {
-            unset($text_domains[$default_domain]->l10n);
-        }
-        return $CURRENTLOCALE;
-    }
-}
-
-/**
- * Sets the path for a domain.
- */
-function _bindtextdomain($domain, $path) {
-    global $text_domains;
-    // ensure $path ends with a slash ('/' should work for both, but lets still play nice)
-    if (substr(php_uname(), 0, 7) == "Windows") {
-      if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/')
-        $path .= '\\';
-    } else {
-      if ($path[strlen($path)-1] != '/')
-        $path .= '/';
-    }
-    if (!array_key_exists($domain, $text_domains)) {
-      // Initialize an empty domain object.
-      $text_domains[$domain] = new domain();
-    }
-    $text_domains[$domain]->path = $path;
-}
-
-/**
- * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
- */
-function _bind_textdomain_codeset($domain, $codeset) {
-    global $text_domains;
-    $text_domains[$domain]->codeset = $codeset;
-}
-
-/**
- * Sets the default domain.
- */
-function _textdomain($domain) {
-    global $default_domain;
-    $default_domain = $domain;
-}
-
-/**
- * Lookup a message in the current domain.
- */
-function _gettext($msgid) {
-    $l10n = _get_reader();
-    return _encode($l10n->translate($msgid));
-}
-
-/**
- * Alias for gettext.
- */
-function __($msgid) {
-    return _gettext($msgid);
-}
-
-/**
- * Plural version of gettext.
- */
-function _ngettext($singular, $plural, $number) {
-    $l10n = _get_reader();
-    return _encode($l10n->ngettext($singular, $plural, $number));
-}
-
-/**
- * Override the current domain.
- */
-function _dgettext($domain, $msgid) {
-    $l10n = _get_reader($domain);
-    return _encode($l10n->translate($msgid));
-}
-
-/**
- * Plural version of dgettext.
- */
-function _dngettext($domain, $singular, $plural, $number) {
-    $l10n = _get_reader($domain);
-    return _encode($l10n->ngettext($singular, $plural, $number));
-}
-
-/**
- * Overrides the domain and category for a single lookup.
- */
-function _dcgettext($domain, $msgid, $category) {
-    $l10n = _get_reader($domain, $category);
-    return _encode($l10n->translate($msgid));
-}
-/**
- * Plural version of dcgettext.
- */
-function _dcngettext($domain, $singular, $plural, $number, $category) {
-    $l10n = _get_reader($domain, $category);
-    return _encode($l10n->ngettext($singular, $plural, $number));
-}
-
-/**
- * Context version of gettext.
- */
-function _pgettext($context, $msgid) {
-    $l10n = _get_reader();
-    return _encode($l10n->pgettext($context, $msgid));
-}
-
-/**
- * Override the current domain in a context gettext call.
- */
-function _dpgettext($domain, $context, $msgid) {
-    $l10n = _get_reader($domain);
-    return _encode($l10n->pgettext($context, $msgid));
-}
-
-/**
- * Overrides the domain and category for a single context-based lookup.
- */
-function _dcpgettext($domain, $context, $msgid, $category) {
-    $l10n = _get_reader($domain, $category);
-    return _encode($l10n->pgettext($context, $msgid));
-}
-
-/**
- * Context version of ngettext.
- */
-function _npgettext($context, $singular, $plural) {
-    $l10n = _get_reader();
-    return _encode($l10n->npgettext($context, $singular, $plural));
-}
-
-/**
- * Override the current domain in a context ngettext call.
- */
-function _dnpgettext($domain, $context, $singular, $plural) {
-    $l10n = _get_reader($domain);
-    return _encode($l10n->npgettext($context, $singular, $plural));
-}
-
-/**
- * Overrides the domain and category for a plural context-based lookup.
- */
-function _dcnpgettext($domain, $context, $singular, $plural, $category) {
-    $l10n = _get_reader($domain, $category);
-    return _encode($l10n->npgettext($context, $singular, $plural));
-}
-
-
-
-// Wrappers to use if the standard gettext functions are available,
-// but the current locale is not supported by the system.
-// Use the standard impl if the current locale is supported, use the
-// custom impl otherwise.
-
-function T_setlocale($category, $locale) {
-    return _setlocale($category, $locale);
-}
-
-function T_bindtextdomain($domain, $path) {
-    if (_check_locale_and_function()) return bindtextdomain($domain, $path);
-    else return _bindtextdomain($domain, $path);
-}
-function T_bind_textdomain_codeset($domain, $codeset) {
-    // bind_textdomain_codeset is available only in PHP 4.2.0+
-    if (_check_locale_and_function('bind_textdomain_codeset'))
-        return bind_textdomain_codeset($domain, $codeset);
-    else return _bind_textdomain_codeset($domain, $codeset);
-}
-function T_textdomain($domain) {
-    if (_check_locale_and_function()) return textdomain($domain);
-    else return _textdomain($domain);
-}
-function T_gettext($msgid) {
-    if (_check_locale_and_function()) return gettext($msgid);
-    else return _gettext($msgid);
-}
-function T_($msgid) {
-    if (_check_locale_and_function()) return _($msgid);
-    return __($msgid);
-}
-function T_ngettext($singular, $plural, $number) {
-    if (_check_locale_and_function())
-        return ngettext($singular, $plural, $number);
-    else return _ngettext($singular, $plural, $number);
-}
-function T_dgettext($domain, $msgid) {
-    if (_check_locale_and_function()) return dgettext($domain, $msgid);
-    else return _dgettext($domain, $msgid);
-}
-function T_dngettext($domain, $singular, $plural, $number) {
-    if (_check_locale_and_function())
-        return dngettext($domain, $singular, $plural, $number);
-    else return _dngettext($domain, $singular, $plural, $number);
-}
-function T_dcgettext($domain, $msgid, $category) {
-    if (_check_locale_and_function())
-        return dcgettext($domain, $msgid, $category);
-    else return _dcgettext($domain, $msgid, $category);
-}
-function T_dcngettext($domain, $singular, $plural, $number, $category) {
-    if (_check_locale_and_function())
-      return dcngettext($domain, $singular, $plural, $number, $category);
-    else return _dcngettext($domain, $singular, $plural, $number, $category);
-}
-
-function T_pgettext($context, $msgid) {
-  if (_check_locale_and_function('pgettext'))
-      return pgettext($context, $msgid);
-  else
-      return _pgettext($context, $msgid);
-}
-
-function T_dpgettext($domain, $context, $msgid) {
-  if (_check_locale_and_function('dpgettext'))
-      return dpgettext($domain, $context, $msgid);
-  else
-      return _dpgettext($domain, $context, $msgid);
-}
-
-function T_dcpgettext($domain, $context, $msgid, $category) {
-  if (_check_locale_and_function('dcpgettext'))
-      return dcpgettext($domain, $context, $msgid, $category);
-  else
-      return _dcpgettext($domain, $context, $msgid, $category);
-}
-
-function T_npgettext($context, $singular, $plural, $number) {
-    if (_check_locale_and_function('npgettext'))
-        return npgettext($context, $singular, $plural, $number);
-    else
-        return _npgettext($context, $singular, $plural, $number);
-}
-
-function T_dnpgettext($domain, $context, $singular, $plural, $number) {
-  if (_check_locale_and_function('dnpgettext'))
-      return dnpgettext($domain, $context, $singular, $plural, $number);
-  else
-      return _dnpgettext($domain, $context, $singular, $plural, $number);
-}
-
-function T_dcnpgettext($domain, $context, $singular, $plural,
-                       $number, $category) {
-    if (_check_locale_and_function('dcnpgettext'))
-        return dcnpgettext($domain, $context, $singular,
-                           $plural, $number, $category);
-    else
-        return _dcnpgettext($domain, $context, $singular,
-                            $plural, $number, $category);
-}
-
-
-
-// Wrappers used as a drop in replacement for the standard gettext functions
-
-if (!function_exists('gettext')) {
-    function bindtextdomain($domain, $path) {
-        return _bindtextdomain($domain, $path);
-    }
-    function bind_textdomain_codeset($domain, $codeset) {
-        return _bind_textdomain_codeset($domain, $codeset);
-    }
-    function textdomain($domain) {
-        return _textdomain($domain);
-    }
-    function gettext($msgid) {
-        return _gettext($msgid);
-    }
-    function _($msgid) {
-        return __($msgid);
-    }
-    function ngettext($singular, $plural, $number) {
-        return _ngettext($singular, $plural, $number);
-    }
-    function dgettext($domain, $msgid) {
-        return _dgettext($domain, $msgid);
-    }
-    function dngettext($domain, $singular, $plural, $number) {
-        return _dngettext($domain, $singular, $plural, $number);
-    }
-    function dcgettext($domain, $msgid, $category) {
-        return _dcgettext($domain, $msgid, $category);
-    }
-    function dcngettext($domain, $singular, $plural, $number, $category) {
-        return _dcngettext($domain, $singular, $plural, $number, $category);
-    }
-    function pgettext($context, $msgid) {
-        return _pgettext($context, $msgid);
-    }
-    function npgettext($context, $singular, $plural, $number) {
-        return _npgettext($context, $singular, $plural, $number);
-    }
-    function dpgettext($domain, $context, $msgid) {
-        return _dpgettext($domain, $context, $msgid);
-    }
-    function dnpgettext($domain, $context, $singular, $plural, $number) {
-        return _dnpgettext($domain, $context, $singular, $plural, $number);
-    }
-    function dcpgettext($domain, $context, $msgid, $category) {
-        return _dcpgettext($domain, $context, $msgid, $category);
-    }
-    function dcnpgettext($domain, $context, $singular, $plural,
-                         $number, $category) {
-      return _dcnpgettext($domain, $context, $singular, $plural,
-                          $number, $category);
-    }
-}
-
-?>
diff --git a/simpleid/www/lib/gettext/gettext.php b/simpleid/www/lib/gettext/gettext.php
deleted file mode 100644
index 81af555..0000000
--- a/simpleid/www/lib/gettext/gettext.php
+++ /dev/null
@@ -1,432 +0,0 @@
-<?php
-/*
-   Copyright (c) 2003, 2009 Danilo Segan <danilo@kvota.net>.
-   Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
-
-   This file is part of PHP-gettext.
-
-   PHP-gettext 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.
-
-   PHP-gettext 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 PHP-gettext; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/**
- * Provides a simple gettext replacement that works independently from
- * the system's gettext abilities.
- * It can read MO files and use them for translating strings.
- * The files are passed to gettext_reader as a Stream (see streams.php)
- *
- * This version has the ability to cache all strings and translations to
- * speed up the string lookup.
- * While the cache is enabled by default, it can be switched off with the
- * second parameter in the constructor (e.g. whenusing very large MO files
- * that you don't want to keep in memory)
- */
-class gettext_reader {
-  //public:
-   var $error = 0; // public variable that holds error code (0 if no error)
-
-   //private:
-  var $BYTEORDER = 0;        // 0: low endian, 1: big endian
-  var $STREAM = NULL;
-  var $short_circuit = false;
-  var $enable_cache = false;
-  var $originals = NULL;      // offset of original table
-  var $translations = NULL;    // offset of translation table
-  var $pluralheader = NULL;    // cache header field for plural forms
-  var $total = 0;          // total string count
-  var $table_originals = NULL;  // table for original strings (offsets)
-  var $table_translations = NULL;  // table for translated strings (offsets)
-  var $cache_translations = NULL;  // original -> translation mapping
-
-
-  /* Methods */
-
-
-  /**
-   * Reads a 32bit Integer from the Stream
-   *
-   * @access private
-   * @return Integer from the Stream
-   */
-  function readint() {
-      if ($this->BYTEORDER == 0) {
-        // low endian
-        $input=unpack('V', $this->STREAM->read(4));
-        return array_shift($input);
-      } else {
-        // big endian
-        $input=unpack('N', $this->STREAM->read(4));
-        return array_shift($input);
-      }
-    }
-
-  function read($bytes) {
-    return $this->STREAM->read($bytes);
-  }
-
-  /**
-   * Reads an array of Integers from the Stream
-   *
-   * @param int count How many elements should be read
-   * @return Array of Integers
-   */
-  function readintarray($count) {
-    if ($this->BYTEORDER == 0) {
-        // low endian
-        return unpack('V'.$count, $this->STREAM->read(4 * $count));
-      } else {
-        // big endian
-        return unpack('N'.$count, $this->STREAM->read(4 * $count));
-      }
-  }
-
-  /**
-   * Constructor
-   *
-   * @param object Reader the StreamReader object
-   * @param boolean enable_cache Enable or disable caching of strings (default on)
-   */
-  function __construct($Reader, $enable_cache = true) {
-    // If there isn't a StreamReader, turn on short circuit mode.
-    if (! $Reader || isset($Reader->error) ) {
-      $this->short_circuit = true;
-      return;
-    }
-
-    // Caching can be turned off
-    $this->enable_cache = $enable_cache;
-
-    $MAGIC1 = "\x95\x04\x12\xde";
-    $MAGIC2 = "\xde\x12\x04\x95";
-
-    $this->STREAM = $Reader;
-    $magic = $this->read(4);
-    if ($magic == $MAGIC1) {
-      $this->BYTEORDER = 1;
-    } elseif ($magic == $MAGIC2) {
-      $this->BYTEORDER = 0;
-    } else {
-      $this->error = 1; // not MO file
-      return false;
-    }
-
-    // FIXME: Do we care about revision? We should.
-    $revision = $this->readint();
-
-    $this->total = $this->readint();
-    $this->originals = $this->readint();
-    $this->translations = $this->readint();
-  }
-
-  /**
-   * Loads the translation tables from the MO file into the cache
-   * If caching is enabled, also loads all strings into a cache
-   * to speed up translation lookups
-   *
-   * @access private
-   */
-  function load_tables() {
-    if (is_array($this->cache_translations) &&
-      is_array($this->table_originals) &&
-      is_array($this->table_translations))
-      return;
-
-    /* get original and translations tables */
-    if (!is_array($this->table_originals)) {
-      $this->STREAM->seekto($this->originals);
-      $this->table_originals = $this->readintarray($this->total * 2);
-    }
-    if (!is_array($this->table_translations)) {
-      $this->STREAM->seekto($this->translations);
-      $this->table_translations = $this->readintarray($this->total * 2);
-    }
-
-    if ($this->enable_cache) {
-      $this->cache_translations = array ();
-      /* read all strings in the cache */
-      for ($i = 0; $i < $this->total; $i++) {
-        $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
-        $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
-        $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
-        $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
-        $this->cache_translations[$original] = $translation;
-      }
-    }
-  }
-
-  /**
-   * Returns a string from the "originals" table
-   *
-   * @access private
-   * @param int num Offset number of original string
-   * @return string Requested string if found, otherwise ''
-   */
-  function get_original_string($num) {
-    $length = $this->table_originals[$num * 2 + 1];
-    $offset = $this->table_originals[$num * 2 + 2];
-    if (! $length)
-      return '';
-    $this->STREAM->seekto($offset);
-    $data = $this->STREAM->read($length);
-    return (string)$data;
-  }
-
-  /**
-   * Returns a string from the "translations" table
-   *
-   * @access private
-   * @param int num Offset number of original string
-   * @return string Requested string if found, otherwise ''
-   */
-  function get_translation_string($num) {
-    $length = $this->table_translations[$num * 2 + 1];
-    $offset = $this->table_translations[$num * 2 + 2];
-    if (! $length)
-      return '';
-    $this->STREAM->seekto($offset);
-    $data = $this->STREAM->read($length);
-    return (string)$data;
-  }
-
-  /**
-   * Binary search for string
-   *
-   * @access private
-   * @param string string
-   * @param int start (internally used in recursive function)
-   * @param int end (internally used in recursive function)
-   * @return int string number (offset in originals table)
-   */
-  function find_string($string, $start = -1, $end = -1) {
-    if (($start == -1) or ($end == -1)) {
-      // find_string is called with only one parameter, set start end end
-      $start = 0;
-      $end = $this->total;
-    }
-    if (abs($start - $end) <= 1) {
-      // We're done, now we either found the string, or it doesn't exist
-      $txt = $this->get_original_string($start);
-      if ($string == $txt)
-        return $start;
-      else
-        return -1;
-    } else if ($start > $end) {
-      // start > end -> turn around and start over
-      return $this->find_string($string, $end, $start);
-    } else {
-      // Divide table in two parts
-      $half = (int)(($start + $end) / 2);
-      $cmp = strcmp($string, $this->get_original_string($half));
-      if ($cmp == 0)
-        // string is exactly in the middle => return it
-        return $half;
-      else if ($cmp < 0)
-        // The string is in the upper half
-        return $this->find_string($string, $start, $half);
-      else
-        // The string is in the lower half
-        return $this->find_string($string, $half, $end);
-    }
-  }
-
-  /**
-   * Translates a string
-   *
-   * @access public
-   * @param string string to be translated
-   * @return string translated string (or original, if not found)
-   */
-  function translate($string) {
-    if ($this->short_circuit)
-      return $string;
-    $this->load_tables();
-
-    if ($this->enable_cache) {
-      // Caching enabled, get translated string from cache
-      if (array_key_exists($string, $this->cache_translations))
-        return $this->cache_translations[$string];
-      else
-        return $string;
-    } else {
-      // Caching not enabled, try to find string
-      $num = $this->find_string($string);
-      if ($num == -1)
-        return $string;
-      else
-        return $this->get_translation_string($num);
-    }
-  }
-
-  /**
-   * Sanitize plural form expression for use in PHP eval call.
-   *
-   * @access private
-   * @return string sanitized plural form expression
-   */
-  function sanitize_plural_expression($expr) {
-    // Get rid of disallowed characters.
-    $expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);
-
-    // Add parenthesis for tertiary '?' operator.
-    $expr .= ';';
-    $res = '';
-    $p = 0;
-    for ($i = 0; $i < strlen($expr); $i++) {
-      $ch = $expr[$i];
-      switch ($ch) {
-      case '?':
-        $res .= ' ? (';
-        $p++;
-        break;
-      case ':':
-        $res .= ') : (';
-        break;
-      case ';':
-        $res .= str_repeat( ')', $p) . ';';
-        $p = 0;
-        break;
-      default:
-        $res .= $ch;
-      }
-    }
-    return $res;
-  }
-
-  /**
-   * Parse full PO header and extract only plural forms line.
-   *
-   * @access private
-   * @return string verbatim plural form header field
-   */
-  function extract_plural_forms_header_from_po_header($header) {
-    if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs))
-      $expr = $regs[2];
-    else
-      $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
-    return $expr;
-  }
-
-  /**
-   * Get possible plural forms from MO header
-   *
-   * @access private
-   * @return string plural form header
-   */
-  function get_plural_forms() {
-    // lets assume message number 0 is header
-    // this is true, right?
-    $this->load_tables();
-
-    // cache header field for plural forms
-    if (! is_string($this->pluralheader)) {
-      if ($this->enable_cache) {
-        $header = $this->cache_translations[""];
-      } else {
-        $header = $this->get_translation_string(0);
-      }
-      $expr = $this->extract_plural_forms_header_from_po_header($header);
-      $this->pluralheader = $this->sanitize_plural_expression($expr);
-    }
-    return $this->pluralheader;
-  }
-
-  /**
-   * Detects which plural form to take
-   *
-   * @access private
-   * @param n count
-   * @return int array index of the right plural form
-   */
-  function select_string($n) {
-    $string = $this->get_plural_forms();
-    $string = str_replace('nplurals',"\$total",$string);
-    $string = str_replace("n",$n,$string);
-    $string = str_replace('plural',"\$plural",$string);
-
-    $total = 0;
-    $plural = 0;
-
-    eval("$string");
-    if ($plural >= $total) $plural = $total - 1;
-    return $plural;
-  }
-
-  /**
-   * Plural version of gettext
-   *
-   * @access public
-   * @param string single
-   * @param string plural
-   * @param string number
-   * @return translated plural form
-   */
-  function ngettext($single, $plural, $number) {
-    if ($this->short_circuit) {
-      if ($number != 1)
-        return $plural;
-      else
-        return $single;
-    }
-
-    // find out the appropriate form
-    $select = $this->select_string($number);
-
-    // this should contains all strings separated by NULLs
-    $key = $single . chr(0) . $plural;
-
-
-    if ($this->enable_cache) {
-      if (! array_key_exists($key, $this->cache_translations)) {
-        return ($number != 1) ? $plural : $single;
-      } else {
-        $result = $this->cache_translations[$key];
-        $list = explode(chr(0), $result);
-        return $list[$select];
-      }
-    } else {
-      $num = $this->find_string($key);
-      if ($num == -1) {
-        return ($number != 1) ? $plural : $single;
-      } else {
-        $result = $this->get_translation_string($num);
-        $list = explode(chr(0), $result);
-        return $list[$select];
-      }
-    }
-  }
-
-  function pgettext($context, $msgid) {
-    $key = $context . chr(4) . $msgid;
-    $ret = $this->translate($key);
-    if (strpos($ret, "\004") !== FALSE) {
-      return $msgid;
-    } else {
-      return $ret;
-    }
-  }
-
-  function npgettext($context, $singular, $plural, $number) {
-    $key = $context . chr(4) . $singular;
-    $ret = $this->ngettext($key, $plural, $number);
-    if (strpos($ret, "\004") !== FALSE) {
-      return $singular;
-    } else {
-      return $ret;
-    }
-
-  }
-}
-
-?>
diff --git a/simpleid/www/lib/gettext/streams.php b/simpleid/www/lib/gettext/streams.php
deleted file mode 100644
index 00cf6cc..0000000
--- a/simpleid/www/lib/gettext/streams.php
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-/*
-   Copyright (c) 2003, 2005, 2006, 2009 Danilo Segan <danilo@kvota.net>.
-
-   This file is part of PHP-gettext.
-
-   PHP-gettext 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.
-
-   PHP-gettext 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 PHP-gettext; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-
-  // Simple class to wrap file streams, string streams, etc.
-  // seek is essential, and it should be byte stream
-class StreamReader {
-  // should return a string [FIXME: perhaps return array of bytes?]
-  function read($bytes) {
-    return false;
-  }
-
-  // should return new position
-  function seekto($position) {
-    return false;
-  }
-
-  // returns current position
-  function currentpos() {
-    return false;
-  }
-
-  // returns length of entire stream (limit for seekto()s)
-  function length() {
-    return false;
-  }
-};
-
-class StringReader {
-  var $_pos;
-  var $_str;
-
-  function __construct($str='') {
-    $this->_str = $str;
-    $this->_pos = 0;
-  }
-
-  function read($bytes) {
-    $data = substr($this->_str, $this->_pos, $bytes);
-    $this->_pos += $bytes;
-    if (strlen($this->_str)<$this->_pos)
-      $this->_pos = strlen($this->_str);
-
-    return $data;
-  }
-
-  function seekto($pos) {
-    $this->_pos = $pos;
-    if (strlen($this->_str)<$this->_pos)
-      $this->_pos = strlen($this->_str);
-    return $this->_pos;
-  }
-
-  function currentpos() {
-    return $this->_pos;
-  }
-
-  function length() {
-    return strlen($this->_str);
-  }
-
-};
-
-
-class FileReader {
-  var $_pos;
-  var $_fd;
-  var $_length;
-
-  function __construct($filename) {
-    if (file_exists($filename)) {
-
-      $this->_length=filesize($filename);
-      $this->_pos = 0;
-      $this->_fd = fopen($filename,'rb');
-      if (!$this->_fd) {
-        $this->error = 3; // Cannot read file, probably permissions
-        return false;
-      }
-    } else {
-      $this->error = 2; // File doesn't exist
-      return false;
-    }
-  }
-
-  function read($bytes) {
-    if ($bytes) {
-      fseek($this->_fd, $this->_pos);
-
-      // PHP 5.1.1 does not read more than 8192 bytes in one fread()
-      // the discussions at PHP Bugs suggest it's the intended behaviour
-      $data = '';
-      while ($bytes > 0) {
-        $chunk  = fread($this->_fd, $bytes);
-        $data  .= $chunk;
-        $bytes -= strlen($chunk);
-      }
-      $this->_pos = ftell($this->_fd);
-
-      return $data;
-    } else return '';
-  }
-
-  function seekto($pos) {
-    fseek($this->_fd, $pos);
-    $this->_pos = ftell($this->_fd);
-    return $this->_pos;
-  }
-
-  function currentpos() {
-    return $this->_pos;
-  }
-
-  function length() {
-    return $this->_length;
-  }
-
-  function close() {
-    fclose($this->_fd);
-  }
-
-};
-
-// Preloads entire file in memory first, then creates a StringReader
-// over it (it assumes knowledge of StringReader internals)
-class CachedFileReader extends StringReader {
-  function __construct($filename) {
-    if (file_exists($filename)) {
-
-      $length=filesize($filename);
-      $fd = fopen($filename,'rb');
-
-      if (!$fd) {
-        $this->error = 3; // Cannot read file, probably permissions
-        return false;
-      }
-      $this->_str = fread($fd, $length);
-      fclose($fd);
-
-    } else {
-      $this->error = 2; // File doesn't exist
-      return false;
-    }
-  }
-};
-
-
-?>
diff --git a/simpleid/www/lib/xtemplate.class.php b/simpleid/www/lib/xtemplate.class.php
deleted file mode 100644
index 84713c6..0000000
--- a/simpleid/www/lib/xtemplate.class.php
+++ /dev/null
@@ -1,1301 +0,0 @@
-<?php
-
-// When developing uncomment the line below, re-comment before making public
-//error_reporting(E_ALL);
-
-/**
- * XTemplate PHP templating engine
- *
- * @package XTemplate
- * @author Barnabas Debreceni [cranx@users.sourceforge.net]
- * @copyright Barnabas Debreceni 2000-2001
- * @author Jeremy Coates [cocomp@users.sourceforge.net]
- * @copyright Jeremy Coates 2002-2007
- * @see license.txt LGPL / BSD license
- * @since PHP 5
- * @link $HeadURL: https://xtpl.svn.sourceforge.net/svnroot/xtpl/trunk/xtemplate.class.php $
- * @version $Id$
- *
- *
- * XTemplate class - http://www.phpxtemplate.org/ (x)html / xml generation with templates - fast & easy
- * Latest stable & Subversion versions available @ http://sourceforge.net/projects/xtpl/
- * License: LGPL / BSD - see license.txt
- * Changelog: see changelog.txt
- */
-class XTemplate {
-
-	/**
-	 * Properties
-	 */
-
-	/**
-	 * Raw contents of the template file
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $filecontents = '';
-
-	/**
-	 * Unparsed blocks
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $blocks = array();
-
-	/**
-	 * Parsed blocks
-	 *
-	 * @var unknown_type
-	 */
-	public $parsed_blocks = array();
-
-	/**
-	 * Preparsed blocks (for file includes)
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $preparsed_blocks = array();
-
-	/**
-	 * Block parsing order for recursive parsing
-	 * (Sometimes reverse :)
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $block_parse_order = array();
-
-	/**
-	 * Store sub-block names
-	 * (For fast resetting)
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $sub_blocks = array();
-
-	/**
-	 * Variables array
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $vars = array();
-
-	/**
-	 * File variables array
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $filevars = array();
-
-	/**
-	 * Filevars' parent block
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $filevar_parent = array();
-
-	/**
-	 * File caching during duration of script
-	 * e.g. files only cached to speed {FILE "filename"} repeats
-	 *
-	 * @access public
-	 * @var array
-	 */
-	public $filecache = array();
-
-	/**
-	 * Location of template files
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $tpldir = '';
-
-	/**
-	 * Filenames lookup table
-	 *
-	 * @access public
-	 * @var null
-	 */
-	public $files = null;
-
-	/**
-	 * Template filename
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $filename = '';
-
-	// moved to setup method so uses the tag_start & end_delims
-	/**
-	 * RegEx for file includes
-	 *
-	 * "/\{FILE\s*\"([^\"]+)\"\s*\}/m";
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $file_delim = '';
-
-	/**
-	 * RegEx for file include variable
-	 *
-	 * "/\{FILE\s*\{([A-Za-z0-9\._]+?)\}\s*\}/m";
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $filevar_delim = '';
-
-	/**
-	 * RegEx for file includes with newlines
-	 *
-	 * "/^\s*\{FILE\s*\{([A-Za-z0-9\._]+?)\}\s*\}\s*\n/m";
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $filevar_delim_nl = '';
-
-	/**
-	 * Template block start delimiter
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $block_start_delim = '<!-- ';
-
-	/**
-	 * Template block end delimiter
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $block_end_delim = '-->';
-
-	/**
-	 * Template block start word
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $block_start_word = 'BEGIN:';
-
-	/**
-	 * Template block end word
-	 *
-	 * The last 3 properties and this make the delimiters look like:
-	 * @example <!-- BEGIN: block_name -->
-	 * if you use the default syntax.
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $block_end_word = 'END:';
-
-	/**
-	 * Template tag start delimiter
-	 *
-	 * This makes the delimiters look like:
-	 * @example {tagname}
-	 * if you use the default syntax.
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $tag_start_delim = '{';
-
-	/**
-	 * Template tag end delimiter
-	 *
-	 * This makes the delimiters look like:
-	 * @example {tagname}
-	 * if you use the default syntax.
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $tag_end_delim = '}';
-	/* this makes the delimiters look like: {tagname} if you use my syntax. */
-
-	/**
-	 * Regular expression element for comments within tags and blocks
-	 *
-	 * @example {tagname#My Comment}
-	 * @example {tagname #My Comment}
-	 * @example <!-- BEGIN: blockname#My Comment -->
-	 * @example <!-- BEGIN: blockname #My Comment -->
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $comment_preg = '( ?#.*?)?';
-
-	/**
-	 * Default main template block name
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $mainblock = 'main';
-
-	/**
-	 * Script output type
-	 *
-	 * @access public
-	 * @var string
-	 */
-	public $output_type = 'HTML';
-
-	/**
-	 * Debug mode
-	 *
-	 * @access public
-	 * @var boolean
-	 */
-	public $debug = false;
-
-	/**
-	 * Null string for unassigned vars
-	 *
-	 * @access protected
-	 * @var array
-	 */
-	protected $_null_string = array('' => '');
-
-	/**
-	 * Null string for unassigned blocks
-	 *
-	 * @access protected
-	 * @var array
-	 */
-	protected $_null_block = array('' => '');
-
-	/**
-	 * Errors
-	 *
-	 * @access protected
-	 * @var string
-	 */
-	protected $_error = '';
-
-	/**
-	 * Auto-reset sub blocks
-	 *
-	 * @access protected
-	 * @var boolean
-	 */
-	protected $_autoreset = true;
-
-	/**
-	 * Set to FALSE to generate errors if a non-existant blocks is referenced
-	 *
-	 * @author NW
-	 * @since 2002/10/17
-	 * @access protected
-	 * @var boolean
-	 */
-	protected $_ignore_missing_blocks = true;
-
-	/**
-     * PHP 5 Constructor - Instantiate the object
-     *
-     * @param string $file Template file to work on
-     * @param string/array $tpldir Location of template files (useful for keeping files outside web server root)
-     * @param array $files Filenames lookup
-     * @param string $mainblock Name of main block in the template
-     * @param boolean $autosetup If true, run setup() as part of constuctor
-     * @return XTemplate
-     */
-	public function __construct($file, $tpldir = '', $files = null, $mainblock = 'main', $autosetup = true) {
-
-		$this->restart($file, $tpldir, $files, $mainblock, $autosetup, $this->tag_start_delim, $this->tag_end_delim);
-	}
-
-	/*
-     * PHP 4 Constructor - Instantiate the object
-     *
-     * @deprecated Use PHP 5 constructor instead
-     * @param string $file Template file to work on
-     * @param string/array $tpldir Location of template files (useful for keeping files outside web server root)
-     * @param array $files Filenames lookup
-     * @param string $mainblock Name of main block in the template
-     * @param boolean $autosetup If true, run setup() as part of constuctor
-     * @return XTemplate
-     *
-	public function XTemplate ($file, $tpldir = '', $files = null, $mainblock = 'main', $autosetup = true) {
-
-		assert('Deprecated - use PHP 5 constructor');
-	}*/
-
-
-	/***************************************************************************/
-	/***[ public stuff ]********************************************************/
-	/***************************************************************************/
-
-	/**
-	 * Restart the class - allows one instantiation with several files processed by restarting
-	 * e.g. $xtpl = new XTemplate('file1.xtpl');
-	 * $xtpl->parse('main');
-	 * $xtpl->out('main');
-	 * $xtpl->restart('file2.xtpl');
-	 * $xtpl->parse('main');
-	 * $xtpl->out('main');
-	 * (Added in response to sf:641407 feature request)
-	 *
-	 * @param string $file Template file to work on
-	 * @param string/array $tpldir Location of template files
-	 * @param array $files Filenames lookup
-	 * @param string $mainblock Name of main block in the template
-	 * @param boolean $autosetup If true, run setup() as part of restarting
-	 * @param string $tag_start {
-	 * @param string $tag_end }
-	 */
-	public function restart ($file, $tpldir = '', $files = null, $mainblock = 'main', $autosetup = true, $tag_start = '{', $tag_end = '}') {
-
-		$this->filename = $file;
-
-		// From SF Feature request 1202027
-		// Kenneth Kalmer
-		$this->tpldir = $tpldir;
-		if (defined('XTPL_DIR') && empty($this->tpldir)) {
-			$this->tpldir = XTPL_DIR;
-		}
-
-		if (is_array($files)) {
-			$this->files = $files;
-		}
-
-		$this->mainblock = $mainblock;
-
-		$this->tag_start_delim = $tag_start;
-		$this->tag_end_delim = $tag_end;
-
-		// Start with fresh file contents
-		$this->filecontents = '';
-
-		// Reset the template arrays
-		$this->blocks = array();
-		$this->parsed_blocks = array();
-		$this->preparsed_blocks = array();
-		$this->block_parse_order = array();
-		$this->sub_blocks = array();
-		$this->vars = array();
-		$this->filevars = array();
-		$this->filevar_parent = array();
-		$this->filecache = array();
-
-		if ($autosetup) {
-			$this->setup();
-		}
-	}
-
-	/**
-     * setup - the elements that were previously in the constructor
-     *
-     * @access public
-     * @param boolean $add_outer If true is passed when called, it adds an outer main block to the file
-     */
-	public function setup ($add_outer = false) {
-
-		$this->tag_start_delim = preg_quote($this->tag_start_delim);
-		$this->tag_end_delim = preg_quote($this->tag_end_delim);
-
-		// Setup the file delimiters
-
-		// regexp for file includes
-		$this->file_delim = "/" . $this->tag_start_delim . "FILE\s*\"([^\"]+)\"" . $this->comment_preg . $this->tag_end_delim . "/m";
-
-		// regexp for file includes
-		$this->filevar_delim = "/" . $this->tag_start_delim . "FILE\s*" . $this->tag_start_delim . "([A-Za-z0-9\._]+?)" . $this->comment_preg . $this->tag_end_delim . $this->comment_preg . $this->tag_end_delim . "/m";
-
-		// regexp for file includes w/ newlines
-		$this->filevar_delim_nl = "/^\s*" . $this->tag_start_delim . "FILE\s*" . $this->tag_start_delim . "([A-Za-z0-9\._]+?)" . $this->comment_preg . $this->tag_end_delim . $this->comment_preg . $this->tag_end_delim . "\s*\n/m";
-
-		if (empty($this->filecontents)) {
-			// read in template file
-			$this->filecontents = $this->_r_getfile($this->filename);
-		}
-
-		if ($add_outer) {
-			$this->_add_outer_block();
-		}
-
-		// preprocess some stuff
-		$this->blocks = $this->_maketree($this->filecontents, '');
-		$this->filevar_parent = $this->_store_filevar_parents($this->blocks);
-		$this->scan_globals();
-	}
-
-	/**
-     * assign a variable
-     *
-     * @example Simplest case:
-     * @example $xtpl->assign('name', 'value');
-     * @example {name} in template
-     *
-     * @example Array assign:
-     * @example $xtpl->assign(array('name' => 'value', 'name2' => 'value2'));
-     * @example {name} {name2} in template
-     *
-     * @example Value as array assign:
-     * @example $xtpl->assign('name', array('key' => 'value', 'key2' => 'value2'));
-     * @example {name.key} {name.key2} in template
-     *
-     * @example Reset array:
-     * @example $xtpl->assign('name', array('key' => 'value', 'key2' => 'value2'));
-     * @example // Other code then:
-     * @example $xtpl->assign('name', array('key3' => 'value3'), false);
-     * @example {name.key} {name.key2} {name.key3} in template
-     *
-     * @access public
-     * @param string $name Variable to assign $val to
-     * @param string / array $val Value to assign to $name
-	 * @param boolean $reset_array Reset the variable array if $val is an array
-     */
-	public function assign ($name, $val = '', $reset_array = true) {
-
-		if (is_array($name)) {
-
-			foreach ($name as $k => $v) {
-
-				$this->vars[$k] = $v;
-			}
-		} elseif (is_array($val)) {
-
-			// Clear the existing values
-    		if ($reset_array) {
-    			$this->vars[$name] = array();
-    		}
-
-        	foreach ($val as $k => $v) {
-
-        		$this->vars[$name][$k] = $v;
-        	}
-
-		} else {
-
-			$this->vars[$name] = $val;
-		}
-	}
-
-	/**
-     * assign a file variable
-     *
-     * @access public
-     * @param string $name Variable to assign $val to
-     * @param string / array $val Values to assign to $name
-     */
-	public function assign_file ($name, $val = '') {
-
-		if (is_array($name)) {
-
-			foreach ($name as $k => $v) {
-
-				$this->_assign_file_sub($k, $v);
-			}
-		} else {
-
-			$this->_assign_file_sub($name, $val);
-		}
-	}
-
-	/**
-     * parse a block
-     *
-     * @access public
-     * @param string $bname Block name to parse
-     */
-	public function parse ($bname) {
-
-		if (isset($this->preparsed_blocks[$bname])) {
-
-			$copy = $this->preparsed_blocks[$bname];
-
-		} elseif (isset($this->blocks[$bname])) {
-
-			$copy = $this->blocks[$bname];
-
-		} elseif ($this->_ignore_missing_blocks) {
-			// ------------------------------------------------------
-			// NW : 17 Oct 2002. Added default of ignore_missing_blocks
-			//      to allow for generalised processing where some
-			//      blocks may be removed from the HTML without the
-			//      processing code needing to be altered.
-			// ------------------------------------------------------
-			// JRC: 3/1/2003 added set error to ignore missing functionality
-			$this->_set_error("parse: blockname [$bname] does not exist");
-			return;
-
-		} else {
-
-			$this->_set_error("parse: blockname [$bname] does not exist");
-		}
-
-		/* from there we should have no more {FILE } directives */
-		if (!isset($copy)) {
-			die('Block: ' . $bname);
-		}
-
-		$copy = preg_replace($this->filevar_delim_nl, '', $copy);
-
-		$var_array = array();
-
-		/* find & replace variables+blocks */
-		preg_match_all("|" . $this->tag_start_delim . "([A-Za-z0-9\._]+?" . $this->comment_preg . ")" . $this->tag_end_delim. "|", $copy, $var_array);
-
-		$var_array = $var_array[1];
-
-		foreach ($var_array as $k => $v) {
-
-			// Are there any comments in the tags {tag#a comment for documenting the template}
-			$any_comments = explode('#', $v);
-			$v = rtrim($any_comments[0]);
-
-			if (sizeof($any_comments) > 1) {
-
-				$comments = $any_comments[1];
-			} else {
-
-				$comments = '';
-			}
-
-			$sub = explode('.', $v);
-
-			if ($sub[0] == '_BLOCK_') {
-
-				unset($sub[0]);
-
-				$bname2 = implode('.', $sub);
-
-				// trinary operator eliminates assign error in E_ALL reporting
-				$var = isset($this->parsed_blocks[$bname2]) ? $this->parsed_blocks[$bname2] : null;
-				$nul = (!isset($this->_null_block[$bname2])) ? $this->_null_block[''] : $this->_null_block[$bname2];
-
-				if ($var === '') {
-
-					if ($nul == '') {
-						// -----------------------------------------------------------
-						// Removed requirement for blocks to be at the start of string
-						// -----------------------------------------------------------
-						//                      $copy=preg_replace("/^\s*\{".$v."\}\s*\n*/m","",$copy);
-						// Now blocks don't need to be at the beginning of a line,
-						//$copy=preg_replace("/\s*" . $this->tag_start_delim . $v . $this->tag_end_delim . "\s*\n*/m","",$copy);
-						$copy = preg_replace("|" . $this->tag_start_delim . $v . $this->tag_end_delim . "|m", '', $copy);
-
-					} else {
-
-						$copy = preg_replace("|" . $this->tag_start_delim . $v . $this->tag_end_delim . "|m", "$nul", $copy);
-					}
-				} else {
-
-					//$var = trim($var);
-					switch (true) {
-						case preg_match('/^\n/', $var) && preg_match('/\n$/', $var):
-							$var = substr($var, 1, -1);
-							break;
-
-						case preg_match('/^\n/', $var):
-							$var = substr($var, 1);
-							break;
-
-						case preg_match('/\n$/', $var):
-							$var = substr($var, 0, -1);
-							break;
-					}
-
-					// SF Bug no. 810773 - thanks anonymous
-					$var = str_replace('\\', '\\\\', $var);
-					// Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
-					$var = str_replace('$', '\\$', $var);
-					// Replaced str_replaces with preg_quote
-					//$var = preg_quote($var);
-					$var = str_replace('\\|', '|', $var);
-					$copy = preg_replace("|" . $this->tag_start_delim . $v . $this->tag_end_delim . "|m", "$var", $copy);
-
-					if (preg_match('/^\n/', $copy) && preg_match('/\n$/', $copy)) {
-						$copy = substr($copy, 1, -1);
-					}
-				}
-			} else {
-
-				$var = $this->vars;
-
-				foreach ($sub as $v1) {
-
-					// NW 4 Oct 2002 - Added isset and is_array check to avoid NOTICE messages
-					// JC 17 Oct 2002 - Changed EMPTY to stlen=0
-					//                if (empty($var[$v1])) { // this line would think that zeros(0) were empty - which is not true
-					if (!isset($var[$v1]) || (!is_array($var[$v1]) && strlen($var[$v1]) == 0)) {
-
-						// Check for constant, when variable not assigned
-						if (defined($v1)) {
-
-							$var[$v1] = constant($v1);
-
-						} else {
-
-							$var[$v1] = null;
-						}
-					}
-
-					$var = $var[$v1];
-				}
-
-				$nul = (!isset($this->_null_string[$v])) ? ($this->_null_string[""]) : ($this->_null_string[$v]);
-				$var = (!isset($var)) ? $nul : $var;
-
-				if ($var === '') {
-					// -----------------------------------------------------------
-					// Removed requriement for blocks to be at the start of string
-					// -----------------------------------------------------------
-					//                    $copy=preg_replace("|^\s*\{".$v." ?#?".$comments."\}\s*\n|m","",$copy);
-					$copy = preg_replace("|" . $this->tag_start_delim . $v . "( ?#" . $comments . ")?" . $this->tag_end_delim . "|m", '', $copy);
-				}
-
-				$var = trim($var);
-				// SF Bug no. 810773 - thanks anonymous
-				$var = str_replace('\\', '\\\\', $var);
-				// Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
-				$var = str_replace('$', '\\$', $var);
-				// Replace str_replaces with preg_quote
-				//$var = preg_quote($var);
-				$var = str_replace('\\|', '|', $var);
-				$copy = preg_replace("|" . $this->tag_start_delim . $v . "( ?#" . $comments . ")?" . $this->tag_end_delim . "|m", "$var", $copy);
-
-				if (preg_match('/^\n/', $copy) && preg_match('/\n$/', $copy)) {
-					$copy = substr($copy, 1);
-				}
-			}
-		}
-
-		if (isset($this->parsed_blocks[$bname])) {
-			$this->parsed_blocks[$bname] .= $copy;
-		} else {
-			$this->parsed_blocks[$bname] = $copy;
-		}
-
-		/* reset sub-blocks */
-		if ($this->_autoreset && (!empty($this->sub_blocks[$bname]))) {
-
-			reset($this->sub_blocks[$bname]);
-
-			foreach ($this->sub_blocks[$bname] as $k => $v) {
-				$this->reset($v);
-			}
-		}
-	}
-
-	/**
-     * returns the parsed text for a block, including all sub-blocks.
-     *
-     * @access public
-     * @param string $bname Block name to parse
-     */
-	public function rparse ($bname) {
-
-		if (!empty($this->sub_blocks[$bname])) {
-
-			reset($this->sub_blocks[$bname]);
-
-			foreach ($this->sub_blocks[$bname] as $k => $v) {
-
-				if (!empty($v)) {
-					$this->rparse($v);
-				}
-			}
-		}
-
-		$this->parse($bname);
-	}
-
-	/**
-     * inserts a loop ( call assign & parse )
-     *
-     * @access public
-     * @param string $bname Block name to assign
-     * @param string $var Variable to assign values to
-     * @param string / array $value Value to assign to $var
-    */
-	public function insert_loop ($bname, $var, $value = '') {
-
-		$this->assign($var, $value);
-		$this->parse($bname);
-	}
-
-	/**
-     * parses a block for every set of data in the values array
-     *
-     * @access public
-     * @param string $bname Block name to loop
-     * @param string $var Variable to assign values to
-     * @param array $values Values to assign to $var
-    */
-	public function array_loop ($bname, $var, &$values) {
-
-		if (is_array($values)) {
-
-			foreach($values as $v) {
-
-				$this->insert_loop($bname, $var, $v);
-			}
-		}
-	}
-
-	/**
-     * returns the parsed text for a block
-     *
-     * @access public
-     * @param string $bname Block name to return
-     * @return string
-     */
-	public function text ($bname = '') {
-
-		$text = '';
-
-		if ($this->debug && $this->output_type == 'HTML') {
-			// JC 20/11/02 echo the template filename if in development as
-			// html comment
-			$text .= '<!-- XTemplate: ' . realpath($this->filename) . " -->\n";
-		}
-
-		$bname = !empty($bname) ? $bname : $this->mainblock;
-
-		$text .= isset($this->parsed_blocks[$bname]) ? $this->parsed_blocks[$bname] : $this->get_error();
-
-		return $text;
-	}
-
-	/**
-     * prints the parsed text
-     *
-     * @access public
-     * @param string $bname Block name to echo out
-     */
-	public function out ($bname) {
-
-		$out = $this->text($bname);
-		//        $length=strlen($out);
-		//header("Content-Length: ".$length); // TODO: Comment this back in later
-
-		echo $out;
-	}
-
-	/**
-     * prints the parsed text to a specified file
-     *
-     * @access public
-     * @param string $bname Block name to write out
-     * @param string $fname File name to write to
-     */
-	public function out_file ($bname, $fname) {
-
-		if (!empty($bname) && !empty($fname) && is_writeable($fname)) {
-
-			$fp = fopen($fname, 'w');
-			fwrite($fp, $this->text($bname));
-			fclose($fp);
-		}
-	}
-
-	/**
-     * resets the parsed text
-     *
-     * @access public
-     * @param string $bname Block to reset
-     */
-	public function reset ($bname) {
-
-		$this->parsed_blocks[$bname] = '';
-	}
-
-	/**
-     * returns true if block was parsed, false if not
-     *
-     * @access public
-     * @param string $bname Block name to test
-     * @return boolean
-     */
-	public function parsed ($bname) {
-
-		return (!empty($this->parsed_blocks[$bname]));
-	}
-
-	/**
-     * sets the string to replace in case the var was not assigned
-     *
-     * @access public
-     * @param string $str Display string for null block
-     * @param string $varname Variable name to apply $str to
-     */
-	public function set_null_string($str, $varname = '') {
-
-		$this->_null_string[$varname] = $str;
-	}
-
-	/**
-	 * Backwards compatibility only
-	 *
-	 * @param string $str
-	 * @param string $varname
-	 * @deprecated Change to set_null_string to keep in with rest of naming convention
-	 */
-	public function SetNullString ($str, $varname = '') {
-		$this->set_null_string($str, $varname);
-	}
-
-	/**
-     * sets the string to replace in case the block was not parsed
-     *
-     * @access public
-     * @param string $str Display string for null block
-     * @param string $bname Block name to apply $str to
-     */
-	public function set_null_block ($str, $bname = '') {
-
-		$this->_null_block[$bname] = $str;
-	}
-
-	/**
-	 * Backwards compatibility only
-	 *
-	 * @param string $str
-	 * @param string $bname
-	 * @deprecated Change to set_null_block to keep in with rest of naming convention
-	 */
-	public function SetNullBlock ($str, $bname = '') {
-		$this->set_null_block($str, $bname);
-	}
-
-	/**
-     * sets AUTORESET to 1. (default is 1)
-     * if set to 1, parse() automatically resets the parsed blocks' sub blocks
-     * (for multiple level blocks)
-     *
-     * @access public
-     */
-	public function set_autoreset () {
-
-		$this->_autoreset = true;
-	}
-
-	/**
-     * sets AUTORESET to 0. (default is 1)
-     * if set to 1, parse() automatically resets the parsed blocks' sub blocks
-     * (for multiple level blocks)
-     *
-     * @access public
-     */
-	public function clear_autoreset () {
-
-		$this->_autoreset = false;
-	}
-
-	/**
-     * scans global variables and assigns to PHP array
-     *
-     * @access public
-     */
-	public function scan_globals () {
-
-		foreach ($GLOBALS as $k => $v) {
-			$GLOB[$k] = $v;
-		}
-
-		/**
-		 * Access global variables as:
-		 * @example {PHP._SERVER.HTTP_HOST}
-		 * in your template!
-		 */
-		$this->assign('PHP', $GLOB);
-	}
-
-	/**
-     * gets error condition / string
-     *
-     * @access public
-     * @return boolean / string
-     */
-	public function get_error () {
-
-		// JRC: 3/1/2003 Added ouptut wrapper and detection of output type for error message output
-		$retval = false;
-
-		if ($this->_error != '') {
-
-			switch ($this->output_type) {
-				case 'HTML':
-				case 'html':
-					$retval = '<b>[XTemplate]</b><ul>' . nl2br(str_replace('* ', '<li>', str_replace(" *\n", "</li>\n", $this->_error))) . '</ul>';
-					break;
-
-				default:
-					$retval = '[XTemplate] ' . str_replace(' *\n', "\n", $this->_error);
-					break;
-			}
-		}
-
-		return $retval;
-	}
-
-	/***************************************************************************/
-	/***[ private stuff ]*******************************************************/
-	/***************************************************************************/
-
-	/**
-     * generates the array containing to-be-parsed stuff:
-     * $blocks["main"],$blocks["main.table"],$blocks["main.table.row"], etc.
-     * also builds the reverse parse order.
-     *
-     * @access public - aiming for private
-     * @param string $con content to be processed
-     * @param string $parentblock name of the parent block in the block hierarchy
-     */
-	public function _maketree ($con, $parentblock='') {
-
-		$blocks = array();
-
-		$con2 = explode($this->block_start_delim, $con);
-
-		if (!empty($parentblock)) {
-
-			$block_names = explode('.', $parentblock);
-			$level = sizeof($block_names);
-
-		} else {
-
-			$block_names = array();
-			$level = 0;
-		}
-
-		// JRC 06/04/2005 Added block comments (on BEGIN or END) <!-- BEGIN: block_name#Comments placed here -->
-		//$patt = "($this->block_start_word|$this->block_end_word)\s*(\w+)\s*$this->block_end_delim(.*)";
-		$patt = "(" . $this->block_start_word . "|" . $this->block_end_word . ")\s*(\w+)" . $this->comment_preg . "\s*" . $this->block_end_delim . "(.*)";
-
-		foreach($con2 as $k => $v) {
-
-			$res = array();
-
-			if (preg_match_all("/$patt/ims", $v, $res, PREG_SET_ORDER)) {
-				// $res[0][1] = BEGIN or END
-				// $res[0][2] = block name
-				// $res[0][3] = comment
-				// $res[0][4] = kinda content
-				$block_word	= $res[0][1];
-				$block_name	= $res[0][2];
-				$comment	= $res[0][3];
-				$content	= $res[0][4];
-
-				if (strtoupper($block_word) == $this->block_start_word) {
-
-					$parent_name = implode('.', $block_names);
-
-					// add one level - array("main","table","row")
-					$block_names[++$level] = $block_name;
-
-					// make block name (main.table.row)
-					$cur_block_name=implode('.', $block_names);
-
-					// build block parsing order (reverse)
-					$this->block_parse_order[] = $cur_block_name;
-
-					//add contents. trinary operator eliminates assign error in E_ALL reporting
-					$blocks[$cur_block_name] = isset($blocks[$cur_block_name]) ? $blocks[$cur_block_name] . $content : $content;
-
-					// add {_BLOCK_.blockname} string to parent block
-					$blocks[$parent_name] .= str_replace('\\', '', $this->tag_start_delim) . '_BLOCK_.' . $cur_block_name . str_replace('\\', '', $this->tag_end_delim);
-
-					// store sub block names for autoresetting and recursive parsing
-					$this->sub_blocks[$parent_name][] = $cur_block_name;
-
-					// store sub block names for autoresetting
-					$this->sub_blocks[$cur_block_name][] = '';
-
-				} else if (strtoupper($block_word) == $this->block_end_word) {
-
-					unset($block_names[$level--]);
-
-					$parent_name = implode('.', $block_names);
-
-					// add rest of block to parent block
-					$blocks[$parent_name] .= $content;
-				}
-			} else {
-
-				// no block delimiters found
-				// Saves doing multiple implodes - less overhead
-				$tmp = implode('.', $block_names);
-
-				if ($k) {
-					$blocks[$tmp] .= $this->block_start_delim;
-				}
-
-				// trinary operator eliminates assign error in E_ALL reporting
-				$blocks[$tmp] = isset($blocks[$tmp]) ? $blocks[$tmp] . $v : $v;
-			}
-		}
-
-		return $blocks;
-	}
-
-	/**
-     * Sub processing for assign_file method
-     *
-     * @access private
-     * @param string $name
-     * @param string $val
-     */
-	private function _assign_file_sub ($name, $val) {
-
-		if (isset($this->filevar_parent[$name])) {
-
-			if ($val != '') {
-
-				$val = $this->_r_getfile($val);
-
-				foreach($this->filevar_parent[$name] as $parent) {
-
-					if (isset($this->preparsed_blocks[$parent]) && !isset($this->filevars[$name])) {
-
-						$copy = $this->preparsed_blocks[$parent];
-
-					} elseif (isset($this->blocks[$parent])) {
-
-						$copy = $this->blocks[$parent];
-					}
-
-					$res = array();
-
-					preg_match_all($this->filevar_delim, $copy, $res, PREG_SET_ORDER);
-
-					if (is_array($res) && isset($res[0])) {
-
-						// Changed as per solution in SF bug ID #1261828
-						foreach ($res as $v) {
-
-							// Changed as per solution in SF bug ID #1261828
-							if ($v[1] == $name) {
-
-								// Changed as per solution in SF bug ID #1261828
-								$copy = preg_replace("/" . preg_quote($v[0]) . "/", "$val", $copy);
-								$this->preparsed_blocks = array_merge($this->preparsed_blocks, $this->_maketree($copy, $parent));
-								$this->filevar_parent = array_merge($this->filevar_parent, $this->_store_filevar_parents($this->preparsed_blocks));
-							}
-						}
-					}
-				}
-			}
-		}
-
-		$this->filevars[$name] = $val;
-	}
-
-	/**
-     * store container block's name for file variables
-     *
-     * @access public - aiming for private
-     * @param array $blocks
-     * @return array
-     */
-	public function _store_filevar_parents ($blocks){
-
-		$parents = array();
-
-		foreach ($blocks as $bname => $con) {
-
-			$res = array();
-
-			preg_match_all($this->filevar_delim, $con, $res);
-
-			foreach ($res[1] as $k => $v) {
-
-				$parents[$v][] = $bname;
-			}
-		}
-		return $parents;
-	}
-
-	/**
-     * Set the error string
-     *
-     * @access private
-     * @param string $str
-     */
-	private function _set_error ($str)    {
-
-		// JRC: 3/1/2003 Made to append the error messages
-		$this->_error .= '* ' . $str . " *\n";
-		// JRC: 3/1/2003 Removed trigger error, use this externally if you want it eg. trigger_error($xtpl->get_error())
-		//trigger_error($this->get_error());
-	}
-
-	/**
-     * returns the contents of a file
-     *
-     * @access protected
-     * @param string $file
-     * @return string
-     */
-	protected function _getfile ($file) {
-
-		if (!isset($file)) {
-			// JC 19/12/02 added $file to error message
-			$this->_set_error('!isset file name!' . $file);
-
-			return '';
-		}
-
-		// check if filename is mapped to other filename
-		if (isset($this->files)) {
-
-			if (isset($this->files[$file])) {
-
-				$file = $this->files[$file];
-			}
-		}
-
-		// prepend template dir
-		if (!empty($this->tpldir)) {
-
-			/**
-			 * Support hierarchy of file locations to search
-			 *
-			 * @example Supply array of filepaths when instantiating
-			 * 			First path supplied that has the named file is prioritised
-			 * 			$xtpl = new XTemplate('myfile.xtpl', array('.','/mypath', '/mypath2'));
-			 * @since 29/05/2007
-			 */
-			if (is_array($this->tpldir)) {
-
-				foreach ($this->tpldir as $dir) {
-
-					if (is_readable($dir . DIRECTORY_SEPARATOR . $file)) {
-						$file = $dir . DIRECTORY_SEPARATOR . $file;
-						break;
-					}
-				}
-			} else {
-
-				$file = $this->tpldir. DIRECTORY_SEPARATOR . $file;
-			}
-		}
-
-		$file_text = '';
-
-		if (isset($this->filecache[$file])) {
-
-			$file_text .= $this->filecache[$file];
-
-			if ($this->debug) {
-				$file_text = '<!-- XTemplate debug cached: ' . realpath($file) . ' -->' . "\n" . $file_text;
-			}
-
-		} else {
-
-			if (is_file($file) && is_readable($file)) {
-
-				if (filesize($file)) {
-
-					if (!($fh = fopen($file, 'r'))) {
-
-						$this->_set_error('Cannot open file: ' . realpath($file));
-						return '';
-					}
-
-					$file_text .= fread($fh,filesize($file));
-					fclose($fh);
-
-				}
-
-				if ($this->debug) {
-					$file_text = '<!-- XTemplate debug: ' . realpath($file) . ' -->' . "\n" . $file_text;
-				}
-
-			} elseif (str_replace('.', '', phpversion()) >= '430' && $file_text = @file_get_contents($file, true)) {
-				// Enable use of include path by using file_get_contents
-				// Implemented at suggestion of SF Feature Request ID #1529478 michaelgroh
-				if ($file_text === false) {
-					$this->_set_error("[" . realpath($file) . "] ($file) does not exist");
-					$file_text = "<b>__XTemplate fatal error: file [$file] does not exist in the include path__</b>";
-				} elseif ($this->debug) {
-					$file_text = '<!-- XTemplate debug: ' . realpath($file) . ' (via include path) -->' . "\n" . $file_text;
-				}
-			} elseif (!is_file($file)) {
-
-				// NW 17 Oct 2002 : Added realpath around the file name to identify where the code is searching.
-				$this->_set_error("[" . realpath($file) . "] ($file) does not exist");
-				$file_text .= "<b>__XTemplate fatal error: file [$file] does not exist__</b>";
-
-			} elseif (!is_readable($file)) {
-
-				$this->_set_error("[" . realpath($file) . "] ($file) is not readable");
-				$file_text .= "<b>__XTemplate fatal error: file [$file] is not readable__</b>";
-			}
-
-			$this->filecache[$file] = $file_text;
-		}
-
-		return $file_text;
-	}
-
-	/**
-     * recursively gets the content of a file with {FILE "filename.tpl"} directives
-     *
-     * @access public - aiming for private
-     * @param string $file
-     * @return string
-     */
-	public function _r_getfile ($file) {
-
-		$text = $this->_getfile($file);
-
-		$res = array();
-
-		while (preg_match($this->file_delim,$text,$res)) {
-
-			$text2 = $this->_getfile($res[1]);
-			$text = preg_replace("'".preg_quote($res[0])."'",$text2,$text);
-		}
-
-		return $text;
-	}
-
-
-	/**
-     * add an outer block delimiter set useful for rtfs etc - keeps them editable in word
-     *
-     * @access private
-     */
-	private function _add_outer_block () {
-
-		$before = $this->block_start_delim . $this->block_start_word . ' ' . $this->mainblock . ' ' . $this->block_end_delim;
-		$after = $this->block_start_delim . $this->block_end_word . ' ' . $this->mainblock . ' ' . $this->block_end_delim;
-
-		$this->filecontents = $before . "\n" . $this->filecontents . "\n" . $after;
-	}
-
-	/**
-     * Debug function - var_dump wrapped in '<pre></pre>' tags
-     *
-     * @access private
-     * @param multiple var_dumps all the supplied arguments
-     */
-	private function _pre_var_dump ($args) {
-
-		if ($this->debug) {
-			echo '<pre>';
-			var_dump(func_get_args());
-			echo '</pre>';
-		}
-	}
-} /* end of XTemplate class. */
-
-?>
diff --git a/simpleid/www/locale.inc.php b/simpleid/www/locale.inc.php
deleted file mode 100644
index 837dde7..0000000
--- a/simpleid/www/locale.inc.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php 
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2012
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-/**
- * Localisation support.
- *
- * @package simpleid
- * @since 0.9
- * @filesource
- */
- 
-include_once 'lib/gettext/gettext.inc.php';
- 
-/**
- * Initialises the localisation system.
- *
- * @param string $locale the locale to use
- */
-function locale_init($locale) {
-    T_setlocale(LC_MESSAGES, $locale);
-    // Set the text domain as 'messages'
-    $domain = 'messages';
-    bindtextdomain($domain, 'locale');
-    // bind_textdomain_codeset is supported only in PHP 4.2.0+
-    if (function_exists('bind_textdomain_codeset')) 
-        bind_textdomain_codeset($domain, 'UTF-8');
-    textdomain($domain);
-}
-
-/**
- * Translates a string.
- *
- * @param string $string the string to translate
- * @param array $variables an array of replacements variables to be made after
- * a translation. Prefix the variable with a @ to make the replacement HTML safe,
- * a % to make the replacement HTML safe and surround with &lt;strong&gt; tags,
- * and ! to replace as is
- * @return string the translated string
- */
-function t($string, $variables = array()) {
-    $translated = gettext($string);
-    
-    foreach ($variables as $variable => $value) {
-        switch ($variable[0]) {
-            case '@':
-                $variables[$variable] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
-                break;
-            case '%':
-            default:
-                $variables[$variable] = '<strong>' . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . '</strong>';
-                break;
-            case '!':
-                // Pass-through.
-        }
-  }
-  return strtr($translated, $variables);
-}
-?>
diff --git a/simpleid/www/locale/messages.pot b/simpleid/www/locale/messages.pot
deleted file mode 100644
index 1eff63d..0000000
--- a/simpleid/www/locale/messages.pot
+++ /dev/null
@@ -1,550 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-03-13 21:46+1100\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: www/common.inc.php:140
-msgid "An encrypted connection (HTTPS) is required for this page."
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:195
-msgid "SimpleID will also be sending the following information to the site."
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:196
-#: www/extensions/ax/ax.extension.php:267
-msgid "Type URL"
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:197
-#: www/extensions/ax/ax.extension.php:268
-#: www/extensions/sreg/sreg.extension.php:134
-#: www/extensions/sreg/sreg.extension.php:186 www/user.inc.php:781
-msgid "Value"
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:203
-msgid "This web site requested to store information about you on SimpleID. Sadly, SimpleID does not support this feature."
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:265
-msgid "SimpleID will send the following information to sites which supports the Attribute Exchange Extension.  If you have also supplied OpenID Connect user information in your identity, or have the Simple Registration Extension installed, these may also be sent as part of this Extension."
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:266
-#: www/extensions/sreg/sreg.extension.php:184 www/user.inc.php:779
-msgid "To change these, <a href=\"!url\">edit your identity file</a>."
-msgstr ""
-
-#: www/extensions/ax/ax.extension.php:274
-msgid "Attribute Exchange Extension"
-msgstr ""
-
-#: www/extensions/pape/pape.extension.php:81
-msgid "This web site's policy requires you to log in again to confirm your identity."
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:114
-msgid "You can view the site's policy in relation to the use of this information at this URL: <a href=\"@url\">@url</a>."
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:132
-msgid "SimpleID will also be sending the following registration information to the site."
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:133
-#: www/extensions/sreg/sreg.extension.php:185
-msgid "Name"
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:182
-msgid "SimpleID will send the following information to sites which supports the Simple Registration Extension."
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:183
-msgid "If you have also supplied OpenID Connect user information in your identity file, these may also be sent as part of this Extension."
-msgstr ""
-
-#: www/extensions/sreg/sreg.extension.php:192
-msgid "Simple Registration Extension"
-msgstr ""
-
-#: www/extensions/ui/ui.extension.php:188
-msgid "Invalid UI icon parameters."
-msgstr ""
-
-#: www/extensions/ui/ui.extension.php:196
-msgid "Unable to get icon."
-msgstr ""
-
-#: www/index.php:42 www/upgrade.php:60
-msgid "No configuration file found.  See the <a href=\"!url\">manual</a> for instructions on how to set up a configuration file."
-msgstr ""
-
-#: www/index.php:113 www/upgrade.php:117
-msgid "Documentation"
-msgstr ""
-
-#: www/index.php:114 www/upgrade.php:118
-msgid "Support"
-msgstr ""
-
-#: www/index.php:118 www/upgrade.php:121
-msgid "Identities directory not found.  See the <a href=\"!url\">manual</a> for instructions on how to set up SimpleID."
-msgstr ""
-
-#: www/index.php:123 www/upgrade.php:125
-msgid "Cache directory not found or not writeable.  See the <a href=\"!url\">manual</a> for instructions on how to set up SimpleID."
-msgstr ""
-
-#: www/index.php:129 www/upgrade.php:129
-msgid "Store directory not found or not writeable.  See the <a href=\"!url\">manual</a> for instructions on how to set up SimpleID."
-msgstr ""
-
-#: www/index.php:134 www/upgrade.php:133
-msgid "register_globals is enabled in PHP configuration, which is not supported by SimpleID.  See the <a href=\"!url\">manual</a> for further information."
-msgstr ""
-
-#: www/index.php:139 www/index.php:143 www/index.php:147 www/index.php:151
-#: www/index.php:155 www/upgrade.php:138 www/upgrade.php:142
-#: www/upgrade.php:146 www/upgrade.php:150 www/upgrade.php:154
-#, php-format
-msgid "One or more required PHP extensions (%extension) is not loaded.  See the <a href=\"!url\">manual</a> for further information on system requirements."
-msgstr ""
-
-#: www/index.php:159 www/upgrade.php:158
-msgid "suhosin.get.max_value_length is less than 1024, which will lead to problems. See the <a href=\"!url\">manual</a> for further information on system requirements."
-msgstr ""
-
-#: www/index.php:279
-msgid "Invalid OpenID message."
-msgstr ""
-
-#: www/index.php:463
-msgid "Protocol Error: openid.return_to not set."
-msgstr ""
-
-#: www/index.php:468
-msgid "Protocol Error: openid.identity not set."
-msgstr ""
-
-#: www/index.php:476
-msgid "Protocol Error: openid.identity set, but not openid.claimed_id."
-msgstr ""
-
-#: www/index.php:482
-msgid "Protocol Error: openid.return_to not set when openid.realm is not set."
-msgstr ""
-
-#: www/index.php:1031 www/index.php:1112 www/user.inc.php:186
-#: www/user.inc.php:485
-msgid "Cancel"
-msgstr ""
-
-#: www/index.php:1036
-msgid "Unable to log into <strong class=\"realm\">@realm</strong>."
-msgstr ""
-
-#: www/index.php:1037
-msgid "Your current identity does not match the requested identity %identity."
-msgstr ""
-
-#: www/index.php:1038
-msgid "<a href=\"!url\">Switch to a different user</a> and try again."
-msgstr ""
-
-#: www/index.php:1050
-msgid "Warning: This web site has not confirmed its identity and might be fraudulent.  Do not share any personal information with this web site unless you are sure it is legitimate. See the <a href=\"!url\" class=\"popup\">SimpleID documentation for details</a> (OpenID version 2.0 return_to discovery failure)"
-msgstr ""
-
-#: www/index.php:1057
-msgid "You are being logged into <strong class=\"realm\">@realm</strong>."
-msgstr ""
-
-#: www/index.php:1058
-msgid "Automatically send my information to this site for any future requests."
-msgstr ""
-
-#: www/index.php:1059
-msgid "OK"
-msgstr ""
-
-#: www/index.php:1066 www/page.inc.php:186
-msgid "This web site has not confirmed its identity and might be fraudulent."
-msgstr ""
-
-#: www/index.php:1066 www/page.inc.php:186
-msgid "Are you sure you wish to automatically send your information to this site for any future requests?"
-msgstr ""
-
-#: www/index.php:1073 www/index.php:1098
-msgid "OpenID Login"
-msgstr ""
-
-#: www/index.php:1097 www/page.inc.php:123 www/upgrade.php:211
-#: www/upgrade.php:262 www/user.inc.php:573 www/user.inc.php:589
-msgid "SimpleID detected a potential security attack.  Please try again."
-msgstr ""
-
-#: www/index.php:1114
-msgid "Log in cancelled."
-msgstr ""
-
-#: www/index.php:1142
-msgid "You were logged in successfully."
-msgstr ""
-
-#: www/page.inc.php:57 www/page.inc.php:222
-msgid "Dashboard"
-msgstr ""
-
-#: www/page.inc.php:88
-msgid "<em>You need to set at least one of OpenID 1.x or OpenID 2 to generate the code.</em>"
-msgstr ""
-
-#: www/page.inc.php:92 www/page.inc.php:223
-msgid "My Profile"
-msgstr ""
-
-#: www/page.inc.php:149
-msgid "Your preferences have been saved."
-msgstr ""
-
-#: www/page.inc.php:178
-msgid "Site"
-msgstr ""
-
-#: www/page.inc.php:179
-msgid "Last access"
-msgstr ""
-
-#: www/page.inc.php:180
-msgid "Automatic"
-msgstr ""
-
-#: www/page.inc.php:181
-msgid "Remove"
-msgstr ""
-
-#: www/page.inc.php:182
-msgid "Submit"
-msgstr ""
-
-#: www/page.inc.php:189 www/page.inc.php:224
-msgid "My Sites"
-msgstr ""
-
-#: www/page.inc.php:265
-msgid "Welcome"
-msgstr ""
-
-#: www/page.inc.php:266
-msgid "You are logged in as %uid (%identity)."
-msgstr ""
-
-#: www/page.inc.php:280 www/user.inc.php:625
-msgid "Login verification adds an extra layer of protection to your account. When enabled, you will need to enter an additional security code whenever you log into SimpleID."
-msgstr ""
-
-#: www/page.inc.php:283
-msgid "Login verification is <strong>enabled</strong>."
-msgstr ""
-
-#: www/page.inc.php:285 www/user.inc.php:571
-msgid "Disable"
-msgstr ""
-
-#: www/page.inc.php:287
-msgid "Login verification is <strong>disabled</strong>. To enable login verification, click the button below."
-msgstr ""
-
-#: www/page.inc.php:289
-msgid "Enable"
-msgstr ""
-
-#: www/page.inc.php:294 www/user.inc.php:642
-msgid "Login Verification"
-msgstr ""
-
-#: www/page.inc.php:307
-msgid "&lt;link&gt; tags"
-msgstr ""
-
-#: www/page.inc.php:309
-msgid "OpenID 1.x"
-msgstr ""
-
-#: www/page.inc.php:310
-msgid "OpenID 2.0"
-msgstr ""
-
-#: www/page.inc.php:311
-msgid "Claim a different identifier"
-msgstr ""
-
-#: www/page.inc.php:319
-msgid "YADIS"
-msgstr ""
-
-#: www/page.inc.php:320
-msgid "Write your own or <a href=\"!url\">download</a> your YADIS document"
-msgstr ""
-
-#: www/page.inc.php:321
-msgid "Add HTTP headers or &lt;meta&gt; tag, e.g.:"
-msgstr ""
-
-#: www/page.inc.php:326
-msgid "Claim your Identifier"
-msgstr ""
-
-#: www/upgrade.php:185
-msgid "Use this script to update your installation whenever you upgrade to a new version of SimpleID."
-msgstr ""
-
-#: www/upgrade.php:186 www/upgrade.php:395
-msgid "For more detailed information, see the <a href=\"!url\">SimpleID documentation</a>."
-msgstr ""
-
-#: www/upgrade.php:187
-msgid "<strong>Back up your installation</strong>. This process will change various files within your SimpleID installation and in case of emergency you may need to revert to a backup."
-msgstr ""
-
-#: www/upgrade.php:188
-msgid "Install your new files in the appropriate location, as described in the <a href=\"!url\">SimpleID documentation</a>."
-msgstr ""
-
-#: www/upgrade.php:189
-msgid "When you have performed the steps above, click <strong>Continue</strong>."
-msgstr ""
-
-#: www/upgrade.php:190 www/upgrade.php:235
-msgid "Continue"
-msgstr ""
-
-#: www/upgrade.php:194 www/upgrade.php:249 www/upgrade.php:286
-msgid "Upgrade"
-msgstr ""
-
-#: www/upgrade.php:220 www/upgrade.php:275
-msgid "Remember to edit upgrade.php to check <code>$upgrade_access_check</code> back to <code>FALSE</code>."
-msgstr ""
-
-#: www/upgrade.php:224
-msgid "Your SimpleID installation is up-to-date.  This script is complete."
-msgstr ""
-
-#: www/upgrade.php:234
-msgid "Click <strong>Continue</strong> to proceed with the upgrade."
-msgstr ""
-
-#: www/upgrade.php:243
-msgid "The version of SimpleID you are updating from has been automatically detected."
-msgstr ""
-
-#: www/upgrade.php:244
-msgid "Original version"
-msgstr ""
-
-#: www/upgrade.php:245
-msgid "Upgrade version"
-msgstr ""
-
-#: www/upgrade.php:280
-msgid "Your SimpleID installation has been upgraded.  Please check the results below for any errors."
-msgstr ""
-
-#: www/upgrade.php:389
-msgid "Access denied. You are not authorised to access this page. Please <a href=\"index.php?q=login\">log in</a> as an administrator (a user whose identity file includes the line <code>administrator=1</code>)."
-msgstr ""
-
-#: www/upgrade.php:390
-msgid "If you cannot log in, you will have to edit <code>upgrade.php</code> to bypass this access check. To do this:"
-msgstr ""
-
-#: www/upgrade.php:391
-msgid "With a text editor find the upgrade.php file."
-msgstr ""
-
-#: www/upgrade.php:392
-msgid "There is a line inside your upgrade.php file that says <code>$upgrade_access_check = TRUE;</code>. Change it to <code>$upgrade_access_check = FALSE;</code>."
-msgstr ""
-
-#: www/upgrade.php:393
-msgid "As soon as the upgrade.php script is done, you must change the file back to its original form with <code>$upgrade_access_check = TRUE;</code>."
-msgstr ""
-
-#: www/upgrade.php:394
-msgid "To avoid having this problem in future, remember to log in to SimpleID as an administrator before you run this script."
-msgstr ""
-
-#: www/upgrade.php:399
-msgid "Access Denied"
-msgstr ""
-
-#: www/user.inc.php:197
-msgid "Login cancelled without a proper OpenID request."
-msgstr ""
-
-#: www/user.inc.php:203 www/user.inc.php:224 www/user.inc.php:234
-msgid "SimpleID detected a potential security attack on your log in.  Please log in again."
-msgstr ""
-
-#: www/user.inc.php:211
-msgid "You seem to be attempting to log in from another web page.  You must use this page to log in."
-msgstr ""
-
-#: www/user.inc.php:229
-msgid "The log in page has expired.  Please log in again."
-msgstr ""
-
-#: www/user.inc.php:248
-msgid "You need to supply the user name and the password in order to log in."
-msgstr ""
-
-#: www/user.inc.php:256
-msgid "The user name or password is not correct."
-msgstr ""
-
-#: www/user.inc.php:270
-msgid "You need to enter the verification code in order to log in."
-msgstr ""
-
-#: www/user.inc.php:279 www/user.inc.php:595
-msgid "The verification code is not correct."
-msgstr ""
-
-#: www/user.inc.php:443
-msgid "You have been logged out."
-msgstr ""
-
-#: www/user.inc.php:503
-msgid "Secure login using <strong>HTTPS</strong>."
-msgstr ""
-
-#: www/user.inc.php:506
-msgid "<strong>WARNING:</strong>  Your password will be sent to SimpleID as plain text."
-msgstr ""
-
-#: www/user.inc.php:513
-msgid "User name:"
-msgstr ""
-
-#: www/user.inc.php:514
-msgid "Password:"
-msgstr ""
-
-#: www/user.inc.php:515
-msgid "Remember me on this computer for two weeks."
-msgstr ""
-
-#: www/user.inc.php:525
-msgid "Log in"
-msgstr ""
-
-#: www/user.inc.php:526
-msgid "Log In"
-msgstr ""
-
-#: www/user.inc.php:530
-msgid "To verify your identity, enter the verification code."
-msgstr ""
-
-#: www/user.inc.php:531
-msgid "If you have lost your verification code, you can <a href=\"!url\">recover your account</a>."
-msgstr ""
-
-#: www/user.inc.php:535 www/user.inc.php:638
-msgid "Verification code:"
-msgstr ""
-
-#: www/user.inc.php:539 www/user.inc.php:585 www/user.inc.php:639
-msgid "Verify"
-msgstr ""
-
-#: www/user.inc.php:540
-msgid "Enter Verification Code"
-msgstr ""
-
-#: www/user.inc.php:593
-msgid "You need to enter the verification code to complete enabling login verification."
-msgstr ""
-
-#: www/user.inc.php:626
-msgid "<strong>WARNING:</strong> If you enable login verification and lose your authenticator app, you will need to <a href=\"!url\">edit your identity file manually</a> before you can log in again."
-msgstr ""
-
-#: www/user.inc.php:630
-msgid "To set up login verification, following these steps."
-msgstr ""
-
-#: www/user.inc.php:631
-msgid "Download an authenticator app that supports TOTP for your smartphone, such as Google Authenticator."
-msgstr ""
-
-#: www/user.inc.php:632
-msgid "Add your SimpleID account to authenticator app using this key.  If you are viewing this page on your smartphone you can use <a href=\"!url\">this link</a> or scan the QR code to add your account."
-msgstr ""
-
-#: www/user.inc.php:635
-msgid "To check that your account has been added properly, enter the verification code from your phone into the box below, and click Verify."
-msgstr ""
-
-#: www/user.inc.php:661
-msgid "User Page"
-msgstr ""
-
-#: www/user.inc.php:664
-msgid "No user specified."
-msgstr ""
-
-#: www/user.inc.php:670
-#, php-format
-msgid "User %uid not found."
-msgstr ""
-
-#: www/user.inc.php:682
-#, php-format
-msgid "This is the user %uid's SimpleID page.  It contains hidden information for the use by OpenID consumers."
-msgstr ""
-
-#: www/user.inc.php:724
-msgid "Private Personal Identifier"
-msgstr ""
-
-#: www/user.inc.php:726
-msgid "This is a private personal identifier."
-msgstr ""
-
-#: www/user.inc.php:778
-msgid "SimpleID may, with your consent, send the following information to sites which supports OpenID Connect."
-msgstr ""
-
-#: www/user.inc.php:781
-msgid "Member"
-msgstr ""
-
-#: www/user.inc.php:799
-msgid "OpenID Connect"
-msgstr ""
-
-#: www/user.inc.php:819
-msgid "Log out and log in as a different user"
-msgstr ""
-
-#: www/user.inc.php:822
-msgid "Log out"
-msgstr ""
diff --git a/simpleid/www/log.inc.php b/simpleid/www/log.inc.php
deleted file mode 100644
index 9e1caf0..0000000
--- a/simpleid/www/log.inc.php
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Functions for logging.
- *
- * @package simpleid
- * @filesource
- */
-
-/** Log level */
-define('SIMPLEID_LOG_DEBUG', 5);
-/** Log level */
-define('SIMPLEID_LOG_INFO', 4);
-/** Log level */
-define('SIMPLEID_LOG_NOTICE', 3);
-/** Log level */
-define('SIMPLEID_LOG_WARN', 2);
-/** Log level */
-define('SIMPLEID_LOG_ERROR', 1);
-/** Log level */
-define('SIMPLEID_LOG_FATAL', 0);
-
-/**
- * This variable holds the pointer to the currently opened log file.  If the
- * log file is not open, this variable is NULL.
- *
- * @global resource $log
- */
-$log = NULL;
-
-
-/**
- * Opens the log file.
- *
- * This function opens a pointed to the log file for later usage.
- *
- * @return bool true if the log file is opened successfully.
- */
-function log_open() {
-    global $log;
-    if (!defined('SIMPLEID_LOGFILE') || (SIMPLEID_LOGFILE == '')) return;
-    $log = fopen(SIMPLEID_LOGFILE, 'a');
-    
-    if ($log === false) {
-        $log = NULL;
-        return false;
-    } else {
-        return true;
-    }
-}
-
-/**
- * Closes the log file, if it is open.
- */
-function log_close() {
-    if ($log != NULL) {
-        fflush($log);
-        fclose($log);
-        $log = NULL;
-    }
-}
-
-/**
- * Logs a DEBUG message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_debug($message) {
-    _log_write($message, SIMPLEID_LOG_DEBUG);
-}
-
-/**
- * Logs an INFO message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_info($message) {
-    _log_write($message, SIMPLEID_LOG_INFO);
-}
-
-/**
- * Logs a NOTICE message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_notice($message) {
-    _log_write($message, SIMPLEID_LOG_NOTICE);
-}
-
-/**
- * Logs a WARN message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_warn($message) {
-    _log_write($message, SIMPLEID_LOG_WARN);
-}
-
-/**
- * Logs a ERROR message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_error($message) {
-    _log_write($message, SIMPLEID_LOG_ERROR);
-}
-
-/**
- * Logs a FATAL message.
- *
- * @param string $message the message to log
- * @see _log_write()
- */
-function log_fatal($message) {
-    _log_write($message, SIMPLEID_LOG_FATAL);
-}
-
-/**
- * Converts an array into a string for logging purposes.
- *
- * @param array $array the array the convert
- * @param array $keys an array of keys to include in the converted string.  Set
- * to false if all the keys in the array should be included
- * @return string the converted string.
- */
-function log_array($array, $keys = false) {
-    $output = array();
-    
-    if ($keys == false) $keys = array_keys($array);
-    
-    foreach ($keys as $key) {
-        $output[] = $key . ": " . $array[$key];
-    }
-    
-    return implode('; ', $output);
-}
-
-/**
- * Logs a message
- *
- * @param string $message the message to log
- * @param int $level the log level
- * @return bool true if the log has been written successfully
- */
-function _log_write($message, $level = false) {
-    global $log;
-    static $levels;
-    
-    if (!$levels) {
-        $levels = array(
-            SIMPLEID_LOG_DEBUG => 'DEBUG',
-            SIMPLEID_LOG_INFO => 'INFO',
-            SIMPLEID_LOG_NOTICE => 'NOTICE',
-            SIMPLEID_LOG_WARN => 'WARN',
-            SIMPLEID_LOG_ERROR => 'ERROR',
-            SIMPLEID_LOG_FATAL => 'FATAL'
-        );
-    }
-    
-    /* If a priority hasn't been specified, use the default value. */
-    if ($level === false) {
-        $level = SIMPLEID_LOG_INFO;
-    }
-
-    /* Abort early if the priority is above the maximum logging level. */
-    if ($level > SIMPLEID_LOGLEVEL) {
-        return false;
-    }
-
-    /* If the log file isn't already open, open it now. */
-    if (($log == NULL) && !log_open()) {
-        return false;
-    }
-
-    /* Build the string containing the complete log line. */
-    $line = sprintf('%1$s %2$s [%3$s] %4$s', strftime(SIMPLEID_DATE_TIME_FORMAT), session_id(), $levels[$level], $message) . "\n";
-
-    /* Write the log line to the log file. */
-    $success = (fwrite($log, $line) !== false);
-
-    return $success;
-}
-
-?>
diff --git a/simpleid/www/openid.inc.php b/simpleid/www/openid.inc.php
deleted file mode 100644
index 8507804..0000000
--- a/simpleid/www/openid.inc.php
+++ /dev/null
@@ -1,1054 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-10
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * OpenID related functions.
- *
- * @package simpleid
- * @filesource
- */
- 
-include_once "bignum.inc.php";
-include_once "random.inc.php";
- 
-/**
- * OpenID default modulus for Diffie-Hellman key exchange.
- *
- * @link http://openid.net/specs/openid-authentication-1_1.html#pvalue, http://openid.net/specs/openid-authentication-2_0.html#pvalue
- */
-define('OPENID_DH_DEFAULT_MOD', '155172898181473697471232257763715539915724801'.
-       '966915404479707795314057629378541917580651227423698188993727816152646631'.
-       '438561595825688188889951272158842675419950341258706556549803580104870537'.
-       '681476726513255747040765857479291291572334510643245094715007229621094194'.
-       '349783925984760375594985848253359305585439638443');
-
-/**
- * OpenID default generator for Diffie-Hellman key exchange.
- */
-define('OPENID_DH_DEFAULT_GEN', '2');
-
-/** Constant for the global variable {@link $version} */
-define('OPENID_VERSION_2', 2);
-/** Constant for the global variable {@link $version} */
-define('OPENID_VERSION_1_1', 1);
-
-/** Constant for OpenID namespace */
-define('OPENID_NS_2_0', 'http://specs.openid.net/auth/2.0');
-/** Constant for OpenID namespace */
-define('OPENID_NS_1_1', 'http://openid.net/signon/1.1');
-/** Constant for OpenID namespace */
-define('OPENID_NS_1_0', 'http://openid.net/signon/1.0');
-
-/**
- * Constant for the OP-local identifier which indicates that SimpleID should choose an identifier
- *
- * @link http://openid.net/specs/openid-authentication-2_0.html#anchor27
- */
-define('OPENID_IDENTIFIER_SELECT', 'http://specs.openid.net/auth/2.0/identifier_select');
-/** Constant for the XRDS service type for return_to verification */
-define('OPENID_RETURN_TO', 'http://specs.openid.net/auth/2.0/return_to');
-
-/** Parameter for {@link openid_indirect_response_url()} */
-define('OPENID_RESPONSE_QUERY', 0);
-/** Parameter for {@link openid_indirect_response_url()} */
-define('OPENID_RESPONSE_FRAGMENT', 1);
-
-/**
- * A mapping of Type URIs of OpenID extnesions to aliases provided in an OpenID
- * request.
- *
- * @global array $openid_ns_to_alias
- */
-$openid_ns_to_alias = array("http://openid.net/extensions/sreg/1.1" => "sreg"); // For sreg 1.0 compatibility
-
-
-/**
- * Detects the OpenID version of the current request
- *
- * @param mixed $request the OpenID request
- * @param string $key the key to look for to determine the OpenID
- * version
- * @return float either OPENID_VERSION_2 or OPENID_VERSION_1_1
- * @see $version
- *
- */
-function openid_get_version($request, $key = 'openid.ns') {
-    if (!isset($request[$key])) return OPENID_VERSION_1_1;
-    if ($request[$key] != OPENID_NS_2_0) return OPENID_VERSION_1_1;
-    return OPENID_VERSION_2;
-}
-
-/**
- * Creates a OpenID message for direct response.
- *
- * The response will be encoded using Key-Value Form Encoding.
- *
- * @param array $data the data in the response
- * @param float $version the message version
- * @return string the message in key-value form encoding
- * @link http://openid.net/specs/openid-authentication-1_1.html#anchor32, http://openid.net/specs/openid-authentication-2_0.html#kvform
- */
-function openid_direct_message($data, $version = OPENID_VERSION_2) {
-    $message = '';
-    $ns = '';
-    
-    // Add namespace for OpenID 2
-    if ($version == OPENID_VERSION_2) $ns = OPENID_NS_2_0;
-    if (($ns != '') && !isset($data['ns'])) $data['ns'] = $ns;
-    
-    foreach ($data as $key => $value) {
-        // Filter out invalid characters
-        if (strpos($key, ':') !== false) return null;
-        if (strpos($key, "\n") !== false) return null;
-        if (strpos($value, "\n") !== false) return null;
-        
-        $message .= "$key:$value\n";
-    }
-    return $message;
-}
-
-/**
- * Sends a direct response.
- *
- * @param string $message an OpenID message encoded using Key-Value Form
- * @param string $status the HTTP status to send
- */
-function openid_direct_response($message, $status = '200 OK') {
-    if (substr(PHP_SAPI, 0, 3) === 'cgi') {
-        header("Status: $status");
-    } else {
-        header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status);
-    }
-    
-    header("Content-Type: text/plain");
-    print $message;
-}
-
-/**
- * Creates a OpenID message for indirect response.
- *
- * The response will be encoded using HTTP Encoding.
- *
- * @param array $data the data in the response
- * @param float $version the message version
- * @return array the message
- * @link http://openid.net/specs/openid-authentication-2_0.html#indirect_comm
- */
-function openid_indirect_message($data, $version = OPENID_VERSION_2) {
-    $ns = '';
-    
-    // Add namespace for OpenID 2
-    if ($version == OPENID_VERSION_2) $ns = OPENID_NS_2_0;
-    if (($ns != '') && !isset($data['openid.ns'])) $data['openid.ns'] = $ns;
-    
-    return $data;
-}
-
-/**
- * Sends an indirect response to a URL.
- *
- * The indirect message is encoded in the URL and returned to the user agent using
- * a HTTP redirect response.  The message can be encoded in either the query component
- * or the fragment component of the URL.
- *
- * @param string $url the URL to which the response is to be sent
- * @param array|string $message an OpenID message, which can either be an array of keys
- * and values, or a URL-encoded query string
- * @param int $component the component of the URL in which the indirect message is
- * encoded, either OPENID_RESPONSE_QUERY or OPENID_RESPONSE_FRAGMENT
- */ 
-function openid_indirect_response($url, $message, $component = OPENID_RESPONSE_QUERY) {
-    if (substr(PHP_SAPI, 0,3) === 'cgi') {
-        header('Status: 303 See Other');
-    } else {
-        header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other');
-    }
-
-    header('Location: ' . openid_indirect_response_url($url, $message, $component));
-    exit;
-}
-
-/**
- * Encodes an indirect message into a URL
- *
- * @param string $url the URL to which the response is to be sent
- * @param array|string $message an OpenID message, which can either be an array of keys
- * and values, or a URL-encoded query string
- * @param int $component the component of the URL in which the indirect message is
- * encoded, either OPENID_RESPONSE_QUERY or OPENID_RESPONSE_FRAGMENT
- * @return string the URL to which the response is to be sent, with the
- * encoded message
- */
-function openid_indirect_response_url($url, $message, $component = OPENID_RESPONSE_QUERY) {
-    // 1. Firstly, get the query string
-    $query = '';
-    
-    if (is_array($message)) {
-        $query = openid_urlencode_message($message);
-    } else {
-        $query = $message;
-    }
-    
-    // 2. If there is no query string, then we just return the URL
-    if (!$query) return $url;
-    
-    // 3. The URL may already have a query and a fragment.  If this is so, we
-    //    need to slot in the new query string properly.  We disassemble and
-    //    reconstruct the URL.
-    $parts = parse_url($url);
-    
-    $url = $parts['scheme'] . '://';
-    if (isset($parts['user'])) {
-        $url .= $parts['user'];
-        if (isset($parts['pass'])) $url .= ':' . $parts['pass'];
-        $url .= '@';
-    }
-    $url .= $parts['host'];
-    if (isset($parts['port'])) $url .= ':' . $parts['port'];
-    if (isset($parts['path'])) $url .= $parts['path'];
-    
-    if (($component == OPENID_RESPONSE_QUERY) || (strpos($url, '#') === FALSE)) {
-        $url .= '?' . ((isset($parts['query'])) ? $parts['query'] . '&' : '') . $query;
-        if (isset($parts['fragment'])) $url .= '#' . $parts['fragment'];
-    } elseif ($component == OPENID_RESPONSE_FRAGMENT) {
-        // In theory $parts['fragment'] should be an empty string, but the
-        // current draft specification does not prohibit putting other things
-        // in the fragment.
-        
-        if (isset($parts['query'])) {
-            $url .= '?' . $parts['query'] . '#' . $parts['fragment'] . '&' . $query;
-        } else {
-            $url .= '#' . $parts['fragment'] . '?' . $query;
-        }
-    }
-    return $url;
-}
-
-/**
- * Encodes a message in application/x-www-form-urlencoded format.
- *
- * @param array $message the OpenID message to encode
- * @return string the encoded message
- * @since 0.8
- */
-function openid_urlencode_message($message) {
-    $pairs = array();
-    
-    foreach ($message as $key => $value) {
-        $pairs[] = $key . '=' . rfc3986_urlencode($value);
-    }
-        
-    return implode('&', $pairs);
-}
-
-/**
- * Sends a direct message indicating an error.  This is a convenience function
- * for {@link openid_direct_response()}.
- *
- * @param string $error the error message
- * @param array $additional any additional data to be sent with the error
- * message
- * @param float $version the message version
- */
-function openid_direct_error($error, $additional = array(), $version = OPENID_VERSION_2) {
-    $message = openid_direct_message(array_merge(array('error' => $error), $additional), $version);
-    openid_direct_response($message, '400 Bad Request');
-}
-
-/**
- * Sends an indirect message indicating an error.  This is a convenience function
- * for {@link openid_indirect_response()}.
- *
- * @param string $url the URL to which the error message is to be sent
- * @param string $error the error message
- * @param array $additional any additional data to be sent with the error
- * message
- * @param float $version the message version
- * @param int $component the component of the URL in which the indirect message is
- * encoded, either OPENID_RESPONSE_QUERY or OPENID_RESPONSE_FRAGMENT
- */
-function openid_indirect_error($url, $error, $additional = array(), $version = OPENID_VERSION_2, $component = OPENID_RESPONSE_QUERY) {
-    $message = openid_indirect_message(array_merge(array('openid.mode'=> 'error', 'openid.error' => $error), $additional), $version);
-    openid_indirect_response($url, $message, $component);
-}
-
-/**
- * Gets the realm from the OpenID request.  This is specified differently
- * depending on the OpenID version.
- *
- * @param mixed $request the OpenID request
- * @param float $version the OpenID version for the message
- * @return string the realm URI
- */
-function openid_get_realm($request, $version) {
-    if ($version == OPENID_VERSION_1_1) {
-        $realm = $request['openid.trust_root'];
-    }
-
-    if ($version >= OPENID_VERSION_2) {
-        $realm = $request['openid.realm'];
-    }
-    
-    if (!$realm) {
-        $realm = $request['openid.return_to'];
-    }
-    
-    return $realm;
-}
-
-/**
- * Parses a direct message.
- *
- * @param string $message the direct message to parse
- * @return array an array containing the parsed key-value pairs
- *
- * @since 0.7
- */
-function openid_parse_direct_message($message) {
-    $data = array();
-
-    $items = explode("\n", $message);
-    foreach ($items as $item) {
-        list ($key, $value) = explode(':', $item, 2);
-        $data[$key] = $value;
-    }
-
-    return $data;
-}
-
-/**
- * Parses a query string.
- *
- * Query strings can be used to receive OpenID indirect messages.
- *
- * @param string $query the query string to parse
- * @return array an array containing the parsed key-value pairs
- *
- * @since 0.7
- */
-function openid_parse_query($query) {
-    $data = array();
-    
-    if ($query === NULL) return array();
-    if ($query === '') return array();
-    
-    $pairs = explode('&', $query);
-    
-    foreach ($pairs as $pair) {
-        list ($key, $value) = explode('=', $pair, 2);
-        $data[$key] = urldecode($value);
-    }
-
-    return $data;
-}
-
-/**
- * Parses the OpenID request to extract namespace information.
- *
- * This function builds a map between namespace aliases and their Type URIs.
- *
- * @param array $request the OpenID request
- */
-function openid_parse_request($request) {
-    global $openid_ns_to_alias;
-    
-    foreach ($request as $key => $value) {
-        if (strpos($key, 'openid.ns.') === 0) {
-            $alias = substr($key, 10);
-            $openid_ns_to_alias[$value] = $alias;
-        }
-    }
-}
-
-/**
- * Determines whether a URL matches a realm.
- *
- * A URL matches a realm if:
- *
- * 1. The URL scheme and port of the URL are identical to those in the realm.
- *    See RFC 3986, section 3.1 for rules about URI matching.
- * 2. The URL's path is equal to or a sub-directory of the realm's path.
- * 3. Either:
- *    (a) The realm's domain contains the wild-card characters "*.", and the
- *        trailing part of the URL's domain is identical to the part of the
- *        realm following the "*." wildcard, or
- *    (b) The URL's domain is identical to the realm's domain
- *
- * @param string $url to URL to test
- * @param string $realm the realm
- * @return bool true if the URL matches the realm
- * @since 0.6
- */
-function openid_url_matches_realm($url, $realm) {
-    $url = parse_url($url);
-    $realm = parse_url($realm);
-    
-    foreach(array('user', 'pass', 'fragment') as $key) {
-        if (array_key_exists($key, $url) || array_key_exists($key, $realm))
-            return false;
-    }
-    
-    if ($url['scheme'] != $realm['scheme']) return false;
-    
-    if (!isset($url['port']))
-        $url['port'] = '';
-    if (!isset($realm['port']))
-        $realm['port'] = '';
-    if (($url['port'] != $realm['port']))
-        return false;
-    
-    if (substr($realm['host'], 0, 2) == '*.') {
-        $realm_re = '/^([^.]+\.)?' . preg_quote(substr($realm['host'], 2)) . '$/i';
-    } else {
-        $realm_re = '/^' . preg_quote($realm['host']) . '$/i';
-    }
-    
-    if (!preg_match($realm_re, $url['host'])) return false;
-    
-    if (!isset($url['path']))
-        $url['path'] = '';
-    if (!isset($realm['path']))
-        $realm['path'] = '';
-    if (substr($realm['path'], -1) == '/') $realm['path'] = substr($realm['path'], 0, -1);
-    if (($url['path'] != $realm['path']) && !preg_match('#^' . preg_quote($realm['path']) . '/.*$#', $url['path'])) return false;
-    
-    return true;
-}
-
-/**
- * Returns the URL of a relying party endpoint for a specified realm.  This URL
- * is used to discover services associated with the realm.
- *
- * If the realm's domain contains the wild-card characters "*.", this is substituted
- * with "www.".
- *
- * @param string $realm the realm
- * @url string the URL
- *
- * @since 0.7
- */
-function openid_realm_discovery_url($realm) {
-    $parts = parse_url($realm);
-    $host = strtr($parts['host'], array('*.' => 'www.'));;
-    
-    $url = $parts['scheme'] . '://';
-    if (isset($parts['user'])) {
-        $url .= $parts['user'];
-        if (isset($parts['pass'])) $url .= ':' . $parts['pass'];
-        $url .= '@';
-    }
-    $url .= $host;
-    if (isset($parts['port'])) $url .= ':' . $parts['port'];
-    if (isset($parts['path'])) $url .= $parts['path'];
-    if (isset($parts['query'])) $url .= '?' . $parts['query'];
-    if (isset($parts['fragment'])) $url .= '#' . $parts['fragment'];
-    return $url;
-}
-
-/**
- * Verifies a return_to URL against the actual URL of the HTTP request.
- *
- * The return_to URL matches if:
- *
- * - The URL scheme, authority, and path are the same; and
- * - Any query parameters that are present in the return_to URL are also present
- *   with the same values in the actual request.
- *
- * @param string $return_to the URL specified in the openid.return_to parameter
- * @param string $actual_url the actual URL requested
- * @return bool true if the URLs match
- *
- * @since 0.7
- */
-function openid_verify_return_to($return_to, $actual_url) {
-    $expected = parse_url($return_to);
-    $actual = parse_url($actual_url);
-    
-    // Schemes are case insensitive
-    if (strtoupper($expected['scheme']) != strtoupper($actual['scheme'])) return false;
-    
-    // Hosts are case insensitive
-    if (strtoupper($expected['host']) != strtoupper($actual['host'])) return false;
-    
-    if (!isset($expected['port']))
-        $expected['port'] = '';
-    if (!isset($actual['port']))
-        $actual['port'] = '';
-    if ($expected['port'] != $actual['port']) return false;
-    
-    if (!isset($expected['path']))
-        $expected['path'] = '';
-    if (!isset($actual['path']))
-        $actual['path'] = '';
-    if ($expected['path'] != $actual['path']) return false;
-    
-    if ($expected['query']) {
-        $expected_query = openid_parse_query($expected['query']);
-        $actual_query = openid_parse_query($actual['query']);
-        
-        foreach ($expected_query as $key => $value) {            
-            if (!array_key_exists($key, $actual_query)) return false;
-            if ($value != $actual_query[$key]) return false;
-        }
-    }
-    
-    return true;
-}
-
-/**
- * Filters an OpenID request to find keys specific to an extension, as specified
- * by the Type URI.
- *
- * For exmaple, if the extension has the Type URI http://example.com/ and the
- * alias example, this function will return an array of all the keys in the
- * OpenID request which starts with openid.example
- *
- * @param string $ns the Type URI of the extension
- * @param array $request the OpenID request
- * @return array the filtered request, with the prefix (in the example above,
- * openid.example.) stripped in the keys.
- */
-function openid_extension_filter_request($ns, $request) {
-    global $openid_ns_to_alias;
-    
-    if (!isset($openid_ns_to_alias[$ns])) return array();
-    
-    $alias = $openid_ns_to_alias[$ns];
-    $return = array();
-    
-    if (is_array($request)) {
-        foreach ($request as $key => $value) {
-            if ($key == 'openid.' . $alias) {
-                $return['#default'] = $value;
-            }
-            if (strpos($key, 'openid.' . $alias . '.') === 0) {
-                $return[substr($key, strlen('openid.' . $alias . '.'))] = $value;
-            }
-        }
-    }
-    
-    return $return;
-}
-
-/**
- * Determines whether an extension is present in an OpenID request.
- *
- * @param string $ns the Type URI of the extension
- * @param array $request the OpenID request
- * @return bool true if the extension is present in the request
- */
-function openid_extension_requested($ns, $request) {
-    global $openid_ns_to_alias;
-    
-    if (!isset($openid_ns_to_alias[$ns])) return false;
-    $alias = $openid_ns_to_alias[$ns];
-    
-    if (is_array($request)) {
-        foreach ($request as $key => $value) {
-            if ((strpos($key, 'openid.' . $alias . '.') === 0) || (strpos($key, 'openid.' . $alias . '=') === 0)) {
-                return true;
-            }
-        }
-    }
-    
-    return false;
-}
-
-/**
- * Returns the OpenID alias for an extension, given a Type URI, based on the
- * alias definitions in the current OpenID request.
- *
- * @param string $ns the Type URI
- * @param bool|string $create whether to create an alias if the Type URI does not already
- * have an alias in the current OpenID request.  If this parameter is a string,
- * then the string specified is the preferred alias to be created, unless a collision
- * occurs
- * @return string the alias, or NULL if the Type URI does not already
- * have an alias in the current OpenID request <i>and</i> $create is false
- */
-function openid_extension_alias($ns, $create = FALSE) {
-    global $openid_ns_to_alias;
-    static $e = 1;
-    
-    if (isset($openid_ns_to_alias[$ns])) return $openid_ns_to_alias[$ns];
-    if ($create !== FALSE) {
-        if ($create === TRUE) {
-            $alias = 'e' . $e;
-            $e++;
-        } elseif (is_string($create)) {
-            $used_aliases = array_values($openid_ns_to_alias);
-        
-            $alias = $create;
-            $i = 0;
-        
-            while (in_array($alias, $used_aliases)) {
-                $i++;
-                $alias = $create . $i;
-            }
-        }
-        $openid_ns_to_alias[$ns] = $alias;
-        return $alias;
-    }
-    return NULL;
-}
-
-
-/* ------- OpenID nonce functions -------------------------------------------- */
-/**
- * Generates a nonce for use in OpenID responses
- *
- * @return string an OpenID nonce
- * @link http://openid.net/specs/openid-authentication-2_0.html#positive_assertions
- */
-function openid_nonce() {
-    return gmstrftime('%Y-%m-%dT%H:%M:%SZ') . bin2hex(random_bytes(4));
-}
-
-/* ------- Diffie-Hellman Key Exchange functions ----------------------------- */
-
-/**
- * Returns the association types supported by this server.
- *
- * @return array an array containing the association types supported by this server as keys
- * and an array containing the key size (mac_size) and HMAC function (hmac_func) as
- * values
- */
-function openid_association_types() {
-    $association_types = array('HMAC-SHA1' => array('mac_size' => 20, 'hmac_func' => '_openid_hmac_sha1'));
-    if (OPENID_SHA256_SUPPORTED) $association_types['HMAC-SHA256'] = array('mac_size' => 32, 'hmac_func' => '_openid_hmac_sha256');
-    return $association_types;
-}
-
-/**
- * Returns the association types supported by this server and the version of
- * OpenID.
- *
- * OpenID version 1 supports an empty string as the session type.  OpenID version 2
- * reqires a session type to be sent.
- *
- * @param bool $is_https whether the transport layer encryption is used for the current
- * connection
- * @param float $version the OpenID version, either OPENID_VERSION_1_1 and OPENID_VERSION_2
- * @return array an array containing the session types supported by this server as keys
- * and an array containing the hash function (hash_func) as
- * values
- */
-function openid_session_types($is_https = FALSE, $version = OPENID_VERSION_2) {
-    $session_types = array(
-        'DH-SHA1' => array('hash_func' => '_openid_sha1'),
-    );
-    if (OPENID_SHA256_SUPPORTED) $session_types['DH-SHA256'] = array('hash_func' => '_openid_sha256');
-    if (($version >= OPENID_VERSION_2) && ($is_https == TRUE)) {
-        // Under OpenID 2.0 no-encryption is only allowed if TLS is used
-        $session_types['no-encryption'] = array();
-    }
-    if ($version == OPENID_VERSION_1_1) $session_types[''] = array();
-    return $session_types;
-}
-
-/**
- * Generates the cryptographic values required for responding to association
- * requests
- *
- * This involves generating a key pair for the OpenID provider, then calculating
- * the shared secret.  The shared secret is then used to encrypt the MAC key.
- *
- * @param string $mac_key the MAC key, in binary representation
- * @param string $dh_consumer_public the consumer's public key, in Base64 representation
- * @param string $dh_modulus modulus - a large prime number
- * @param string $dh_gen generator - a primitive root modulo
- * @param string $hash_func the hash function
- * @return array an array containing (a) dh_server_public - the server's public key (in Base64), and (b)
- * enc_mac_key encrypted MAC key (in Base64), encrypted using the Diffie-Hellman shared secret
- */
-function openid_dh_server_assoc($mac_key, $dh_consumer_public, $dh_modulus = NULL, $dh_gen = NULL, $hash_func = '_openid_sha1') {
-    
-    // Generate a key pair for the server
-    $key_pair = openid_dh_generate_key_pair($dh_modulus, $dh_gen);
-    
-    // Generate the shared secret
-    $ZZ = openid_dh_shared_secret($dh_consumer_public, $key_pair['private'], $dh_modulus);
-
-    return array(
-        'dh_server_public' => $key_pair['public'],
-        'enc_mac_key' => openid_encrypt_mac_key($ZZ, $mac_key, $hash_func)
-    );
-}
-
-/**
- * Complete association by obtaining the session MAC key from the key obtained
- * from the Diffie-Hellman key exchange
- *
- * @param string $enc_mac_key the encrypted session MAC key, in Base64 represnetation
- * @param string $dh_server_public the server's public key, in Base64 representation
- * @param string $dh_consumer_private the consumer's private key, in Base64 representation
- * @param string $dh_modulus modulus, in Base64 representation
- * @param string $hash_func the hash function
- * @return string the decrypted session MAC key, in Base64 representation
- */
-function openid_dh_consumer_assoc($enc_mac_key, $dh_server_public, $dh_consumer_private, $dh_modulus = NULL, $hash_func = '_openid_sha1') {
-    // Retrieve the shared secret
-    $ZZ = openid_dh_shared_secret($dh_server_public, $dh_consumer_private, $dh_modulus);
-    
-    // Decode the encrypted MAC key
-    $encrypted_mac_key = base64_decode($enc_mac_key);
-    
-    return openid_encrypt_mac_key($ZZ, $encrypted_mac_key, $hash_func);
-}
-
-/**
- * Calculates the shared secret for Diffie-Hellman key exchange.
- *
- * This is the second step in the Diffle-Hellman key exchange process.  The other
- * party (in OpenID 1.0 terms, the consumer) has already generated the public
- * key ($dh_consumer_public) and sent it to this party (the server).  The Diffie-Hellman
- * modulus ($dh_modulus) and generator ($dh_gen) have either been sent or previously agreed.
- *
- * @param string $their_public the other party's public key, in Base64 representation
- * @param string $my_private this party's private key, in Base64 representation
- * @param string $dh_modulus modulus, in Base64 representation
- * @return resource the shared secret (as a bignum)
- *
- * @see openid_dh_generate_key_pair()
- * @link http://www.ietf.org/rfc/rfc2631.txt RFC 2631
- */
-function openid_dh_shared_secret($their_public, $my_private, $dh_modulus = NULL) {
-    // Decode the keys
-    $y = _openid_base64_to_bignum($their_public);
-    $x = _openid_base64_to_bignum($my_private);
-    
-    if ($dh_modulus != NULL) {
-        $p = _openid_base64_to_bignum($dh_modulus);
-    } else {
-        $p = bignum_new(OPENID_DH_DEFAULT_MOD);
-    }
-
-    // Generate the shared secret = their public ^ my private mod p = my public ^ their private mod p
-    $ZZ = bignum_powmod($y, $x, $p);
-
-    return $ZZ;
-}
-
-/**
- * Generates a key pair for Diffie-Hellman key exchange.
- *
- * @param string $dh_modulus modulus, in Base64 representation
- * @param string $dh_gen generator, in Base64 representation
- * @return array an array containing: (a) private - the private key, in Base64
- * and (b) public - the public key, in Base64
- */
-function openid_dh_generate_key_pair($dh_modulus = NULL, $dh_gen = NULL) {
-    if ($dh_modulus != NULL) {
-        $p = _openid_base64_to_bignum($dh_modulus);
-    } else {
-        $p = bignum_new(OPENID_DH_DEFAULT_MOD);
-    }
-
-    if ($dh_gen != NULL) {
-        $g = _openid_base64_to_bignum($dh_gen);
-    } else {
-        $g = bignum_new(OPENID_DH_DEFAULT_GEN);
-    }
-
-    // Generate the private key - a random number which is less than p
-    $rand = _openid_dh_rand($p);
-    $x = bignum_add($rand, 1);
-    
-    // Calculate the public key is g ^ private mod p
-    $y = bignum_powmod($g, $x, $p);
-    
-    return array('private' => _openid_bignum_to_base64($x), 'public' => _openid_bignum_to_base64($y));
-}
-
-
-/**
- * Encrypts/decrypts and encodes the MAC key.
- *
- * @param resource $ZZ the Diffie-Hellman key exchange shared secret as a bignum
- * @param string $mac_key a byte stream containing the MAC key
- * @param string $hash_func the hash function
- * @return string the encrypted MAC key in Base64 representation
- */
-function openid_encrypt_mac_key($ZZ, $mac_key, $hash_func = '_openid_sha1') {
-    // Encrypt/decrypt the MAC key using the shared secret and the hash function
-    $encrypted_mac_key = _openid_xor($ZZ, $mac_key, $hash_func);
-    
-    // Encode the encrypted/decrypted MAC key
-    $enc_mac_key = base64_encode($encrypted_mac_key);
-    
-    return $enc_mac_key;
-}
-
-/**
- * Encrypts/decrypts using XOR.
- *
- * @param string $key the encryption key as a bignum.  This is usually
- * the shared secret (ZZ) calculated from the Diffie-Hellman key exchange
- * @param string $plain_cipher the plaintext or ciphertext
- * @param string $hash_func the hash function
- * @return string the ciphertext or plaintext
- */
-function _openid_xor($key, $plain_cipher, $hash_func = '_openid_sha1') {
-    $decoded_key = bignum_val($key, 256);
-    $hashed_key = call_user_func($hash_func, $decoded_key);
-    
-    $cipher_plain = "";
-    for ($i = 0; $i < strlen($plain_cipher); $i++) {
-        $cipher_plain .= chr(ord($plain_cipher[$i]) ^ ord($hashed_key[$i]));
-    }
-  
-    return $cipher_plain;
-}
-
-/**
- * Generates a random integer, which will be used to derive a private key
- * for Diffie-Hellman key exchange.  The integer must be less than $stop
- *
- * @param resource $stop a prime number as a bignum
- * @return resource the random integer as a bignum
- */
-function _openid_dh_rand($stop) {
-    static $duplicate_cache = array();
-  
-    // Used as the key for the duplicate cache
-    $rbytes = bignum_val($stop, 256);
-  
-    if (array_key_exists($rbytes, $duplicate_cache)) {
-        list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
-    } else {
-        if ($rbytes[0] == "\x00") {
-            $nbytes = strlen($rbytes) - 1;
-        } else {
-            $nbytes = strlen($rbytes);
-        }
-    
-        $mxrand = bignum_pow(bignum_new(256), $nbytes);
-
-        // If we get a number less than this, then it is in the
-        // duplicated range.
-        $duplicate = bignum_mod($mxrand, $stop);
-
-        if (count($duplicate_cache) > 10) {
-            $duplicate_cache = array();
-        }
-    
-        $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
-    }
-  
-    do {
-        $bytes = "\x00" . random_bytes($nbytes);
-        $n = bignum_new($bytes, 256);
-        // Keep looping if this value is in the low duplicated range
-    } while (bignum_cmp($n, $duplicate) < 0);
-
-    return bignum_mod($n, $stop);
-}
-
-/* ------- Arbitary precision arithmetic and conversion functions ------------ */
-/**
- * Converts an arbitary precision integer, encoded in Base64, to a bignum
- *
- * @param string $str arbitary precision integer, encoded in Base64
- * @return resource the string representation
- */
-function _openid_base64_to_bignum($str) {
-    return bignum_new(base64_decode($str), 256);
-}
-
-/**
- * Converts a string representation of an integer to an arbitary precision
- * integer, then converts it to Base64 encoding.
- *
- * @param string $str the string representation
- * @return string the Base64 encoded arbitary precision integer
- */
-function _openid_bignum_to_base64($str) {
-    return base64_encode(bignum_val($str, 256));
-}
-
-/**
- * Encode an integer as big-endian signed two's complement binary string.
- *
- * @param string $num the binary integer
- * @return string the signed two's complement binary string
- * @link http://openid.net/specs/openid-authentication-2_0.html#btwoc
- */
-function _openid_btwoc($num) {
-    return pack('H*', $num);
-}
-
-/* ------- Hash and HMAC functions ------------------------------------------- */
-/**
- * Calculates a signature of an OpenID message
- *
- * @param array $data the data in the message
- * @param array $keys a list of keys in the message to be signed (without the
- * 'openid.' prefix)
- * @param string $mac_key the MAC key used to sign the message, in Base64 representation
- * @param string $hmac_func the HMAC function used in the signing process
- * @param float $version the OpenID version
- * @return string the signature encoded in Base64
- */
-function openid_sign($data, $keys, $mac_key, $hmac_func = '_openid_hmac_sha1', $version = OPENID_VERSION_2) {
-    $signature = '';
-    $sign_data = array();
-
-    foreach ($keys as $key) {
-        if (array_key_exists('openid.' . $key, $data)) {
-            $sign_data[$key] = $data['openid.' . $key];
-        }
-    }
-    
-    $signature_base_string = _openid_signature_base_string($sign_data, $version);
-    $secret = base64_decode($mac_key);
-    $signature = call_user_func($hmac_func, $secret, $signature_base_string);
-
-    return base64_encode($signature);
-}
-
-/**
- * Calculates the base string from which an OpenID signature is generated.
- *
- * OpenID versions 1 and 2 specify that messages are to be encoded using Key-Value
- * Encoding when generating signatures.  However, future OpenID version may
- * specify different ways of encoding the message, such as OAuth.
- * 
- * @param array $data the data to sign
- * @param float $version the OpenID version
- * @return string the signature base string
- * @link http://openid.net/specs/openid-authentication-2_0.html#anchor11
- */
-function _openid_signature_base_string($data, $version) {
-    switch ($version) {
-        case OPENID_VERSION_1_1:
-        case OPENID_VERSION_2:
-            // We set OPENID_VERSION_1_1 because we don't want to sign the namespace header
-            $signature_base_string = openid_direct_message($data, OPENID_VERSION_1_1);
-            break;
-        default:
-            // We set OPENID_VERSION_1_1 because we don't want to sign the namespace header
-            $signature_base_string = openid_direct_message($data, OPENID_VERSION_1_1);
-    }
-    return $signature_base_string;
-}
-
-/**
- * Obtains the SHA1 hash of a string in binary representation.
- *
- * @param string $text the text to be hashed
- * @return string the hash in binary representation
- */
-function _openid_sha1($text) {
-    return sha1($text, true);
-}
-
-/**
- * Obtains the keyed hash value using the HMAC method and the SHA1 algorithm
- *
- * @param string $key the key in binary representation
- * @param string $text the text to be hashed
- * @return string the hash in binary representation
- */
-function _openid_hmac_sha1($key, $text) {
-    if (function_exists('hash_hmac') && function_exists('hash_algos') && (in_array('sha1', hash_algos()))) {
-        return hash_hmac('sha1', $text, $key, true);
-    } else {
-        if (!defined('OPENID_SHA1_BLOCKSIZE')) define('OPENID_SHA1_BLOCKSIZE', 64);
-        
-        if (strlen($key) > OPENID_SHA1_BLOCKSIZE) {
-            $key = _openid_sha1($key);
-        }
-    
-        $key = str_pad($key, OPENID_SHA1_BLOCKSIZE, chr(0x00));
-        $ipad = str_repeat(chr(0x36), OPENID_SHA1_BLOCKSIZE);
-        $opad = str_repeat(chr(0x5c), OPENID_SHA1_BLOCKSIZE);
-        $hash1 = _openid_sha1(($key ^ $ipad) . $text);
-        $hmac = _openid_sha1(($key ^ $opad) . $hash1);
-        return $hmac;
-    }
-}
-
-// Check if SHA-256 support is available
-if (function_exists('hash_hmac') && function_exists('hash_algos') && (in_array('sha256', hash_algos()))) {
-    
-    /**
-     * Whether the current installation of PHP supports SHA256.  SHA256 is supported
-     * if the hash module is properly compiled and loaded into PHP.
-     */
-    define('OPENID_SHA256_SUPPORTED', true);
-    
-    /**
-     * Obtains the SHA256 hash of a string in binary representation.
-     *
-     * @param string $text the text to be hashed
-     * @return string $hash the hash in binary representation
-     */
-    function _openid_sha256($text) {
-        return hash('sha256', $text, true);
-    }
-    
-    /**
-     * Obtains the keyed hash value using the HMAC method and the SHA256 algorithm
-     *
-     * @param string $key the key in binary representation
-     * @param string $text the text to be hashed
-     * @return string the hash in binary representation
-     */
-    function _openid_hmac_sha256($key, $text) {
-        return hash_hmac('sha256', $text, $key, true);
-    }
-} else {
-    /** @ignore */
-    define('OPENID_SHA256_SUPPORTED', false);
-}
-
-if (!function_exists('rfc3986_urlencode')) {
-    /**
-     * Encodes a URL using RFC 3986.
-     *
-     * PHP's rfc3986_urlencode function encodes a URL using RFC 1738 for PHP versions
-     * prior to 5.3.  RFC 1738 has been
-     * updated by RFC 3986, which change the list of characters which needs to be
-     * encoded.
-     *
-     * Strictly correct encoding is required for various purposes, such as OAuth
-     * signature base strings.
-     *
-     * @param string $s the URL to encode
-     * @return string the encoded URL
-     */
-    function rfc3986_urlencode($s) {
-        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-            return rawurlencode($s);
-        } else {
-            return str_replace('%7E', '~', rawurlencode($s));
-        }
-    }
-}
-?>
\ No newline at end of file
diff --git a/simpleid/www/page.inc.php b/simpleid/www/page.inc.php
deleted file mode 100644
index c1c5ef6..0000000
--- a/simpleid/www/page.inc.php
+++ /dev/null
@@ -1,331 +0,0 @@
-<?php 
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Functions for displaying various pages in SimpleID.
- *
- * @package simpleid
- * @filesource
- * @since 0.7
- */
- 
-/**
- * Displays the dashboard page.
- */
-function page_dashboard() {
-    global $user;
-    global $xtpl;
-    
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-    
-    if ($user == NULL) {
-        user_login_form('');
-        return;
-    }
-    
-    user_header();
-    page_nav();
-    
-    $blocks = _page_welcome_block();
-    
-    $blocks = array_merge($blocks, _page_dashboard_otp_block(), extension_invoke_all('page_dashboard'));
-    $blocks = array_map('page_render_block', $blocks);
-    $xtpl->assign('blocks', implode($blocks));
-    $xtpl->parse('main.blocks');
-    
-    $xtpl->assign('title', t('Dashboard'));
-    $xtpl->parse('main');
-    $xtpl->out('main');
-
-}
-
-/**
- * Displays the profile page.
- */
-function page_profile() {
-    global $user;
-    global $xtpl;
-    
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-    
-    if ($user == NULL) {
-        user_login_form('my/profile');
-        return;
-    }
-    
-    user_header();
-    page_nav();
-    
-    $blocks = _page_discovery_block();
-
-    $blocks = array_merge($blocks, _user_page_profile(), extension_invoke_all('page_profile'));
-    $blocks = array_map('page_render_block', $blocks); 
-    $xtpl->assign('blocks', implode($blocks));
-    $xtpl->parse('main.blocks');
-    
-    $xtpl->assign(array('js_locale_label' => 'code', 'js_locale_text' => addslashes(t('<em>You need to set at least one of OpenID 1.x or OpenID 2 to generate the code.</em>'))));
-    $xtpl->parse('main.js_locale');
-    
-    $xtpl->assign('javascript', '<script src="' . get_base_path() . 'html/page-profile.js" type="text/javascript"></script>');
-    $xtpl->assign('title', t('My Profile'));
-    $xtpl->parse('main');
-    $xtpl->out('main');
-}
-
-/**
- * Returns the user's home page.
- */
-function page_sites() {
-    global $user;
-    global $xtpl;
-    
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-    
-    if ($user == NULL) {
-        user_login_form('my/sites');
-        return;
-    }
-    
-    user_header();
-    page_nav();
-    
-    if (isset($user['rp'])) {
-        $user_rps =& $user['rp'];
-    } else {
-        $user_rps = array();
-    }
-    
-    if (isset($_POST['tk'])) {
-        if (!validate_form_token($_POST['tk'], 'autorelease')) {
-            set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-        } else {
-            if (isset($_POST['autorelease'])) {
-                foreach ($_POST['autorelease'] as $realm => $autorelease) {
-                    if (isset($user_rps[$realm])) {
-                        $user_rps[$realm]['auto_release'] = ($autorelease) ? 1 : 0;
-                    }
-                }
-            }
-            
-            if (isset($_POST['remove'])) {
-                foreach ($_POST['remove'] as $realm => $autorelease) {
-                    if (isset($user_rps[$realm])) {
-                        unset($user_rps[$realm]);
-                    }
-                }
-            }
-            
-            if (isset($_POST['update-all'])) {
-                foreach ($user_rps as $realm => $values) {
-                    $user_rps[$realm]['auto_release'] = (isset($_POST['autorelease'][$realm]) && $_POST['autorelease'][$realm]) ? 1 : 0;
-                }
-            }
-            
-            user_save($user);
-    
-            set_message(t('Your preferences have been saved.'));
-        }
-    }
-    
-    if ($user_rps) {
-        uksort($user_rps, '_page_sites_sort');
-        foreach ($user_rps as $realm => $rp) {
-            $xtpl->assign('realm_name', preg_replace('@^https?://(www\.|\*\.)?@', '<span class="url-elide">$0</span>', htmlspecialchars($rp['realm'], ENT_QUOTES, 'UTF-8')));
-            $xtpl->assign('realm', htmlspecialchars($rp['realm'], ENT_QUOTES, 'UTF-8'));
-            $xtpl->assign('last_time', htmlspecialchars($rp['last_time'], ENT_QUOTES, 'UTF-8'));
-            $xtpl->assign('last_time_formatted', htmlspecialchars(strftime(SIMPLEID_DATE_TIME_FORMAT, $rp['last_time']), ENT_QUOTES, 'UTF-8'));
-            $xtpl->assign('auto_release', (isset($rp['auto_release']) && $rp['auto_release']) ? 'checked="checked"' : '');
-            
-            if (SIMPLEID_VERIFY_RETURN_URL_USING_REALM) {
-                // $rp_info would usually expire by now, so we allow for stale results to be retrieved to improve performance
-                $rp_info = simpleid_get_rp_info($realm, TRUE);
-                if (!isset($rp_info['return_to_verified']) || !$rp_info['return_to_verified']) $xtpl->assign('realm_class', 'return-to-suspect');
-            }
-            
-            $xtpl->parse('main.sites.realm');
-        }
-    }
-    
-    if (!$user_rps || (count($user_rps) == 0)) {
-        $xtpl->assign('disabled', 'disabled="disabled"');
-    }
-    
-    $xtpl->assign('token', get_form_token('autorelease'));
-    
-    $xtpl->assign('realm_label', t('Site'));
-    $xtpl->assign('last_time_label', t('Last access'));
-    $xtpl->assign('auto_release_label', t('Automatic'));
-    $xtpl->assign('remove_label', t('Remove'));
-    $xtpl->assign('submit_button', t('Submit'));    
-    
-    $xtpl->parse('main.sites');
-    
-    $xtpl->assign(array('js_locale_label' => 'openid_suspect', 'js_locale_text' => addslashes(t('This web site has not confirmed its identity and might be fraudulent.')) . '\n\n' . addslashes(t('Are you sure you wish to automatically send your information to this site for any future requests?'))));
-    $xtpl->parse('main.js_locale');
-    
-    $xtpl->assign('title', t('My Sites'));
-    $xtpl->assign('javascript', '<script src="' . get_base_path() . 'html/openid-consent.js" type="text/javascript"></script>');
-    $xtpl->parse('main');
-    $xtpl->out('main');
-}
-
-/**
- * A custom sort function for realms.  This strips out the following:
- *
- * - http://
- * - https://
- * - www.
- * - *.
- *
- * @param string $a
- * @param string $b
- * @return int
- */
-function _page_sites_sort($a, $b) {
-    $a = preg_replace('@^https?://(www\.|\*\.)?@', '', $a);
-    $b = preg_replace('@^https?://(www\.|\*\.)?@', '', $b);
-    return strcasecmp($a, $b);
-}
-
-/**
- * Set up the navigation section in the header
- */
-function page_nav() {
-    global $user;
-    global $xtpl;
-    
-    $xtpl->assign('nav_base', trim(simpleid_url(' ', '', true)));
-    
-    $xtpl->assign('nav_dashboard_label', t('Dashboard'));
-    $xtpl->assign('nav_profile_label', t('My Profile'));
-    $xtpl->assign('nav_sites_label', t('My Sites'));
-    
-    $xtpl->parse('main.nav_toggle');
-    $xtpl->parse('main.nav');
-}
-
-/**
- * Renders a particular block.
- *
- * @param array $block the block to render
- * @return string the HTML of the rendered block
- */
-function page_render_block($block) {
-    static $xtpl_block;
-    
-    if (!$xtpl_block) $xtpl_block = new XTemplate('html/block.xtpl');
-    
-    $xtpl_block->reset('block');
-    $xtpl_block->assign('id', $block['id']);
-    $xtpl_block->assign('title', $block['title']);
-    $xtpl_block->assign('content', $block['content']);
-    
-    if (isset($block['links'])) {
-        $xtpl_block->assign('links', $block['links']);
-        $xtpl_block->parse('block.links');
-    }
-    
-    $xtpl_block->parse('block');
-    return $xtpl_block->text('block');
-}
-
-/**
- * Returns the welcome block.
- *
- * @return array the welcome block
- */
-function _page_welcome_block() {
-    global $user;
-    
-    return array(array(
-        'id' => 'welcome',
-        'title' => t('Welcome'),
-        'content' => t('You are logged in as %uid (%identity).', array('%uid' => $user['uid'], '%identity' => $user['identity']))
-    ));
-}
-
-/**
- * Returns the dashboard OTP block.
- *
- * @return array the dashboard OTP block
- */
-function _page_dashboard_otp_block() {
-    global $user;
-
-    $base_path = get_base_path();
-
-    $html = '<p>' . t('Login verification adds an extra layer of protection to your account. When enabled, you will need to enter an additional security code whenever you log into SimpleID.') . '</p>';
-
-    if (isset($user['otp'])) {
-        $html .= '<p>' . t('Login verification is <strong>enabled</strong>.') . '</p>';
-        $html .= '<form action="' . $base_path . 'index.php" method="post" enctype="application/x-www-form-urlencoded"><input type="hidden" name="tk" value="'. get_form_token('dashboard_otp') . '"/>';
-        $html .= '<input type="hidden" name="q" value="otp"/><input type="submit" name="op" value="' . t('Disable') . '" /></form>';
-    } else {
-        $html .= '<p>' . t('Login verification is <strong>disabled</strong>. To enable login verification, click the button below.') . '</p>';
-        $html .= '<form action="' . $base_path . 'index.php" method="post" enctype="application/x-www-form-urlencoded"><input type="hidden" name="tk" value="'. get_form_token('dashboard_otp') . '"/>';
-        $html .= '<input type="hidden" name="q" value="otp"/><input type="submit" name="op" value="' . t('Enable') . '" /></form>';
-    }
-    
-    return array(array(
-        'id' => 'otp',
-        'title' => t('Login Verification'),
-        'content' => $html
-    ));
-}
-
-/**
- * Returns a block containing discovery information.
- *
- * @return array the discovery block
- */
-function _page_discovery_block() {
-    global $user;
-    
-    $html = "<h3>" . t('&lt;link&gt; tags') . "</h3>";
-    
-    $html .= "<div><label><input type=\"checkbox\" name=\"openid1\" value=\"1\" id=\"discovery-openid1\" class=\"discovery-checkbox\" />" . t('OpenID 1.x') . "</label>";
-    $html .= "<label><input type=\"checkbox\" name=\"openid2\" value=\"1\" id=\"discovery-openid2\" class=\"discovery-checkbox\" />" . t('OpenID 2.0') . "</label>";
-    $html .= "<label><input type=\"checkbox\" name=\"local-id\" value=\"1\" id=\"discovery-local-id\" class=\"discovery-checkbox\" />" . t('Claim a different identifier') . "</label></div>";
-    $html .= "<pre id=\"discovery-link-tags\">";
-    $html .= "</pre>";
-    $html .= "<ul id=\"discovery-templates\"><li class=\"openid1\">&lt;link rel=&quot;openid.server&quot; href=&quot;" . htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8') . "&quot; /&gt;</li>\n";
-    $html .= "<li class=\"openid2\">&lt;link rel=&quot;openid2.provider&quot; href=&quot;" . htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8') ."&quot; /&gt;</li>\n";
-    $html .= "<li class=\"openid1-local-id\">&lt;link rel=&quot;openid.delegate&quot; href=&quot;" . htmlspecialchars($user['identity'], ENT_QUOTES, 'UTF-8') . "&quot; /&gt;</li>\n";
-    $html .= "<li class=\"openid2-local-id\">&lt;link rel=&quot;openid2.local_id&quot; href=&quot;" . htmlspecialchars($user['identity'], ENT_QUOTES, 'UTF-8') ."&quot; /&gt;</li></ul>\n";
-
-    $html .= "<h3>" . t('YADIS') . "</h3>";
-    $html .= "<ol><li>" . t('Write your own or <a href="!url">download</a> your YADIS document', array('!url' => simpleid_url('xrds/'. $user['uid'], '', true))) . "</li>";
-    $html .= "<li><div>" . t('Add HTTP headers or &lt;meta&gt; tag, e.g.:') . "<div><pre>&lt;meta http-equiv=&quot;X-XRDS-Location&quot; content=&quot;" . htmlspecialchars(simpleid_url('xrds/'. $user['uid']), ENT_QUOTES, 'UTF-8') . "&quot; /></pre>";
-    $html .= "</li></ol>";
-    
-    return array(array(
-        'id' => 'discovery',
-        'title' => t('Claim your Identifier'),
-        'content' => $html,
-        'links' => '<a href="http://simpleid.org/docs/1/identity-claim/">More information</a>'
-    ));
-}
-?>
diff --git a/simpleid/www/random.inc.php b/simpleid/www/random.inc.php
deleted file mode 100644
index efee496..0000000
--- a/simpleid/www/random.inc.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2010
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Functions related to generating random bits and unique values.
- *
- * @package simpleid
- * @since 0.8
- * @filesource
- */
-
-if (!defined('SIMPLEID_RAND_SOURCE')) {
-    /**
-     * The source of random bits.  On Unix-like systems, this could be /dev/random
-     * or /dev/urandom
-     */
-    define('SIMPLEID_RAND_SOURCE', '/dev/urandom');
-}
-
-/**
- * Obtains a number of random bytes.  This function uses an entropy source specified
- * in SIMPLEID_RAND_SOURCE.  If SIMPLEID_RAND_SOURCE is not available, the mt_rand()
- * PHP function is used
- * If the native PHP random_bytes function exists (PHP 7+), this function won't be defined here.
- *
- * @param int $num_bytes the number of bytes to generate
- * @return string a string containing random bytes
- */
-if(!function_exists('random_bytes')) {
-    function random_bytes($num_bytes) {
-        static $f = null;
-        $bytes = '';
-        if ($f === null) {
-            if (SIMPLEID_RAND_SOURCE === null) {
-                $f = FALSE;
-            } else {
-                $f = @fopen(SIMPLEID_RAND_SOURCE, "r");
-            }
-        }
-        if ($f === FALSE) {
-            $bytes = '';
-            for ($i = 0; $i < $num_bytes; $i += 4) {
-                $bytes .= pack('L', mt_rand());
-            }
-            $bytes = substr($bytes, 0, $num_bytes);
-        } else {
-            $bytes = fread($f, $num_bytes);
-        }
-        return $bytes;
-    }
-}
-
-/**
- * Obtains a random string of a specified number of bytes of entropy.
- *
- * The function calls the {@link random_bytes()} function with the specified
- * number of bytes, then converts to a string containing only alphanumeric
- * characters (case sensitive), plus the characters ., _ and -.
- *
- * The conversion method is based on the Base64 encoding.  However, non-standard
- * characters are used so that users are not confused and attempt to decode
- * the returned string.
- *
- * @param int $num_bytes the approximate number of bytes of entropy in the
- * random string
- * @return string the random string
- */
-function random_secret($num_bytes = 32) {
-    return strtr(base64_encode(random_bytes($num_bytes)),
-        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
-        '-_.9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA');
-}
-
-/**
- * Generates a relatively unique identifier which can be used as, among other things,
- * an OpenID association handle or an OAuth client identifier.  The identifier
- * returned is at least 24 characters long and contains only hexadecimal characters.
- *
- * Note that the identifier returned is not cryptographically secure.
- *
- * @return string a relatively unique identifier
- */
-function random_id() {
-    $timeofday = gettimeofday();
-    return vsprintf('%08x%08x', $timeofday) . bin2hex(random_bytes(4));
-}
-?>
diff --git a/simpleid/www/simpleweb.inc.php b/simpleid/www/simpleweb.inc.php
deleted file mode 100644
index 48cdbc6..0000000
--- a/simpleid/www/simpleweb.inc.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php 
-/*
- * SimpleWeb
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * Simpleweb is a minimalist web framework.  It is similar to {@link http://webpy.org web.py},
- * but in PHP.
- *
- * The key to Simpleweb is the <i>route array</i>.  The route array is an array that maps
- * URLs (called <i>patterns</i>) to PHP functions or methods (called <i>routes</i>).
- *
- * Patterns are regular expressions, which are tested against the URL one at a time.
- * Subpatterns (i.e. patterns within parentheses) are then passed on as arguments
- * to the route.
- *
- * Routes are either functions, static methods or object methods.  A function is
- * denoted by the function name.  A static method is denoted by the class name,
- * followed by :: then the method name.  An object method is denoted by the class
- * name, followed by -&gt; then the method name.  An instance of the class will be
- * created before an object method is called.
- *
- * An example of a routes array is given below:
- *
- * <code>
- * <?php
- * $routes = array(
- *     'a' => 'function1',
- *     'b/(.+)' => 'function2',   // arguments
- *     'c' => 'ClassA::method',   // static method
- *     'd' => 'ClassB->method',   // object method
- * );
- * ?>
- * </code>
- *
- * Once the route array is populated, the {@link simpleweb_run()} function
- * is then called to handle the URL.
- *
- * @package simpleweb
- * @since 0.7
- */
-
-/**
- * Handles a supplied request, based on a set of routes.
- *
- * @param array $routes the routes array, as described in {@link simpleweb.inc this page}
- * @param string $request_path the request path against which the routes are applied.  If
- * NULL, then the request URI supplied by the web server will be used.
- * @param string $not_found_route the default route if none of the patterns match.  If
- * NULL, then an HTTP 404 error is raised
- * @return mixed the result from calling the route.
- *
- */
- 
-function simpleweb_run($routes, $request_path = NULL, $not_found_route = NULL) {
-    if ($request_path == NULL) {
-        // We take the request path from the request URI
-        $request_path = $_SERVER['REQUEST_URI'];
-        
-        // Strip off all parts to the script file name.  Sadly, PHP is historically
-        // buggy in its treatment of SCRIPT_NAME, so we need to try a few methods
-        // to strip them
-        $script_name = basename($_SERVER['SCRIPT_NAME']);
-        $script_dir = dirname($_SERVER['SCRIPT_NAME']);
-        
-        if (strpos($request_path, $script_name) !== false) {
-            $request_path = substr($request_path, strpos($request_path, $script_name) + strlen($script_name));
-        } elseif ($script_dir != '/') {
-            $request_path = str_replace($script_dir, '', $request_path);
-        }
-        
-        $request_path = trim($request_path, '/');
-    }
-    
-    // Strip off GET parameters when passed in SAPI CGI mode
-    $request_path = strtok($request_path, '?');
-    
-    foreach ($routes as $pattern => $route) {
-        
-        if (!isset($route)) continue;
-        $regex = '#^' . trim($pattern, '/') . '$#i';
-        
-        if (!preg_match($regex, $request_path, $args) > 0) continue;
-        
-        $args = (count($args) > 1) ? array_slice($args, 1) : array();
-        return _simpleweb_invoke($route, $args);
-    }
-    
-    if ($not_found_route) return _simpleweb_invoke($not_found_route, array($request_path));
-    
-    _simpleweb_not_found();
-}
-
-/**
- * Invokes a route.
- *
- * @param string $route the route
- * @param array $args the arguments
- * @return mixed the result from calling the route.
- */
-function _simpleweb_invoke($route, $args = array()) {
-    if (strpos($route, '::') !== false) {
-        list($class, $method) = split($route, '::', 2);
-        return call_user_func_array(array($class, $method), $args);
-    } elseif(strpos($route, '->') !== false) {
-        list($class, $method) = split($route, '->', 2);
-        $object &= new $class;
-        return call_user_func_array(array($object, $method), $args);
-    } else {
-        return call_user_func_array($route, $args);
-    }
-}
-
-/**
- * Displays a HTTP 404 Not Found error and exits.
- */
-function _simpleweb_not_found() {
-    switch ($_SERVER['REDIRECT_STATUS']) { 
- 	    case '403':
- 	        $status = '403 Forbidden';  
- 	        break;
- 	    case '404':
- 		default: 
- 		    $status = '404 Not Found'; 
- 		    break; 
-    } 
-    
-    if (substr(PHP_SAPI, 0, 3) === 'cgi') {
-        header('Status: ' . $status);
-    } else {
-        header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status);
-    }
-    header('Content-Type: text/html');
-    
-    print '<!doctype html><html><head><title>' . $status . '</title></head><body><h1>' . $status . '</h1></body></html>';
-    
-    exit;
-}
-?>
diff --git a/simpleid/www/upgrade.php b/simpleid/www/upgrade.php
deleted file mode 100644
index a4d5940..0000000
--- a/simpleid/www/upgrade.php
+++ /dev/null
@@ -1,466 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2009
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
-
-/**
- * SimpleID upgrade script.
- *
- * This script performs various upgrades to SimpleID's storage backend, which
- * are required for different versions of SimpleID.
- *
- * @package simpleid
- * @since 0.7
- * @filesource
- */
-
-/**
- * Access control for this script.
- *
- * If you are upgrading your SimpleID installation using the upgrade.php script,
- * and you are not logged in as an administrator, you will need to modify the access
- * check statement below.
- *
- * Change the TRUE to a FALSE to disable the access
- * check. After finishing the upgrade, be sure to open this file again
- * and change the FALSE back to a TRUE.
- *
- * @global bool $upgrade_access_check
- */
-$upgrade_access_check = TRUE;
-
-/* ----- Do not modify anything following this line ------------------------- */
-
-include_once "version.inc.php";
-include_once "locale.inc.php";
-if (file_exists("config.php")) {
-    include_once "config.php";
-} elseif (file_exists("config.inc")) {
-    include_once "config.inc";
-    define('UPGRADE_LEGACY_CONFIG_INC', TRUE);
-} else {
-    die(t('No configuration file found.  See the <a href="!url">manual</a> for instructions on how to set up a configuration file.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-}
-include_once "config.default.php";
-include_once "log.inc.php";
-include_once "common.inc.php";
-include_once "simpleweb.inc.php";
-include_once "openid.inc.php";
-include_once "user.inc.php";
-include_once "cache.inc.php";
-include_once SIMPLEID_STORE . ".store.php";
-include "lib/xtemplate.class.php";
-
-define('CACHE_DIR', SIMPLEID_CACHE_DIR);
-
-define('PRE_0_7_0_VERSION', '0.6.0 or earlier');
-
-/**
- * This variable holds the upgrade functions for each version of SimpleID
- *
- * @global array $upgrade_functions
- */
-$upgrade_functions = array(
-    '0.9.0' => array('upgrade_config_inc_to_php', 'upgrade_delete_token'),
-    '0.7.0' => array('upgrade_rp_to_store', 'upgrade_token_to_store')
-);
-
-
-/**
- * This variable holds an instance of the XTemplate engine.
- *
- * @global object $xtpl
- */
-$xtpl = NULL;
-
-/**
- * This variable holds the combined $_GET and $_POST superglobal arrays.
- *
- * @global array $GETPOST
- */
-$GETPOST = array_merge($_GET, $_POST);
-
-upgrade_start();
-
-/**
- * Entry point for SimpleID upgrade script.
- *
- * @see user_init()
- */
-function upgrade_start() {
-    global $xtpl, $GETPOST;
-    
-    locale_init(SIMPLEID_LOCALE);
-        
-    $xtpl = new XTemplate('html/template.xtpl');
-    $xtpl->assign('version', SIMPLEID_VERSION);
-    $xtpl->assign('base_path', get_base_path());
-    $xtpl->assign('css', '@import url(' . get_base_path() . 'html/upgrade.css);');
-    $xtpl->assign('footer_doc', t('Documentation'));
-    $xtpl->assign('footer_support', t('Support'));
-    
-    if (!is_dir(SIMPLEID_IDENTITIES_DIR)) {
-        indirect_fatal_error(t('Identities directory not found.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    }
-    
-    if (!is_dir(SIMPLEID_CACHE_DIR) || !is_writeable(SIMPLEID_CACHE_DIR)) {
-        indirect_fatal_error(t('Cache directory not found or not writeable.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    }
-    
-    if (!is_dir(SIMPLEID_STORE_DIR) || !is_writeable(SIMPLEID_STORE_DIR)) {
-        indirect_fatal_error(t('Store directory not found or not writeable.  See the <a href="!url">manual</a> for instructions on how to set up SimpleID.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    }
-
-    if ((@ini_get('register_globals') === 1) || (@ini_get('register_globals') === '1') || (strtolower(@ini_get('register_globals')) == 'on')) {
-        indirect_fatal_error(t('register_globals is enabled in PHP configuration, which is not supported by SimpleID.  See the <a href="!url">manual</a> for further information.', array('!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    
-    if (!bignum_loaded()) {
-        log_fatal('gmp/bcmath PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'gmp/bcmath', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('preg_match')) {
-        log_fatal('pcre PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'pcre', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('session_start')) {
-        log_fatal('session PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'session', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('xml_parser_create_ns')) {
-        log_fatal('xml PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'xml', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (!function_exists('hash')) {
-        log_fatal('hash PHP extension not loaded.');
-        indirect_fatal_error(t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'hash', '!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-    if (is_numeric(@ini_get('suhosin.get.max_value_length')) && (@ini_get('suhosin.get.max_value_length') < 1024)) {
-        log_fatal('suhosin.get.max_value_length < 1024');
-        indirect_fatal_error(t('suhosin.get.max_value_length is less than 1024, which will lead to problems. See the <a href="!url">manual</a> for further information on system requirements.', array('!url' => 'http://simpleid.org/docs/1/system-requirements/')));
-    }
-
-    $q = (isset($GETPOST['q'])) ? $GETPOST['q'] : '';
-    $q = explode('/', $q);
-    
-    extension_init();
-    user_init(NULL);
-    upgrade_user_init();
-    
-    $routes = array(
-        'upgrade-selection' => 'upgrade_selection',
-        'upgrade-apply' => 'upgrade_apply',
-        '.*' => 'upgrade_info'
-    );
-    
-    simpleweb_run($routes, implode('/', $q));
-}
-
-/**
- * Displays the upgrade info page.
- */
-function upgrade_info() {
-    global $xtpl;
-    
-    $xtpl->assign('token', get_form_token('upgrade_info'));
-    
-    $xtpl->assign('intro', t('Use this script to update your installation whenever you upgrade to a new version of SimpleID.'));
-    $xtpl->assign('simpleid_docs', t('For more detailed information, see the <a href="!url">SimpleID documentation</a>.', array('!url' => 'http://simpleid.org/docs/1/upgrading/')));
-    $xtpl->assign('step1', t('<strong>Back up your installation</strong>. This process will change various files within your SimpleID installation and in case of emergency you may need to revert to a backup.'));
-    $xtpl->assign('step2', t('Install your new files in the appropriate location, as described in the <a href="!url">SimpleID documentation</a>.', array('!url' => 'http://simpleid.org/docs/1/installing/')));
-    $xtpl->assign('click_continue', t('When you have performed the steps above, click <strong>Continue</strong>.'));
-    $xtpl->assign('continue_button', t('Continue'));
-    
-    $xtpl->parse('main.upgrade_info');
-    
-    $xtpl->assign('title', t('Upgrade'));
-    $xtpl->parse('main');
-    
-    $xtpl->out('main');
-}
-
-/**
- * Detects the current installed version of SimpleID, selects the individual upgrade
- * functions applicable to this upgrade and displays the upgrade
- * selection page.
- */
-function upgrade_selection() {
-    global $xtpl, $upgrade_access_check;
-    
-    cache_expire(array('upgrade' => 0));
-    
-    if (!validate_form_token($_POST['tk'], 'upgrade_info')) {
-        set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-        upgrade_info();
-        return;
-    }
-
-    $functions = upgrade_get_functions();
-    
-    if (count($functions) == 0) {
-        if (!$upgrade_access_check) {
-            $xtpl->assign('edit_upgrade_php', t('Remember to edit upgrade.php to check <code>$upgrade_access_check</code> back to <code>FALSE</code>.'));
-            $xtpl->parse('main.selection.selection_complete.upgrade_access_check');
-        }
-        
-        $xtpl->assign('script_complete', t('Your SimpleID installation is up-to-date.  This script is complete.'));
-        
-        $xtpl->parse('main.upgrade_selection.selection_complete');
-    } else {
-        $handle = random_id();
-        cache_set('upgrade', $handle, $functions);
-        
-        $xtpl->assign('handle', $handle);
-        $xtpl->assign('token', get_form_token('upgrade_selection'));
-        
-        $xtpl->assign('click_continue', t('Click <strong>Continue</strong> to proceed with the upgrade.'));
-        $xtpl->assign('continue_button', t('Continue'));
-        
-        $xtpl->parse('main.upgrade_selection.selection_continue');
-    }
-    
-    $xtpl->assign('original_version', upgrade_get_version());
-    $xtpl->assign('this_version', SIMPLEID_VERSION);
-    
-    $xtpl->assign('version_detected', t('The version of SimpleID you are updating from has been automatically detected.'));
-    $xtpl->assign('original_version_label', t('Original version'));
-    $xtpl->assign('this_version_label', t('Upgrade version'));
-    
-    $xtpl->parse('main.upgrade_selection');
-    
-    $xtpl->assign('title', t('Upgrade'));
-    $xtpl->parse('main');
-    
-    $xtpl->out('main');
-}
-
-/**
- * Applies the upgrade.
- */
-function upgrade_apply() {
-    global $xtpl, $upgrade_access_check;
-    
-    if (!validate_form_token($_POST['tk'], 'upgrade_selection')) {
-        set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-        upgrade_selection();
-        return;
-    }
-    
-    $results = '';
-    $functions = cache_get('upgrade', $_POST['handle']);
-    
-    foreach ($functions as $function) {
-        $results .= call_user_func($function);
-    }
-    
-    if (!$upgrade_access_check) {
-        $xtpl->assign('edit_upgrade_php', t('Remember to edit upgrade.php to check <code>$upgrade_access_check</code> back to <code>TRUE</code>.'));
-        $xtpl->parse('main.upgrade_results.upgrade_access_check');
-    }
-    $xtpl->assign('results', $results);
-    
-    $xtpl->assign('upgrade_complete', t('Your SimpleID installation has been upgraded.  Please check the results below for any errors.'));
-    
-    $xtpl->parse('main.upgrade_results');
-    
-    cache_expire(array('upgrade' => 0));
-    
-    $xtpl->assign('title', t('Upgrade'));
-    $xtpl->parse('main');
-    
-    $xtpl->out('main');
-}
-
-/**
- * Detects the current installed version of SimpleID
- *
- * The current installed version of SimpleID is taken from the {@link store_get() version}
- * application setting.  This setting is only available for versions 0.7 or later, so
- * if it is absent we can assume it's prior to version 0.7.
- *
- * @return string the detected version, or the string '0.6.0 or earlier'
- */
-function upgrade_get_version() {
-    return store_get('version', '0.6.0 or earlier');
-}
-
-/**
- * Sets the current version of SimpleID.
- *
- * This function sets the version application setting via {@link store_get()}.
- * A specific version can be specified, or it can be taken from {@link SIMPLEID_VERSION}.
- *
- * @param string $version the version to set
- */
-function upgrade_set_version($version = NULL) {
-    if ($version == NULL) $version = SIMPLEID_VERSION;
-    store_set('version', $version);
-}
-
-/**
- * Selects the upgrade functions applicable for this upgrade.
- *
- * The upgrade functions are specified by the {@link $upgrade_functions}
- * variable.  This variable is an associative array containing version numbers
- * as keys and an array of upgrade function names as values.  This function
- * merges all the upgrade function names of the version between the current
- * installed version and the upgraded version.
- *
- * @param string $version the version of SimpleID to upgrade from, calls
- * {@link upgrade_get_version()} if not specified
- * @return array an array of strings, containing the list of upgrade functions
- * to call.  The functions should be called in the same order as they appear
- * in this array
- *
- */
-function upgrade_get_functions($version = NULL) {
-    global $upgrade_functions;
-    
-    if ($version == NULL) $version = upgrade_get_version();
-    $functions = array();
-    
-    uksort($upgrade_functions, '_upgrade_version_reverse_sort');
-    
-    foreach ($upgrade_functions as $upgrade_version => $upgrades) {
-        if (version_compare($version, $upgrade_version, '<')) {
-            $functions = array_merge($functions, $upgrades);
-        }
-    }
-    
-    if (version_compare($version, SIMPLEID_VERSION, '<')) $functions[] = 'upgrade_set_version';
-    
-    return $functions;
-}
-
-/**
- * Callback function for uksort() to reverse sort version numbers.
- *
- * @param string $a
- * @param string $b
- * @return int
- */
-function _upgrade_version_reverse_sort($a, $b) {
-    return -version_compare($a, $b);
-}
-
-/**
- * Determines whether the current user has permission to run this script.
- *
- * A user has permission to run this script if:
- *
- * - administrator=1 appears in the user's identity file; or
- * - {@link $upgrade_access_check} is false
- *
- * If the user does not have permission, {@link upgade_access_denied()} is called
- */
-function upgrade_user_init() {
-    global $user, $upgrade_access_check;
-    
-    if ($upgrade_access_check) {
-        if (($user == NULL) || ($user['administrator'] != 1)) upgrade_access_denied();
-    }
-}
-
-/**
- * Displays a page notifying the user that he or she does not have permission to
- * run the upgrade script.
- */
-function upgrade_access_denied() {
-    global $xtpl;
-    
-    $xtpl->assign('login_required', t('Access denied. You are not authorised to access this page. Please <a href="index.php?q=login">log in</a> as an administrator (a user whose identity file includes the line <code>administrator=1</code>).'));    
-    $xtpl->assign('edit_upgrade_php', t('If you cannot log in, you will have to edit <code>upgrade.php</code> to bypass this access check. To do this:'));
-    $xtpl->assign('edit_upgrade_php1', t('With a text editor find the upgrade.php file.'));
-    $xtpl->assign('edit_upgrade_php2', t('There is a line inside your upgrade.php file that says <code>$upgrade_access_check = TRUE;</code>. Change it to <code>$upgrade_access_check = FALSE;</code>.'));
-    $xtpl->assign('edit_upgrade_php3', t('As soon as the upgrade.php script is done, you must change the file back to its original form with <code>$upgrade_access_check = TRUE;</code>.'));
-    $xtpl->assign('edit_upgrade_php4', t('To avoid having this problem in future, remember to log in to SimpleID as an administrator before you run this script.'));
-    $xtpl->assign('simpleid_docs', t('For more detailed information, see the <a href="!url">SimpleID documentation</a>.', array('!url' => 'http://simpleid.org/docs/1/upgrading/')));
-    
-    $xtpl->parse('main.upgrade_access_denied');
-    
-    $xtpl->assign('title', t('Access Denied'));
-    $xtpl->parse('main');
-    
-    $xtpl->out('main');
-    exit;
-}
-
-/* ------------------------------------------------------------------------------------------------------- */
-
-/**
- * Moves the user's site preferences from the cache to the store.
- *
- * @since 0.7
- */
-function upgrade_rp_to_store() {
-    $dir = opendir(SIMPLEID_IDENTITIES_DIR);
-    
-    while (($file = readdir($dir)) !== false) {
-        $filename = SIMPLEID_IDENTITIES_DIR . '/' . $file;
-        
-        if ((filetype($filename) != "file") || (!preg_match('/^(.+)\.identity$/', $file, $matches))) continue;
-        
-        $uid = $matches[1];
-        
-        $user = user_load($uid);
-        $rp = cache_get('rp', $uid);
-        if ($rp != NULL) {
-            $user['rp'] = $rp;
-            user_save($user);
-            cache_delete('rp', $uid);
-        }
-    }
-}
-
-/**
- * Moves the site token from the cache to the store.
- *
- * @since 0.7
- */
-function upgrade_token_to_store() {
-    $site_token = cache_get('token', SIMPLEID_BASE_URL);
-    
-    if ($site_token != NULL) {
-        store_set('site-token', $site_token);
-        cache_delete('token', SIMPLEID_BASE_URL);
-    }
-}
-
-/**
- * Checks that config.inc has been renamed to config.php
- *
- * @since 0.9
- */
-function upgrade_config_inc_to_php() {
-    if (defined('UPGRADE_LEGACY_CONFIG_INC')) {
-        return '<p>You will need to rename <code>config.inc</code> to <code>config.php</code>.</p>';
-    }
-}
-
-/**
- * Deletes the site-token setting for a more secure version
- *
- * @since 0.9
- */
-function upgrade_delete_token() {
-    store_del('site-token');
-}
-?>
diff --git a/simpleid/www/user.inc.php b/simpleid/www/user.inc.php
deleted file mode 100644
index d10b5c0..0000000
--- a/simpleid/www/user.inc.php
+++ /dev/null
@@ -1,1065 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * Includes code Drupal OpenID module (http://drupal.org/project/openid)
- * Rowan Kerr <rowan@standardinteractive.com>
- * James Walker <james@bryght.com>
- *
- * Copyright (C) Rowan Kerr and James Walker
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-/**
- * User functions.
- *
- * @package simpleid
- * @filesource
- */
-
-/**
- * The time the nonce used in the login process will last.
- */
-define('SIMPLEID_LOGIN_NONCE_EXPIRES_IN', 3600);
-
-/**
- * The time (in seconds) the auto login cookie will last.  This is currently
- * set as 2 weeks.
- */
-define('SIMPLEID_USER_AUTOLOGIN_EXPIRES_IN', 1209600);
-
-/**
- * This variable holds data on the currently logged-in user.  If the user is
- * not logged in, this variable is NULL.
- *
- * @global array $user
- */
-$user = NULL;
-
-/**
- * Initialises the user system.  Loads data for the currently logged-in user,
- * if any.
- *
- * @param string $q the SimpleID command, if any
- */
-function user_init($q = NULL) {
-    global $user;
-    global $xtpl;
-
-    log_debug('user_init');
-
-    $user = NULL;
-
-    // session_name() has to be called before session_set_cookie_params()
-    session_name(simpleid_cookie_name('sess'));
-
-    // Note the last parameter (httponly) requires PHP 5.2
-    session_set_cookie_params(0, get_base_path(), ini_get('session.cookie_domain'), false, true);
-    session_start();
-
-    if (isset($_SESSION['user']) && (cache_get('user', $_SESSION['user']) == session_id())) {
-        $user = user_load($_SESSION['user']);
-
-        // If user has just been actively been authenticated in the previous request, then we
-        // make it as actively authenticated in this request.
-        if (isset($_SESSION['user_auth_active']) && $_SESSION['user_auth_active']) {
-            $user['auth_active'] = true;
-            unset($_SESSION['user_auth_active']);
-        }
-    } else {
-        if (($q == 'login') || ($q == 'logout')) return;
-        user_auto_login();
-    }
-}
-
-/**
- * Attempts to automatically login using credentials presented by the user agent.
- *
- * The user agent may present various credentials as part of its request.  These
- * may include cookies and SSL client certificates.  This function calls the
- * {@link hook_user_auto_login()} hook of enabled extensions to see if any
- * of these credentials can be used to automatically login a user.
- */
-function user_auto_login() {
-    global $simpleid_extensions;
-
-    $extensions = $simpleid_extensions;
-
-    if (!in_array('user_cookieauth', $extensions)) $extensions[] = 'user_cookieauth';
-
-    foreach ($extensions as $extension) {
-        $test_user = extension_invoke($extension, 'user_auto_login');
-        if ($test_user != NULL) {
-            _user_login($test_user);
-        }
-    }
-}
-
-/**
- * Loads user data for a specified user name.
- *
- * @param string $uid the name of the user to load
- * @return mixed data for the specified user, or NULL if the user name does not
- * exist
- * @see user_load_from_identity()
- */
-function user_load($uid) {
-    if (store_user_exists($uid)) {
-        $user = store_user_load($uid);
-        $user["uid"] = $uid;
-
-        if (isset($user["identity"])) {
-            $user["local_identity"] = true;
-        } else {
-            $user["identity"] = simpleid_url('user/' . rawurlencode($uid));
-            $user["local_identity"] = false;
-        }
-
-        return $user;
-    } else {
-        return NULL;
-    }
-}
-
-/**
- * Loads user data for a specified OpenID Identity URI.
- *
- * @param string $identity the Identity URI of the user to load
- * @return mixed data for the specified user, or NULL if the user name does not
- * exist
- * @see user_load()
- */
-function user_load_from_identity($identity) {
-    $uid = store_get_uid($identity);
-    if ($uid !== NULL) return user_load($uid);
-
-    return NULL;
-}
-
-/**
- * Stores user data for a specified user name.
- *
- * @param array $user the user to save
- */
-function user_save($user) {
-    $uid = $user['uid'];
-    store_user_save($uid, $user, array('uid', 'identity', 'pass'));
-}
-
-/**
- * Attempts to log in a user, using the user name and password specified in the
- * HTTP request.
- */
-function user_login() {
-    global $user, $GETPOST;
-
-    // If the user is already logged in, return
-    if (isset($user['uid'])) openid_indirect_response(simpleid_url(), '');
-
-    // Require HTTPS or return an error
-    check_https('error', true);
-
-    $destination = (isset($GETPOST['destination'])) ? $GETPOST['destination'] : '';
-    $state = (isset($GETPOST['s'])) ? $GETPOST['s'] : '';
-    $fixed_uid = (isset($_POST['fixed_uid'])) ? $_POST['name'] : NULL;
-    $mode = $_POST['mode'];
-
-    $query = ($state) ? 's=' . rawurlencode($state) : '';
-
-    if (isset($_POST['op']) && $_POST['op'] == t('Cancel')) {
-        global $version;
-
-        $request = unpickle($state);
-        $version = openid_get_version($request);
-
-        if (isset($request['openid.return_to'])) {
-            $return_to = $request['openid.return_to'];
-            $response = simpleid_checkid_error(FALSE);
-            simpleid_assertion_response($response, $return_to);
-        } else {
-            indirect_fatal_error(t('Login cancelled without a proper OpenID request.'));
-        }
-        return;
-    }
-
-    if (!isset($_POST['mode']) || !in_array($_POST['mode'], array('credentials', 'otp'))) {
-        set_message(t('SimpleID detected a potential security attack on your log in.  Please log in again.'));
-        user_login_form($destination, $state, $fixed_uid);
-        return;
-    }
-
-    if (!isset($_POST['nonce'])) {
-        if (isset($_POST['destination'])) {
-            // User came from a log in form.
-            set_message(t('You seem to be attempting to log in from another web page.  You must use this page to log in.'));
-        }
-        user_login_form($destination, $state, $fixed_uid, $mode);
-        return;
-    }
-
-    $time = strtotime(substr($_POST['nonce'], 0, 20));
-    // Some old versions of PHP does not recognise the T in the ISO 8601 date.  We may need to convert the T to a space
-    if (($time == -1) || ($time === FALSE)) $time = strtotime(strtr(substr($_POST['nonce'], 0, 20), 'T', ' '));
-    $nonce = cache_get('user-nonce', $_POST['nonce']);
-
-    if (!$nonce) {
-        log_warn('Login attempt: Nonce ' . $_POST['nonce'] . ' not issued or is being reused.');
-        set_message(t('SimpleID detected a potential security attack on your log in.  Please log in again.'));
-        user_login_form($destination, $state, $fixed_uid, $mode);
-        return;
-    } elseif ($time < time() - SIMPLEID_LOGIN_NONCE_EXPIRES_IN) {
-        log_notice('Login attempt: Nonce ' . $_POST['nonce'] . ' expired.');
-        set_message(t('The log in page has expired.  Please log in again.'));
-        user_login_form($destination, $state, $fixed_uid, $mode);
-        return;
-    } elseif ($nonce['mode'] != $mode) {
-        log_warn('Login attempt: Mode saved with nonce ' . $_POST['nonce'] . ' (' . $nonce['mode'] . ') does not match ' . $mode);
-        set_message(t('SimpleID detected a potential security attack on your log in.  Please log in again.'));
-        user_login_form($destination, $state, $fixed_uid, $mode);
-    } else {
-        cache_delete('user-nonce', $_POST['nonce']);
-    }
-
-    switch ($mode) {
-        case 'credentials':
-            if (!isset($_POST['name'])) $_POST['name'] = '';
-            if (!isset($_POST['pass'])) $_POST['pass'] = '';
-
-            if (($_POST['name'] == '') || ($_POST['pass'] == '')) {
-                if (isset($_POST['destination'])) {
-                    // User came from a log in form.
-                    set_message(t('You need to supply the user name and the password in order to log in.'));
-                }
-                if (isset($_POST['nonce'])) cache_delete('user-nonce', $_POST['nonce']);
-                user_login_form($destination, $state, $fixed_uid);
-                return;
-            }
-
-            if (user_verify_credentials($_POST['name'], $_POST) === false) {
-                set_message(t('The user name or password is not correct.'));
-                user_login_form($destination, $state, $fixed_uid);
-                return;
-            }
-
-            $test_user = user_load($_POST['name']);
-            if (isset($test_user['otp']) && ($test_user['otp']['type'] != 'recovery')) {
-                log_info('One time password required');
-                user_login_form($destination, $state, $test_user['uid'], 'otp');
-                return;
-            }
-            break;
-        case 'otp':
-            if (!isset($_POST['otp']) || ($_POST['otp'] == '')) {
-                set_message(t('You need to enter the verification code in order to log in.'));
-                if (isset($_POST['nonce'])) cache_delete('user-nonce', $_POST['nonce']);
-                user_login_form($destination, $state, $nonce['uid'], 'otp');
-                return;
-            }
-
-            $test_user = user_load($nonce['uid']);
-
-            if (user_verify_otp($test_user['otp'], $_POST['otp']) === false) {
-                set_message(t('The verification code is not correct.'));
-                user_login_form($destination, $state, $nonce['uid'], 'otp');
-                return;
-            }
-            user_save($test_user); // Save the drift
-
-            break;
-    }
-
-    _user_login($test_user, true);
-
-    openid_indirect_response(simpleid_url($destination, $query), '');
-}
-
-/**
- * Verifies a set of credentials for a specified user.
- *
- * A set of credentials comprises:
- *
- * - A user name
- * - Some kind of verifying information, such as a plaintext password, a hashed
- *   password (e.g. digest) or some other kind of identifying information.
- *
- * The user name is passed to this function using the $uid parameter.  The user
- * name may or may not exist.  If the user name does not exist, this function
- * <strong>must</strong> return false.
- *
- * The credentials are supplied as an array using the $credentials parameter.
- * Typically this array will be a subset of the $_POST superglobal passed to the
- * {@link user_login()} function.  Thus it will generally contain the keys 'pass' and
- * 'digest'.
- *
- * This function calls the {@link hook_user_verify_credentials()} hook to
- * check whether the credentials supplied matches the credentials
- * for the specified user in the store.
- *
- * @param string $uid the name of the user to verify
- * @param array $credentials the credentials supplied by the browser
- * @return bool whether the credentials supplied matches those for the specified
- * user
- */
-function user_verify_credentials($uid, $credentials) {
-    global $simpleid_extensions;
-
-    $extensions = $simpleid_extensions;
-
-    if (!in_array('user_passauth', $extensions)) $extensions[] = 'user_passauth';
-
-    foreach ($extensions as $extension) {
-        $result = extension_invoke($extension, 'user_verify_credentials', $uid, $credentials);
-        if ($result === true) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-/**
- * Verifies a one time password (OTP) specified by the user.
- *
- * This function compares an OTP supplied by a user with the OTP
- * calculated based on the current time and the parameters of the
- * algorithm.  The parameters, such as the secret key, are supplied
- * using in $params.  These parameters are typically stored for each
- * user in the user store.
- *
- * To allow for clocks going out of sync, the current time will be
- * by a number (in time steps) specified in $params['drift'].  If
- * the OTP supplied by the user is accepted, $params['drift'] will
- * be also be updated with the latest difference.
- *
- * To allow for network delay, the function will accepts OTPs which
- * is a number of time steps away from the OTP calculated from the
- * adjusted time.  The maximum number of time steps is specified in
- * the $max_drift parameter.
- *
- * @param array &$params the OTP parameters stored
- * @param string $code the OTP supplied by the user
- * @param int $max_drift the maximum drift allowed for network delay, in
- * time steps
- * @return bool whether the OTP supplied matches the OTP generated based on
- * the specified parameters, within the maximum drift
- */
-function user_verify_otp(&$params, $code, $max_drift = 1) {
-    switch ($params['type']) {
-        case 'totp':
-            $time = time();
-
-            $test_code = user_totp($params['secret'], $time, $params['period'], $params['drift'], $params['algorithm'], $params['digits']);
-
-            if ($test_code == intval($code)) return true;
-
-            for ($i = -$max_drift; $i <= $max_drift; $i++) {
-                $test_code = user_totp($params['secret'], $time, $params['period'], $params['drift'] + $i, $params['algorithm'], $params['digits']);
-                if ($test_code == intval($code)) {
-                    $params['drift'] = $i;
-                    return true;
-                }
-            }
-            return false;
-            break;
-        default:
-            return false;
-    }
-}
-
-
-/**
- * Sets the user specified by the parameter as the active user.
- *
- * @param array $login_user the user to log in
- * @param bool $auth_active whether the user has been actively authenticated
- * in this session
- *
- */
-function _user_login($login_user, $auth_active = false) {
-    global $user;
-
-    if ($auth_active) {
-        // Set the current authentication time
-        $login_user['auth_time'] = time();
-        user_save($login_user);
-
-        // Set user has been actively authenticated this and the next request only
-        $login_user['auth_active'] = true;
-        $_SESSION['user_auth_active'] = true;
-        log_info('Login successful: ' . $login_user['uid'] . '['. gmstrftime('%Y-%m-%dT%H:%M:%SZ', $login_user['auth_time']) . ']');
-
-    }
-
-    $user = $login_user;
-    $_SESSION['user'] = $login_user['uid'];
-    cache_set('user', $login_user['uid'], session_id());
-
-
-    if ($auth_active) {
-        if (isset($_POST['autologin']) && ($_POST['autologin'] == 1)) user_cookieauth_create_cookie();
-    }
-}
-
-/**
- * Attempts to log out a user and returns to the login form.
- *
- * @param string $destination the destination value to be included in the
- * login form
- */
-function user_logout($destination = NULL) {
-    global $user, $GETPOST;
-
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-
-    $state = (isset($GETPOST['s'])) ? $GETPOST['s'] : '';
-    if ($destination == NULL) {
-        if (isset($GETPOST['destination'])) {
-            $destination = $GETPOST['destination'];
-        } else {
-            $destination = '';
-        }
-    }
-
-    _user_logout();
-
-    set_message(t('You have been logged out.'));
-
-    user_login_form($destination, $state);
-}
-
-/**
- * Logs out the user by deleting the relevant session information.
- */
-function _user_logout() {
-    global $user;
-
-    $uid = $user['uid'];
-
-    user_cookieauth_invalidate();
-    session_destroy();
-
-    cache_delete('user', $uid);
-    unset($_SESSION['user']);
-    $user = NULL;
-
-    log_info('Logout successful: ' . $uid);
-}
-
-/**
- * Displays a user login or a login verification form.
- *
- * @param string $destination the SimpleID location to which the user is directed
- * if login is successful
- * @param string $state the current SimpleID state, if required by the location
- * @param string $fixed_uid the user name to be included in the login form; if NULL, the user
- * is asked to supply the user name.  If $mode is otp this cannot be null
- * @param string $mode either credentials (login form) or otp (login verification
- * form)
- */
-function user_login_form($destination = '', $state = NULL, $fixed_uid = NULL, $mode = 'credentials') {
-    global $xtpl;
-
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-
-    if ($state) {
-        $xtpl->assign('state', htmlspecialchars($state, ENT_QUOTES, 'UTF-8'));
-        $xtpl->assign('cancel_button', t('Cancel'));
-        $xtpl->parse('main.login.state');
-    }
-
-    cache_expire(array('user-nonce' => SIMPLEID_LOGIN_NONCE_EXPIRES_IN));
-    $nonce = openid_nonce();
-    cache_set('user-nonce', $nonce, array('mode' => $mode, 'uid' => $fixed_uid));
-
-    $base_path = get_base_path();
-    $xtpl->assign('javascript', '<script src="' . $base_path . 'html/user-login.js" type="text/javascript"></script>');
-
-    header('X-Frame-Options: DENY');
-
-    switch ($mode) {
-        case 'credentials':
-            $security_class = (SIMPLEID_ALLOW_AUTOCOMPLETE) ? 'allow-autocomplete ' : '';
-            if (is_https()) {
-                $security_class .= 'secure';
-                $xtpl->assign('security_message', t('Secure login using <strong>HTTPS</strong>.'));
-            } elseif (SIMPLEID_ALLOW_PLAINTEXT) {
-                $security_class .= 'unsecure';
-                $xtpl->assign('security_message', t('<strong>WARNING:</strong>  Your password will be sent to SimpleID as plain text.'));
-            }
-            $xtpl->assign('security_class', $security_class);
-            $xtpl->parse('main.login.login_security');
-
-            extension_invoke_all('user_login_form', $destination, $state);
-
-            $xtpl->assign('name_label', t('User name:'));
-            $xtpl->assign('pass_label', t('Password:'));
-            $xtpl->assign('autologin_label', t('Remember me on this computer for two weeks.'));
-
-            if ($fixed_uid == NULL) {
-                $xtpl->parse('main.login.credentials.input_uid');
-            } else {
-                $xtpl->assign('uid', htmlspecialchars($fixed_uid, ENT_QUOTES, 'UTF-8'));
-                $xtpl->parse('main.login.credentials.fixed_uid');
-            }
-
-            $xtpl->parse('main.login.credentials');
-            $xtpl->assign('submit_button', t('Log in'));
-            $xtpl->assign('title', t('Log In'));
-            break;
-        case 'otp':
-            // Note this is called from user_login(), so $_POST is always filled
-            $xtpl->assign('otp_instructions_label', t('To verify your identity, enter the verification code.'));
-            $xtpl->assign('otp_recovery_label', t('If you have lost your verification code, you can <a href="!url">recover your account</a>.',
-                array('!url' => 'http://simpleid.org/docs/1/common-problems/#otp')
-            ));
-
-            $xtpl->assign('otp_label', t('Verification code:'));
-            $xtpl->assign('autologin', (isset($_POST['autologin']) && ($_POST['autologin'] == 1)) ? '1' : '0');
-            $xtpl->parse('main.login.otp');
-
-            $xtpl->assign('submit_button', t('Verify'));
-            $xtpl->assign('title', t('Enter Verification Code'));
-        default:
-    }
-
-
-    $xtpl->assign('mode', $mode);
-    $xtpl->assign('page_class', 'dialog-page');
-    $xtpl->assign('destination', htmlspecialchars($destination, ENT_QUOTES, 'UTF-8'));
-    $xtpl->assign('nonce', htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8'));
-
-    $xtpl->parse('main.login');
-    $xtpl->parse('main.framekiller');
-    $xtpl->parse('main');
-    $xtpl->out('main');
-}
-
-/**
- * Displays the page used to set up login verification using one-time
- * passwords.
- */
-function user_otp_page() {
-    global $xtpl, $user;
-
-    // Require HTTPS, redirect if necessary
-    check_https('redirect', true);
-
-    if ($user == NULL) {
-        user_login_form('my/profile');
-        return;
-    }
-
-    if ($_POST['op'] == t('Disable')) {
-        if (!isset($_POST['tk']) || !validate_form_token($_POST['tk'], 'dashboard_otp')) {
-            set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-            page_dashboard();
-            return;
-        }
-
-        if (isset($user['otp'])) {
-            unset($user['otp']);
-            user_save($user);
-        }
-        set_message('Login verification has been disabled.');
-        page_dashboard();
-        return;
-    } elseif ($_POST['op'] == t('Verify')) {
-        $params = $_SESSION['otp_setup'];
-
-        if (!isset($_POST['tk']) || !validate_form_token($_POST['tk'], 'otp')) {
-            set_message(t('SimpleID detected a potential security attack.  Please try again.'));
-            page_dashboard();
-            return;
-        } elseif (!isset($_POST['otp']) || ($_POST['otp'] == '')) {
-            set_message(t('You need to enter the verification code to complete enabling login verification.'));
-        } elseif (user_verify_otp($params, $_POST['otp'], 10) === false) {
-            set_message(t('The verification code is not correct.'));
-        } else {
-            unset($_SESSION['otp_setup']);
-            $user['otp'] = $params;
-            user_save($user);
-
-            set_message('Login verification has been enabled.');
-            page_dashboard();
-            return;
-        }
-    } else {
-        $params = array(
-            'type' => 'totp',
-            'secret' => random_bytes(10),
-            'algorithm' => 'sha1',
-            'digits' => 6,
-            'period' => 30,
-            'drift' => 0,
-        );
-        $_SESSION['otp_setup'] = $params;
-    }
-
-    $code = strtr(bignum_val(bignum_new($params['secret'], 256), 32), '0123456789abcdefghijklmnopqrstuv', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567');
-    for ($i = 0; $i < strlen($code); $i += 4) {
-        $xtpl->assign('secret' . ($i + 1), substr($code, $i, 4));
-    }
-
-    $url = 'otpauth://totp/SimpleID?secret=' . $code . '&digits=' . $params['digits'] . '&period=' . $params['period'];
-    $xtpl->assign('qr', addslashes($url));
-
-    $xtpl->assign('about_otp', t('Login verification adds an extra layer of protection to your account. When enabled, you will need to enter an additional security code whenever you log into SimpleID.'));
-    $xtpl->assign('otp_warning', t('<strong>WARNING:</strong> If you enable login verification and lose your authenticator app, you will need to <a href="!url">edit your identity file manually</a> before you can log in again.',
-        array('!url' => 'http://simpleid.org/docs/1/common-problems/#otp')
-    ));
-
-    $xtpl->assign('setup_otp', t('To set up login verification, following these steps.'));
-    $xtpl->assign('download_app', t('Download an authenticator app that supports TOTP for your smartphone, such as Google Authenticator.'));
-    $xtpl->assign('add_account', t('Add your SimpleID account to authenticator app using this key.  If you are viewing this page on your smartphone you can use <a href="!url">this link</a> or scan the QR code to add your account.',
-        array('!url' => $url)
-    ));
-    $xtpl->assign('verify_code', t('To check that your account has been added properly, enter the verification code from your phone into the box below, and click Verify.'));
-
-    $xtpl->assign('token', get_form_token('otp'));
-    $xtpl->assign('otp_label', t('Verification code:'));
-    $xtpl->assign('submit_button', t('Verify'));
-
-    $xtpl->assign('page_class', 'dialog-page');
-    $xtpl->assign('title', t('Login Verification'));
-
-    $xtpl->parse('main.otp');
-    $xtpl->parse('main.framekiller');
-
-    $xtpl->parse('main');
-    $xtpl->out('main');
-
-}
-
-
-/**
- * Returns the user's public page.
- *
- * @param string $uid the user ID
- */
-function user_public_page($uid = NULL) {
-    global $xtpl, $user;
-
-    $xtpl->assign('title', t('User Page'));
-    if ($uid == NULL) {
-        header_response_code('400 Bad Request');
-        set_message(t('No user specified.'));
-    } else {
-        $user = user_load($uid);
-
-        if ($user == NULL) {
-            header_response_code('404 Not Found');
-            set_message(t('User %uid not found.', array('%uid' => $uid)));
-        } else {
-            header('Vary: Accept');
-
-            $content_type = negotiate_content_type(array('text/html', 'application/xml', 'application/xhtml+xml', 'application/xrds+xml'));
-
-            if ($content_type == 'application/xrds+xml') {
-                user_xrds($uid);
-                return;
-            } else {
-                header('X-XRDS-Location: ' . simpleid_url('xrds/' . rawurlencode($uid)));
-
-                set_message(t('This is the user %uid\'s SimpleID page.  It contains hidden information for the use by OpenID consumers.', array('%uid' => $uid)));
-
-                $xtpl->assign('title', htmlspecialchars($uid, ENT_QUOTES, 'UTF-8'));
-                $xtpl->assign('provider', htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8'));
-                $xtpl->assign('xrds', htmlspecialchars(simpleid_url('xrds/' . rawurlencode($uid)), ENT_QUOTES, 'UTF-8'));
-                if ($user["local_identity"]) {
-                    $xtpl->assign('local_id', htmlspecialchars($user["identity"], ENT_QUOTES, 'UTF-8'));
-                }
-            }
-        }
-    }
-
-    $xtpl->parse('main.provider');
-    if ($user["local_identity"]) $xtpl->parse('main.local_id');
-    $xtpl->parse('main');
-    $xtpl->out('main');
-}
-
-/**
- * Returns the public page for a private personal ID.
- *
- * @param string $ppid the PPID
- */
-function user_ppid_page($ppid = NULL) {
-    global $xtpl;
-
-    header('Vary: Accept');
-
-    $content_type = negotiate_content_type(array('text/html', 'application/xml', 'application/xhtml+xml', 'application/xrds+xml'));
-
-    if (($content_type == 'application/xrds+xml') || ($_GET['format'] == 'xrds')) {
-        header('Content-Type: application/xrds+xml');
-        header('Content-Disposition: inline; filename=yadis.xml');
-
-        $xtpl->assign('simpleid_base_url', htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8'));
-        $xtpl->parse('xrds.user_xrds');
-        $xtpl->parse('xrds');
-        $xtpl->out('xrds');
-        return;
-    } else {
-        header('X-XRDS-Location: ' . simpleid_url('ppid/' . rawurlencode($ppid), 'format=xrds'));
-
-        $xtpl->assign('title', t('Private Personal Identifier'));
-
-        set_message(t('This is a private personal identifier.'));
-
-        $xtpl->parse('main');
-        $xtpl->out('main');
-    }
-}
-
-/**
- * Returns the user's public XRDS page.
- *
- * @param string $uid the user ID
- */
-function user_xrds($uid) {
-    global $xtpl;
-
-    $user = user_load($uid);
-
-    if ($user != NULL) {
-        header('Content-Type: application/xrds+xml');
-        header('Content-Disposition: inline; filename=yadis.xml');
-
-        if (($user != NULL) && ($user["local_identity"])) {
-            $xtpl->assign('local_id', htmlspecialchars($user["identity"], ENT_QUOTES, 'UTF-8'));
-            $xtpl->parse('xrds.user_xrds.local_id');
-            $xtpl->parse('xrds.user_xrds.local_id2');
-        }
-
-        $xtpl->assign('simpleid_base_url', htmlspecialchars(simpleid_url(), ENT_QUOTES, 'UTF-8'));
-        $xtpl->parse('xrds.user_xrds');
-        $xtpl->parse('xrds');
-        $xtpl->out('xrds');
-    } else {
-        if (substr(PHP_SAPI, 0,3) === 'cgi') {
-            header('Status: 404 Not Found');
-        } else {
-            header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
-        }
-
-        set_message('User <strong>' . htmlspecialchars($uid, ENT_QUOTES, 'UTF-8') . '</strong> not found.');
-        $xtpl->parse('main');
-        $xtpl->out('main');
-    }
-}
-
-/**
- * Returns a block containing OpenID Connect user information.
- *
- * @return array the OpenID Connect user information block
- */
-function _user_page_profile() {
-    global $user;
-
-    $html = '<p>' . t('SimpleID may, with your consent, send the following information to sites which supports OpenID Connect.') . '</p>';
-    $html .= '<p>' . t('To change these, <a href="!url">edit your identity file</a>.', array('!url' => 'http://simpleid.org/docs/1/identity-files/')) . '</p>';
-
-    $html .= "<table><tr><th>" . t('Member') . "</th><th>" . t('Value') . "</th></tr>";
-
-    if (isset($user['user_info'])) {
-        foreach ($user['user_info'] as $member => $value) {
-            if (is_array($value)) {
-                foreach ($value as $submember => $subvalue) {
-                    $html .= "<tr><td>" . htmlspecialchars($member, ENT_QUOTES, 'UTF-8') . " (" .htmlspecialchars($submember, ENT_QUOTES, 'UTF-8') . ")</td><td>" . htmlspecialchars($subvalue, ENT_QUOTES, 'UTF-8') . "</td></tr>";
-                }
-            } else {
-                $html .= "<tr><td>" . htmlspecialchars($member, ENT_QUOTES, 'UTF-8') . "</td><td>" . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . "</td></tr>";
-            }
-        }
-    }
-
-    $html .= "</table>";
-
-    return array(array(
-        'id' => 'userinfo',
-        'title' => t('OpenID Connect'),
-        'content' => $html
-    ));
-}
-
-/**
- * Set up the user section in the header, showing the currently logged in user.
- *
- * @param string $state the SimpleID state to retain once the user has logged out,
- * if required.
- */
-function user_header($state = NULL) {
-    global $user;
-    global $xtpl;
-
-    if ($user != NULL) {
-        $xtpl->assign('uid', htmlspecialchars($user['uid'], ENT_QUOTES, 'UTF-8'));
-        $xtpl->assign('identity', htmlspecialchars($user['identity'], ENT_QUOTES, 'UTF-8'));
-        if ($state != NULL) {
-            $xtpl->assign('url', htmlspecialchars(simpleid_url('logout', 'destination=continue&s=' . rawurlencode($state), true)));
-            $xtpl->assign('logout', t('Log out and log in as a different user'));
-        } else {
-            $xtpl->assign('url', htmlspecialchars(simpleid_url('logout', '', true)));
-            $xtpl->assign('logout', t('Log out'));
-        }
-        $xtpl->parse('main.user.logout');
-        $xtpl->parse('main.user');
-    }
-}
-
-/**
- * Verifies a set of credentials using the default user name-password authentication
- * method.
- *
- * @param string $uid the name of the user to verify
- * @param array $credentials the credentials supplied by the browser
- * @return bool whether the credentials supplied matches those for the specified
- * user
- */
-function user_passauth_user_verify_credentials($uid, $credentials) {
-    $allowed_algorithms = array('md5', 'sha1');
-    if (function_exists('hash_algos')) $allowed_algorithms = array_merge($allowed_algorithms, hash_algos());
-    if (function_exists('hash_pbkdf2')) $allowed_algorithms[] = 'pbkdf2';
-
-    $test_user = user_load($uid);
-
-    if ($test_user == NULL) return false;
-
-    $hash_function_salt = explode(':', $test_user['pass'], 3);
-
-    $hash = $hash_function_salt[0];
-    $function = (isset($hash_function_salt[1])) ? $hash_function_salt[1] : 'md5';
-    if (!in_array($function, $allowed_algorithms)) $function = 'md5';
-    $salt_suffix = (isset($hash_function_salt[2])) ? ':' . $hash_function_salt[2] : '';
-
-    switch ($function) {
-        case 'pbkdf2':
-            list ($algo, $iterations, $salt) = explode(':', $hash_function_salt[2]);
-            $length = (function_exists('hash')) ? strlen(hash($algo, '')) : 0;
-            $test_hash = hash_pbkdf2($algo, $credentials['pass'], $salt, $iterations, $length);
-            break;
-        case 'md5':
-        case 'sha1':
-            $test_hash = call_user_func($function, $credentials['pass'] . $salt_suffix);
-            break;
-        default:
-            $test_hash = hash($function, $credentials['pass'] . $salt_suffix);
-    }
-
-    return secure_compare($test_hash, $hash);
-}
-
-/**
- * Creates a auto login cookie.  The login cookie will be based on the
- * current log in user.
- *
- * @param string $id the ID of the series of auto login cookies,  Cookies
- * belonging to the same user and computer have the same ID.  If none is specified,
- * one will be generated
- * @param int $expires the time at which the cookie will expire.  If none is specified
- * the time specified in {@link SIMPLEID_USER_AUTOLOGIN_EXPIRES_IN} will be
- * used
- *
- */
-function user_cookieauth_create_cookie($id = NULL, $expires = NULL) {
-    global $user;
-
-    if ($expires == NULL) {
-        log_debug('Automatic login token created for ' . $user['uid']);
-    } else {
-        log_debug('Automatic login token renewed for ' . $user['uid']);
-    }
-
-    if ($id == NULL) $id = random_id();
-    if ($expires == NULL) $expires = time() + SIMPLEID_USER_AUTOLOGIN_EXPIRES_IN;
-    $token = random_secret();
-    $uid_hash = get_form_token($user['uid'], FALSE);
-
-    $data = array(
-        'uid' => $user['uid'],
-        'token' => $token,
-        'expires' => $expires,
-        'uaid' => get_user_agent_id(),
-        'ip' => $_SERVER['REMOTE_ADDR']
-    );
-
-    cache_set('autologin-'. $uid_hash, $id, $data);
-
-    // Note the last parameter (httponly) requires PHP 5.2
-    setcookie(simpleid_cookie_name('auth'), 'cookieauth:' . $uid_hash . ':' . $id . ':' . $token, $expires, get_base_path(), '', false, true);
-}
-
-/**
- * Verifies a auto login cookie.  If valid, log in the user automatically.
- */
-function user_cookieauth_user_auto_login() {
-    if (!isset($_COOKIE[simpleid_cookie_name('auth')])) return NULL;
-
-    $cookie = $_COOKIE[simpleid_cookie_name('auth')];
-
-    list($authtype, $uid_hash, $id, $token) = explode(':', $cookie);
-    if ($authtype != 'cookieauth') return NULL;
-
-    log_debug('Automatic login token detected: ' . implode(':', ['cookieauth', $uid_hash, $id]));
-
-    cache_expire(array('autologin-' . $uid_hash => SIMPLEID_USER_AUTOLOGIN_EXPIRES_IN));
-    $data = cache_get('autologin-' . $uid_hash, $id);
-
-    if (!$data) {  // Cookie doesn't exist
-        log_notice('Automatic login: Token does not exist on server');
-        return NULL;
-    }
-
-    if ($data['expires'] < time()) {  // Cookie expired
-        log_notice('Automatic login: Token on server expired');
-        return NULL;
-    }
-
-    if ($data['token'] != $token) {
-        log_warn('Automatic login: Token on server does not match');
-        // Token not the same - panic
-        cache_expire(array('autologin-' . $uid_hash => 0));
-        user_cookieauth_invalidate();
-        return NULL;
-    }
-
-    if ($data['uaid'] != get_user_agent_id()) {
-        log_warn('Automatic login: User agent ID does not match');
-        // Token not the same - panic
-        cache_expire(array('autologin-' . $uid_hash => 0));
-        user_cookieauth_invalidate();
-        return NULL;
-    }
-
-    // Load the user, tag it as an auto log in
-    $test_user = user_load($data['uid']);
-
-    if ($test_user != NULL) {
-        log_debug('Automatic login token accepted for ' . $data['uid']);
-
-        $test_user['autologin'] = TRUE;
-
-        // Renew the token
-        user_cookieauth_create_cookie($id, $data['expires']);
-
-        return $test_user;
-    } else {
-        log_warn('Automatic login token accepted for ' . $data['uid'] . ', but no such user exists');
-        return NULL;
-    }
-}
-
-/**
- * Removes the auto login cookie from the user agent and the SimpleID
- * cache.
- */
-function user_cookieauth_invalidate() {
-    if (isset($_COOKIE[simpleid_cookie_name('auth')])) {
-        $cookie = $_COOKIE[simpleid_cookie_name('auth')];
-
-        list($uid_hash, $id, $token) = explode(':', $cookie);
-
-        cache_delete('autologin-' . $uid_hash, $id);
-
-        setcookie(simpleid_cookie_name('auth'), "", time() - 3600);
-    }
-}
-
-/**
- * Calculates a Time-Based One-Time Password (TOTP) based on RFC 6238.
- *
- * This function returns an integer calculated from the TOTP algorithm.
- * The returned integer may need to be zero-padded to return a string
- * with the required number of digits
- *
- * @param string $secret the shared secret as a binary string
- * @param int $time the time to use in the HOTP algorithm.  If NULL, the
- * current time is used
- * @param int $period the time step in seconds
- * @param int $drift the number of time steps to be added to the time to
- * adjust for transmission delay
- * @param string $algorithm the hashing algorithm as supported by
- * the hash_hmac() function
- * @param int $digits the number of digits in the one-time password
- * @return int the one-time password
- * @link http://tools.ietf.org/html/rfc6238
- */
-function user_totp($secret, $time = NULL, $period = 30, $drift = 0, $algorithm = 'sha1', $digits = 6) {
-    if ($time == NULL) $time = time();
-    $counter = floor($time / $period) + $drift;
-    $data = pack('NN', 0, $counter);
-    return user_hotp($secret, $data, $algorithm, $digits);
-}
-
-/**
- * Calculates a HMAC-Based One-Time Password (HOTP) based on RFC 4226.
- *
- * This function returns an integer calculated from the HOTP algorithm.
- * The returned integer may need to be zero-padded to return a string
- * with the required number of digits
- *
- * @param string $secret the shared secret as a binary string
- * @param string $data the counter value as a 64 bit in
- * big endian encoding
- * @param string $algorithm the hashing algorithm as supported by
- * the hash_hmac() function
- * @param int $digits the number of digits in the one-time password
- * @return int the one-time password
- * @link http://tools.ietf.org/html/rfc4226
- */
-function user_hotp($secret, $data, $algorithm = 'sha1', $digits = 6) {
-    // unpack produces a 1-based array, we use array_merge to convert it to 0-based
-    $hmac = array_merge(unpack('C*', hash_hmac(strtolower($algorithm), $data, $secret, true)));
-    $offset = $hmac[19] & 0xf;
-    $code = ($hmac[$offset + 0] & 0x7F) << 24 |
-        ($hmac[$offset + 1] & 0xFF) << 16 |
-        ($hmac[$offset + 2] & 0xFF) << 8 |
-        ($hmac[$offset + 3] & 0xFF);
-    return $code % pow(10, $digits);
-}
-
-
-if (!function_exists('hash_pbkdf2') && function_exists('hash_hmac')) {
-    function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = false) {
-        $result = '';
-        $hLen = strlen(hash($algo, '', true));
-        if ($length == 0) {
-            $length = $hLen;
-            if (!$raw_output) $length *= 2;
-        }
-        $l = ceil($length / $hLen);
-
-        for ($i = 1; $i <= $l; $i++) {
-            $U = hash_hmac($algo, $salt . pack('N', $i), $password, true);
-            $T = $U;
-            for ($j = 1; $j < $iterations; $j++) {
-                $T ^= ($U = hash_hmac($algo, $U, $password, true));
-            }
-            $result .= $T;
-        }
-
-        return substr(($raw_output) ? $result : bin2hex($result), 0, $length);
-    }
-}
-
-
-?>
diff --git a/simpleid/www/version.inc.php b/simpleid/www/version.inc.php
deleted file mode 100644
index 1d97917..0000000
--- a/simpleid/www/version.inc.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-8
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
- * $Id$
- */
- 
-/**
- * Defines the current version of SimpleID.
- *
- * @package simpleid
- */
- 
-/**
- * The current version of SimpleID
- */
-define('SIMPLEID_VERSION', '1.0.6');
-?>