<commit_before>/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var initCategorySelection = function () {
    $('div.category ul.dropdown-menu li a').click(function (e) {
        e.preventDefault();
        var selectedCategory = $(this).text();
        window.location = createQuery({
            category: selectedCategory
        });
    });
};

var createQuery = function (options) {
    options = options || {};
    var searchUrl = caramel.url('/assets/' + store.asset.type + '/list');
    var q = {};
    var input = $('#search').val();
    var tag = $('#selectedTag').val();
    var category = options.category || undefined;
    var searchQueryString = '?';
    q = parseUsedDefinedQuery(input);
    if (category) {
        if (category == "All Categories") {
            category = "";
        }
        q.category = category;
    }
    if(tag){
        q.tags = tag;
    }
    if (propCount(q) >= 1) {
        searchQueryString += 'q=';
        searchQueryString += JSON.stringify(q);
        searchQueryString = searchQueryString.replace('{', '').replace('}', '');
    }
    return searchUrl + searchQueryString;
};

var propCount = function (obj) {
    var count = 0;
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            count++;
        }
    }
    return count;
};

var parseUsedDefinedQuery = function (input) {
    var terms;
    var q = {};
    var term;
    var arr = [];
    var previous;
    // clear prefix white spaces and tail white spaces
    input = input.replace(/^\s+/, '').replace(/\s+$/, '');
    //Use case #1 : The user has only entered a name
    if ((!isTokenizedTerm(input)) && (!isEmpty(input))) {
        q.name = encodeURIComponent(input);
        return q;
    }
    input = input.trim();
    input = replaceAll(input,"(\\s)*:(\\s)*", ":");
    //Use case #2: The user has entered a complex query
    //and one or more properties in the query could values
    //with spaces
    //E.g. name:This is a test tags:wso2
    terms = input.split(' ');

    for (var index = 0; index < terms.length; index++) {
        term = terms[index];
        term = term.trim(); //Remove any whitespaces
        //If this term is not empty and does not have a : then it should be appended to the
        //previous term
        if ((!isEmpty(term)) && (!isTokenizedTerm(term))) {
            previous = arr.length - 1;
            arr[previous] = arr[previous] + ' ' + term;
        } else {
            arr.push(term);
        }
    }
    return parseArrToJSON(arr);
};
/**
 * Replace all the occurrences of $regex by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {regex} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
var replaceAll = function(originalString, regex, replace) {
    return originalString.replace(new RegExp(regex, 'g'), replace);
};
var isTokenizedTerm = function (term) {
    return term.indexOf(':') > -1;
};
var isEmpty = function (input) {
    return (input.length === 0);
};

var parseArrToJSON = function (items) {
    var item;
    var components;
    var obj = {};
    var key;
    var value;
    for (var index = 0; index < items.length; index++) {
        item = items[index];
        components = item.split(':');
        if (components.length == 2) {
            key = components[0];
            value = components[1];
            obj[key] = value;
        }
    }
    return obj;
};

$(window).load(function () {
    initCategorySelection();
});
<commit_msg>Fix for REGISTRY-3319<commit_after>/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var initCategorySelection = function () {
    $('div.category ul.dropdown-menu li a').click(function (e) {
        e.preventDefault();
        var selectedCategory = $(this).text();
        window.location = createQuery({
            category: selectedCategory
        });
    });
};

var createQuery = function (options) {
    options = options || {};
    var searchUrl = caramel.url('/assets/' + store.asset.type + '/list');
    var q = {};
    var input = $('#search').val();
    var tag = $('#selectedTag').val();
    var category = options.category || undefined;
    var searchQueryString = '?';
    q = parseUsedDefinedQuery(input);
    if (category) {
        if (category == "All Categories") {
            category = "";
        }
        q.category = category;
    }
    if(tag){
        q.tags = tag;
    }
    if (propCount(q) >= 1) {
        searchQueryString += 'q=';
        searchQueryString += encodeURIComponent(JSON.stringify(q).replace('{', '').replace('}', ''));
    }
    return searchUrl + searchQueryString;
};

var propCount = function (obj) {
    var count = 0;
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            count++;
        }
    }
    return count;
};

var parseUsedDefinedQuery = function (input) {
    var terms;
    var q = {};
    var term;
    var arr = [];
    var previous;
    // clear prefix white spaces and tail white spaces
    input = input.trim();
    input = replaceAll(input,"(\\s)*:(\\s)*", ":");
    //Use case #1 : The user has only entered a name
    if ((!isTokenizedTerm(input)) && (!isEmpty(input))) {
        if(input.indexOf('"') > -1){
            q.name = JSON.stringify(JSON.parse(input));
        } else {
            q.name = encodeURIComponent(input);
        }
        return q;
    }

    //Use case #2: The user has entered a complex query
    //and one or more properties in the query could values
    //with spaces
    //E.g. name:This is a test tags:wso2
    terms = input.split(' ');

    for (var index = 0; index < terms.length; index++) {
        term = terms[index];
        term = term.trim(); //Remove any whitespaces
        //If this term is not empty and does not have a : then it should be appended to the
        //previous term
        if ((!isEmpty(term)) && (!isTokenizedTerm(term))) {
            previous = arr.length - 1;
            arr[previous] = arr[previous] + ' ' + term;
        } else {
            arr.push(term);
        }
    }
    return parseArrToJSON(arr);
};
/**
 * Replace all the occurrences of $regex by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {regex} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
var replaceAll = function(originalString, regex, replace) {
    return originalString.replace(new RegExp(regex, 'g'), replace);
};
var isTokenizedTerm = function (term) {
    return term.indexOf(':') > -1;
};
var isEmpty = function (input) {
    return (input.length === 0);
};

var parseArrToJSON = function (items) {
    var item;
    var components;
    var obj = {};
    var key;
    var value;
    for (var index = 0; index < items.length; index++) {
        item = items[index];
        components = item.split(':');
        if (components.length == 2) {
            key = components[0];
            value = components[1];
            obj[key] = value;
        }
    }
    return obj;
};

$(window).load(function () {
    initCategorySelection();
});
<|endoftext|>


<commit_before>(function(YustSDK, $, window, document, undefined){

    var serverIP = 'http://54.247.168.152:3000';
    var   socket
        , widget = 'mario'
    ;

    YustSDK.init = function(){
        console.log('// Connecting...');
        socket = window.io.connect( serverIP);

        var gameId = Math.random();
        console.log('game id generated: ', gameId);

        socket.on('connect', function(){
            console.log('conected!');
            var qrcode = new QRCode("qrcode", {
                text: "http://54.247.168.152:3000/client/app?gameId=" + gameId,
                width: 256,
                height: 256,
                colorDark : "#000000",
                colorLight : "#ffffff",
                correctLevel : QRCode.CorrectLevel.H
            });
            socket.emit('createGame', {gameId:gameId});
        });
        // switch para cada widget ?
        socket.on( widget, function (data) {
            console.log('// Receiving data');
            console.log( data );
            YustSDK.bind( data.m, data.t, data.v );
        });
    };

    YustSDK.bind = function( event, timestamp, value ){
        console.log('// Binding event...');
        var keyDirection = value === 'r' ? 39 : 37;
        switch( event ){
            case 'press':
                window.keysDown[keyDirection] = true;
                break;
            case 'release':
                delete window.keysDown[keyDirection];
                break;
        }
    }

    return YustSDK;

})(YustSDK = window.YustSDK || {}, jQuery, window, document);

YustSDK.init();
<commit_msg>type in port<commit_after>(function(YustSDK, $, window, document, undefined){

    var serverIP = 'http://54.247.168.152:3000';
    var   socket
        , widget = 'mario'
    ;

    YustSDK.init = function(){
        console.log('// Connecting...');
        socket = window.io.connect( serverIP);

        var gameId = Math.random();
        console.log('game id generated: ', gameId);

        socket.on('connect', function(){
            console.log('conected!');
            var qrcode = new QRCode("qrcode", {
                text: "http://54.247.168.152/client/app?gameId=" + gameId,
                width: 256,
                height: 256,
                colorDark : "#000000",
                colorLight : "#ffffff",
                correctLevel : QRCode.CorrectLevel.H
            });
            socket.emit('createGame', {gameId:gameId});
        });
        // switch para cada widget ?
        socket.on( widget, function (data) {
            console.log('// Receiving data');
            console.log( data );
            YustSDK.bind( data.m, data.t, data.v );
        });
    };

    YustSDK.bind = function( event, timestamp, value ){
        console.log('// Binding event...');
        var keyDirection = value === 'r' ? 39 : 37;
        switch( event ){
            case 'press':
                window.keysDown[keyDirection] = true;
                break;
            case 'release':
                delete window.keysDown[keyDirection];
                break;
        }
    }

    return YustSDK;

})(YustSDK = window.YustSDK || {}, jQuery, window, document);

YustSDK.init();
<|endoftext|>


<commit_before>/* eslint-env mocha */
/* global expect, testContext */
/* eslint-disable prefer-arrow-callback, no-unused-expressions */
import {surveyProgress} from '../survey'

describe(testContext(__filename), function () {
  describe('surveyProgress()', function () {
    it('contains the correct progress info for completed surveys', function () {
      const completedSurvey = {
        id: '641216c8-4bb8-4602-87a9-a6b6124b16fd',
        completedBy: [],
        createdAt: '2016-07-18T15:38:58.959Z',
        updatedAt: '2016-07-18T15:38:58.959Z',
        cycleId: '8c95a5f2-2937-4884-995e-06390ebd3a53',
        projectId: 'ec4b9161-7b3c-49bf-9bd8-30b44a9e554c',
        questions: [
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['6a955799-b9a3-4034-944f-32288d8d579c'],
            response: {
              values: [{subjectId: '6a955799-b9a3-4034-944f-32288d8d579c', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa'],
            response: {
              values: [{subjectId: 'a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['2eb9470b-f176-455b-a925-7a6f984114b4'],
            response: {
              values: [{subjectId: '2eb9470b-f176-455b-a925-7a6f984114b4', value: 'response'}]
            },
          }
        ],
      }

      const result = surveyProgress(completedSurvey)
      expect(result.completed).to.be.true
      expect(result.responseCount).to.eq(3)
    })

    it('returns the correct progress info for incomplete surveys', function () {
      const incompleteSurvey = {
        id: '641216c8-4bb8-4602-87a9-a6b6124b16fd',
        completedBy: [],
        createdAt: '2016-07-18T15:38:58.959Z',
        updatedAt: '2016-07-18T15:38:58.959Z',
        cycleId: '8c95a5f2-2937-4884-995e-06390ebd3a53',
        projectId: 'ec4b9161-7b3c-49bf-9bd8-30b44a9e554c',
        questions: [
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['6a955799-b9a3-4034-944f-32288d8d579c'],
            response: {
              values: [{subjectId: '6a955799-b9a3-4034-944f-32288d8d579c', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa'],
            response: {
              values: [{subjectId: 'a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['2eb9470b-f176-455b-a925-7a6f984114b4'],
            response: {
              values: [],
            }
          }
        ],
      }

      const result = surveyProgress(incompleteSurvey)
      expect(result.completed).to.be.false
      expect(result.responseCount).to.eq(2)
    })
  })
})
<commit_msg>adding test for invalid input<commit_after>/* eslint-env mocha */
/* global expect, testContext */
/* eslint-disable prefer-arrow-callback, no-unused-expressions */
import {surveyProgress} from '../survey'

describe(testContext(__filename), function () {
  describe('surveyProgress()', function () {
    it('contains the correct progress info for completed surveys', function () {
      const completedSurvey = {
        id: '641216c8-4bb8-4602-87a9-a6b6124b16fd',
        completedBy: [],
        createdAt: '2016-07-18T15:38:58.959Z',
        updatedAt: '2016-07-18T15:38:58.959Z',
        cycleId: '8c95a5f2-2937-4884-995e-06390ebd3a53',
        projectId: 'ec4b9161-7b3c-49bf-9bd8-30b44a9e554c',
        questions: [
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['6a955799-b9a3-4034-944f-32288d8d579c'],
            response: {
              values: [{subjectId: '6a955799-b9a3-4034-944f-32288d8d579c', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa'],
            response: {
              values: [{subjectId: 'a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['2eb9470b-f176-455b-a925-7a6f984114b4'],
            response: {
              values: [{subjectId: '2eb9470b-f176-455b-a925-7a6f984114b4', value: 'response'}]
            },
          }
        ],
      }

      const result = surveyProgress(completedSurvey)
      expect(result.completed).to.be.true
      expect(result.responseCount).to.eq(3)
    })

    it('returns the correct progress info for incomplete surveys', function () {
      const incompleteSurvey = {
        id: '641216c8-4bb8-4602-87a9-a6b6124b16fd',
        completedBy: [],
        createdAt: '2016-07-18T15:38:58.959Z',
        updatedAt: '2016-07-18T15:38:58.959Z',
        cycleId: '8c95a5f2-2937-4884-995e-06390ebd3a53',
        projectId: 'ec4b9161-7b3c-49bf-9bd8-30b44a9e554c',
        questions: [
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['6a955799-b9a3-4034-944f-32288d8d579c'],
            response: {
              values: [{subjectId: '6a955799-b9a3-4034-944f-32288d8d579c', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa'],
            response: {
              values: [{subjectId: 'a1a2fd2c-b522-4d11-aa71-d2a4d471fdaa', value: 'response'}]
            },
          },
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['2eb9470b-f176-455b-a925-7a6f984114b4'],
            response: {
              values: [],
            }
          }
        ],
      }

      const result = surveyProgress(incompleteSurvey)
      expect(result.completed).to.be.false
      expect(result.responseCount).to.eq(2)
    })

    it('throws an error if the survey is invalid', function () {
      const incompleteSurvey = {
        id: '641216c8-4bb8-4602-87a9-a6b6124b16fd',
        completedBy: [],
        cycleId: '8c95a5f2-2937-4884-995e-06390ebd3a53',
        projectId: 'ec4b9161-7b3c-49bf-9bd8-30b44a9e554c',
        questions: [
          {
            questionId: '679644be-361f-4ae5-bbf5-1138e5a09d2e',
            subjectIds: ['6a955799-b9a3-4034-944f-32288d8d579c'],
            response: {},
          },
        ],
      }

      expect(() => surveyProgress(incompleteSurvey)).to.throw
    })
  })
})
<|endoftext|>


<commit_before>/**
 * ActivateModule component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { sprintf, __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_MODULES } from '../googlesitekit/modules/datastore/constants';
import useActivateModuleCallback from '../hooks/useActivateModuleCallback';
import CTA from './notifications/CTA';
const { useSelect } = Data;

export default function ActivateModuleCTA( props ) {
	const { moduleSlug, title, description } = props;

	const module = useSelect( ( select ) =>
		select( CORE_MODULES ).getModule( moduleSlug )
	);

	const activateModuleCallback = useActivateModuleCallback( moduleSlug );

	if ( ! activateModuleCallback ) {
		return null;
	}

	let moduleTitle = title;
	let moduleDescription = description;

	// Special-cases for default title and description.
	// TODO: Solve these in a more appropriate way, e.g. by updating module registration data.
	switch ( moduleSlug ) {
		case 'analytics':
			if ( ! title ) {
				moduleTitle = __(
					'Learn more about what visitors do on your site',
					'google-site-kit'
				);
			}
			if ( ! description ) {
				moduleDescription = __(
					'Connect with Google Analytics to see unique visitors, goal completions, top pages and more',
					'google-site-kit'
				);
			}
			break;
		case 'pagespeed-insights':
			if ( ! description ) {
				moduleDescription = __(
					'Google PageSpeed Insights gives you metrics about performance, accessibility, SEO and PWA',
					'google-site-kit'
				);
			}
			break;
	}

	return (
		<CTA
			title={
				moduleTitle ||
				sprintf(
					/* translators: %s: Module name */
					__( 'Activate %s', 'google-site-kit' ),
					module.name
				)
			}
			description={
				moduleDescription ||
				sprintf(
					/* translators: %s: Module name */
					__( '%s module needs to be configured', 'google-site-kit' ),
					module.name
				)
			}
			ctaLabel={ sprintf(
				/* translators: %s: Module name */
				__( 'Set up %s', 'google-site-kit' ),
				module.name
			) }
			onClick={ activateModuleCallback }
		/>
	);
}

ActivateModuleCTA.propTypes = {
	moduleSlug: PropTypes.string.isRequired,
	title: PropTypes.string,
	description: PropTypes.string,
};
<commit_msg>Remove ActivateModuleCTA component.<commit_after><|endoftext|>


<commit_before>var needle = require('needle');
var cheerio = require('cheerio');
var config = require('./config');

var Spider = function(opts) {
    this.rules = opts.rules || config;
    this.callback = opts.callback;
    if (opts.run) this.run();
    return this;
};

Spider.prototype.run = function(rules) {
    console.time("[+] 规则运行时间.");
    this.once(rules || this.rules, function(once) {
        this.get(once.url, function(jQuery) {
            this.once(once.rules, function(one) {
                if (one.list) {
                    if (one.rule.url) {
                        this.list(one, jQuery, function(rule) {
                            console.info("[+] [" + once.url + "]运行规则: ", rule);
                            this.run(rule);
                        });
                    } else {
                        console.error("[-] [" + once.url + "]列表中不含网址规则,无法继续操作!");
                    }
                } else {
                    this.one(one, jQuery, function(data) {
                        console.info("[+] [" + once.url + "]获取一条数据: ", data);
                        console.timeEnd("[+] 规则运行时间.");
                        this.callback(data);
                    });
                }
            });
        });
    });
};

Spider.prototype.list = function(spider, $, cb) {
    $(spider.list).each(function(i, v) {
        var one = {};
        for (var k in spider.rule) {
            switch (spider.rule[k].type) {
                case 'text':
                    one[k] = v.find(spider.rule[k].text).text();
                    break;

                case 'html':
                    one[k] = v.find(spider.rule[k].text).html();
                    break;

                case 'val':
                    one[k] = v.find(spider.rule[k].text).val();
                    break;

                default:
                    one[k] = v.find(spider.rule[k].text).attr(spider.rule[k].type);
                    break;
            }
        }
        this.once(spider.link, function(once) {
            once.url = one.url;
            cb(once);
        });
    });
};

Spider.prototype.one = function(spider, $, cb) {
    var one = {};
    for (var k in spider.rule) {
        switch (spider.rule[k].type) {
            case 'text':
                one[k] = $(spider.rule[k].text).text();
                break;

            case 'html':
                one[k] = $(spider.rule[k].text).html();
                break;

            case 'val':
                one[k] = $(spider.rule[k].text).val();
                break;

            default:
                one[k] = $(spider.rule[k].text).attr(spider.rule[k].type);
                break;
        }
    }
    cb(one);
};

Spider.prototype.get = function(url, cb) {
    needle.get(url, function(err, res) {
        if (!err) {
            try {
                cb(cheerio.load(res.body));
            } catch (e) {
                console.error("[-] [" + url + "]页面处理失败: ", e);
            }
        } else {
            console.log("[-] [" + url + "]网页访问错误: ", err);
        }
    });
};

Spider.prototype.more = function(list, cb) {

};

Spider.prototype.once = function(more, cb) {
    if (this.isArray(more)) {
        more.forEach(function(once) {
            cb(once);
        });
    } else {
        cb(more);
    }
};

Spider.prototype.isArray = function(object) {
    return object && typeof object === 'object' && Array == object.constructor;
};

exports = module.exports = Spider;
<commit_msg>添加函数调试信息<commit_after>var needle = require('needle');
var cheerio = require('cheerio');
var config = require('./config');

var Spider = function(opts) {
    this.rules = opts.rules || config;
    this.callback = opts.callback;
    if (opts.run) this.run();
    return this;
};

Spider.prototype.run = function(rules) {
    console.trace();
    console.time("[+] 规则运行时间.");
    this.once(rules || this.rules, function(once) {
        this.get(once.url, function(jQuery) {
            this.once(once.rules, function(one) {
                if (one.list) {
                    if (one.rule.url) {
                        this.list(one, jQuery, function(rule) {
                            console.info("[+] [" + once.url + "]运行规则: ", rule);
                            this.run(rule);
                        });
                    } else {
                        console.error("[-] [" + once.url + "]列表中不含网址规则,无法继续操作!");
                    }
                } else {
                    this.one(one, jQuery, function(data) {
                        console.info("[+] [" + once.url + "]获取一条数据: ", data);
                        console.timeEnd("[+] 规则运行时间.");
                        this.callback(data);
                    });
                }
            });
        });
    });
};

Spider.prototype.list = function(spider, $, cb) {
    console.trace();
    $(spider.list).each(function(i, v) {
        var one = {};
        for (var k in spider.rule) {
            switch (spider.rule[k].type) {
                case 'text':
                    one[k] = v.find(spider.rule[k].text).text();
                    break;

                case 'html':
                    one[k] = v.find(spider.rule[k].text).html();
                    break;

                case 'val':
                    one[k] = v.find(spider.rule[k].text).val();
                    break;

                default:
                    one[k] = v.find(spider.rule[k].text).attr(spider.rule[k].type);
                    break;
            }
        }
        this.once(spider.link, function(once) {
            once.url = one.url;
            cb(once);
        });
    });
};

Spider.prototype.one = function(spider, $, cb) {
    console.trace();
    var one = {};
    for (var k in spider.rule) {
        switch (spider.rule[k].type) {
            case 'text':
                one[k] = $(spider.rule[k].text).text();
                break;

            case 'html':
                one[k] = $(spider.rule[k].text).html();
                break;

            case 'val':
                one[k] = $(spider.rule[k].text).val();
                break;

            default:
                one[k] = $(spider.rule[k].text).attr(spider.rule[k].type);
                break;
        }
    }
    cb(one);
};

Spider.prototype.get = function(url, cb) {
    console.trace();
    needle.get(url, function(err, res) {
        if (!err) {
            try {
                cb(cheerio.load(res.body));
            } catch (e) {
                console.error("[-] [" + url + "]页面处理失败: ", e);
            }
        } else {
            console.log("[-] [" + url + "]网页访问错误: ", err);
        }
    });
};

Spider.prototype.more = function(list, cb) {

};

Spider.prototype.once = function(more, cb) {
    console.trace();
    if (this.isArray(more)) {
        more.forEach(function(once) {
            cb(once);
        });
    } else {
        cb(more);
    }
};

Spider.prototype.isArray = function(object) {
    console.trace();
    return object && typeof object === 'object' && Array == object.constructor;
};

exports = module.exports = Spider;
<|endoftext|>


<commit_before>function Spiral(graphType) {
  this.option = {
    graphType: graphType || "points",
    numberOfPoints: null,
    period: null,
    margin: {
      top: 10,
      right: 10,
      bottom: 10,
      left: 30
    },
    svgHeight: 0,
    svgWidth: 0,
    spacing: 1,
    lineWidth: 50,
    targetElement: '#chart',
    data: [],
    x: d3.scale.linear().range([0, 730]).domain([-750, 750]),
    y: d3.scale.linear().range([480, 0]).domain([-500, 500]),
  }
};

Spiral.prototype.cartesian = function(radius, angle, size) {
  var classObj = this;
  var option = classObj.option;

  var size = size || 1;
  var xPos = option.x(radius * Math.cos(angle));
  var yPos = option.y(radius * Math.sin(angle));
  return [xPos, yPos, size];
},
Spiral.prototype.render = function() {
  var classObj = this;
  var option = classObj.option;

  var svg = d3.select(option.targetElement)
    .append("svg")
    .attr("width", option.svgWidth)
    .attr("height", option.svgHeight)

  if (option.graphType === "points") {
    svg.append("g")
      .attr("transform", "translate(" + option.margin.left + "," + option.margin.top + ")");

    svg.selectAll("g").selectAll("dot")
      .data(option.data)
        .enter().append("circle")
          .attr("r", function(d) { return d[2]; })
          .attr("cx", function(d) { return d[0]; })
          .attr("cy", function(d) { return d[1]; });
  } else if (option.graphType === "custom-path") {
    option.data.forEach(function(datum, t, dataSet){
      var start = startAngle(t, option.period);
      var end = endAngle(t, option.period);

      var startCenter = radius(option.spacing, start);
      var endCenter = radius(option.spacing, end);
      var startInnerRadius = startCenter - option.lineWidth*0.5;
      var startOuterRadius = startCenter + option.lineWidth*0.5;
      var endInnerRadius = endCenter - option.lineWidth*0.5;
      var endOuterRadius = endCenter + option.lineWidth*0.5;

      var ctrlInnerRad = 0.01;
      var ctrlOuterRad = 0.01;
      var angle = theta(t, option.period);
      var rad = radius(option.spacing, angle);
      var innerControlPoint = classObj.cartesian(rad - option.lineWidth*0.5 + ctrlInnerRad, angle);
      var outerControlPoint = classObj.cartesian(rad + option.lineWidth*0.5 + ctrlOuterRad, angle);

      var startPoint = classObj.cartesian(startInnerRadius, start);
      var point2 = classObj.cartesian(startOuterRadius, start);
      var point3 = classObj.cartesian(endOuterRadius, end);
      var point4 = classObj.cartesian(endInnerRadius, end);
      var arcPath = "M"+startPoint[0]+" "+startPoint[1]+"L"+point2[0]+" "+point2[1];
      arcPath += "Q"+outerControlPoint[0]+" "+outerControlPoint[1]+" "+point3[0]+" "+point3[1];
      arcPath += "L"+point4[0]+" "+point4[1];
      arcPath += "Q"+innerControlPoint[0]+" "+innerControlPoint[1]+" "+startPoint[0]+" "+startPoint[1]+"Z";
      datum[1] = arcPath
    });

    svg.append("g")
      .attr("transform", "translate(" + option.margin.left + "," + option.margin.top + ")");
    svg.selectAll("g").selectAll("path")
      .data(option.data.slice(100))
      .enter().append("path")
        .style("fill", function(d) { return "black"; })
        .style("opacity", function(d) {return d[2]/9})
        .attr("d", function(d) { return d[1]});
  } else if (option.graphType === "non-spiral") {
    // --------------------vvv Standard Line Graph vvv---------------------------
    var x2 = d3.scale.linear().range([0, 730]);
    var y2 = d3.scale.linear().range([480, 0]);
    x2.domain(d3.extent(option.data, function(d) { return d[0]; }));
    y2.domain(d3.extent(option.data, function(d) { return d[1]; }));

    var xAxis = d3.svg.axis().scale(x2)
      .orient("bottom").ticks(5);

    var yAxis = d3.svg.axis().scale(y2)
      .orient("left").ticks(5);

    var line = d3.svg.line()
      .x(function(d) { return x2(d[0]); })
      .y(function(d) { return y2(d[1]); });

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate("+option.margin.left+"," + 480 + ")")
      .call(xAxis)
      .append("text")
        .attr("x", 710)
        .attr("y", -3)
        .attr("dy", "-.35em")
        .style("text-anchor", "middle")
        .text("time");

    svg.append("g")
      .attr("class", "y axis")
      .attr("transform", "translate("+option.margin.left+",0)")
      .call(yAxis)
      .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("Signal (a.u.)");

    svg.append("path")
      .datum(option.data)
      .attr("class", "line")
      .attr("d", line)
      .attr("fill", "none")
      .attr("stroke-width", "1")
      .attr("stroke", "steelblue")
      .attr("transform", "translate("+option.margin.left+",0)")
  }
},
Spiral.prototype.randomData = function() {
  var classObj = this;
  var option = classObj.option;

  option.data = [];
  for (var i=0; i<option.numberOfPoints; i++){
    var angle = theta(i, option.period);
    var rad = radius(option.spacing, angle);
    var size = 1 + Math.random()*1.5;
    if (i % 10 === 0) {
      size = 5.5 + Math.random()*3;
    }

    if (option.graphType === 'non-spiral') {
      option.data.push([i, size*option.period, 2])
    } else {
      option.data.push(this.cartesian(rad, angle, size));
    }
  }
},
Spiral.prototype.setParam = function(param, value) {
  var classObj = this;
  var option = classObj.option;

  option[param] = value;

  if (['svgHeight', 'svgWidth', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1) {
    var width = option.svgWidth - option.margin.left - option.margin.right;
    var height = option.svgHeight - option.margin.top - option.margin.bottom;
    option.x = d3.scale.linear().range([0, width]).domain([-option.svgWidth, option.svgWidth]);
    option.y = d3.scale.linear().range([height, 0]).domain([-option.svgHeight, option.svgHeight]);
  }
},
Spiral.prototype.redraw = function() {
  var classObj = this;
  var option = classObj.option;

  var graphContainer = document.getElementById(option.targetElement.substr(1));
  while (graphContainer.firstChild) {
    graphContainer.removeChild(graphContainer.firstChild)
  }
  classObj.render();
},
Spiral.prototype.autocorrelate = function() {
  var n = this.option.numberOfPoints;
  var index = this.option.graphType === 'non-spiral' ? 1 : 2;

  var sum = 0;
  for (var i=0; i<n; i++) {
    sum += this.option.data[i][index];
  }
  var avg = sum/n;

  var sigma2 = 0;
  for (var j=0; j < n; j++) {
    sigma2 += Math.pow((this.option.data[j][index] - avg),2);
  }
  console.log(n, avg, sigma2)

  var coeff;
  var coeffArray = [];

  for (var tau=0; tau < n; tau++) {
    var sigma1 = 0;
    for (var j=0; j < n-tau; j++) {
      sigma1 += (this.option.data[j][index] - avg) * (this.option.data[j+tau][index] - avg);
    }

    coeff = sigma1 / sigma2;
    coeffArray.push([tau, coeff]);
  }

  return coeffArray;
}

function theta(t, period) {
  return 2 * Math.PI / (period) * t;
}

function startAngle(t, period) {
  return (theta(t-1, period) + theta(t, period))/2;
}

function endAngle(t, period) {
  return (theta(t+1, period) + theta(t, period))/2;
}

function radius(spacing, angle) {
  return spacing * angle;
}<commit_msg>Tweak random data<commit_after>function Spiral(graphType) {
  this.option = {
    graphType: graphType || "points",
    numberOfPoints: null,
    period: null,
    margin: {
      top: 10,
      right: 10,
      bottom: 10,
      left: 30
    },
    svgHeight: 0,
    svgWidth: 0,
    spacing: 1,
    lineWidth: 50,
    targetElement: '#chart',
    data: [],
    x: d3.scale.linear().range([0, 730]).domain([-750, 750]),
    y: d3.scale.linear().range([480, 0]).domain([-500, 500]),
  }
};

Spiral.prototype.cartesian = function(radius, angle, size) {
  var classObj = this;
  var option = classObj.option;

  var size = size || 1;
  var xPos = option.x(radius * Math.cos(angle));
  var yPos = option.y(radius * Math.sin(angle));
  return [xPos, yPos, size];
},
Spiral.prototype.render = function() {
  var classObj = this;
  var option = classObj.option;

  var svg = d3.select(option.targetElement)
    .append("svg")
    .attr("width", option.svgWidth)
    .attr("height", option.svgHeight)

  if (option.graphType === "points") {
    svg.append("g")
      .attr("transform", "translate(" + option.margin.left + "," + option.margin.top + ")");

    svg.selectAll("g").selectAll("dot")
      .data(option.data)
        .enter().append("circle")
          .attr("r", function(d) { return d[2]; })
          .attr("cx", function(d) { return d[0]; })
          .attr("cy", function(d) { return d[1]; });
  } else if (option.graphType === "custom-path") {
    option.data.forEach(function(datum, t, dataSet){
      var start = startAngle(t, option.period);
      var end = endAngle(t, option.period);

      var startCenter = radius(option.spacing, start);
      var endCenter = radius(option.spacing, end);
      var startInnerRadius = startCenter - option.lineWidth*0.5;
      var startOuterRadius = startCenter + option.lineWidth*0.5;
      var endInnerRadius = endCenter - option.lineWidth*0.5;
      var endOuterRadius = endCenter + option.lineWidth*0.5;

      var ctrlInnerRad = 0.01;
      var ctrlOuterRad = 0.01;
      var angle = theta(t, option.period);
      var rad = radius(option.spacing, angle);
      var innerControlPoint = classObj.cartesian(rad - option.lineWidth*0.5 + ctrlInnerRad, angle);
      var outerControlPoint = classObj.cartesian(rad + option.lineWidth*0.5 + ctrlOuterRad, angle);

      var startPoint = classObj.cartesian(startInnerRadius, start);
      var point2 = classObj.cartesian(startOuterRadius, start);
      var point3 = classObj.cartesian(endOuterRadius, end);
      var point4 = classObj.cartesian(endInnerRadius, end);
      var arcPath = "M"+startPoint[0]+" "+startPoint[1]+"L"+point2[0]+" "+point2[1];
      arcPath += "Q"+outerControlPoint[0]+" "+outerControlPoint[1]+" "+point3[0]+" "+point3[1];
      arcPath += "L"+point4[0]+" "+point4[1];
      arcPath += "Q"+innerControlPoint[0]+" "+innerControlPoint[1]+" "+startPoint[0]+" "+startPoint[1]+"Z";
      datum[1] = arcPath
    });

    svg.append("g")
      .attr("transform", "translate(" + option.margin.left + "," + option.margin.top + ")");
    svg.selectAll("g").selectAll("path")
      .data(option.data.slice(100))
      .enter().append("path")
        .style("fill", function(d) { return "black"; })
        .style("opacity", function(d) {return d[2]/9})
        .attr("d", function(d) { return d[1]});
  } else if (option.graphType === "non-spiral") {
    // --------------------vvv Standard Line Graph vvv---------------------------
    var x2 = d3.scale.linear().range([0, 730]);
    var y2 = d3.scale.linear().range([480, 0]);
    x2.domain(d3.extent(option.data, function(d) { return d[0]; }));
    y2.domain(d3.extent(option.data, function(d) { return d[1]; }));

    var xAxis = d3.svg.axis().scale(x2)
      .orient("bottom").ticks(5);

    var yAxis = d3.svg.axis().scale(y2)
      .orient("left").ticks(5);

    var line = d3.svg.line()
      .x(function(d) { return x2(d[0]); })
      .y(function(d) { return y2(d[1]); });

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate("+option.margin.left+"," + 480 + ")")
      .call(xAxis)
      .append("text")
        .attr("x", 710)
        .attr("y", -3)
        .attr("dy", "-.35em")
        .style("text-anchor", "middle")
        .text("time");

    svg.append("g")
      .attr("class", "y axis")
      .attr("transform", "translate("+option.margin.left+",0)")
      .call(yAxis)
      .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("Signal (a.u.)");

    svg.append("path")
      .datum(option.data)
      .attr("class", "line")
      .attr("d", line)
      .attr("fill", "none")
      .attr("stroke-width", "1")
      .attr("stroke", "steelblue")
      .attr("transform", "translate("+option.margin.left+",0)")
  }
},
Spiral.prototype.randomData = function() {
  var classObj = this;
  var option = classObj.option;

  option.data = [];
  for (var i=0; i<option.numberOfPoints; i++){
    var angle = theta(i, option.period);
    var rad = radius(option.spacing, angle);
    var size = 1 + Math.random()*1;
    if (i % 10 === 0) {
      size = 1.2 + Math.random()*1.5;
    }

    if (option.graphType === 'non-spiral') {
      option.data.push([i, size*option.period, 2])
    } else {
      option.data.push(this.cartesian(rad, angle, size));
    }
  }
},
Spiral.prototype.setParam = function(param, value) {
  var classObj = this;
  var option = classObj.option;

  option[param] = value;

  if (['svgHeight', 'svgWidth', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1) {
    var width = option.svgWidth - option.margin.left - option.margin.right;
    var height = option.svgHeight - option.margin.top - option.margin.bottom;
    option.x = d3.scale.linear().range([0, width]).domain([-option.svgWidth, option.svgWidth]);
    option.y = d3.scale.linear().range([height, 0]).domain([-option.svgHeight, option.svgHeight]);
  }
},
Spiral.prototype.redraw = function() {
  var classObj = this;
  var option = classObj.option;

  var graphContainer = document.getElementById(option.targetElement.substr(1));
  while (graphContainer.firstChild) {
    graphContainer.removeChild(graphContainer.firstChild)
  }
  classObj.render();
},
Spiral.prototype.autocorrelate = function() {
  var n = this.option.numberOfPoints;
  var index = this.option.graphType === 'non-spiral' ? 1 : 2;

  var sum = 0;
  for (var i=0; i<n; i++) {
    sum += this.option.data[i][index];
  }
  var avg = sum/n;

  var sigma2 = 0;
  for (var j=0; j < n; j++) {
    sigma2 += Math.pow((this.option.data[j][index] - avg),2);
  }
  console.log(n, avg, sigma2)

  var coeff;
  var coeffArray = [];

  for (var tau=0; tau < n; tau++) {
    var sigma1 = 0;
    for (var j=0; j < n-tau; j++) {
      sigma1 += (this.option.data[j][index] - avg) * (this.option.data[j+tau][index] - avg);
    }

    coeff = sigma1 / sigma2;
    coeffArray.push([tau, coeff]);
  }

  return coeffArray;
}

function theta(t, period) {
  return 2 * Math.PI / (period) * t;
}

function startAngle(t, period) {
  return (theta(t-1, period) + theta(t, period))/2;
}

function endAngle(t, period) {
  return (theta(t+1, period) + theta(t, period))/2;
}

function radius(spacing, angle) {
  return spacing * angle;
}<|endoftext|>


<commit_before>/*
Notes:

* It takes fewer steps to animate fast springs than slow springs. In other words,
  steps-per-ms is constant. What changes is how drastically the states
  change at each step.

*/

function spring(options) {
  /* Create a new spring object. Override any property with your own options
  object.

  Returns an object with all required spring properties. */
  return {
    distance: options.distance || 0,
    mass: options.mass || 0,
    stiffness: options.stiffness || 0,
    friction: options.friction || 1,
    speed: options.speed || 0
  };
}

function tickSpring(spring) {
  /* Mutates a spring object, updating it to its next state. */
  var dampingForce = (-1 * spring.friction) * spring.speed;
  var springForce = (-1 * spring.stiffness) * spring.distance;
  var totalForce = springForce + dampingForce;
  var acceleration = totalForce / spring.mass;

  spring.speed += acceleration;
  // Update distance from 0 (resting).
  spring.distance += spring.speed / 100;

  return spring;
}

function isSpringAtRest(spring) {
  /* Find out whether a spring is at rest. A spring is at rest when near 0
  distance at a speed less than 0.2.

  Returns a boolean. */
  return Math.round(spring.distance) === 0 && Math.abs(spring.speed) < 0.2;
}

/*
module.exports = {
  extend: extend,
  spring: spring,
  tickSpring: tickSpring,
  isSpringAtRest: isSpringAtRest,
};
*/<commit_msg>isSpringAtRest -> isSpringResting, add animateSpring<commit_after>/*
Notes:

* It takes fewer steps to animate fast springs than slow springs. In other words,
  steps-per-ms is constant. What changes is how drastically the states
  change at each step.

*/

function spring(options) {
  /* Create a new spring object. Override any property with your own options
  object.

  Returns an object with all required spring properties. */
  return {
    distance: options.distance || 0,
    mass: options.mass || 1,
    stiffness: options.stiffness || 0,
    friction: options.friction || 1,
    speed: options.speed || 0
  };
}

function tickSpring(spring) {
  /* Mutates a spring object, updating it to its next state. */
  var dampingForce = (-1 * spring.friction) * spring.speed;
  var springForce = (-1 * spring.stiffness) * spring.distance;
  var totalForce = springForce + dampingForce;
  var acceleration = totalForce / spring.mass;

  spring.speed += acceleration;
  // Update distance from 0 (resting).
  spring.distance += spring.speed / 100;

  return spring;
}

function isSpringResting(spring) {
  /* Find out whether a spring is at rest. A spring is at rest when near 0
  distance at a speed less than 0.2.

  Returns a boolean. */
  return Math.round(spring.distance) === 0 && Math.abs(spring.speed) < 0.2;
}

function animateSpring(spring, callback) {
  /* Animate a spring from its current state to resting state.
  Takes a callback which will be called with the spring object over and over
  and over until the spring is at rest. */
  spring = Object.create(spring);

  var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;

  function looper() {
    tickSpring(spring);
    if(isSpringResting(spring)) return;
    callback(spring.distance);
    requestAnimationFrame(looper);
  }

  looper();
}

/*
module.exports = {
  extend: extend,
  spring: spring,
  tickSpring: tickSpring,
  isSpringAtRest: isSpringAtRest,
};
*/<|endoftext|>


<commit_before>/*
 * Sprint JavaScript Library v1.0.0
 * http://sprintjs.com
 */

var Sprint;

(function() {
  "use strict"

  var d = document
  var matchSelector;

  ["m", "webkitM", "msM", "mozM"].forEach(function(prefix) {
    var name = prefix + "atchesSelector"
    if (!matchSelector && Element.prototype[name]) {
      matchSelector = name
    }
  })

  function selectElements(selector) {
    if (selector == "body") {
      return [d.body]
    }
    // "#id", ".class" or "tagName"
    else if (/^[\#.]?[\w-]+$/.test(selector)) {
      switch (selector[0]) {
        case "#":
          return [d.getElementById(selector.slice(1))]
        case ".":
          return d.getElementsByClassName(selector.slice(1))
        default:
          return d.getElementsByTagName(selector)
      }
    }
    return d.querySelectorAll(selector)
  }

  function Init(selector) {
    switch (typeof selector) {
      case "string":
        if (selector[0] == "<") {
          var tmp = d.createElement("div")
          tmp.innerHTML = selector.trim()
          this.dom = [tmp.firstChild]
        }
        else {
          this.dom = selectElements(selector)
        }
        this.length = this.dom.length
        break
      case "function":
        this.dom = [d]
        this.length = 1
        this.on("DOMContentLoaded", selector)
        break
      default:
        var selectorLength = selector.length
        if (selectorLength === 0) {
          this.dom = selector
          this.length = selectorLength
        }
        else {
          this.dom = selectorLength ? selector : [selector]
          this.length = selectorLength || 1
        }
    }
  }

  Init.prototype = {
    addClass: function(name) {
      this.updateClass("add", name)
      return this
    },
    append: function(content) {
      if (typeof content == "string") {
        if (content[0] == "<") {
          this.each(function() {
            this.insertAdjacentHTML("beforeend", content)
          })
        }
      }
      else {
        if (content instanceof Init) {
          content = content.get()
        }
        else if (!content.length) {
          content = [content]
        }
        this.each(function() {
          var i = -1
          var l = content.length
          while (++i < l) {
            this.insertAdjacentHTML("beforeend", content[i].outerHTML)
          }
        })
      }
      return this
    },
    appendTo: function(selector) {
      var dom = []
      var node = this.get(0)
      var parentNodes = selectElements(selector)
      var i = -1
      var l = parentNodes.length

      while (++i < l) {
        var cloned = node.cloneNode(true)
        dom.push(cloned)
        parentNodes[i].appendChild(cloned)
      }

      this.dom = dom
      this.length = dom.length
      return this
    },
    attr: function(name, value) {
      if (value === undefined) {
        var attributes = []
        this.each(function() {
          attributes.push(this.getAttribute(name))
        })
        return attributes.length == 1 ? attributes[0] : attributes
      }
      else {
        this.each(function() {
          this.setAttribute(name, value)
        })
        return this
      }
    },
    before: function(content) {
      if (typeof content == "string") {
        if (content[0] != "<") return this
        this.each(function() {
          this.insertAdjacentHTML("beforebegin", content)
        })
      }
      else {
        // content can be a live HTMLCollection. Creating a new static array
        // in order to avoid the newly insterted nodes to be added to content.
        var elementsToInsert = []

        if (content.nodeType) {
          // DOM node: document.createTextNode() or document.createElement()
          elementsToInsert.push(content)
        }
        else {
          // array: $("div"), [element1, element2], document.getElementsByTagName, etc.
          var contentArray = content instanceof Init ? content.get() : content
          var i = -1
          var l = contentArray.length

          while (++i < l) {
            var el = contentArray[i]
            elementsToInsert.push(el)
            var prt = el.parentNode
            if (prt) {
              prt.removeChild(el)
            }
          }
        }

        this.each(function() {
          var self = this
          elementsToInsert.forEach(function(el) {
            self.parentNode.insertBefore(el.cloneNode(true), self)
          })
        })
      }
      return this
    },
    children: function(selector) {
      var dom = []
      if (selector) {
        var self = this
        this.each(function() {
          var nodes = this.childNodes
          var i = -1
          var l = nodes.length

          while (++i < l) {
            var node = nodes[i]
            if (node.nodeType == 1 && self.is(selector, node)) {
              dom.push(node)
            }
          }
        })
      }
      else
        this.each(function() {
          var nodes = this.childNodes
          var i = -1
          var l = nodes.length

          while (++i < l) {
            var node = nodes[i]
            node.nodeType == 1 && dom.push(node)
          }
        })
      return Sprint(dom)
    },
    closest: function(selector) {
      var dom = []
      var self = this
      this.each(function() {
        var prt = this.parentNode
        var root = d.documentElement
        while (prt != root) {
          if (self.is(selector, prt)) {
            dom.push(prt)
            break
          }
          else {
            prt = prt.parentNode
          }
        }
      })
      return Sprint(dom)
    },
    each: function(callback) {
      // callback(index, element) where element == this
      var i = -1
      var l = this.length

      while (++i < l) {
        var node = this.get(i)
        callback.call(node, i, node)
      }
      return this
    },
    empty: function() {
      this.each(function() {
        this.innerHTML = ""
      })
      return this
    },
    eq: function(index) {
      var dom = index < this.length ? [this.get(index)] : []
      return Sprint(dom)
    },
    filter: function(selector) {
      var dom = []
      var self = this
      this.each(function() {
        if (self.is(selector, this)) {
          dom.push(this)
        }
      })
      return Sprint(dom)
    },
    find: function(selector) {
      var dom = []
      this.each(function() {
        var nodes = this.querySelectorAll(selector)
        var i = -1
        var l = nodes.length

        while (++i < l) {
          dom.push(nodes.item(i))
        }
      })
      return Sprint(dom)
    },
    get: function(index) {
      return index === undefined ? this.dom : this.dom[index]
    },
    hasClass: function(name) {
      var classFound = false
      this.each(function() {
        if (!classFound && this.classList.contains(name)) {
          classFound = true
        }
      })
      return classFound
    },
    is: function(selector, element) {
      var el = element || this.get(0)
      return el[matchSelector](selector)
    },
    next: function(selector) {
      var dom = []
      if (selector === undefined) {
        this.each(function() {
          dom.push(this.nextElementSibling)
        })
      }
      else {
        var self = this
        this.each(function() {
          var next = this.nextElementSibling
          self.is(selector, next) && dom.push(next)
        })
      }
      return Sprint(dom)
    },
    off: function(type, callback) {
      switch (arguments.length) {
        case 0:
          this.each(function(i, el) {
            if (!this.sprintEventListeners) return
            Object.keys(this.sprintEventListeners).forEach(function(key) {
              el.sprintEventListeners[key].forEach(function(callbackReference) {
                el.removeEventListener(key, callbackReference)
              })
            })
          })
          this.sprintEventListeners = {}
          break
        case 1:
          this.each(function(i, el) {
            if (!this.sprintEventListeners) return
            this.sprintEventListeners[type].forEach(function(callbackReference) {
              el.removeEventListener(type, callbackReference)
            })
            delete this.sprintEventListeners[type]
          })
          break
        case 2:
          this.each(function() {
            if (!this.sprintEventListeners) return
            var updatedSprintEventListeners = []
            this.sprintEventListeners[type].forEach(function(callbackReference) {
              callback != callbackReference && updatedSprintEventListeners.push(callbackReference)
            })
            this.removeEventListener(type, callback)
            this.sprintEventListeners[type] = updatedSprintEventListeners
          })
          break
      }
      return this
    },
    on: function(type, callback) {
      this.each(function() {
        var callbackReference = callback
        this.sprintEventListeners || (this.sprintEventListeners = {})
        this.sprintEventListeners[type] || (this.sprintEventListeners[type] = [])
        this.sprintEventListeners[type].push(callbackReference)
        this.addEventListener(type, callbackReference)
      })
      return this
    },
    parent: function(selector) {
      var dom = []
      if (selector) {
        var self = this
        this.each(function() {
          var prt = this.parentNode
          if (self.is(selector, prt)) {
            dom.push(prt)
          }
        })
      }
      else {
        this.each(function() {
          dom.push(this.parentNode)
        })
      }
      return Sprint(dom)
    },
    removeAttr: function(name) {
      this.each(function() {
        this.removeAttribute(name)
      })
      return this
    },
    removeClass: function(name) {
      name === undefined
        ? this.removeAttr("class")
        : this.updateClass("remove", name)
      return this
    },
    size: function() {
      return this.get().length
    },
    text: function(content) {
      if (content === undefined) {
        var texts = []
        this.each(function() {
          texts.push(this.textContent)
        })
        return texts.length == 1 ? texts[0] : texts
      }
      else {
        this.each(function() {
          this.textContent = content
        })
        return this
      }
    },
    toggleClass: function(name) {
      this.updateClass("toggle", name)
      return this
    },
    wrap: function(element) {
      // single element
      if (element.match(/</g).length < 3) {
        /*var div = document.createElement("div")
        var p = document.querySelector("p")
        var parent = p.parentNode
        var next = p.nextSibling
        div.appendChild(p)
        parent.insertBefore(div, next)*/
      }
      // nested elements
      else {
        // use my this.children method to find the most inner element
        // use my before() and next() methods
      }
    },

    // undocumented, mostly for internal use
    updateClass: function(method, name) {
      this.each(function() {
        this.classList[method](name)
      })
    }
  }

  // public

  Sprint = function(selector) {
    return new Init(selector)
  }

  window.$ === undefined && (window.$ = Sprint)
})();
<commit_msg>Refactor .append() and .before()<commit_after>/*
 * Sprint JavaScript Library v1.0.0
 * http://sprintjs.com
 */

var Sprint;

(function() {
  "use strict"

  var d = document
  var matchSelector = (function() {
    var prefixes = ["m", "webkitM", "msM", "mozM"]
    var i = -1
    var l = prefixes.length
    while (++i < l) {
      var name = prefixes[i] + "atchesSelector"
      if (Element.prototype[name]) {
        return name
      }
    }
  })()

  function selectElements(selector) {
    if (selector == "body") {
      return [d.body]
    }
    // "#id", ".class" or "tagName"
    else if (/^[\#.]?[\w-]+$/.test(selector)) {
      switch (selector[0]) {
        case "#":
          return [d.getElementById(selector.slice(1))]
        case ".":
          return d.getElementsByClassName(selector.slice(1))
        default:
          return d.getElementsByTagName(selector)
      }
    }
    return d.querySelectorAll(selector)
  }

  function insertHTML(position, content) {
    if (typeof content == "string") {
      if (content[0] != "<") return this
      this.each(function() {
        this.insertAdjacentHTML(position, content)
      })
    }
    else {
      // content can be a live HTMLCollection. Creating a new static array
      // in order to avoid the newly insterted nodes to be added to content.
      var elementsToInsert = []

      if (content.nodeType) {
        // DOM node: document.createTextNode() or document.createElement()
        elementsToInsert.push(content)
      }
      else {
        // array: $("div"), [element1, element2], document.getElementsByTagName, etc.
        var contentArray = content instanceof Init ? content.get() : content
        var i = -1

        // contentArray.length can't be cached as it'll change if removeChild() is called
        while (++i < contentArray.length) {
          var el = contentArray[i]
          elementsToInsert.push(el)
          var prt = el.parentNode
          if (prt) {
            prt.removeChild(el)
            i--
          }
        }
      }

      this.each(function() {
        var self = this
        elementsToInsert.forEach(function(el) {
          //self.parentNode.insertBefore(el.cloneNode(true), self)
          self.insertAdjacentHTML(position, el.outerHTML)
        })
      })
    }
  }

  function Init(selector) {
    switch (typeof selector) {
      case "string":
        if (selector[0] == "<") {
          var tmp = d.createElement("div")
          tmp.innerHTML = selector.trim()
          this.dom = [tmp.firstChild]
        }
        else {
          this.dom = selectElements(selector)
        }
        this.length = this.dom.length
        break
      case "function":
        this.dom = [d]
        this.length = 1
        this.on("DOMContentLoaded", selector)
        break
      default:
        var selectorLength = selector.length
        if (selectorLength === 0) {
          this.dom = selector
          this.length = selectorLength
        }
        else {
          this.dom = selectorLength ? selector : [selector]
          this.length = selectorLength || 1
        }
    }
  }

  Init.prototype = {
    addClass: function(name) {
      this.updateClass("add", name)
      return this
    },
    append: function(content) {
      insertHTML.call(this, "beforeend", content)
      return this
    },
    appendTo: function(selector) {
      var dom = []
      var node = this.get(0)
      var parentNodes = selectElements(selector)
      var i = -1
      var l = parentNodes.length

      while (++i < l) {
        var cloned = node.cloneNode(true)
        dom.push(cloned)
        parentNodes[i].appendChild(cloned)
      }

      this.dom = dom
      this.length = dom.length
      return this
    },
    attr: function(name, value) {
      if (value === undefined) {
        var attributes = []
        this.each(function() {
          attributes.push(this.getAttribute(name))
        })
        return attributes.length == 1 ? attributes[0] : attributes
      }
      else {
        this.each(function() {
          this.setAttribute(name, value)
        })
        return this
      }
    },
    before: function(content) {
      insertHTML.call(this, "beforebegin", content)
      return this
    },
    children: function(selector) {
      var dom = []
      if (selector) {
        var self = this
        this.each(function() {
          var nodes = this.childNodes
          var i = -1
          var l = nodes.length

          while (++i < l) {
            var node = nodes[i]
            if (node.nodeType == 1 && self.is(selector, node)) {
              dom.push(node)
            }
          }
        })
      }
      else
        this.each(function() {
          var nodes = this.childNodes
          var i = -1
          var l = nodes.length

          while (++i < l) {
            var node = nodes[i]
            node.nodeType == 1 && dom.push(node)
          }
        })
      return Sprint(dom)
    },
    closest: function(selector) {
      var dom = []
      var self = this
      this.each(function() {
        var prt = this.parentNode
        var root = d.documentElement
        while (prt != root) {
          if (self.is(selector, prt)) {
            dom.push(prt)
            break
          }
          else {
            prt = prt.parentNode
          }
        }
      })
      return Sprint(dom)
    },
    each: function(callback) {
      // callback(index, element) where element == this
      var i = -1
      var l = this.length

      while (++i < l) {
        var node = this.get(i)
        callback.call(node, i, node)
      }
      return this
    },
    empty: function() {
      this.each(function() {
        this.innerHTML = ""
      })
      return this
    },
    eq: function(index) {
      var dom = index < this.length ? [this.get(index)] : []
      return Sprint(dom)
    },
    filter: function(selector) {
      var dom = []
      var self = this
      this.each(function() {
        if (self.is(selector, this)) {
          dom.push(this)
        }
      })
      return Sprint(dom)
    },
    find: function(selector) {
      var dom = []
      this.each(function() {
        var nodes = this.querySelectorAll(selector)
        var i = -1
        var l = nodes.length

        while (++i < l) {
          dom.push(nodes.item(i))
        }
      })
      return Sprint(dom)
    },
    get: function(index) {
      return index === undefined ? this.dom : this.dom[index]
    },
    hasClass: function(name) {
      var classFound = false
      this.each(function() {
        if (!classFound && this.classList.contains(name)) {
          classFound = true
        }
      })
      return classFound
    },
    is: function(selector, element) {
      var el = element || this.get(0)
      return el[matchSelector](selector)
    },
    next: function(selector) {
      var dom = []
      if (selector === undefined) {
        this.each(function() {
          dom.push(this.nextElementSibling)
        })
      }
      else {
        var self = this
        this.each(function() {
          var next = this.nextElementSibling
          self.is(selector, next) && dom.push(next)
        })
      }
      return Sprint(dom)
    },
    off: function(type, callback) {
      switch (arguments.length) {
        case 0:
          this.each(function(i, el) {
            if (!this.sprintEventListeners) return
            Object.keys(this.sprintEventListeners).forEach(function(key) {
              el.sprintEventListeners[key].forEach(function(callbackReference) {
                el.removeEventListener(key, callbackReference)
              })
            })
          })
          this.sprintEventListeners = {}
          break
        case 1:
          this.each(function(i, el) {
            if (!this.sprintEventListeners) return
            this.sprintEventListeners[type].forEach(function(callbackReference) {
              el.removeEventListener(type, callbackReference)
            })
            delete this.sprintEventListeners[type]
          })
          break
        case 2:
          this.each(function() {
            if (!this.sprintEventListeners) return
            var updatedSprintEventListeners = []
            this.sprintEventListeners[type].forEach(function(callbackReference) {
              callback != callbackReference && updatedSprintEventListeners.push(callbackReference)
            })
            this.removeEventListener(type, callback)
            this.sprintEventListeners[type] = updatedSprintEventListeners
          })
          break
      }
      return this
    },
    on: function(type, callback) {
      this.each(function() {
        var callbackReference = callback
        this.sprintEventListeners || (this.sprintEventListeners = {})
        this.sprintEventListeners[type] || (this.sprintEventListeners[type] = [])
        this.sprintEventListeners[type].push(callbackReference)
        this.addEventListener(type, callbackReference)
      })
      return this
    },
    parent: function(selector) {
      var dom = []
      if (selector) {
        var self = this
        this.each(function() {
          var prt = this.parentNode
          if (self.is(selector, prt)) {
            dom.push(prt)
          }
        })
      }
      else {
        this.each(function() {
          dom.push(this.parentNode)
        })
      }
      return Sprint(dom)
    },
    removeAttr: function(name) {
      this.each(function() {
        this.removeAttribute(name)
      })
      return this
    },
    removeClass: function(name) {
      name === undefined
        ? this.removeAttr("class")
        : this.updateClass("remove", name)
      return this
    },
    size: function() {
      return this.get().length
    },
    text: function(content) {
      if (content === undefined) {
        var texts = []
        this.each(function() {
          texts.push(this.textContent)
        })
        return texts.length == 1 ? texts[0] : texts
      }
      else {
        this.each(function() {
          this.textContent = content
        })
        return this
      }
    },
    toggleClass: function(name) {
      this.updateClass("toggle", name)
      return this
    },
    wrap: function(element) {
      // single element
      if (element.match(/</g).length < 3) {
        /*var div = document.createElement("div")
        var p = document.querySelector("p")
        var parent = p.parentNode
        var next = p.nextSibling
        div.appendChild(p)
        parent.insertBefore(div, next)*/
      }
      // nested elements
      else {
        // use my this.children method to find the most inner element
        // use my before() and next() methods
      }
    },

    // undocumented, mostly for internal use
    updateClass: function(method, name) {
      this.each(function() {
        this.classList[method](name)
      })
    }
  }

  // public

  Sprint = function(selector) {
    return new Init(selector)
  }

  window.$ === undefined && (window.$ = Sprint)
})();
<|endoftext|>


<commit_before>import {points}         from './primitiveTypes/points.js';
import {lines}          from './primitiveTypes/lines.js';
import {linesLoop}      from './primitiveTypes/linesLoop.js';
import {linesStrip}     from './primitiveTypes/linesStrip.js';
import {triangles}      from './primitiveTypes/triangles.js';
import {trianglesStrip} from './primitiveTypes/trianglesStrip.js';
import {trianglesFan}   from './primitiveTypes/trianglesFan.js';
import {drawTriangles}  from './draw/drawTriangles.js';

/**
 * @author niekes / http://niekes.com/
 */

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        distance        = 1,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        primitiveType   = 'POINTS',
        processData = {
            POINTS          : points,
            LINES           : lines,
            LINES_LOOP      : linesLoop,
            LINES_STRIP     : linesStrip,
            TRIANGLES       : triangles,
            TRIANGLES_STRIP : trianglesStrip,
            TRIANGLES_FAN   : trianglesFan
        },
        draw = {
            TRIANGLES   : drawTriangles
        };

    function _3d(data){
        return processData[primitiveType](data, angleX, angleY, angleZ, origin, scale, distance);
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.distance = function(_){
        return arguments.length ? (distance = _, _3d) : distance;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.primitiveType = function(_){
        return arguments.length ? (primitiveType = _, _3d) : primitiveType;
    };

    _3d.draw = function(d){
        if(primitiveType !== 'POINTS' || primitiveType !== 'LINES'){
            return draw[primitiveType](d);
        }
    };

    return _3d;
}
<commit_msg>add x, y & z access function<commit_after>import {points}         from './primitiveTypes/points.js';
import {lines}          from './primitiveTypes/lines.js';
import {linesLoop}      from './primitiveTypes/linesLoop.js';
import {linesStrip}     from './primitiveTypes/linesStrip.js';
import {triangles}      from './primitiveTypes/triangles.js';
import {trianglesStrip} from './primitiveTypes/trianglesStrip.js';
import {trianglesFan}   from './primitiveTypes/trianglesFan.js';
import {drawTriangles}  from './draw/drawTriangles.js';
import {x as pointX,
        y as pointY,
        z as pointZ,
        }               from './point';

/**
 * @author Stefan Nieke / http://niekes.com/
 */

export default function() {

    var origin          = [0, 0],
        scale           = 1,
        distance        = 1,
        angleX          = 0,
        angleY          = 0,
        angleZ          = 0,
        x               = pointX,
        y               = pointY,
        z               = pointY,
        primitiveType   = 'POINTS',
        processData = {
            POINTS          : points,
            LINES           : lines,
            LINES_LOOP      : linesLoop,
            LINES_STRIP     : linesStrip,
            TRIANGLES       : triangles,
            TRIANGLES_STRIP : trianglesStrip,
            TRIANGLES_FAN   : trianglesFan
        },
        draw = {
            TRIANGLES   : drawTriangles
        };

    function _3d(data){
        return processData[primitiveType](data, angleX, angleY, angleZ, origin, scale, distance);
    }

    _3d.origin = function(_){
        return arguments.length ? (origin = _, _3d) : origin;
    };

    _3d.scale = function(_){
        return arguments.length ? (scale = _, _3d) : scale;
    };

    _3d.distance = function(_){
        return arguments.length ? (distance = _, _3d) : distance;
    };

    _3d.rotateX = function(_){
        return arguments.length ? (angleX = _, _3d) : angleX;
    };

    _3d.rotateY = function(_){
        return arguments.length ? (angleY = _, _3d) : angleY;
    };

    _3d.rotateZ = function(_){
        return arguments.length ? (angleZ = _, _3d) : angleZ;
    };

    _3d.primitiveType = function(_){
        return arguments.length ? (primitiveType = _, _3d) : primitiveType;
    };

    _3d.x = function(_){
        return arguments.length ? (x = typeof _ === 'function' ? _ : +_, _3d) : x;
    };

    _3d.y = function(_){
        return arguments.length ? (y = typeof _ === 'function' ? _ : +_, _3d) : y;
    };

    _3d.z = function(_){
        return arguments.length ? (z = typeof _ === 'function' ? _ : +_, _3d) : z;
    };

    _3d.draw = function(d){
        if(!((primitiveType === 'POINTS') || (primitiveType === 'LINES'))){
            return draw[primitiveType](d);
        }
    };

    return _3d;
}
<|endoftext|>


<commit_before>const _ = require('underscore');
const userAgent = require('./ua');
const {
  isNullOrUndefined,
} = require('./utils');

const AV = global.AV || {};

// All internal configuration items
AV._config = AV._config || {};
const AVConfig = AV._config;

_.extend(AVConfig, {

  // 服务器节点地区，默认中国大陆
  region: 'cn',

  // 服务器的 URL，默认初始化时被设置为大陆节点地址
  APIServerURL: AVConfig.APIServerURL || '',

  // 禁用 currentUser，通常用于多用户环境
  disableCurrentUser: false,

  // Internal config can modifie the UserAgent
  userAgent,

  // set production environment or test environment
  // 1: production environment, 0: test environment, null: default environment
  applicationProduction: null,
});

/**
 * Contains all AV API classes and functions.
 * @namespace AV
 */

// Helpers
// -------

// Shared empty constructor function to aid in prototype-chain creation.
var EmptyConstructor = function() {};

// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
  var child;

  // The constructor function for the new subclass is either defined by you
  // (the "constructor" property in your `extend` definition), or defaulted
  // by us to simply call the parent's constructor.
  if (protoProps && protoProps.hasOwnProperty('constructor')) {
    child = protoProps.constructor;
  } else {
    /** @ignore */
    child = function(){ parent.apply(this, arguments); };
  }

  // Inherit class (static) properties from parent.
  _.extend(child, parent);

  // Set the prototype chain to inherit from `parent`, without calling
  // `parent`'s constructor function.
  EmptyConstructor.prototype = parent.prototype;
  child.prototype = new EmptyConstructor();

  // Add prototype properties (instance properties) to the subclass,
  // if supplied.
  if (protoProps) {
    _.extend(child.prototype, protoProps);
  }

  // Add static properties to the constructor function, if supplied.
  if (staticProps) {
    _.extend(child, staticProps);
  }

  // Correctly set child's `prototype.constructor`.
  child.prototype.constructor = child;

  // Set a convenience property in case the parent's prototype is
  // needed later.
  child.__super__ = parent.prototype;

  return child;
};

/**
 * Call this method to set production environment variable.
 * @function AV.setProduction
 * @param {Boolean} production True is production environment,and
 *  it's true by default.
 */
AV.setProduction = (production) => {
  if (!isNullOrUndefined(production)) {
    AVConfig.applicationProduction = production ? 1 : 0;
  } else {
    // change to default value
    AVConfig.applicationProduction = null;
  }
};

/**
 * Returns prefix for localStorage keys used by this instance of AV.
 * @param {String} path The relative suffix to append to it.
 *     null or undefined is treated as the empty string.
 * @return {String} The full key name.
 * @private
 */
AV._getAVPath = function(path) {
  if (!AV.applicationId) {
    throw new Error("You need to call AV.initialize before using AV.");
  }
  if (!path) {
    path = "";
  }
  if (!_.isString(path)) {
    throw new Error("Tried to get a localStorage path that wasn't a String.");
  }
  if (path[0] === "/") {
    path = path.substring(1);
  }
  return "AV/" + AV.applicationId + "/" + path;
};

/**
 * Returns the unique string for this app on this machine.
 * Gets reset when localStorage is cleared.
 * @private
 */
AV._installationId = null;
AV._getInstallationId = function() {
  // See if it's cached in RAM.
  if (AV._installationId) {
    return AV.Promise.resolve(AV._installationId);
  }

  // Try to get it from localStorage.
  var path = AV._getAVPath("installationId");
  return AV.localStorage.getItemAsync(path).then(function(_installationId){
    AV._installationId = _installationId;
    if (!AV._installationId) {
      // It wasn't in localStorage, so create a new one.
      var hexOctet = function() {
        return Math.floor((1+Math.random())*0x10000).toString(16).substring(1);
      };
      AV._installationId = (
        hexOctet() + hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + hexOctet() + hexOctet());
      return AV.localStorage.setItemAsync(path, AV._installationId);
    }
    else {
      return _installationId;
    }
  });
};

AV._parseDate = function(iso8601) {
  var regexp = new RegExp(
    "^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})" + "T" +
    "([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})" +
    "(.([0-9]+))?" + "Z$");
  var match = regexp.exec(iso8601);
  if (!match) {
    return null;
  }

  var year = match[1] || 0;
  var month = (match[2] || 1) - 1;
  var day = match[3] || 0;
  var hour = match[4] || 0;
  var minute = match[5] || 0;
  var second = match[6] || 0;
  var milli = match[8] || 0;

  return new Date(Date.UTC(year, month, day, hour, minute, second, milli));
};

// A self-propagating extend function.
AV._extend = function(protoProps, classProps) {
  var child = inherits(this, protoProps, classProps);
  child.extend = this.extend;
  return child;
};

// Helper function to get a value from a Backbone object as a property
// or as a function.
AV._getValue = function(object, prop) {
  if (!(object && object[prop])) {
    return null;
  }
  return _.isFunction(object[prop]) ? object[prop]() : object[prop];
};

/**
 * Converts a value in a AV Object into the appropriate representation.
 * This is the JS equivalent of Java's AV.maybeReferenceAndEncode(Object)
 * if seenObjects is falsey. Otherwise any AV.Objects not in
 * seenObjects will be fully embedded rather than encoded
 * as a pointer.  This array will be used to prevent going into an infinite
 * loop because we have circular references.  If <seenObjects>
 * is set, then none of the AV Objects that are serialized can be dirty.
 * @private
 */
AV._encode = function(value, seenObjects, disallowObjects, full) {
  if (value instanceof AV.Object) {
    if (disallowObjects) {
      throw new Error("AV.Objects not allowed here");
    }
    if (!seenObjects || _.include(seenObjects, value) || !value._hasData) {
      return value._toPointer();
    }
    return value._toFullJSON(seenObjects.concat(value), full);
  }
  if (value instanceof AV.ACL) {
    return value.toJSON();
  }
  if (_.isDate(value)) {
    return full ? { "__type": "Date", "iso": value.toJSON() } : value.toJSON();
  }
  if (value instanceof AV.GeoPoint) {
    return value.toJSON();
  }
  if (_.isArray(value)) {
    return _.map(value, function(x) {
      return AV._encode(x, seenObjects, disallowObjects, full);
    });
  }
  if (_.isRegExp(value)) {
    return value.source;
  }
  if (value instanceof AV.Relation) {
    return value.toJSON();
  }
  if (value instanceof AV.Op) {
    return value.toJSON();
  }
  if (value instanceof AV.File) {
    if (!value.url() && !value.id) {
      throw new Error("Tried to save an object containing an unsaved file.");
    }
    return value._toFullJSON(seenObjects, full);
  }
  if (_.isObject(value)) {
    return _.mapObject(value, (v, k) => AV._encode(v, seenObjects, disallowObjects, full));
  }
  return value;
};

/**
 * The inverse function of AV._encode.
 * @private
 */
AV._decode = function(value, key) {
  if (!_.isObject(value) || _.isDate(value)) {
    return value;
  }
  if (_.isArray(value)) {
    return _.map(value, v => AV._decode(v));
  }
  if (value instanceof AV.Object) {
    return value;
  }
  if (value instanceof AV.File) {
    return value;
  }
  if (value instanceof AV.Op) {
    return value;
  }
  if (value instanceof AV.GeoPoint) {
    return value;
  }
  if (value instanceof AV.ACL) {
    return value;
  }
  if (key === 'ACL') {
    return new AV.ACL(value);
  }
  if (value.__op) {
    return AV.Op._decode(value);
  }
  var className;
  if (value.__type === "Pointer") {
    className = value.className;
    var pointer = AV.Object._create(className);
    if(Object.keys(value).length > 3) {
        const v = _.clone(value);
        delete v.__type;
        delete v.className;
        pointer._finishFetch(v, true);
    }else{
        pointer._finishFetch({ objectId: value.objectId }, false);
    }
    return pointer;
  }
  if (value.__type === "Object") {
    // It's an Object included in a query result.
    className = value.className;
    const v = _.clone(value);
    delete v.__type;
    delete v.className;
    var object = AV.Object._create(className);
    object._finishFetch(v, true);
    return object;
  }
  if (value.__type === "Date") {
    return AV._parseDate(value.iso);
  }
  if (value.__type === "GeoPoint") {
    return new AV.GeoPoint({
      latitude: value.latitude,
      longitude: value.longitude
    });
  }
  if (value.__type === "Relation") {
    if (!key) throw new Error('key missing decoding a Relation');
    var relation = new AV.Relation(null, key);
    relation.targetClassName = value.className;
    return relation;
  }
  if (value.__type === 'File') {
    var file = new AV.File(value.name);
    const v = _.clone(value);
    delete v.__type;
    file._finishFetch(v);
    return file;
  }
  return _.mapObject(value, AV._decode);
};

/**
 * The inverse function of {@link AV.Object#toFullJSON}.
 * @since 2.0.0
 * @param {Object}
 * return {AV.Object|AV.File|any}
 */
AV.parseJSON = AV._decode;

AV._encodeObjectOrArray = function(value) {
  var encodeAVObject = function(object) {
    if (object && object._toFullJSON){
      object = object._toFullJSON([]);
    }

    return _.mapObject(object, function(value) {
      return AV._encode(value, []);
    });
  };

  if (_.isArray(value)) {
    return value.map(function(object) {
      return encodeAVObject(object);
    });
  } else {
    return encodeAVObject(value);
  }
};

AV._arrayEach = _.each;

/**
 * Does a deep traversal of every item in object, calling func on every one.
 * @param {Object} object The object or array to traverse deeply.
 * @param {Function} func The function to call for every item. It will
 *     be passed the item as an argument. If it returns a truthy value, that
 *     value will replace the item in its parent container.
 * @returns {} the result of calling func on the top-level object itself.
 * @private
 */
AV._traverse = function(object, func, seen) {
  if (object instanceof AV.Object) {
    seen = seen || [];
    if (_.indexOf(seen, object) >= 0) {
      // We've already visited this object in this call.
      return;
    }
    seen.push(object);
    AV._traverse(object.attributes, func, seen);
    return func(object);
  }
  if (object instanceof AV.Relation || object instanceof AV.File) {
    // Nothing needs to be done, but we don't want to recurse into the
    // object's parent infinitely, so we catch this case.
    return func(object);
  }
  if (_.isArray(object)) {
    _.each(object, function(child, index) {
      var newChild = AV._traverse(child, func, seen);
      if (newChild) {
        object[index] = newChild;
      }
    });
    return func(object);
  }
  if (_.isObject(object)) {
    AV._each(object, function(child, key) {
      var newChild = AV._traverse(child, func, seen);
      if (newChild) {
        object[key] = newChild;
      }
    });
    return func(object);
  }
  return func(object);
};

/**
 * This is like _.each, except:
 * * it doesn't work for so-called array-like objects,
 * * it does work for dictionaries with a "length" attribute.
 * @private
 */
AV._objectEach = AV._each = function(obj, callback) {
  if (_.isObject(obj)) {
    _.each(_.keys(obj), function(key) {
      callback(obj[key], key);
    });
  } else {
    _.each(obj, callback);
  }
};

module.exports = AV;
<commit_msg>fix: default the full param of AV._encode to true (#455)<commit_after>const _ = require('underscore');
const userAgent = require('./ua');
const {
  isNullOrUndefined,
} = require('./utils');

const AV = global.AV || {};

// All internal configuration items
AV._config = AV._config || {};
const AVConfig = AV._config;

_.extend(AVConfig, {

  // 服务器节点地区，默认中国大陆
  region: 'cn',

  // 服务器的 URL，默认初始化时被设置为大陆节点地址
  APIServerURL: AVConfig.APIServerURL || '',

  // 禁用 currentUser，通常用于多用户环境
  disableCurrentUser: false,

  // Internal config can modifie the UserAgent
  userAgent,

  // set production environment or test environment
  // 1: production environment, 0: test environment, null: default environment
  applicationProduction: null,
});

/**
 * Contains all AV API classes and functions.
 * @namespace AV
 */

// Helpers
// -------

// Shared empty constructor function to aid in prototype-chain creation.
var EmptyConstructor = function() {};

// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
  var child;

  // The constructor function for the new subclass is either defined by you
  // (the "constructor" property in your `extend` definition), or defaulted
  // by us to simply call the parent's constructor.
  if (protoProps && protoProps.hasOwnProperty('constructor')) {
    child = protoProps.constructor;
  } else {
    /** @ignore */
    child = function(){ parent.apply(this, arguments); };
  }

  // Inherit class (static) properties from parent.
  _.extend(child, parent);

  // Set the prototype chain to inherit from `parent`, without calling
  // `parent`'s constructor function.
  EmptyConstructor.prototype = parent.prototype;
  child.prototype = new EmptyConstructor();

  // Add prototype properties (instance properties) to the subclass,
  // if supplied.
  if (protoProps) {
    _.extend(child.prototype, protoProps);
  }

  // Add static properties to the constructor function, if supplied.
  if (staticProps) {
    _.extend(child, staticProps);
  }

  // Correctly set child's `prototype.constructor`.
  child.prototype.constructor = child;

  // Set a convenience property in case the parent's prototype is
  // needed later.
  child.__super__ = parent.prototype;

  return child;
};

/**
 * Call this method to set production environment variable.
 * @function AV.setProduction
 * @param {Boolean} production True is production environment,and
 *  it's true by default.
 */
AV.setProduction = (production) => {
  if (!isNullOrUndefined(production)) {
    AVConfig.applicationProduction = production ? 1 : 0;
  } else {
    // change to default value
    AVConfig.applicationProduction = null;
  }
};

/**
 * Returns prefix for localStorage keys used by this instance of AV.
 * @param {String} path The relative suffix to append to it.
 *     null or undefined is treated as the empty string.
 * @return {String} The full key name.
 * @private
 */
AV._getAVPath = function(path) {
  if (!AV.applicationId) {
    throw new Error("You need to call AV.initialize before using AV.");
  }
  if (!path) {
    path = "";
  }
  if (!_.isString(path)) {
    throw new Error("Tried to get a localStorage path that wasn't a String.");
  }
  if (path[0] === "/") {
    path = path.substring(1);
  }
  return "AV/" + AV.applicationId + "/" + path;
};

/**
 * Returns the unique string for this app on this machine.
 * Gets reset when localStorage is cleared.
 * @private
 */
AV._installationId = null;
AV._getInstallationId = function() {
  // See if it's cached in RAM.
  if (AV._installationId) {
    return AV.Promise.resolve(AV._installationId);
  }

  // Try to get it from localStorage.
  var path = AV._getAVPath("installationId");
  return AV.localStorage.getItemAsync(path).then(function(_installationId){
    AV._installationId = _installationId;
    if (!AV._installationId) {
      // It wasn't in localStorage, so create a new one.
      var hexOctet = function() {
        return Math.floor((1+Math.random())*0x10000).toString(16).substring(1);
      };
      AV._installationId = (
        hexOctet() + hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + "-" +
        hexOctet() + hexOctet() + hexOctet());
      return AV.localStorage.setItemAsync(path, AV._installationId);
    }
    else {
      return _installationId;
    }
  });
};

AV._parseDate = function(iso8601) {
  var regexp = new RegExp(
    "^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})" + "T" +
    "([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})" +
    "(.([0-9]+))?" + "Z$");
  var match = regexp.exec(iso8601);
  if (!match) {
    return null;
  }

  var year = match[1] || 0;
  var month = (match[2] || 1) - 1;
  var day = match[3] || 0;
  var hour = match[4] || 0;
  var minute = match[5] || 0;
  var second = match[6] || 0;
  var milli = match[8] || 0;

  return new Date(Date.UTC(year, month, day, hour, minute, second, milli));
};

// A self-propagating extend function.
AV._extend = function(protoProps, classProps) {
  var child = inherits(this, protoProps, classProps);
  child.extend = this.extend;
  return child;
};

// Helper function to get a value from a Backbone object as a property
// or as a function.
AV._getValue = function(object, prop) {
  if (!(object && object[prop])) {
    return null;
  }
  return _.isFunction(object[prop]) ? object[prop]() : object[prop];
};

/**
 * Converts a value in a AV Object into the appropriate representation.
 * This is the JS equivalent of Java's AV.maybeReferenceAndEncode(Object)
 * if seenObjects is falsey. Otherwise any AV.Objects not in
 * seenObjects will be fully embedded rather than encoded
 * as a pointer.  This array will be used to prevent going into an infinite
 * loop because we have circular references.  If <seenObjects>
 * is set, then none of the AV Objects that are serialized can be dirty.
 * @private
 */
AV._encode = function(value, seenObjects, disallowObjects, full = true) {
  if (value instanceof AV.Object) {
    if (disallowObjects) {
      throw new Error("AV.Objects not allowed here");
    }
    if (!seenObjects || _.include(seenObjects, value) || !value._hasData) {
      return value._toPointer();
    }
    return value._toFullJSON(seenObjects.concat(value), full);
  }
  if (value instanceof AV.ACL) {
    return value.toJSON();
  }
  if (_.isDate(value)) {
    return full ? { "__type": "Date", "iso": value.toJSON() } : value.toJSON();
  }
  if (value instanceof AV.GeoPoint) {
    return value.toJSON();
  }
  if (_.isArray(value)) {
    return _.map(value, function(x) {
      return AV._encode(x, seenObjects, disallowObjects, full);
    });
  }
  if (_.isRegExp(value)) {
    return value.source;
  }
  if (value instanceof AV.Relation) {
    return value.toJSON();
  }
  if (value instanceof AV.Op) {
    return value.toJSON();
  }
  if (value instanceof AV.File) {
    if (!value.url() && !value.id) {
      throw new Error("Tried to save an object containing an unsaved file.");
    }
    return value._toFullJSON(seenObjects, full);
  }
  if (_.isObject(value)) {
    return _.mapObject(value, (v, k) => AV._encode(v, seenObjects, disallowObjects, full));
  }
  return value;
};

/**
 * The inverse function of AV._encode.
 * @private
 */
AV._decode = function(value, key) {
  if (!_.isObject(value) || _.isDate(value)) {
    return value;
  }
  if (_.isArray(value)) {
    return _.map(value, v => AV._decode(v));
  }
  if (value instanceof AV.Object) {
    return value;
  }
  if (value instanceof AV.File) {
    return value;
  }
  if (value instanceof AV.Op) {
    return value;
  }
  if (value instanceof AV.GeoPoint) {
    return value;
  }
  if (value instanceof AV.ACL) {
    return value;
  }
  if (key === 'ACL') {
    return new AV.ACL(value);
  }
  if (value.__op) {
    return AV.Op._decode(value);
  }
  var className;
  if (value.__type === "Pointer") {
    className = value.className;
    var pointer = AV.Object._create(className);
    if(Object.keys(value).length > 3) {
        const v = _.clone(value);
        delete v.__type;
        delete v.className;
        pointer._finishFetch(v, true);
    }else{
        pointer._finishFetch({ objectId: value.objectId }, false);
    }
    return pointer;
  }
  if (value.__type === "Object") {
    // It's an Object included in a query result.
    className = value.className;
    const v = _.clone(value);
    delete v.__type;
    delete v.className;
    var object = AV.Object._create(className);
    object._finishFetch(v, true);
    return object;
  }
  if (value.__type === "Date") {
    return AV._parseDate(value.iso);
  }
  if (value.__type === "GeoPoint") {
    return new AV.GeoPoint({
      latitude: value.latitude,
      longitude: value.longitude
    });
  }
  if (value.__type === "Relation") {
    if (!key) throw new Error('key missing decoding a Relation');
    var relation = new AV.Relation(null, key);
    relation.targetClassName = value.className;
    return relation;
  }
  if (value.__type === 'File') {
    var file = new AV.File(value.name);
    const v = _.clone(value);
    delete v.__type;
    file._finishFetch(v);
    return file;
  }
  return _.mapObject(value, AV._decode);
};

/**
 * The inverse function of {@link AV.Object#toFullJSON}.
 * @since 2.0.0
 * @param {Object}
 * return {AV.Object|AV.File|any}
 */
AV.parseJSON = AV._decode;

AV._encodeObjectOrArray = function(value) {
  var encodeAVObject = function(object) {
    if (object && object._toFullJSON){
      object = object._toFullJSON([]);
    }

    return _.mapObject(object, function(value) {
      return AV._encode(value, []);
    });
  };

  if (_.isArray(value)) {
    return value.map(function(object) {
      return encodeAVObject(object);
    });
  } else {
    return encodeAVObject(value);
  }
};

AV._arrayEach = _.each;

/**
 * Does a deep traversal of every item in object, calling func on every one.
 * @param {Object} object The object or array to traverse deeply.
 * @param {Function} func The function to call for every item. It will
 *     be passed the item as an argument. If it returns a truthy value, that
 *     value will replace the item in its parent container.
 * @returns {} the result of calling func on the top-level object itself.
 * @private
 */
AV._traverse = function(object, func, seen) {
  if (object instanceof AV.Object) {
    seen = seen || [];
    if (_.indexOf(seen, object) >= 0) {
      // We've already visited this object in this call.
      return;
    }
    seen.push(object);
    AV._traverse(object.attributes, func, seen);
    return func(object);
  }
  if (object instanceof AV.Relation || object instanceof AV.File) {
    // Nothing needs to be done, but we don't want to recurse into the
    // object's parent infinitely, so we catch this case.
    return func(object);
  }
  if (_.isArray(object)) {
    _.each(object, function(child, index) {
      var newChild = AV._traverse(child, func, seen);
      if (newChild) {
        object[index] = newChild;
      }
    });
    return func(object);
  }
  if (_.isObject(object)) {
    AV._each(object, function(child, key) {
      var newChild = AV._traverse(child, func, seen);
      if (newChild) {
        object[key] = newChild;
      }
    });
    return func(object);
  }
  return func(object);
};

/**
 * This is like _.each, except:
 * * it doesn't work for so-called array-like objects,
 * * it does work for dictionaries with a "length" attribute.
 * @private
 */
AV._objectEach = AV._each = function(obj, callback) {
  if (_.isObject(obj)) {
    _.each(_.keys(obj), function(key) {
      callback(obj[key], key);
    });
  } else {
    _.each(obj, callback);
  }
};

module.exports = AV;
<|endoftext|>