/* 
 * More info at: http://phpjs.org
 * 
 * This is version: 3.01
 * php.js is copyright 2009 Kevin van Zonneveld.
 * 
 * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
 * (http://kevin.vanzonneveld.net), Onno Marsman, Michael White
 * (http://getsprink.com), Waldo Malqui Silva, Paulo Ricardo F. Santos,
 * Theriault, Jack, Jonas Raoni Soares Silva (http://www.jsfromhell.com),
 * Philip Peterson, Ates Goral (http://magnetiq.com), Legaev Andrey, Ratheous,
 * Alex, Martijn Wieringa, Nate, lmeyrick
 * (https://sourceforge.net/projects/bcmath-js/), Enrique Gonzalez, Philippe
 * Baumann, Webtoolkit.info (http://www.webtoolkit.info/), Ole Vrijenhoek, Ash
 * Searle (http://hexmen.com/blog/), Jani Hartikainen, Carlos R. L. Rodrigues
 * (http://www.jsfromhell.com), travc, WebDevHobo
 * (http://webdevhobo.blogspot.com/), stag019, GeekFG
 * (http://geekfg.blogspot.com),
 * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
 * T.Wild, Erkekjetter, pilus, d3x, Johnny Mast (http://www.phpvrouwen.nl),
 * Michael Grier, marrtins, Andrea Giammarchi
 * (http://webreflection.blogspot.com), Felix Geisendoerfer
 * (http://www.debuggable.com/felix), Martin (http://www.erlenwiese.de/), Marc
 * Palau, Michael White, Kankrelune (http://www.webfaktory.info/), Public
 * Domain (http://www.json.org/json2.js), majak, gettimeofday, Steven Levithan
 * (http://blog.stevenlevithan.com), Pellentesque Malesuada, Josh Fraser
 * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
 * Lars Fischer, Joris, Arpad Ray (mailto:arpad@php.net), Breaking Par
 * Consulting Inc
 * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
 * KELAN, Mirek Slugen, AJ, Alfonso Jimenez (http://www.alfonsojimenez.com),
 * Caio Ariede (http://caioariede.com), Mailfaker (http://www.weedem.fr/),
 * Tyler Akins (http://rumkin.com), Aman Gupta, Thunder.m, mdsjack
 * (http://www.mdsjack.bo.it), Oleg Eremeev, Sakimori, Karol Kowalski,
 * gorthaur, Steve Hilder, David, Francois, David James, Steve Clay,
 * class_exists, Marco, noname, madipta, sankai, Slawomir Kaniecki, Frank
 * Forte, Nathan, T. Wild, ger, nobbler, marc andreu, john
 * (http://www.jd-tech.net), Arno, ReverseSyntax, Scott Cariss, Mateusz
 * "loonquawl" Zalega, Douglas Crockford (http://javascript.crockford.com),
 * Denny Wardhana, mktime, Marc Jansen, Ole Vrijenhoek
 * (http://www.nervous.nl/), T0bsn, Gilbert, Peter-Paul Koch
 * (http://www.quirksmode.org/js/beat.html), MeEtc (http://yass.meetcweb.com),
 * Bryan Elliott, Tim Wiel, Brad Touesnard, Soren Hansen, duncan, djmix,
 * Lincoln Ramsay, Bayron Guevara, lmeyrick
 * (https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, Pyerre, Jon
 * Hohle, Thiago Mata (http://thiagomata.blog.com), David Randall, Subhasis
 * Deb, J A R, 0m3r, Francesco, Paul, Hyam Singer
 * (http://www.impact-computing.com/), Raphael (Ao RUDLER), Sanjoy Roy,
 * kenneth, Stoyan Kyosev (http://www.svest.org/), LH, Ozh, nord_ua, date,
 * XoraX (http://www.xorax.info), echo is bad, JB, Eugene Bulkin
 * (http://doubleaw.com/), Der Simon (http://innerdom.sourceforge.net/),
 * Manish, Itsacon (http://www.itsacon.net/), Pierre-Luc Paour, Martin Pool,
 * Kirk Strobeck, Rick Waldron, Kristof Coomans (SCK-CEN Belgian Nucleair
 * Research Centre), Saulo Vallory, Wagner B. Soares, Valentina De Rosa, Jason
 * Wong (http://carrot.org/), Christoph, Daniel Esteban, Mick@el, rezna, Simon
 * Willison (http://simonwillison.net), Gabriel Paderni, Marco van Oort,
 * penutbutterjelly, Philipp Lenssen, Anton Ongson, Blues
 * (http://tech.bluesmoon.info/), Tomasz Wesolowski, Eric Nagel, Bobby Drake,
 * Luke Godfrey, Pul, Artur Tchernychev, uestla, Yves Sucaet, sowberry,
 * hitwork, Orlando, Norman "zEh" Fuchs, Ulrich, johnrembo, Nick Callen,
 * ejsanders, Aidan Lister (http://aidanlister.com/), Brian Tafoya
 * (http://www.premasolutions.com/), Philippe Jausions
 * (http://pear.php.net/user/jausions), kilops, dptr1988, HKM, metjay,
 * strcasecmp, strcmp, Alan C, Taras Bogach, ChaosNo1, Alexander Ermolaev
 * (http://snippets.dzone.com/user/AlexanderErmolaev), Le Torbi, James, Chris,
 * DxGx, Pedro Tainha (http://www.pedrotainha.com), Christian Doebler,
 * setcookie, Greg Frazier, Tod Gentille, Alexander M Beedie, T.J. Leahy,
 * baris ozdil, FGFEmperor, daniel airton wermann (http://wermann.com.br),
 * 3D-GRAF, jakes, gabriel paderni, Yannoo, FremyCompany, Luis Salazar
 * (http://www.freaky-media.com/), Matteo, stensi, Billy, Jalal Berrami, vlado
 * houba, Victor, fearphage (http://http/my.opera.com/fearphage/), Tim de
 * Koning, taith, Robin, Cord, Matt Bradley, Atli Þór, Maximusya, Andrej
 * Pavlovic, Dino, rem, mk.keck, Greenseed, Garagoth, Russell Walker
 * (http://www.nbill.co.uk/), YUI Library:
 * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at
 * http://hacks.bluesmoon.info/strftime/strftime.js, Andreas, Jamie Beck
 * (http://www.terabit.ca/), DtTvB
 * (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Leslie Hoare, Ben
 * Bryan, Diogo Resende, Howard Yeend, Allan Jensen (http://www.winternet.no),
 * davook, Benjamin Lupton, Rival, Luke Smith (http://lucassmith.name),
 * booeyOH, Cagri Ekin, Amir Habibi (http://www.residence-mixte.com/), Kheang
 * Hok Chin (http://www.distantia.ca/), Jay Klehr
 * 
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * 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 KEVIN VAN ZONNEVELD 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.
 */ 


function unserialize (data) {
    // Takes a string representation of variable and recreates it  
    // 
    // version: 911.815
    // discuss at: http://phpjs.org/functions/unserialize
    // +     original by: Arpad Ray (mailto:arpad@php.net)
    // +     improved by: Pedro Tainha (http://www.pedrotainha.com)
    // +     bugfixed by: dptr1988
    // +      revised by: d3x
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +        input by: Brett Zamir (http://brett-zamir.me)
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     improved by: Chris
    // +     improved by: James
    // +        input by: Martin (http://www.erlenwiese.de/)
    // +     bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     improved by: Le Torbi
    // +     input by: kilops
    // +     bugfixed by: Brett Zamir (http://brett-zamir.me)
    // -      depends on: utf8_decode
    // %            note: We feel the main purpose of this function should be to ease the transport of data between php & js
    // %            note: Aiming for PHP-compatibility, we have to translate objects to arrays
    // *       example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    // *       returns 1: ['Kevin', 'van', 'Zonneveld']
    // *       example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
    // *       returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
    var that = this;
    var utf8Overhead = function(chr) {
        // http://phpjs.org/functions/unserialize:571#comment_95906
        var code = chr.charCodeAt(0);
        if (code < 0x0080) {
            return 0;
        }
        if (code < 0x0800) {
             return 1;
        }
        return 2;
    };


    var error = function (type, msg, filename, line){throw new that.window[type](msg, filename, line);};
    var read_until = function (data, offset, stopchr){
        var buf = [];
        var chr = data.slice(offset, offset + 1);
        var i = 2;
        while (chr != stopchr) {
            if ((i+offset) > data.length) {
                error('Error', 'Invalid');
            }
            buf.push(chr);
            chr = data.slice(offset + (i - 1),offset + i);
            i += 1;
        }
        return [buf.length, buf.join('')];
    };
    var read_chrs = function (data, offset, length){
        var buf;

        buf = [];
        for (var i = 0;i < length;i++){
            var chr = data.slice(offset + (i - 1),offset + i);
            buf.push(chr);
            length -= utf8Overhead(chr); 
        }
        return [buf.length, buf.join('')];
    };
    var _unserialize = function (data, offset){
        var readdata;
        var readData;
        var chrs = 0;
        var ccount;
        var stringlength;
        var keyandchrs;
        var keys;

        if (!offset) {offset = 0;}
        var dtype = (data.slice(offset, offset + 1)).toLowerCase();

        var dataoffset = offset + 2;
        var typeconvert = function(x) {return x;};

        switch (dtype){
            case 'i':
                typeconvert = function (x) {return parseInt(x, 10);};
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case 'b':
                typeconvert = function (x) {return parseInt(x, 10) !== 0;};
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case 'd':
                typeconvert = function (x) {return parseFloat(x);};
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case 'n':
                readdata = null;
            break;
            case 's':
                ccount = read_until(data, dataoffset, ':');
                chrs = ccount[0];
                stringlength = ccount[1];
                dataoffset += chrs + 2;

                readData = read_chrs(data, dataoffset+1, parseInt(stringlength, 10));
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 2;
                if (chrs != parseInt(stringlength, 10) && chrs != readdata.length){
                    error('SyntaxError', 'String length mismatch');
                }

                // Length was calculated on an utf-8 encoded string
                // so wait with decoding
                //readdata = that.utf8_decode(readdata);
            break;
            case 'a':
                readdata = {};

                keyandchrs = read_until(data, dataoffset, ':');
                chrs = keyandchrs[0];
                keys = keyandchrs[1];
                dataoffset += chrs + 2;

                for (var i = 0; i < parseInt(keys, 10); i++){
                    var kprops = _unserialize(data, dataoffset);
                    var kchrs = kprops[1];
                    var key = kprops[2];
                    dataoffset += kchrs;

                    var vprops = _unserialize(data, dataoffset);
                    var vchrs = vprops[1];
                    var value = vprops[2];
                    dataoffset += vchrs;

                    readdata[key] = value;
                }

                dataoffset += 1;
            break;
            default:
                error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
            break;
        }
        return [dtype, dataoffset - offset, typeconvert(readdata)];
    };
    
    return _unserialize((data+''), 0)[2];
}

function utf8_decode ( str_data ) {
    // Converts a UTF-8 encoded string to ISO-8859-1  
    // 
    // version: 909.322
    // discuss at: http://phpjs.org/functions/utf8_decode
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +      input by: Aman Gupta
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Norman "zEh" Fuchs
    // +   bugfixed by: hitwork
    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: utf8_decode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
    
    str_data += '';
    
    while ( i < str_data.length ) {
        c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if ((c1 > 191) && (c1 < 224)) {
            c2 = str_data.charCodeAt(i+1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i+1);
            c3 = str_data.charCodeAt(i+2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

