<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sk">
	<id>http://www.kiwiki.info/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-checkboxList-core.js</id>
	<title>MediaWiki:Gadget-checkboxList-core.js - História úprav</title>
	<link rel="self" type="application/atom+xml" href="http://www.kiwiki.info/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-checkboxList-core.js"/>
	<link rel="alternate" type="text/html" href="http://www.kiwiki.info/index.php?title=MediaWiki:Gadget-checkboxList-core.js&amp;action=history"/>
	<updated>2026-05-06T12:02:14Z</updated>
	<subtitle>História úprav pre túto stránku na wiki</subtitle>
	<generator>MediaWiki 1.34.0</generator>
	<entry>
		<id>http://www.kiwiki.info/index.php?title=MediaWiki:Gadget-checkboxList-core.js&amp;diff=12139&amp;oldid=prev</id>
		<title>Juraj: Vytvorená stránka „/** &lt;pre&gt;  * Adds support for checkbox lists (Template:Checklist)  *  * Examples/Tests: &lt;https://rs.wiki/User:Cqm/Scrapbook_4&gt;  *  * History:  * - 1.0: Original impl…“</title>
		<link rel="alternate" type="text/html" href="http://www.kiwiki.info/index.php?title=MediaWiki:Gadget-checkboxList-core.js&amp;diff=12139&amp;oldid=prev"/>
		<updated>2020-04-16T18:13:23Z</updated>

		<summary type="html">&lt;p&gt;Vytvorená stránka „/** &amp;lt;pre&amp;gt;  * Adds support for checkbox lists (&lt;a href=&quot;/index.php/%C5%A0abl%C3%B3na:Checklist&quot; title=&quot;Šablóna:Checklist&quot;&gt;Template:Checklist&lt;/a&gt;)  *  * Examples/Tests: &amp;lt;https://rs.wiki/User:Cqm/Scrapbook_4&amp;gt;  *  * History:  * - 1.0: Original impl…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nová stránka&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/** &amp;lt;pre&amp;gt;&lt;br /&gt;
 * Adds support for checkbox lists ([[Template:Checklist]])&lt;br /&gt;
 *&lt;br /&gt;
 * Examples/Tests: &amp;lt;https://rs.wiki/User:Cqm/Scrapbook_4&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * History:&lt;br /&gt;
 * - 1.0: Original implementation - Cqm&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * DATA STORAGE STRUCTURE&lt;br /&gt;
 * ----------------------&lt;br /&gt;
 *&lt;br /&gt;
 * In its raw, uncompressed format, the stored data is as follows:&lt;br /&gt;
 * {&lt;br /&gt;
 *     hashedPageName1: [&lt;br /&gt;
 *         [0, 1, 0, 1, 0, 1],&lt;br /&gt;
 *         [1, 0, 1, 0, 1, 0],&lt;br /&gt;
 *         [0, 0, 0, 0, 0, 0]&lt;br /&gt;
 *     ],&lt;br /&gt;
 *     hashedPageName2: [&lt;br /&gt;
 *         [0, 1, 0, 1, 0, 1],&lt;br /&gt;
 *         [1, 0, 1, 0, 1, 0],&lt;br /&gt;
 *         [0, 0, 0, 0, 0, 0]&lt;br /&gt;
 *     ]&lt;br /&gt;
 * }&lt;br /&gt;
 *&lt;br /&gt;
 * Where `hashedPageNameX` is the value of wgPageName passed through our `hashString` function,&lt;br /&gt;
 * the arrays of numbers representing tables on a page (from top to bottom) and the numbers&lt;br /&gt;
 * representing whether a row is highlighted or not, depending on if it is 1 or 0 respectively.&lt;br /&gt;
 *&lt;br /&gt;
 * During compression, these numbers are collected into groups of 6 and converted to base64.&lt;br /&gt;
 * For example:&lt;br /&gt;
 *&lt;br /&gt;
 *   1. [0, 1, 0, 1, 0, 1]&lt;br /&gt;
 *   2. 0x010101             (1 + 4 + 16 = 21)&lt;br /&gt;
 *   3. BASE_64_URL[21]      (U)&lt;br /&gt;
 *&lt;br /&gt;
 * Once each table's rows have been compressed into strings, they are concatenated using `.` as a&lt;br /&gt;
 * delimiter. The hashed page name (which is guaranteed to be 8 characters long) is then prepended&lt;br /&gt;
 * to this string to look something like the following:&lt;br /&gt;
 *&lt;br /&gt;
 *   XXXXXXXXab.dc.ef&lt;br /&gt;
 *&lt;br /&gt;
 *&lt;br /&gt;
 * The first character of a hashed page name is then used to form the object that is actually&lt;br /&gt;
 * stored. As the hashing function uses hexadecimal, this gives us 16 possible characters (0-9A-Z).&lt;br /&gt;
 *&lt;br /&gt;
 * {&lt;br /&gt;
 *     A: ...&lt;br /&gt;
 *     B: ...&lt;br /&gt;
 *     C: ...&lt;br /&gt;
 *     // etc.&lt;br /&gt;
 * }&lt;br /&gt;
 *&lt;br /&gt;
 * The final step of compression is to merge each page's data together under it's respective top&lt;br /&gt;
 * level key. this is done by concatenation again, separated by a `!`.&lt;br /&gt;
 *&lt;br /&gt;
 * The resulting object is then converted to a string and persisted in local storage. When&lt;br /&gt;
 * uncompressing data, simply perform the following steps in reverse.&lt;br /&gt;
 *&lt;br /&gt;
 * For the implementation of this algorithm, see:&lt;br /&gt;
 * - `compress`&lt;br /&gt;
 * - `parse`&lt;br /&gt;
 * - `hashString`&lt;br /&gt;
 *&lt;br /&gt;
 * Note that while rows could theoretically be compressed further by using all ASCII characters,&lt;br /&gt;
 * eventually we'd start using characters outside printable ASCII which makes debugging painful.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*jshint bitwise:false, camelcase:true, curly:true, eqeqeq:true, es3:false,&lt;br /&gt;
    forin:true, immed:true, indent:4, latedef:true, newcap:true,&lt;br /&gt;
    noarg:true, noempty:true, nonew:true, plusplus:true, quotmark:single,&lt;br /&gt;
    undef:true, unused:true, strict:true, trailing:true,&lt;br /&gt;
    browser:true, devel:false, jquery:true,&lt;br /&gt;
    onevar:true&lt;br /&gt;
*/&lt;br /&gt;
    'use strict';&lt;br /&gt;
&lt;br /&gt;
        // constants&lt;br /&gt;
    var STORAGE_KEY = 'rs:checkList',&lt;br /&gt;
        LIST_CLASS = 'checklist',&lt;br /&gt;
        CHECKED_CLASS = 'checked',&lt;br /&gt;
        NO_TOGGLE_PARENT_CLASS = 'no-toggle-parent',&lt;br /&gt;
        INDEX_ATTRIBUTE = 'data-checklist-index',&lt;br /&gt;
        BASE_64_URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',&lt;br /&gt;
        PAGE_SEPARATOR = '!',&lt;br /&gt;
        LIST_SEPARATOR = '.',&lt;br /&gt;
        CASTAGNOLI_POLYNOMIAL = 0x04c11db7,&lt;br /&gt;
        UINT32_MAX = 0xffffffff,&lt;br /&gt;
&lt;br /&gt;
        conf = mw.config.get([&lt;br /&gt;
            'debug',&lt;br /&gt;
            'wgPageName'&lt;br /&gt;
        ]),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        self = {&lt;br /&gt;
            /*&lt;br /&gt;
             * Stores the current uncompressed data for the current page.&lt;br /&gt;
             */&lt;br /&gt;
            data: null,&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Perform initial checks on the page and browser.&lt;br /&gt;
             */&lt;br /&gt;
            init: function () {&lt;br /&gt;
                var $lists = $(['ul.' + LIST_CLASS,&lt;br /&gt;
                                'div.' + LIST_CLASS + ' &amp;gt; ul'].join(', ')),&lt;br /&gt;
                    hashedPageName = self.hashString(mw.config.get('wgPageName'));&lt;br /&gt;
&lt;br /&gt;
                // check we have some tables to interact with&lt;br /&gt;
                if (!$lists.length) {&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // check the browser supports local storage&lt;br /&gt;
                if (!rs.hasLocalStorage()) {&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                self.data = self.load(hashedPageName, $lists.length);&lt;br /&gt;
                self.initLists(hashedPageName, $lists);&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Initialise table highlighting.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName The current page name as a hash.&lt;br /&gt;
             * @param $lists A list of checkbox lists on the current page.&lt;br /&gt;
             */&lt;br /&gt;
            initLists: function (hashedPageName, $lists) {&lt;br /&gt;
                $lists.each(function (listIndex) {&lt;br /&gt;
                    var $this = $(this),&lt;br /&gt;
                        toggleParent = !(&lt;br /&gt;
                            $this.hasClass(NO_TOGGLE_PARENT_CLASS) ||&lt;br /&gt;
                            $this.parent('div.' + LIST_CLASS).hasClass(NO_TOGGLE_PARENT_CLASS)&lt;br /&gt;
                        ),&lt;br /&gt;
                        // list items&lt;br /&gt;
                        $items = $this.find('li'),&lt;br /&gt;
                        listData = self.data[listIndex];&lt;br /&gt;
&lt;br /&gt;
                    // initialise list items if necessary&lt;br /&gt;
                    while ($items.length &amp;gt; listData.length) {&lt;br /&gt;
                        listData.push(0);&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    $items.each(function (itemIndex) {&lt;br /&gt;
                        var $this = $(this),&lt;br /&gt;
                            itemData = listData[itemIndex];&lt;br /&gt;
&lt;br /&gt;
                        // initialize checking based on the cookie&lt;br /&gt;
                        self.setChecked($this, itemData);&lt;br /&gt;
&lt;br /&gt;
                        // give the item a unique index in the list&lt;br /&gt;
                        $this.attr(INDEX_ATTRIBUTE, itemIndex);&lt;br /&gt;
&lt;br /&gt;
                        // set mouse events&lt;br /&gt;
                        $this&lt;br /&gt;
                            .click(function (e) {&lt;br /&gt;
                                var $this = $(this),&lt;br /&gt;
                                    $parent = $this.parent('ul').parent('li'),&lt;br /&gt;
                                    $childItems = $this.children('ul').children('li'),&lt;br /&gt;
                                    isChecked;&lt;br /&gt;
&lt;br /&gt;
                                // don't bubble up to parent lists&lt;br /&gt;
                                e.stopPropagation();&lt;br /&gt;
&lt;br /&gt;
                                function checkChildItems() {&lt;br /&gt;
                                    var $this = $(this),&lt;br /&gt;
                                        index = $this.attr(INDEX_ATTRIBUTE),&lt;br /&gt;
                                        $childItems = $this.children('ul').children('li'),&lt;br /&gt;
                                        childIsChecked = $this.hasClass(CHECKED_CLASS);&lt;br /&gt;
&lt;br /&gt;
                                    if (&lt;br /&gt;
                                        (isChecked &amp;amp;&amp;amp; !childIsChecked) ||&lt;br /&gt;
                                        (!isChecked &amp;amp;&amp;amp; childIsChecked)&lt;br /&gt;
                                    ) {&lt;br /&gt;
                                        listData[index] = 1 - listData[index];&lt;br /&gt;
                                        self.setChecked($this, listData[index]);&lt;br /&gt;
                                    }&lt;br /&gt;
&lt;br /&gt;
                                    if ($childItems.length) {&lt;br /&gt;
                                        $childItems.each(checkChildItems);&lt;br /&gt;
                                    }&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                                function checkParent($parent) {&lt;br /&gt;
                                    var parentIndex = $parent.attr(INDEX_ATTRIBUTE),&lt;br /&gt;
                                        parentIsChecked = $parent.hasClass(CHECKED_CLASS),&lt;br /&gt;
                                        parentShouldBeChecked = true,&lt;br /&gt;
                                        $myParent = $parent.parent('ul').parent('li');&lt;br /&gt;
&lt;br /&gt;
                                    $parent.children('ul').children('li').each(function () {&lt;br /&gt;
                                        var $child = $(this),&lt;br /&gt;
                                            childIsChecked = $child.hasClass(CHECKED_CLASS);&lt;br /&gt;
&lt;br /&gt;
                                        if (!childIsChecked) {&lt;br /&gt;
                                            parentShouldBeChecked = false;&lt;br /&gt;
                                        }&lt;br /&gt;
                                    });&lt;br /&gt;
&lt;br /&gt;
                                    if (&lt;br /&gt;
                                        (parentShouldBeChecked &amp;amp;&amp;amp; !parentIsChecked &amp;amp;&amp;amp; toggleParent) ||&lt;br /&gt;
                                        (!parentShouldBeChecked &amp;amp;&amp;amp; parentIsChecked)&lt;br /&gt;
                                    ) {&lt;br /&gt;
                                        listData[parentIndex] = 1 - listData[parentIndex];&lt;br /&gt;
                                        self.setChecked($parent, listData[parentIndex]);&lt;br /&gt;
                                    }&lt;br /&gt;
&lt;br /&gt;
                                    if ($myParent.length) {&lt;br /&gt;
                                        checkParent($myParent);&lt;br /&gt;
                                    }&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                                // don't toggle highlight when clicking links&lt;br /&gt;
                                if ((e.target.tagName !== 'A') &amp;amp;&amp;amp; (e.target.tagName !== 'IMG')) {&lt;br /&gt;
                                    // 1 -&amp;gt; 0&lt;br /&gt;
                                    // 0 -&amp;gt; 1&lt;br /&gt;
                                    listData[itemIndex] = 1 - listData[itemIndex];&lt;br /&gt;
&lt;br /&gt;
                                    self.setChecked($this, listData[itemIndex]);&lt;br /&gt;
                                    isChecked = $this.hasClass(CHECKED_CLASS);&lt;br /&gt;
&lt;br /&gt;
                                    if ($childItems.length) {&lt;br /&gt;
                                        $childItems.each(checkChildItems);&lt;br /&gt;
                                    }&lt;br /&gt;
&lt;br /&gt;
                                    // if the list has a parent&lt;br /&gt;
                                    // check if all the children are checked and uncheck the parent if not&lt;br /&gt;
                                    if ($parent.length) {&lt;br /&gt;
                                        checkParent($parent);&lt;br /&gt;
                                    }&lt;br /&gt;
&lt;br /&gt;
                                    self.save(hashedPageName);&lt;br /&gt;
                                }&lt;br /&gt;
                            });&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    // TODO: figure out where to put this&lt;br /&gt;
                    /*&lt;br /&gt;
                    // add a button for reset&lt;br /&gt;
                    var button = new OO.ui.ButtonWidget( {&lt;br /&gt;
                        label: 'Reset',&lt;br /&gt;
                        icon: 'cancel',&lt;br /&gt;
                        title: 'Resets all checkboxes in the list'&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    button.$element.click(function () {&lt;br /&gt;
                        $items.each(function (itemIndex) {&lt;br /&gt;
                            listData[itemIndex] = 0;&lt;br /&gt;
                            self.setChecked($(this), 0);&lt;br /&gt;
                        });&lt;br /&gt;
&lt;br /&gt;
                        self.save(hashedPageName, $lists.length);&lt;br /&gt;
                    });&lt;br /&gt;
                    */&lt;br /&gt;
                });&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Change the list item checkbox based on mouse events.&lt;br /&gt;
             *&lt;br /&gt;
             * @param $item The list item element.&lt;br /&gt;
             * @param val The value to control what class to add (if any).&lt;br /&gt;
             *            0 -&amp;gt; unchecked (no class)&lt;br /&gt;
             *            1 -&amp;gt; light on&lt;br /&gt;
             *            2 -&amp;gt; mouse over&lt;br /&gt;
             */&lt;br /&gt;
            setChecked: function ($item, val) {&lt;br /&gt;
                $item.removeClass(CHECKED_CLASS);&lt;br /&gt;
&lt;br /&gt;
                switch (val) {&lt;br /&gt;
                    // checked&lt;br /&gt;
                    case 1:&lt;br /&gt;
                        $item.addClass(CHECKED_CLASS);&lt;br /&gt;
                        break;&lt;br /&gt;
                }&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Merge the updated data for the current page into the data for other pages into local storage.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName A hash of the current page name.&lt;br /&gt;
             */&lt;br /&gt;
            save: function (hashedPageName) {&lt;br /&gt;
                    // load the existing data so we know where to save it&lt;br /&gt;
                var curData = localStorage.getItem(STORAGE_KEY),&lt;br /&gt;
                    compressedData;&lt;br /&gt;
&lt;br /&gt;
                if (curData === null) {&lt;br /&gt;
                    curData = {};&lt;br /&gt;
                } else {&lt;br /&gt;
                    curData = JSON.parse(curData);&lt;br /&gt;
                    curData = self.parse(curData);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // merge in our updated data and compress it&lt;br /&gt;
                curData[hashedPageName] = self.data;&lt;br /&gt;
                compressedData = self.compress(curData);&lt;br /&gt;
&lt;br /&gt;
                // convert to a string and save to localStorage&lt;br /&gt;
                compressedData = JSON.stringify(compressedData);&lt;br /&gt;
                localStorage.setItem(STORAGE_KEY, compressedData);&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Compress the entire data set using tha algoritm documented at the top of the page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param data The data to compress.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the compressed data.&lt;br /&gt;
             */&lt;br /&gt;
            compress: function (data) {&lt;br /&gt;
                var ret = {};&lt;br /&gt;
                &lt;br /&gt;
                Object.keys(data).forEach(function (hashedPageName) {&lt;br /&gt;
                    var pageData = data[hashedPageName],&lt;br /&gt;
                        pageKey = hashedPageName.charAt(0);&lt;br /&gt;
&lt;br /&gt;
                    if (!ret.hasOwnProperty(pageKey)) {&lt;br /&gt;
                        ret[pageKey] = {};&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    ret[pageKey][hashedPageName] = [];&lt;br /&gt;
&lt;br /&gt;
                    pageData.forEach(function (tableData) {&lt;br /&gt;
                        var compressedListData = '',&lt;br /&gt;
                            i, j, k;&lt;br /&gt;
&lt;br /&gt;
                        for (i = 0; i &amp;lt; Math.ceil(tableData.length / 6); i += 1) {&lt;br /&gt;
                            k = tableData[6 * i];&lt;br /&gt;
&lt;br /&gt;
                            for (j = 1; j &amp;lt; 6; j += 1) {&lt;br /&gt;
                                k = 2 * k + ((6 * i + j &amp;lt; tableData.length) ? tableData[6 * i + j] : 0);&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
                            compressedListData += BASE_64_URL.charAt(k);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        ret[pageKey][hashedPageName].push(compressedListData);&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    ret[pageKey][hashedPageName] = ret[pageKey][hashedPageName].join(LIST_SEPARATOR);&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                Object.keys(ret).forEach(function (pageKey) {&lt;br /&gt;
                    var hashKeys = Object.keys(ret[pageKey]),&lt;br /&gt;
                        hashedData = [];&lt;br /&gt;
&lt;br /&gt;
                    hashKeys.forEach(function (key) {&lt;br /&gt;
                        var pageData = ret[pageKey][key];&lt;br /&gt;
                        hashedData.push(key + pageData);&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    hashedData = hashedData.join(PAGE_SEPARATOR);&lt;br /&gt;
                    ret[pageKey] = hashedData;&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Get the existing data for the current page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param hashedPageName A hash of the current page name.&lt;br /&gt;
             * @param numLists The number of lists on the current page. Used to ensure the loaded&lt;br /&gt;
             *                 data matches the number of lists on the page thus handling cases&lt;br /&gt;
             *                 where lists have been added or removed. This does not check the&lt;br /&gt;
             *                 amount of items in the given lists.&lt;br /&gt;
             *&lt;br /&gt;
             * @return The data for the current page.&lt;br /&gt;
             */&lt;br /&gt;
            load: function (hashedPageName, numLists) {&lt;br /&gt;
                var data = localStorage.getItem(STORAGE_KEY),&lt;br /&gt;
                    pageData;&lt;br /&gt;
&lt;br /&gt;
                if (data === null) {&lt;br /&gt;
                    pageData = [];&lt;br /&gt;
                } else {&lt;br /&gt;
                    data = JSON.parse(data);&lt;br /&gt;
                    data = self.parse(data);&lt;br /&gt;
&lt;br /&gt;
                    if (data.hasOwnProperty(hashedPageName)) {&lt;br /&gt;
                        pageData = data[hashedPageName];&lt;br /&gt;
                    } else {&lt;br /&gt;
                        pageData = [];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // if more lists were added&lt;br /&gt;
                // add extra arrays to store the data in&lt;br /&gt;
                // also populates if no existing data was found&lt;br /&gt;
                while (numLists &amp;gt; pageData.length) {&lt;br /&gt;
                    pageData.push([]);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // if lists were removed, remove data from the end of the list&lt;br /&gt;
                // as there's no way to tell which was removed&lt;br /&gt;
                while (numLists &amp;lt; pageData.length) {&lt;br /&gt;
                    pageData.pop();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                return pageData;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Parse the compressed data as loaded from local storage using the algorithm desribed&lt;br /&gt;
             * at the top of the page.&lt;br /&gt;
             *&lt;br /&gt;
             * @param data The data to parse.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the parsed data.&lt;br /&gt;
             */&lt;br /&gt;
            parse: function (data) {&lt;br /&gt;
                var ret = {};&lt;br /&gt;
&lt;br /&gt;
                Object.keys(data).forEach(function (pageKey) {&lt;br /&gt;
                    var pageData = data[pageKey].split(PAGE_SEPARATOR);&lt;br /&gt;
&lt;br /&gt;
                    pageData.forEach(function (listData) {&lt;br /&gt;
                        var hashedPageName = listData.substr(0, 8);&lt;br /&gt;
&lt;br /&gt;
                        listData = listData.substr(8).split(LIST_SEPARATOR);&lt;br /&gt;
                        ret[hashedPageName] = [];&lt;br /&gt;
&lt;br /&gt;
                        listData.forEach(function (itemData, index) {&lt;br /&gt;
                            var i, j, k;&lt;br /&gt;
&lt;br /&gt;
                            ret[hashedPageName].push([]);&lt;br /&gt;
&lt;br /&gt;
                            for (i = 0; i &amp;lt; itemData.length; i += 1) {&lt;br /&gt;
                                k = BASE_64_URL.indexOf(itemData.charAt(i));&lt;br /&gt;
&lt;br /&gt;
                                // input validation&lt;br /&gt;
                                if (k &amp;lt; 0) {&lt;br /&gt;
                                    k = 0;&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                                for (j = 5; j &amp;gt;= 0; j -= 1) {&lt;br /&gt;
                                    ret[hashedPageName][index][6 * i + j] = (k &amp;amp; 0x1);&lt;br /&gt;
                                    k &amp;gt;&amp;gt;= 1;&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            },&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * Hash a string into a big endian 32 bit hex string. Used to hash page names.&lt;br /&gt;
             *&lt;br /&gt;
             * @param input The string to hash.&lt;br /&gt;
             *&lt;br /&gt;
             * @return the result of the hash.&lt;br /&gt;
             */&lt;br /&gt;
            hashString: function (input) {&lt;br /&gt;
                var ret = 0,&lt;br /&gt;
                    table = [],&lt;br /&gt;
                    i, j, k;&lt;br /&gt;
&lt;br /&gt;
                // guarantee 8-bit chars&lt;br /&gt;
                input = window.unescape(window.encodeURI(input));&lt;br /&gt;
&lt;br /&gt;
                // calculate the crc (cyclic redundancy check) for all 8-bit data&lt;br /&gt;
                // bit-wise operations discard anything left of bit 31&lt;br /&gt;
                for (i = 0; i &amp;lt; 256; i += 1) {&lt;br /&gt;
                    k = (i &amp;lt;&amp;lt; 24);&lt;br /&gt;
&lt;br /&gt;
                    for (j = 0; j &amp;lt; 8; j += 1) {&lt;br /&gt;
                        k = (k &amp;lt;&amp;lt; 1) ^ ((k &amp;gt;&amp;gt;&amp;gt; 31) * CASTAGNOLI_POLYNOMIAL);&lt;br /&gt;
                    }&lt;br /&gt;
                    table[i] = k;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // the actual calculation&lt;br /&gt;
                for (i = 0; i &amp;lt; input.length; i += 1) {&lt;br /&gt;
                    ret = (ret &amp;lt;&amp;lt; 8) ^ table[(ret &amp;gt;&amp;gt;&amp;gt; 24) ^ input.charCodeAt(i)];&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // make negative numbers unsigned&lt;br /&gt;
                if (ret &amp;lt; 0) {&lt;br /&gt;
                    ret += UINT32_MAX;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // 32-bit hex string, padded on the left&lt;br /&gt;
                ret = '0000000' + ret.toString(16).toUpperCase();&lt;br /&gt;
                ret = ret.substr(ret.length - 8);&lt;br /&gt;
&lt;br /&gt;
                return ret;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
    // disable for debugging&lt;br /&gt;
    if (!(['User:Cqm/Scrapbook_4'].indexOf(conf.wgPageName) &amp;amp;&amp;amp; conf.debug)) {&lt;br /&gt;
        $(self.init);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
    // sample data for testing the algorithm used&lt;br /&gt;
    var data = {&lt;br /&gt;
        // page1&lt;br /&gt;
        '0FF47C63': [&lt;br /&gt;
            [0, 1, 1, 0, 1, 0],&lt;br /&gt;
            [0, 1, 1, 0, 1, 0, 1, 1, 1],&lt;br /&gt;
            [0, 0, 0, 0, 1, 1, 0, 0]&lt;br /&gt;
        ],&lt;br /&gt;
        // page2&lt;br /&gt;
        '02B75ABA': [&lt;br /&gt;
            [0, 1, 0, 1, 1, 0],&lt;br /&gt;
            [1, 1, 1, 0, 1, 0, 1, 1, 0],&lt;br /&gt;
            [0, 0, 1, 1, 0, 0, 0, 0]&lt;br /&gt;
        ],&lt;br /&gt;
        // page3&lt;br /&gt;
        '0676470D': [&lt;br /&gt;
            [1, 0, 0, 1, 0, 1],&lt;br /&gt;
            [1, 0, 0, 1, 0, 1, 0, 0, 0],&lt;br /&gt;
            [1, 1, 1, 1, 0, 0, 1, 1]&lt;br /&gt;
        ]&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    console.log('input', data);&lt;br /&gt;
&lt;br /&gt;
    var compressedData = self.compress(data);&lt;br /&gt;
    console.log('compressed', compressedData);&lt;br /&gt;
&lt;br /&gt;
    var parsedData = self.parse(compressedData);&lt;br /&gt;
    console.log(parsedData);&lt;br /&gt;
    */&lt;br /&gt;
/* &amp;lt;/pre&amp;gt; */&lt;/div&gt;</summary>
		<author><name>Juraj</name></author>
		
	</entry>
</feed>