<commit_before>(function () {
/**
 * Options:
 *
 * element - element housing visualization
 *
 */

var
  CN_FIRST  = 'humble-vis-first',
  CN_LAST   = 'humble-vis-last',

  T_VISUALIZATION   = '

';
  T_CHILD_CONTAINER = '

';

function Visualization (options) {
  this.options = options || {};
  this.children = [];
  this.node = null;
  this.rendered = false;
}

Visualization.prototype = {

  render : function (element) {

    var o = this.options;

    element = element || o.element;
    if (!element) throw 'No element to render within.';

    this.node = bonzo.create(T_VISUALIZATION)[0];
    this.container = element;
    bonzo(element).append(this.node);

    _.each(this.children, function (child) {
      this._renderChild(child);
    }, this);
    this._updateClasses();

    this.rendered = true;
  },

  add : function (child) {
    this.children.push(child);
    if (this.rendered) {
      this._renderChild(child);
      this._updateClasses();
    }
    return child;
  },

  remove : function (child) {
    var
      children  = this.children,
      index     = this.indexOf(child);
    if (index !== -1) {
      children.splice(index, 1);
      bonzo(child.element).remove();
      this._updateClasses();
      return true;
    }
  },

  setPosition : function (child, newIndex) {
    var
      children  = this.children;
    if (newIndex >= 0 && newIndex < children.length && this.remove(child)) {
      if (newIndex === children.length)
        bonzo(this.node).append(child.node);
      else
        this.node[0].insertBefore(child.node[0], children[newIndex].node[0]);
      children.splice(newIndex, 0, child);
      this._updateClasses();
      return true;
    }
  },

  indexOf : function (child) {
    return _.indexOf(this.children, child);
  },

  getChild : function (index) {
    var children = this.children;
    if (index < children.length) return children[index];
  },

  isFirst : function (child) {
    return (this.indexOf(child) === 0 ? true : false);
  },

  isLast : function (child) {
    return (this.indexOf(child) === this.children.length - 1 ? true : false);
  },

  _renderChild : function (child) {
    var
      childContainer = bonzo.create(T_CHILD_CONTAINER)[0];

    bonzo(this.node).append(childContainer);
    child.render(childContainer);
  },

  _updateClasses : function () {

    var
      children  = this.children,
      first     = 0,
      last      = children.length -1,
      node;

    _.each(children, function (child, index) {
      node = bonzo(child.container);

      if (index === first)
        node.addClass(CN_FIRST);
      else
        node.removeClass(CN_FIRST);

      if (index === last)
        node.addClass(CN_LAST);
      else
        node.removeClass(CN_LAST);
    });
  }
};

humblevis.Visualization = Visualization;

})();
<commit_msg>Fix elemnent of child removal.<commit_after>(function () {
/**
 * Options:
 *
 * element - element housing visualization
 *
 */

var
  CN_FIRST  = 'humble-vis-first',
  CN_LAST   = 'humble-vis-last',

  T_VISUALIZATION   = '

';
  T_CHILD_CONTAINER = '

';

function Visualization (options) {
  this.options = options || {};
  this.children = [];
  this.node = null;
  this.rendered = false;
}

Visualization.prototype = {

  render : function (element) {

    var o = this.options;

    element = element || o.element;
    if (!element) throw 'No element to render within.';

    this.node = bonzo.create(T_VISUALIZATION)[0];
    this.container = element;
    bonzo(element).append(this.node);

    _.each(this.children, function (child) {
      this._renderChild(child);
    }, this);
    this._updateClasses();

    this.rendered = true;
  },

  add : function (child) {
    this.children.push(child);
    if (this.rendered) {
      this._renderChild(child);
      this._updateClasses();
    }
    return child;
  },

  remove : function (child) {
    var
      children  = this.children,
      index     = this.indexOf(child);
    if (index !== -1) {
      children.splice(index, 1);
      bonzo(child.container).remove();
      this._updateClasses();
      return true;
    }
  },

  setPosition : function (child, newIndex) {
    var
      children  = this.children;
    if (newIndex >= 0 && newIndex < children.length && this.remove(child)) {
      if (newIndex === children.length)
        bonzo(this.node).append(child.node);
      else
        this.node[0].insertBefore(child.node[0], children[newIndex].node[0]);
      children.splice(newIndex, 0, child);
      this._updateClasses();
      return true;
    }
  },

  indexOf : function (child) {
    return _.indexOf(this.children, child);
  },

  getChild : function (index) {
    var children = this.children;
    if (index < children.length) return children[index];
  },

  isFirst : function (child) {
    return (this.indexOf(child) === 0 ? true : false);
  },

  isLast : function (child) {
    return (this.indexOf(child) === this.children.length - 1 ? true : false);
  },

  _renderChild : function (child) {
    var
      childContainer = bonzo.create(T_CHILD_CONTAINER)[0];

    bonzo(this.node).append(childContainer);
    child.render(childContainer);
  },

  _updateClasses : function () {

    var
      children  = this.children,
      first     = 0,
      last      = children.length -1,
      node;

    _.each(children, function (child, index) {
      node = bonzo(child.container);

      if (index === first)
        node.addClass(CN_FIRST);
      else
        node.removeClass(CN_FIRST);

      if (index === last)
        node.addClass(CN_LAST);
      else
        node.removeClass(CN_LAST);
    });
  }
};

humblevis.Visualization = Visualization;

})();
<|endoftext|>


<commit_before>var Cdefend = function()
{
    this.width = 140;
    this.height = 140;
}

Cdefend.prototype.setup = function()
{
    this.durationCounter = 0;
    this.duration = 5.35;
}

Cdefend.prototype.update = function(dt)
{
    this.durationCounter += dt;
    return this.durationCounter > this.duration;
}

Cdefend.prototype.draw = function(ctx)
{
    ctx.save();
    ctx.lineWidth = 3;
    ctx.fillStyle = "#FFF";
    ctx.strokeStyle = "#000";
    ctx.beginPath();
    ctx.rect(
        150 + 75 * this.durationCounter,
        265,
        40,
        40);
    ctx.rect(
        100 + 85 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        200 + 70 * this.durationCounter,
        345,
        40,
        40);
    ctx.rect(
        50 + 70 * this.durationCounter,
        345,
        40,
        40);
    ctx.rect(
        50 + 70 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        -36 + 70 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        -36 + 70 * this.durationCounter,
        265,
        40,
        40);
    ctx.fill();
    ctx.stroke();
    ctx.restore();
}<commit_msg>Minor comments for Cdefend class.<commit_after>//Cdefend constructor
var Cdefend = function()
{
    this.width = 140;
    this.height = 140;
}

//Setup
Cdefend.prototype.setup = function()
{
    this.durationCounter = 0;
    this.duration = 5.35;
}

//Update
Cdefend.prototype.update = function(dt)
{
    this.durationCounter += dt;
    return this.durationCounter > this.duration;
}

//Draw
Cdefend.prototype.draw = function(ctx)
{
    ctx.save();
    ctx.lineWidth = 3;
    ctx.fillStyle = "#FFF";
    ctx.strokeStyle = "#000";
    ctx.beginPath();
    ctx.rect(
        150 + 75 * this.durationCounter,
        265,
        40,
        40);
    ctx.rect(
        100 + 85 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        200 + 70 * this.durationCounter,
        345,
        40,
        40);
    ctx.rect(
        50 + 70 * this.durationCounter,
        345,
        40,
        40);
    ctx.rect(
        50 + 70 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        -36 + 70 * this.durationCounter,
        305,
        40,
        40);
    ctx.rect(
        -36 + 70 * this.durationCounter,
        265,
        40,
        40);
    ctx.fill();
    ctx.stroke();
    ctx.restore();
}<|endoftext|>


<commit_before>"use strict";

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange')
const { ExchangeError } = require ('./base/errors')

//  ---------------------------------------------------------------------------

module.exports = class coinmarketcap extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinmarketcap',
            'name': 'CoinMarketCap',
            'rateLimit': 10000,
            'version': 'v1',
            'countries': 'US',
            'hasCORS': true,
            'hasPrivateAPI': false,
            'hasCreateOrder': false,
            'hasCancelOrder': false,
            'hasFetchBalance': false,
            'hasFetchOrderBook': false,
            'hasFetchTrades': false,
            'hasFetchTickers': true,
            'hasFetchCurrencies': true,
            'has': {
                'fetchCurrencies': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/28244244-9be6312a-69ed-11e7-99c1-7c1797275265.jpg',
                'api': {
                    'public': 'https://api.coinmarketcap.com',
                    'files': 'https://files.coinmarketcap.com',
                    'charts': 'https://graph.coinmarketcap.com',
                },
                'www': 'https://coinmarketcap.com',
                'doc': 'https://coinmarketcap.com/api',
            },
            'requiredCredentials': {
                'apiKey': false,
                'secret': false,
            },
            'api': {
                'files': {
                    'get': [
                        'generated/stats/global.json',
                    ],
                },
                'graphs': {
                    'get': [
                        'currencies/{name}/',
                    ],
                },
                'public': {
                    'get': [
                        'ticker/',
                        'ticker/{id}/',
                        'global/',
                    ],
                },
            },
            'currencyCodes': [
                'AUD',
                'BRL',
                'CAD',
                'CHF',
                'CNY',
                'EUR',
                'GBP',
                'HKD',
                'IDR',
                'INR',
                'JPY',
                'KRW',
                'MXN',
                'RUB',
                'USD',
            ],
        });
    }

    async fetchOrderBook (symbol, params = {}) {
        throw new ExchangeError ('Fetching order books is not supported by the API of ' + this.id);
    }

    currencyCode (base, name) {
        const currencies = {
            'Bitgem': 'Bitgem',
            'NetCoin': 'NetCoin',
        };
        if (name in currencies)
            return currencies[name];
        return base;
    }

    async fetchMarkets () {
        let markets = await this.publicGetTicker ({
            'limit': 0,
        });
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let currencies = this.currencyCodes;
            for (let i = 0; i < currencies.length; i++) {
                let quote = currencies[i];
                let quoteId = quote.toLowerCase ();
                let baseId = market['id'];
                let base = this.currencyCode (market['symbol'], market['name']);
                let symbol = base + '/' + quote;
                let id = baseId + '/' + quote;
                result.push ({
                    'id': id,
                    'symbol': symbol,
                    'base': base,
                    'quote': quote,
                    'baseId': baseId,
                    'quoteId': quoteId,
                    'info': market,
                });
            }
        }
        return result;
    }

    async fetchGlobal (currency = 'USD') {
        await this.loadMarkets ();
        let request = {};
        if (currency)
            request['convert'] = currency;
        return await this.publicGetGlobal (request);
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        if ('last_updated' in ticker)
            if (ticker['last_updated'])
                timestamp = parseInt (ticker['last_updated']) * 1000;
        let change = undefined;
        if ('percent_change_24h' in ticker)
            if (ticker['percent_change_24h'])
                change = this.safeFloat (ticker, 'percent_change_24h');
        let last = undefined;
        let symbol = undefined;
        let volume = undefined;
        if (market) {
            let priceKey = 'price_' + market['quoteId'];
            if (priceKey in ticker)
                if (ticker[priceKey])
                    last = this.safeFloat (ticker, priceKey);
            symbol = market['symbol'];
            let volumeKey = '24h_volume_' + market['quoteId'];
            if (volumeKey in ticker)
                if (ticker[volumeKey])
                    volume = this.safeFloat (ticker, volumeKey);
        }
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': undefined,
            'ask': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': last,
            'change': change,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': volume,
            'info': ticker,
        };
    }

    async fetchTickers (currency = 'USD', params = {}) {
        await this.loadMarkets ();
        let request = {
            'limit': 10000,
        };
        if (currency)
            request['convert'] = currency;
        let response = await this.publicGetTicker (this.extend (request, params));
        let tickers = {};
        for (let t = 0; t < response.length; t++) {
            let ticker = response[t];
            let id = ticker['id'] + '/' + currency;
            let symbol = id;
            let market = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            }
            tickers[symbol] = this.parseTicker (ticker, market);
        }
        return tickers;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = this.extend ({
            'convert': market['quote'],
            'id': market['baseId'],
        }, params);
        let response = await this.publicGetTickerId (request);
        let ticker = response[0];
        return this.parseTicker (ticker, market);
    }

    async fetchCurrencies (params = {}) {
        let currencies = await this.publicGetTicker (this.extend ({
            'limit': 0
        }, params));
        let result = {};
        for (let i = 0; i < currencies.length; i++) {
            let currency = currencies[i];
            let id = currency['symbol'];
            let name = currency['name'];
            // todo: will need to rethink the fees
            // to add support for multiple withdrawal/deposit methods and
            // differentiated fees for each particular method
            let precision = 8; // default precision, todo: fix "magic constants"
            let code = this.currencyCode (id, name);
            result[code] = {
                'id': id,
                'code': code,
                'info': currency,
                'name': name,
                'active': true,
                'status': 'ok',
                'fee': undefined, // todo: redesign
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': Math.pow (10, -precision),
                        'max': Math.pow (10, precision),
                    },
                    'price': {
                        'min': Math.pow (10, -precision),
                        'max': Math.pow (10, precision),
                    },
                    'cost': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'withdraw': {
                        'min': undefined,
                        'max': undefined,
                    },
                },
            };
        }
        return result;
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api] + '/' + this.version + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (Object.keys (query).length)
            url += '?' + this.urlencode (query);
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('error' in response) {
            if (response['error']) {
                throw new ExchangeError (this.id + ' ' + this.json (response));
            }
        }
        return response;
    }
}
<commit_msg>BatCoin (BAT) coinmarketcap fix #1171<commit_after>"use strict";

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange')
const { ExchangeError } = require ('./base/errors')

//  ---------------------------------------------------------------------------

module.exports = class coinmarketcap extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinmarketcap',
            'name': 'CoinMarketCap',
            'rateLimit': 10000,
            'version': 'v1',
            'countries': 'US',
            'hasCORS': true,
            'hasPrivateAPI': false,
            'hasCreateOrder': false,
            'hasCancelOrder': false,
            'hasFetchBalance': false,
            'hasFetchOrderBook': false,
            'hasFetchTrades': false,
            'hasFetchTickers': true,
            'hasFetchCurrencies': true,
            'has': {
                'fetchCurrencies': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/28244244-9be6312a-69ed-11e7-99c1-7c1797275265.jpg',
                'api': {
                    'public': 'https://api.coinmarketcap.com',
                    'files': 'https://files.coinmarketcap.com',
                    'charts': 'https://graph.coinmarketcap.com',
                },
                'www': 'https://coinmarketcap.com',
                'doc': 'https://coinmarketcap.com/api',
            },
            'requiredCredentials': {
                'apiKey': false,
                'secret': false,
            },
            'api': {
                'files': {
                    'get': [
                        'generated/stats/global.json',
                    ],
                },
                'graphs': {
                    'get': [
                        'currencies/{name}/',
                    ],
                },
                'public': {
                    'get': [
                        'ticker/',
                        'ticker/{id}/',
                        'global/',
                    ],
                },
            },
            'currencyCodes': [
                'AUD',
                'BRL',
                'CAD',
                'CHF',
                'CNY',
                'EUR',
                'GBP',
                'HKD',
                'IDR',
                'INR',
                'JPY',
                'KRW',
                'MXN',
                'RUB',
                'USD',
            ],
        });
    }

    async fetchOrderBook (symbol, params = {}) {
        throw new ExchangeError ('Fetching order books is not supported by the API of ' + this.id);
    }

    currencyCode (base, name) {
        const currencies = {
            'Bitgem': 'Bitgem',
            'NetCoin': 'NetCoin',
            'BatCoin': 'BatCoin',
        };
        if (name in currencies)
            return currencies[name];
        return base;
    }

    async fetchMarkets () {
        let markets = await this.publicGetTicker ({
            'limit': 0,
        });
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let currencies = this.currencyCodes;
            for (let i = 0; i < currencies.length; i++) {
                let quote = currencies[i];
                let quoteId = quote.toLowerCase ();
                let baseId = market['id'];
                let base = this.currencyCode (market['symbol'], market['name']);
                let symbol = base + '/' + quote;
                let id = baseId + '/' + quote;
                result.push ({
                    'id': id,
                    'symbol': symbol,
                    'base': base,
                    'quote': quote,
                    'baseId': baseId,
                    'quoteId': quoteId,
                    'info': market,
                });
            }
        }
        return result;
    }

    async fetchGlobal (currency = 'USD') {
        await this.loadMarkets ();
        let request = {};
        if (currency)
            request['convert'] = currency;
        return await this.publicGetGlobal (request);
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        if ('last_updated' in ticker)
            if (ticker['last_updated'])
                timestamp = parseInt (ticker['last_updated']) * 1000;
        let change = undefined;
        if ('percent_change_24h' in ticker)
            if (ticker['percent_change_24h'])
                change = this.safeFloat (ticker, 'percent_change_24h');
        let last = undefined;
        let symbol = undefined;
        let volume = undefined;
        if (market) {
            let priceKey = 'price_' + market['quoteId'];
            if (priceKey in ticker)
                if (ticker[priceKey])
                    last = this.safeFloat (ticker, priceKey);
            symbol = market['symbol'];
            let volumeKey = '24h_volume_' + market['quoteId'];
            if (volumeKey in ticker)
                if (ticker[volumeKey])
                    volume = this.safeFloat (ticker, volumeKey);
        }
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': undefined,
            'ask': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': last,
            'change': change,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': volume,
            'info': ticker,
        };
    }

    async fetchTickers (currency = 'USD', params = {}) {
        await this.loadMarkets ();
        let request = {
            'limit': 10000,
        };
        if (currency)
            request['convert'] = currency;
        let response = await this.publicGetTicker (this.extend (request, params));
        let tickers = {};
        for (let t = 0; t < response.length; t++) {
            let ticker = response[t];
            let id = ticker['id'] + '/' + currency;
            let symbol = id;
            let market = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            }
            tickers[symbol] = this.parseTicker (ticker, market);
        }
        return tickers;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = this.extend ({
            'convert': market['quote'],
            'id': market['baseId'],
        }, params);
        let response = await this.publicGetTickerId (request);
        let ticker = response[0];
        return this.parseTicker (ticker, market);
    }

    async fetchCurrencies (params = {}) {
        let currencies = await this.publicGetTicker (this.extend ({
            'limit': 0
        }, params));
        let result = {};
        for (let i = 0; i < currencies.length; i++) {
            let currency = currencies[i];
            let id = currency['symbol'];
            let name = currency['name'];
            // todo: will need to rethink the fees
            // to add support for multiple withdrawal/deposit methods and
            // differentiated fees for each particular method
            let precision = 8; // default precision, todo: fix "magic constants"
            let code = this.currencyCode (id, name);
            result[code] = {
                'id': id,
                'code': code,
                'info': currency,
                'name': name,
                'active': true,
                'status': 'ok',
                'fee': undefined, // todo: redesign
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': Math.pow (10, -precision),
                        'max': Math.pow (10, precision),
                    },
                    'price': {
                        'min': Math.pow (10, -precision),
                        'max': Math.pow (10, precision),
                    },
                    'cost': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'withdraw': {
                        'min': undefined,
                        'max': undefined,
                    },
                },
            };
        }
        return result;
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api] + '/' + this.version + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (Object.keys (query).length)
            url += '?' + this.urlencode (query);
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('error' in response) {
            if (response['error']) {
                throw new ExchangeError (this.id + ' ' + this.json (response));
            }
        }
        return response;
    }
}
<|endoftext|>


<commit_before>var queryString = {};
var workspaceModel;

var Platform=function()
{
	this.name=ko.observable("");
	this.url=ko.observable("");
	this.id =ko.observable(-1);
	this.init=function(data)
	{
		this.name(data.name);
		this.url(data.url);
		this.id(data.id)
		return this;
	}
}

var Catalogue=function()
{
	this.name=ko.observable("");
	this.url=ko.observable("");
	this.id =ko.observable(-1);
	this.init=function(data)
	{
		this.name(data.name);
		this.url(data.url);
		this.id(data.id)
		return this;
	}
}
var WorkspaceModel=function()
{
	this.name=ko.observable(queryString["wsName"]);
	this.platforms=ko.observableArray();
	this.catalogues=ko.observableArray();
	this.addPlatform=function()
	{
		this.platforms.push(new Platform());
		$( "[title]" ).tooltip();

	};
	this.deletePlatform=function(platform)
	{
		this.platforms.remove(platform);
	}.bind(this);
	this.addCatalogue=function()
	{
		this.catalogues.push(new Catalogue());
		$( "[title]" ).tooltip();
	};
	this.deleteCatalogue=function(catalogue)
	{
		this.catalogues.remove(catalogue);
	}.bind(this);
	this.init=function(data)
	{
		this.name(data.name);
		if(data.platforms.length!=0)
			this.platforms($.map(data.platforms, function(item){return new Platform().init(item)}));
		if(data.catalogues.length!=0)
			this.catalogues($.map(data.catalogues, function(item){return new Catalogue().init(item)}));
		return this;
	}
}

function saveConfiguration() {
	if($('form').parsley().isValid())
	{
		var configurationJson=ko.toJSON(workspaceModel);
		console.log("New configuration:");
		console.log(configurationJson);
		$.ajax({
			url : serverURL + "workspaces/" + queryString["wsId"] ,
			method : 'PUT',
			contentType : "application/json; charset=utf-8",
			dataType : 'json',
			xhrFields : {
				withCredentials : true
			},
			data : configurationJson,
			success : function (data) {
				$("#successSaveConfiDialog").dialog({
					modal : true,
					draggable : false,
					buttons : {
						ok : function () {
							$(this).dialog("close");
							window.location.reload();
						}
					}
				});
			},
			error : function (err) {
				$('#errorDialog').text(err.responseText);
				$('#errorDialog').dialog({
					modal : true,
					buttons : {
						Ok : function () {
							$(this).dialog("close");
						}
					}
				});
			}
		});
	}
}

$(document).ready(function () {
	$( "[title]" ).tooltip();
	queryString = getQueryString();
	wsId=queryString["wsId"];
	$.ajax({
		url : serverURL + "workspaces/" + wsId,
		dataType : "json",
		xhrFields : {
			withCredentials : true
		},
		success : function (data) {
			document.getElementById("nav_workspace").text = "Workspace: " +data.name;
		}
	});
	workspaceModel=new WorkspaceModel();
	loadConfiguration(wsId);
	ko.applyBindings(workspaceModel);

	$("#accordion").accordion({
		active : false,
		collapsible : false,
		heightStyle : "content"
	});
});

function loadConfiguration(wsId)
{	$.ajax({
		url : serverURL + "workspaces/" + wsId,
		dataType : "json",
		xhrFields : {
			withCredentials : true
		},
		success : function (data) {
			workspaceModel.init(data);
		}
	});
}
<commit_msg>no message<commit_after>var queryString = {};
var workspaceModel;

var Platform=function()
{
	this.name=ko.observable("");
	this.url=ko.observable("");
	this.id =ko.observable(-1);
	this.init=function(data)
	{
		this.name(data.name);
		this.url(data.url);
		this.id(data.id);
		return this;
	}
}

var Catalogue=function()
{
	this.name=ko.observable("");
	this.url=ko.observable("");
	this.id =ko.observable(-1);
	this.init=function(data)
	{
		this.name(data.name);
		this.url(data.url);
		this.id(data.id);
		return this;
	}
}
var WorkspaceModel=function()
{
	this.name=ko.observable(queryString["wsName"]);
	this.platforms=ko.observableArray();
	this.catalogues=ko.observableArray();
	this.addPlatform=function()
	{
		this.platforms.push(new Platform());
		$( "[title]" ).tooltip();

	};
	this.deletePlatform=function(platform)
	{
		this.platforms.remove(platform);
	}.bind(this);
	this.addCatalogue=function()
	{
		this.catalogues.push(new Catalogue());
		$( "[title]" ).tooltip();
	};
	this.deleteCatalogue=function(catalogue)
	{
		this.catalogues.remove(catalogue);
	}.bind(this);
	this.init=function(data)
	{
		this.name(data.name);
		if(data.platforms.length!=0)
			this.platforms($.map(data.platforms, function(item){return new Platform().init(item)}));
		if(data.catalogues.length!=0)
			this.catalogues($.map(data.catalogues, function(item){return new Catalogue().init(item)}));
		return this;
	}
}

function saveConfiguration() {
	if($('form').parsley().isValid())
	{
		var configurationJson=ko.toJSON(workspaceModel);
		console.log("New configuration:");
		console.log(configurationJson);
		$.ajax({
			url : serverURL + "workspaces/" + queryString["wsId"] ,
			method : 'PUT',
			contentType : "application/json; charset=utf-8",
			dataType : 'json',
			xhrFields : {
				withCredentials : true
			},
			data : configurationJson,
			success : function (data) {
				$("#successSaveConfiDialog").dialog({
					modal : true,
					draggable : false,
					buttons : {
						ok : function () {
							$(this).dialog("close");
							window.location.reload();
						}
					}
				});
			},
			error : function (err) {
				$('#errorDialog').text(err.responseText);
				$('#errorDialog').dialog({
					modal : true,
					buttons : {
						Ok : function () {
							$(this).dialog("close");
						}
					}
				});
			}
		});
	}
}

$(document).ready(function () {
	$( "[title]" ).tooltip();
	queryString = getQueryString();
	wsId=queryString["wsId"];
	$.ajax({
		url : serverURL + "workspaces/" + wsId,
		dataType : "json",
		xhrFields : {
			withCredentials : true
		},
		success : function (data) {
			document.getElementById("nav_workspace").text = "Workspace: " +data.name;
		}
	});
	workspaceModel=new WorkspaceModel();
	loadConfiguration(wsId);
	ko.applyBindings(workspaceModel);

	$("#accordion").accordion({
		active : false,
		collapsible : false,
		heightStyle : "content"
	});
});

function loadConfiguration(wsId)
{	$.ajax({
		url : serverURL + "workspaces/" + wsId,
		dataType : "json",
		xhrFields : {
			withCredentials : true
		},
		success : function (data) {
			workspaceModel.init(data);
		}
	});
}
<|endoftext|>


<commit_before>/* global App */

/**
 * Features module
 *
 * HTML5 feature detection based on the concepts and ideas by Modernizr
 * @link http://html5please.com/
 * @link http://caniuse.com/
 * @link https://github.com/NielsLeenheer/html5test/
 *
 * Modified: 2015/12/06
 * @author softwarespot
 */
App.namespace('core').features = (function featuresModule(window, document, $, core, undefined) {
    // Constants

    // SemVer version number of the module
    var VERSION = '1.0.0';

    // Unique global identifier. Internal usage only
    // var GUID = '3B8C44B7-6A3B-4F84-A031-2D7B5D4ED211';

    // Fields

    // Store if the module has been initialised
    var _isInitialised = false;

    // Native functions
    var _nativeCSS = window.CSS;
    var _nativeHistory = window.history;
    var _nativeLocalStorage = window.localStorage;
    var _nativeNavigator = window.navigator;
    var _nativePromise = window.Promise;
    var _nativeSessionStorage = window.sessionStorage;

    // Store has* results
    // Note: Opera 12 supports window.supportsCSS according to caniuse.com
    var _hasCSSSupports = (core.isFunction(_nativeCSS) && core.isFunction(_nativeCSS.supports)) || window.supportsCSS;
    var _hasGeoLocation = core.isObject(_nativeNavigator) &&
        'geolocation' in _nativeNavigator;

    var _hasHistory = core.isObject(_nativeHistory) &&
        'pushState' in _nativeHistory;

    var _hasLocalStorage = _isStorage(_nativeLocalStorage);
    var _hasSessionStorage = _isStorage(_nativeSessionStorage);
    var _hasWebStorage = _hasLocalStorage && _hasSessionStorage;

    var _hasPromise = core.isFunction(_nativePromise) &&
        'all' in _nativePromise &&
        'race' in _nativePromise &&
        'reject' in _nativePromise &&
        'resolve' in _nativePromise;

    // Hold the input data, with the key being the input type and the value of either true or false as
    // whether or not it's supported by the following browser
    var _inputs = null;

    // Methods

    /**
     * Initialise the module
     *
     * @return {undefined}
     */
    function init() {
        if (_isInitialised) {
            return;
        }

        // Initialise the input object literal
        _getInputs();

        _isInitialised = true;
    }

    /**
     * Destroy the module
     *
     * @return {undefined}
     */
    function destroy() {
        _isInitialised = false;
    }

    /**
     * Get the version number of the module
     *
     * @returns {number} Version number
     */
    function getVersion() {
        return VERSION;
    }

    // CSS

    /**
     * Checl if CSSSupports exists
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasCSSSupports() {
        return _hasCSSSupports;
    }

    // EVENTS
    // https://github.com/Modernizr/Modernizr/blob/master/src/hasEvent.js
    // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/hashchange.js

    // HISTORY

    /**
     * Check if the History API exists
     *
     * Based on the concept by Modernizr URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasHistory() {
        return _hasHistory;
    }

    // GEOLOCATION

    /**
     * Check if the geolocation API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/geolocation.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasGeoLocation() {
        return _hasGeoLocation;
    }

    // INPUTS

    /**
     * Check if an input type is supported
     *
     * @param {string} inputType Input type
     * @return {boolean} True the type is supported; otherwise, false
     */
    function hasInput(inputType) {
        // Coerce as a string
        var hasInputResult = _inputs[core.toString(inputType)];
        return core.isUndefined(hasInputResult) ? false : hasInputResult;
    }

    /**
     * Initialise the input object literal
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/commits/master/feature-detects/inputtypes.js
     *
     * @return {undefined}
     */
    function _getInputs() {
        if (!core.isNull(_inputs)) {
            return;
        }

        // Regular expressions
        var reEmailNumberUrl = /^(?:email|number|url)$/;
        var reRange = /(?:^range$)/;
        var reSearchTel = /^(?:search|tel)$/;

        // Create an empty object literal
        _inputs = {};

        // Input types that will are split as an array
        var inputTypes = 'color date datetime datetime-local email month number range search tel time url week'.split(' ');

        // Create a temporary input element
        var input = document.createElement('input');

        // Document element to bind the input element to
        var documentElem = document.documentElement;

        // Inline stylesheet
        var cssStyles = 'position:absolute;visibility:hidden;';

        // Data to test with
        var testData = '=)';

        // Iterate through the array. A polyfill is available at
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill
        inputTypes.forEach(function forEachInputType(inputType) {

            // Set the attribute type of the input element
            input.setAttribute('type', inputType);

            // Check the type is not text and that it contains a 'style' property
            var isValid = input.type !== 'text' && 'style' in input;

            // If invalid then simply return and don't continue
            if (!isValid) {
                return;
            }

            // First check to see if the type we give it sticks
            // If the type does, we feed it a textual value, which shouldn't be valid
            // If the value doesn't stick, we know there's input sanitization which infers a custom UI
            input.value = testData;

            // Set the style of the input element
            input.style.cssText = cssStyles;

            // If a range type
            if (reRange.test(inputType) && core.isDefined(input.style.WebkitAppearance)) {

                // Append the input element to the current document
                documentElem.appendChild(input);

                // Cache the defaultView
                var defaultView = document.defaultView;

                // Safari 2-4 allows the smiley as a value, despite making a slider
                isValid = defaultView.getComputedStyle &&

                    defaultView.getComputedStyle(input, null)
                    .WebkitAppearance !== 'textfield' &&

                    // The mobile Android web browser has a false positive, so
                    // check the height to see if the widget is actually there
                    (input.offsetHeight !== 0);

                documentElem.removeChild(input);

                // If a search or tel type
            } else if (reSearchTel.test(inputType)) {
                // Specification doesn't define any special parsing or detectable UI
                // behaviours so we pass these through as true

                // Interestingly, Opera fails the earlier test, so it doesn't
                // even make it here (I doubt anymore!)

                // If a email, number or url type
            } else if (reEmailNumberUrl.test(inputType)) {

                // The following types come with pre-backed validation
                isValid = input.checkValidity && input.checkValidity() === false;

                // For all other types check if the value has been sanitised
            } else {

                // If the upgraded input component rejects the :) text, we've got a winner
                isValid = input.value !== testData;

            }

            // Add to the internal object literal
            _inputs[inputType] = !!isValid;

        });
    }

    // PROMISE

    /**
     * Check if the Promise API exists
     *
     * Based on the concept by Modernizr URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es6/promises.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasPromise() {
        return _hasPromise;
    }

    // STORAGE

    /**
     * Check if the localStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasLocalStorage() {
        return _hasLocalStorage;
    }

    /**
     * Check if the sessionStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/sessionstorage.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasSessionStorage() {
        return _hasSessionStorage;
    }

    /**
     * Check if a valid storage object
     *
     * @param {type} storage Storage object
     * @return {boolean} storage True, is valid storage object; otherwise, false
     */
    function _isStorage(storage) {
        return core.isObject(storage) &&
            'key' in storage &&
            'getItem' in storage &&
            'setItem' in storage &&
            'removeItem' in storage &&
            'clear' in storage;
    }

    /**
     * Check if the webStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasWebStorage() {
        return _hasWebStorage;
    }

    // Public API
    return {
        init: init,
        destroy: destroy,
        getVersion: getVersion,
        hasCSSSupports: hasCSSSupports,
        hasHistory: hasHistory,
        hasPromise: hasPromise,
        hasInput: hasInput,
        hasLocalStorage: hasLocalStorage,
        hasSessionStorage: hasSessionStorage,
        hasWebStorage: hasWebStorage,
        hasGeoLocation: hasGeoLocation,
    };
})(window, window.document, window.jQuery, window.App.core);
<commit_msg>Added isStyleSupported<commit_after>/* global App */

/**
 * Features module
 *
 * HTML5 feature detection based on the concepts and ideas by Modernizr
 * @link http://html5please.com/
 * @link http://caniuse.com/
 * @link https://github.com/NielsLeenheer/html5test/
 *
 * Modified: 2015/12/06
 * @author softwarespot
 */
App.namespace('core').features = (function featuresModule(window, document, $, core, undefined) {
    // Constants

    // SemVer version number of the module
    var VERSION = '1.0.0';

    // Unique global identifier. Internal usage only
    // var GUID = '3B8C44B7-6A3B-4F84-A031-2D7B5D4ED211';

    // Fields

    // Store if the module has been initialised
    var _isInitialised = false;

    // Native functions
    var _nativeCSS = window.CSS;
    var _nativeHistory = window.history;
    var _nativeLocalStorage = window.localStorage;
    var _nativeNavigator = window.navigator;
    var _nativePromise = window.Promise;
    var _nativeSessionStorage = window.sessionStorage;

    // Store has* results
    // Note: Opera 12 supports window.supportsCSS according to caniuse.com
    var _hasCSSSupports = (core.isFunction(_nativeCSS) && core.isFunction(_nativeCSS.supports)) || window.supportsCSS;
    var _hasGeoLocation = core.isObject(_nativeNavigator) &&
        'geolocation' in _nativeNavigator;

    var _hasHistory = core.isObject(_nativeHistory) &&
        'pushState' in _nativeHistory;

    var _hasLocalStorage = _isStorage(_nativeLocalStorage);
    var _hasSessionStorage = _isStorage(_nativeSessionStorage);
    var _hasWebStorage = _hasLocalStorage && _hasSessionStorage;

    var _hasPromise = core.isFunction(_nativePromise) &&
        'all' in _nativePromise &&
        'race' in _nativePromise &&
        'reject' in _nativePromise &&
        'resolve' in _nativePromise;

    // Hold the input data, with the key being the input type and the value of either true or false as
    // whether or not it's supported by the following browser
    var _inputs = null;

    // Cache the HTML node
    var _html = document.documentElement;
    var _prefixes = ['Khtml', 'Moz', 'Ms', 'O', 'Webkit'];

    // Methods

    /**
     * Initialise the module
     *
     * @return {undefined}
     */
    function init() {
        if (_isInitialised) {
            return;
        }

        // Initialise the input object literal
        _getInputs();

        _isInitialised = true;
    }

    /**
     * Destroy the module
     *
     * @return {undefined}
     */
    function destroy() {
        _isInitialised = false;
    }

    /**
     * Get the version number of the module
     *
     * @returns {number} Version number
     */
    function getVersion() {
        return VERSION;
    }

    // CSS

    /**
     * Checl if CSSSupports exists
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasCSSSupports() {
        return _hasCSSSupports;
    }

    // EVENTS
    // https://github.com/Modernizr/Modernizr/blob/master/src/hasEvent.js
    // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/hashchange.js

    // HISTORY

    /**
     * Check if the History API exists
     *
     * Based on the concept by Modernizr URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasHistory() {
        return _hasHistory;
    }

    // GEOLOCATION

    /**
     * Check if the geolocation API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/geolocation.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasGeoLocation() {
        return _hasGeoLocation;
    }

    // INPUTS

    /**
     * Check if an input type is supported
     *
     * @param {string} inputType Input type
     * @return {boolean} True the type is supported; otherwise, false
     */
    function hasInput(inputType) {
        // Coerce as a string
        var hasInputResult = _inputs[core.toString(inputType)];
        return core.isUndefined(hasInputResult) ? false : hasInputResult;
    }

    /**
     * Initialise the input object literal
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/commits/master/feature-detects/inputtypes.js
     *
     * @return {undefined}
     */
    function _getInputs() {
        if (!core.isNull(_inputs)) {
            return;
        }

        // Regular expressions
        var reEmailNumberUrl = /^(?:email|number|url)$/;
        var reRange = /(?:^range$)/;
        var reSearchTel = /^(?:search|tel)$/;

        // Create an empty object literal
        _inputs = {};

        // Input types that will are split as an array
        var inputTypes = 'color date datetime datetime-local email month number range search tel time url week'.split(' ');

        // Create a temporary input element
        var input = document.createElement('input');

        // Document element to bind the input element to
        var documentElem = document.documentElement;

        // Inline stylesheet
        var cssStyles = 'position:absolute;visibility:hidden;';

        // Data to test with
        var testData = '=)';

        // Iterate through the array. A polyfill is available at
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill
        inputTypes.forEach(function forEachInputType(inputType) {

            // Set the attribute type of the input element
            input.setAttribute('type', inputType);

            // Check the type is not text and that it contains a 'style' property
            var isValid = input.type !== 'text' && 'style' in input;

            // If invalid then simply return and don't continue
            if (!isValid) {
                return;
            }

            // First check to see if the type we give it sticks
            // If the type does, we feed it a textual value, which shouldn't be valid
            // If the value doesn't stick, we know there's input sanitization which infers a custom UI
            input.value = testData;

            // Set the style of the input element
            input.style.cssText = cssStyles;

            // If a range type
            if (reRange.test(inputType) && core.isDefined(input.style.WebkitAppearance)) {

                // Append the input element to the current document
                documentElem.appendChild(input);

                // Cache the defaultView
                var defaultView = document.defaultView;

                // Safari 2-4 allows the smiley as a value, despite making a slider
                isValid = defaultView.getComputedStyle &&

                    defaultView.getComputedStyle(input, null)
                    .WebkitAppearance !== 'textfield' &&

                    // The mobile Android web browser has a false positive, so
                    // check the height to see if the widget is actually there
                    (input.offsetHeight !== 0);

                documentElem.removeChild(input);

                // If a search or tel type
            } else if (reSearchTel.test(inputType)) {
                // Specification doesn't define any special parsing or detectable UI
                // behaviours so we pass these through as true

                // Interestingly, Opera fails the earlier test, so it doesn't
                // even make it here (I doubt anymore!)

                // If a email, number or url type
            } else if (reEmailNumberUrl.test(inputType)) {

                // The following types come with pre-backed validation
                isValid = input.checkValidity && input.checkValidity() === false;

                // For all other types check if the value has been sanitised
            } else {

                // If the upgraded input component rejects the :) text, we've got a winner
                isValid = input.value !== testData;

            }

            // Add to the internal object literal
            _inputs[inputType] = !!isValid;

        });
    }

    // PROMISE

    /**
     * Check if the Promise API exists
     *
     * Based on the concept by Modernizr URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es6/promises.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasPromise() {
        return _hasPromise;
    }

    // STORAGE

    /**
     * Check if the localStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasLocalStorage() {
        return _hasLocalStorage;
    }

    /**
     * Check if the sessionStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/sessionstorage.js
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasSessionStorage() {
        return _hasSessionStorage;
    }

    /**
     * Check if the webStorage API exists
     *
     * Based on the concept by Modernizr, URL: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/
     *
     * @return {boolean} True, the feature exists; otherwise, false
     */
    function hasWebStorage() {
        return _hasWebStorage;
    }

    /**
     * Check if a CSS style is supported. Automatically checks for common vendor prefixes
     *
     * @param {string} property CSS property to check (without the vendor prefix)
     * @return {boolean} True, the style is supported; otherwise, false
     */
    function isStyleSupported(property) {
        if (!core.isString(property) || property.length === 0) {
            return false;
        }

        // Appears the style is supported
        if (!core.isUndefined(_html.style[property])) {
            return true;
        }

        // Check common vendor prefixes
        property = core.stringLCFirst(property);

        var length = _prefixes.length;
        while (length-- > 0) {
            if (!core.isUndefined(_html.style[_prefixes[length] + property])) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if a valid storage object
     *
     * @param {type} storage Storage object
     * @return {boolean} storage True, is valid storage object; otherwise, false
     */
    function _isStorage(storage) {
        return core.isObject(storage) &&
            'key' in storage &&
            'getItem' in storage &&
            'setItem' in storage &&
            'removeItem' in storage &&
            'clear' in storage;
    }

    // Public API
    return {
        init: init,
        destroy: destroy,
        getVersion: getVersion,
        hasCSSSupports: hasCSSSupports,
        hasGeoLocation: hasGeoLocation,
        hasHistory: hasHistory,
        hasInput: hasInput,
        hasLocalStorage: hasLocalStorage,
        hasPromise: hasPromise,
        hasSessionStorage: hasSessionStorage,
        hasWebStorage: hasWebStorage,
        isStyleSupported: isStyleSupported,
    };
})(window, window.document, window.jQuery, window.App.core);
<|endoftext|>


<commit_before>/* global Gallery */
(function ($, Gallery) {
	"use strict";
	/**
	 * Stores the gallery configuration
	 *
	 * @param {{features: *}} config
	 * @constructor
	 */
	var Config = function (config) {
		this.galleryFeatures = this.setGalleryFeatures(config.features);
		this.mediaTypes = config.mediatypes;
	};

	Config.prototype = {
		galleryFeatures: [],
		mediaTypes: {},
		cachedMediaTypesString: '',
		albumPermissions: null,
		albumInfo: null,
		albumSorting: null,
		albumError: false,
		infoLoaded: false,

		/**
		 * Saves the list of features which have been enabled in the app
		 *
		 * @param configFeatures
		 *
		 * @returns {Array}
		 */
		setGalleryFeatures: function (configFeatures) {
			var features = [];
			if (!$.isEmptyObject(configFeatures)) {
				for (var i = 0, keys = Object.keys(configFeatures); i < keys.length; i++) {
					if (configFeatures[keys[i]] === 'yes') {
						features.push(keys[i]);
					}
				}
			}

			return features;
		},

		/**
		 * Returns the list of supported media types in a string
		 *
		 * @returns {string}
		 */
		getMediaTypes: function () {
			if (this.cachedMediaTypesString === '') {
				var types = '';
				for (var i = 0, keys = Object.keys(this.mediaTypes); i < keys.length; i++) {
					types += keys[i] + ';';
				}

				this.cachedMediaTypesString = types.slice(0, -1);
			}

			return this.cachedMediaTypesString;
		},

		/**
		 * Stores the configuration about the current album
		 *
		 * @param albumConfig
		 */
		setAlbumConfig: function (albumConfig) {
			this.albumPermissions = this.setAlbumPermissions(albumConfig);
			this.albumInfo = this.setAlbumInfo(albumConfig);
			this.albumSorting = this.setAlbumSorting(albumConfig);
			this.albumError = albumConfig.error;
		},

		/**
		 * Saves the permissions for the current album
		 *
		 * @param albumConfig
		 *
		 * @returns {{fileid: *, permissions: *}}
		 */
		setAlbumPermissions: function (albumConfig) {
			return {
				fileid: albumConfig.fileid,
				permissions: albumConfig.permissions
			};
		},

		/**
		 * Saves the description and copyright information for the current album
		 *
		 * @param {{path, information, description_link, copyright_link}} albumConfig
		 *
		 * @returns {{}}
		 */
		setAlbumInfo: function (albumConfig) {
			var albumPath = albumConfig.path;
			var albumInfo = albumConfig.information;
			var params = {};
			if (!$.isEmptyObject(albumInfo)) {
				var docPath = albumPath;
				var level = albumInfo.level;
				if (level > 0) {
					if (docPath.indexOf('/') !== -1) {
						var folders = docPath.split('/');
						folders = folders.slice(-0, -level);
						docPath = folders.join('/') + '/';
					} else {
						docPath = '';
					}
				}

				/* jshint camelcase: false */
				params = {
					description: albumInfo.description,
					descriptionLink: albumInfo.description_link,
					copyright: albumInfo.copyright,
					copyrightLink: albumInfo.copyright_link,
					filePath: docPath,
					inherit: albumInfo.inherit,
					level: albumInfo.level
				};
			}

			return params;
		},

		/**
		 * Saves the sorting configuration for the current album
		 *
		 * @param {{sorting}} albumConfig
		 *
		 * @returns {{type: string, order: string, albumOrder: string}}
		 */
		setAlbumSorting: function (albumConfig) {
			var sortType = 'name';
			var sortOrder = 'asc';
			var albumSortOrder = 'asc';
			if (!$.isEmptyObject(albumConfig.sorting)) {
				if (!$.isEmptyObject(albumConfig.sorting.type)) {
					sortType = albumConfig.sorting.type;
				}
				if (!$.isEmptyObject(albumConfig.sorting.order)) {
					sortOrder = albumConfig.sorting.order;
					if (sortType === 'name') {
						albumSortOrder = sortOrder;
					}
				}
			}

			return {
				type: sortType,
				order: sortOrder,
				albumOrder: albumSortOrder
			};
		},

		/**
		 * Updates the sorting order
		 */
		updateAlbumSorting: function (sortConfig) {
			this.albumSorting = {
				type: sortConfig.type,
				order: sortConfig.order,
				albumOrder: sortConfig.albumOrder
			};
		}
	};

	Gallery.Config = Config;
})(jQuery, Gallery);
<commit_msg>Disable native SVG in Internet Explorer IE can't always retrieve the dimension of the SVG and can't scale them, so if the user encounters such a file, it will break the layout of the app<commit_after>/* global Gallery */
(function ($, Gallery) {
	"use strict";
	/**
	 * Stores the gallery configuration
	 *
	 * @param {{features: *}} config
	 * @constructor
	 */
	var Config = function (config) {
		this.galleryFeatures = this._setGalleryFeatures(config.features);
		this.mediaTypes = this._setMediaTypes(config.mediatypes);
	};

	Config.prototype = {
		galleryFeatures: [],
		mediaTypes: {},
		cachedMediaTypesString: '',
		albumPermissions: null,
		albumInfo: null,
		albumSorting: null,
		albumError: false,
		infoLoaded: false,

		/**
		 * Returns the list of supported media types in a string
		 *
		 * @returns {string}
		 */
		getMediaTypes: function () {
			return this.cachedMediaTypesString;
		},

		/**
		 * Stores the configuration about the current album
		 *
		 * @param albumConfig
		 */
		setAlbumConfig: function (albumConfig) {
			this.albumPermissions = this._setAlbumPermissions(albumConfig);
			this.albumInfo = this._setAlbumInfo(albumConfig);
			this.albumSorting = this._setAlbumSorting(albumConfig);
			this.albumError = albumConfig.error;
		},

		/**
		 * Updates the sorting order
		 */
		updateAlbumSorting: function (sortConfig) {
			this.albumSorting = {
				type: sortConfig.type,
				order: sortConfig.order,
				albumOrder: sortConfig.albumOrder
			};
		},

		/**
		 * Saves the list of features which have been enabled in the app
		 *
		 * @param configFeatures
		 *
		 * @returns {Array}
		 * @private
		 */
		_setGalleryFeatures: function (configFeatures) {
			var features = [];
			var feature = null;
			if (!$.isEmptyObject(configFeatures)) {
				for (var i = 0, keys = Object.keys(configFeatures); i < keys.length; i++) {
					feature = keys[i];
					if (configFeatures[feature] === 'yes' && this._validateFeature(feature)) {
						features.push(feature);
					}
				}
			}

			return features;
		},

		/**
		 * Saves the list of supported media types
		 *
		 * @param mediaTypes
		 *
		 * @returns {Array}
		 * @private
		 */
		_setMediaTypes: function (mediaTypes) {
			var supportedMediaTypes = [];
			var mediaType = null;
			var mediaTypesString = '';
			for (var i = 0, keys = Object.keys(mediaTypes); i < keys.length; i++) {
				mediaType = keys[i];
				if (this._validateMediaType(mediaType)) {
					mediaTypesString += mediaType + ';';
					supportedMediaTypes.push(mediaType);
				}
			}
			this.cachedMediaTypesString = mediaTypesString.slice(0, -1);

			return supportedMediaTypes;
		},

		/**
		 * Determines if we can accept the feature in this browser environment
		 *
		 * @param feature
		 *
		 * @returns {bool}
		 * @private
		 */
		_validateFeature: function (feature) {
			var isAcceptable = true;
			if (feature === 'native_svg' && Gallery.ieVersion !== false) {
				isAcceptable = false;
			}

			return isAcceptable;
		},

		/**
		 * Determines if we can accept the media type in this browser environment
		 *
		 * @param mediaType
		 *
		 * @returns {bool}
		 * @private
		 */
		_validateMediaType: function (mediaType) {
			var isAcceptable = true;
			if (mediaType === 'image/svg+xml' && Gallery.ieVersion !== false) {
				isAcceptable = false;
			}

			return isAcceptable;
		},

		/**
		 * Saves the permissions for the current album
		 *
		 * @param albumConfig
		 *
		 * @returns {{fileid: *, permissions: *}}
		 * @private
		 */
		_setAlbumPermissions: function (albumConfig) {
			return {
				fileid: albumConfig.fileid,
				permissions: albumConfig.permissions
			};
		},

		/**
		 * Saves the description and copyright information for the current album
		 *
		 * @param {{path, information, description_link, copyright_link}} albumConfig
		 *
		 * @returns {{}}
		 * @private
		 */
		_setAlbumInfo: function (albumConfig) {
			var albumPath = albumConfig.path;
			var albumInfo = albumConfig.information;
			var params = {};
			if (!$.isEmptyObject(albumInfo)) {
				var docPath = albumPath;
				var level = albumInfo.level;
				if (level > 0) {
					if (docPath.indexOf('/') !== -1) {
						var folders = docPath.split('/');
						folders = folders.slice(-0, -level);
						docPath = folders.join('/') + '/';
					} else {
						docPath = '';
					}
				}

				/* jshint camelcase: false */
				params = {
					description: albumInfo.description,
					descriptionLink: albumInfo.description_link,
					copyright: albumInfo.copyright,
					copyrightLink: albumInfo.copyright_link,
					filePath: docPath,
					inherit: albumInfo.inherit,
					level: albumInfo.level
				};
			}

			return params;
		},

		/**
		 * Saves the sorting configuration for the current album
		 *
		 * @param {{sorting}} albumConfig
		 *
		 * @returns {{type: string, order: string, albumOrder: string}}
		 * @private
		 */
		_setAlbumSorting: function (albumConfig) {
			var sortType = 'name';
			var sortOrder = 'asc';
			var albumSortOrder = 'asc';
			if (!$.isEmptyObject(albumConfig.sorting)) {
				if (!$.isEmptyObject(albumConfig.sorting.type)) {
					sortType = albumConfig.sorting.type;
				}
				if (!$.isEmptyObject(albumConfig.sorting.order)) {
					sortOrder = albumConfig.sorting.order;
					if (sortType === 'name') {
						albumSortOrder = sortOrder;
					}
				}
			}

			return {
				type: sortType,
				order: sortOrder,
				albumOrder: albumSortOrder
			};
		}
	};

	Gallery.Config = Config;
})(jQuery, Gallery);
<|endoftext|>


<commit_before>var recommend = {
    searchName: mw.config.get('wgPageName'),
    myId: mw.config.get('wgArticleId'),
    category: '',
    pageRec: mw.config.get('wgRecByUser')||[],
    arr: [],
    item: 0,
    netData:'',

    funAddBox: function(){
        $('.comments-body').before('

');
    },

    funGetPageRec: function(){
        var self = this;
        this.pageRec.forEach(function(item,i){
            if(i<4) {
                var content = '';
                content += '
' +
                    '
' +
                    item.title + '' + item.siteName + '

';
                self.arr.push(item.title+item.siteName);
                self.funGetImg(item.title, i, item.site);
                $('.recommend').append(content);
            }
        });
    },

    funGetCategory: function(){
        var self = this;
        if($('#mw-normal-catlinks').length!=0) {
            $('#mw-normal-catlinks li:not(.last)').each(function () {
                self.category += $(this).text() + ' ';
            });
        }
    },

    funGetNetRec: function(){
        var self = this;
        $.ajax({
            url:'http://121.42.179.100:8080/queryService/webapi/page/recommend/',
            data:{content:self.searchName,category:self.category,sitePrefix:mw.config.get('wgHuijiPrefix')},
            success: function (data) {
                var content = '';
                var len = self.pageRec.length;
                self.netData = data;
                if (data.length == 0) return;

                //除去指定推荐，剩下的进行遍历
                document.body.clientWidth>768?pcTraverse():mobilTraverse();
                $('.recommend').append(content);

                function pcTraverse(){
                    for (var i = len; i < 10; i++) {
                        var item = data[i - len];
                        var searchtitle = item.title;
                        var id = item.id;

                        //排除本词条和重复词条
//                    if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                        var sitePrefix = item.sitePrefix;

                        //去em标签
                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                        content += '

' +
                            '' + item.title + '' + item.siteName + '

';
                        self.funGetImg(searchtitle, i, sitePrefix, item.address, false);
                    }
                    self.item = i;
                }
                function mobilTraverse(){
                    for (var i = len; i < 4; i++) {
                        var item = data[i - len];
                        var searchtitle = item.title;
                        var id = item.id;

                        //排除本词条和重复词条
//                    if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                        var sitePrefix = item.sitePrefix;

                        //去em标签
                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                        content += '

' +
                            '' + item.title + '' + item.siteName + '

';
                        self.funGetImg(searchtitle, i, sitePrefix, item.address, false);
                    }
                    self.item = i;
                }
//                }

            },
            type: 'post'
        });
    },

    funGetImg: function(title,id,sitePrefix,address,ajax){
        var self = this;
        $.ajax({
            url:'http://'+sitePrefix+'.huiji.wiki/api.php?action=query&prop=pageimages&format=json&pithumbsize=250&titles='+title,
            type: 'get',
            success: function(data){
                var x;
                for( x in data.query.pages) {
                    if (data.query.pages[x].thumbnail) {
                        var img = '';
                        var percent = data.query.pages[x].thumbnail.width / data.query.pages[x].thumbnail.height;

                        $('#' + id ).prepend(img);
                        $('#' + id).removeClass('re-opacity');

                        self.funClipImg(percent,id);

                    } else {
                        $('#' + id).removeClass('re-opacity');
                        $('#' + id).prepend('');
                    }
                }
                if(ajax == false) {
                    if ($('.recommend-header').length == 0) {
                        $('.recommend').before('
更多推荐
');
                    }

                    //最后一次取图
                    if (id == self.item-1) {
                        if ($('.recommend .recommend-item').length == 0) $('.recommend').remove();
                        setTimeout(function(){
                            lazyLoad.autocheck();
                        },100);
                        if(document.body.clientWidth>768)
                        doOwl();
                    }
                }

                function doOwl(){
                    $("#recommend").owlCarousel({
                        items: 5,
                        beforeMove: function () {
                            var sp = $('.owl-wrapper').css('transform').split(',');
                            var len = self.pageRec.length;
                            var data = self.netData;
                            var n = self.item;
                            sp = Math.abs(parseInt(sp[4]));

                            if(n<30) {
                                if (sp > ($('.owl-item').length - 5) * $('.owl-item').width()) {
                                    setTimeout(function(){
                                        var load = '

';
                                        self.funAddItem(load,n);
                                    },100);
                                    for (var i = n; i < n + 2; i++) {
                                        var item = data[i - len];
                                        var searchtitle = item.title;
                                        var id = item.id;
                                        //排除本词条和重复词条
//                                        if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                                        var sitePrefix = item.sitePrefix;

                                        //去em标签
                                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                                        self.funGetImg2(searchtitle, i, sitePrefix, address, item, n, true);
//                                        }
                                        self.item++;
                                    }
                                }
                            }else{
                                if (sp > ($('.owl-item').length - 5) * $('.owl-item').width()) {
                                    setTimeout(function(){
                                        for(var i=n; i<n+2; i++){
                                            var img = '

' +
                                                'U FOUND ME
cool cool cool!

';
                                            self.funAddItem(img,n);
                                            self.item++;
                                        }
                                    },100);

                                }
                            }
                        }
                    });
                }
            }
        });
    },

    funClipImg: function(percent,id){
        var wid,wid2;
        //更宽裁剪两边
        if (percent > 0.7) {
            wid = percent * 100 - 70;
            wid2 = percent * 100 + 70;
            $('#' + id).find('img').css({'clip': 'rect(0,' + wid2 + 'px,200px,' + wid + 'px)', 'left': '-' + wid + 'px', 'height': '200px'});
        }
        //更高裁剪上下
        else if (percent < 0.7) {
            wid = 1 / percent * 70 - 100;
            wid2 = 1 / percent * 70 + 100;
            $('#' + id).find('img').css({'clip': 'rect(' + wid + 'px,140px,' + wid2 + 'px,0)', 'top': '-' + wid + 'px', 'width': '140px'});
        }
        else {
            $('#' + id).find('img').css('height', '200px');
            $('#' + id).removeClass('re-opacity');
        }
    },

    funAddItem: function(img,n){
        $('#recommend').data('owlCarousel').addItem(img);
        $('#recommend').data('owlCarousel').jumpTo(n);
    },

    funGetImg2: function(title,id,sitePrefix, address, item, n, ajax){
        var self = this;
        $.ajax({
            url: 'http://' + sitePrefix + '.huiji.wiki/api.php?action=query&prop=pageimages&format=json&pithumbsize=250&titles=' + title,
            type: 'get',
            success: function (data) {
                var x;
                var img;
                for (x in data.query.pages) {
                    if (data.query.pages[x].thumbnail) {
                        img = '

' +
                            '' + item.title + '' + item.siteName + '

';
                        var percent = data.query.pages[x].thumbnail.width / data.query.pages[x].thumbnail.height;
                        if($('.recommend-load').length>0){
                            $('#recommend').data('owlCarousel').removeItem();
                        }
                        self.funAddItem(img,n);
                        self.funClipImg(percent,id);

                    } else {
                        img = '

' +
                            '' + item.title + '' + item.siteName + '

';
                        if($('.recommend-load').length>0){
                            $('#recommend').data('owlCarousel').removeItem();
                        }
                        self.funAddItem(img,n);
                    }
                }
            }
        });
    },

    init: function(){
        if(mw.config.get('wgRec')||$('body').hasClass('ns-0')&&!mw.config.get('wgNoRec')){
            this.funAddBox();
            this.funGetPageRec();
            this.funGetCategory();
            this.funGetNetRec();
        }
    }
}

var lazyLoad = {
    area1: $('#recommend').get(0),
    //懒加载子域集合
    arr:[this.area1],

    getClient:function (){
    var l, t, w, h;
        l = document.documentElement.scrollLeft || document.body.scrollLeft;
        t = document.documentElement.scrollTop || document.body.scrollTop;
        w = document.documentElement.clientWidth;
        h = document.documentElement.clientHeight;
        return { left: l, top: t, width: w, height: h };
    },
    getSubClient:function (p){
        var l = 0, t = 0, w, h;
        w = p.offsetWidth;
        h = p.offsetHeight;
        while(p.offsetParent){
            l += p.offsetLeft;
            t += p.offsetTop;
            p = p.offsetParent;
        }
        return { left: l, top: t, width: w, height: h };
    },
    intens:function (rec1, rec2){
        var lc1, lc2, tc1, tc2, w1, h1;
        lc1 = rec1.left + rec1.width / 2;
        lc2 = rec2.left + rec2.width / 2;
        tc1 = rec1.top + rec1.height / 2 ;
        tc2 = rec2.top + rec2.height / 2 ;
        w1 = (rec1.width + rec2.width) / 2 ;
        h1 = (rec1.height + rec2.height) / 2;
        return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2)
= 0; i--) {
            if (arr[i]) {
                prec2 = self.getSubClient(arr[i]);
                if (self.intens(prec1, prec2)) {
                    callback(arr[i]);
    // 加载资源后，删除监测
                    delete arr[i];
                }
            }
        }
    },
    autocheck: function (){
        var prec1 = this.getClient();
        var arr = [$('#recommend').get(0)];
        this.detection(arr, prec1, function(obj){
            $('.lazy-loading img').each(function(){
                this.src = $(this).data('src');
                $(this).removeAttr('data-src');
            })
        })
    },

    init: function(){
        var self = this;
        self.autocheck();
        window.onscroll = function(){
            self.autocheck()
        };
        window.onresize = function(){
            self.autocheck()
        }
    }

}
$(function(){

    recommend.init();

    lazyLoad.init();
});
<commit_msg>recommend bug<commit_after>var recommend = {
    searchName: mw.config.get('wgPageName'),
    myId: mw.config.get('wgArticleId'),
    category: '',
    pageRec: mw.config.get('wgRecByUser')||[],
    arr: [],
    item: 0,
    netData:'',

    funAddBox: function(){
        $('.comments-body').before('

');
    },

    funGetPageRec: function(){
        var self = this;
        this.pageRec.forEach(function(item,i){
            if(i<4) {
                var content = '';
                var address = 'http://' + item.site + '.huiji.wiki/wiki/' + item.title;
                content += '
' +
                    '
' +
                    item.title + '' + item.siteName + '

';
                self.arr.push(item.title+item.siteName);
                self.funGetImg(item.title, i, item.site,address,false);
                $('.recommend').append(content);
            }
        });
    },

    funGetCategory: function(){
        var self = this;
        if($('#mw-normal-catlinks').length!=0) {
            $('#mw-normal-catlinks li:not(.last)').each(function () {
                self.category += $(this).text() + ' ';
            });
        }
    },

    funGetNetRec: function(){
        var self = this;
        $.ajax({
            url:'http://121.42.179.100:8080/queryService/webapi/page/recommend/',
            data:{content:self.searchName,category:self.category,sitePrefix:mw.config.get('wgHuijiPrefix')},
            success: function (data) {
                var content = '';
                var len = self.pageRec.length;
                self.netData = data;
                if (data.length == 0) return;

                //除去指定推荐，剩下的进行遍历
                document.body.clientWidth>768?pcTraverse():mobilTraverse();
                $('.recommend').append(content);

                function pcTraverse(){
                    for (var i = len; i < 10; i++) {
                        var item = data[i - len];
                        var searchtitle = item.title;
                        var id = item.id;

                        //排除本词条和重复词条
//                    if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                        var sitePrefix = item.sitePrefix;

                        //去em标签
                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                        content += '

' +
                            '' + item.title + '' + item.siteName + '

';
                        self.funGetImg(searchtitle, i, sitePrefix, item.address, false);
                    }
                    self.item = i;
                }
                function mobilTraverse(){
                    for (var i = len; i < 4; i++) {
                        var item = data[i - len];
                        var searchtitle = item.title;
                        var id = item.id;

                        //排除本词条和重复词条
//                    if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                        var sitePrefix = item.sitePrefix;

                        //去em标签
                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                        content += '

' +
                            '' + item.title + '' + item.siteName + '

';
                        self.funGetImg(searchtitle, i, sitePrefix, item.address, false );
                    }
                    self.item = i;
                }
//                }

            },
            type: 'post'
        });
    },

    funGetImg: function(title,id,sitePrefix,address,ajax){
        var self = this;
        $.ajax({
            url:'http://'+sitePrefix+'.huiji.wiki/api.php?action=query&prop=pageimages&format=json&pithumbsize=250&titles='+title,
            type: 'get',
            success: function(data){
                var x;
                for( x in data.query.pages) {
                    if (data.query.pages[x].thumbnail) {
                        var img = '';
                        var percent = data.query.pages[x].thumbnail.width / data.query.pages[x].thumbnail.height;

                        $('#' + id ).prepend(img);
                        $('#' + id).removeClass('re-opacity');

                        self.funClipImg(percent,id);

                    } else {
                        $('#' + id).removeClass('re-opacity');
                        $('#' + id).prepend('');
                    }
                }
                if(ajax == false) {
                    if ($('.recommend-header').length == 0) {
                        $('.recommend').before('
更多推荐
');
                    }

                    //最后一次取图
                    if (id == self.item-1) {
                        if ($('.recommend .recommend-item').length == 0) $('.recommend').remove();
                        setTimeout(function(){
                            lazyLoad.autocheck();
                        },100);
                        if(document.body.clientWidth>768)
                        doOwl();
                    }
                }

                function doOwl(){
                    $("#recommend").owlCarousel({
                        items: 5,
                        beforeMove: function () {
                            var sp = $('.owl-wrapper').css('transform').split(',');
                            var len = self.pageRec.length;
                            var data = self.netData;
                            var n = self.item;
                            sp = Math.abs(parseInt(sp[4]));

                            if(n<30) {
                                if (sp > ($('.owl-item').length - 5) * $('.owl-item').width()) {
                                    setTimeout(function(){
                                        var load = '

';
                                        self.funAddItem(load,n);
                                    },100);
                                    for (var i = n; i < n + 2; i++) {
                                        var item = data[i - len];
                                        var searchtitle = item.title;
                                        var id = item.id;
                                        //排除本词条和重复词条
//                                        if (id != self.myId && self.arr.indexOf(searchtitle+item.siteName)<0) {
                                        var sitePrefix = item.sitePrefix;

                                        //去em标签
                                        searchtitle = searchtitle.replace(//g, '').replace(/<\/em>/g, '');

                                        self.funGetImg2(searchtitle, i, sitePrefix, address, item, n, true);
//                                        }
                                        self.item++;
                                    }
                                }
                            }else{
                                if (sp > ($('.owl-item').length - 5) * $('.owl-item').width()) {
                                    setTimeout(function(){
                                        for(var i=n; i<n+2; i++){
                                            var img = '

' +
                                                'U FOUND ME
cool cool cool!

';
                                            self.funAddItem(img,n);
                                            self.item++;
                                        }
                                    },100);

                                }
                            }
                        }
                    });
                }
            }
        });
    },

    funClipImg: function(percent,id){
        var wid,wid2;
        //更宽裁剪两边
        if (percent > 0.7) {
            wid = percent * 100 - 70;
            wid2 = percent * 100 + 70;
            $('#' + id).find('img').css({'clip': 'rect(0,' + wid2 + 'px,200px,' + wid + 'px)', 'left': '-' + wid + 'px', 'height': '200px'});
        }
        //更高裁剪上下
        else if (percent < 0.7) {
            wid = 1 / percent * 70 - 100;
            wid2 = 1 / percent * 70 + 100;
            $('#' + id).find('img').css({'clip': 'rect(' + wid + 'px,140px,' + wid2 + 'px,0)', 'top': '-' + wid + 'px', 'width': '140px'});
        }
        else {
            $('#' + id).find('img').css('height', '200px');
            $('#' + id).removeClass('re-opacity');
        }
    },

    funAddItem: function(img,n){
        $('#recommend').data('owlCarousel').addItem(img);
        $('#recommend').data('owlCarousel').jumpTo(n);
    },

    funGetImg2: function(title,id,sitePrefix, address, item, n, ajax){
        var self = this;
        $.ajax({
            url: 'http://' + sitePrefix + '.huiji.wiki/api.php?action=query&prop=pageimages&format=json&pithumbsize=250&titles=' + title,
            type: 'get',
            success: function (data) {
                var x;
                var img;
                for (x in data.query.pages) {
                    if (data.query.pages[x].thumbnail) {
                        img = '

' +
                            '' + item.title + '' + item.siteName + '

';
                        var percent = data.query.pages[x].thumbnail.width / data.query.pages[x].thumbnail.height;
                        if($('.recommend-load').length>0){
                            $('#recommend').data('owlCarousel').removeItem();
                        }
                        self.funAddItem(img,n);
                        self.funClipImg(percent,id);

                    } else {
                        img = '

' +
                            '' + item.title + '' + item.siteName + '

';
                        if($('.recommend-load').length>0){
                            $('#recommend').data('owlCarousel').removeItem();
                        }
                        self.funAddItem(img,n);
                    }
                }
            }
        });
    },

    init: function(){
        if(mw.config.get('wgRec')||$('body').hasClass('ns-0')&&!mw.config.get('wgNoRec')){
            this.funAddBox();
            this.funGetPageRec();
            this.funGetCategory();
            this.funGetNetRec();
        }
    }
}

var lazyLoad = {
    area1: $('#recommend').get(0),
    //懒加载子域集合
    arr:[this.area1],

    getClient:function (){
    var l, t, w, h;
        l = document.documentElement.scrollLeft || document.body.scrollLeft;
        t = document.documentElement.scrollTop || document.body.scrollTop;
        w = document.documentElement.clientWidth;
        h = document.documentElement.clientHeight;
        return { left: l, top: t, width: w, height: h };
    },
    getSubClient:function (p){
        var l = 0, t = 0, w, h;
        w = p.offsetWidth;
        h = p.offsetHeight;
        while(p.offsetParent){
            l += p.offsetLeft;
            t += p.offsetTop;
            p = p.offsetParent;
        }
        return { left: l, top: t, width: w, height: h };
    },
    intens:function (rec1, rec2){
        var lc1, lc2, tc1, tc2, w1, h1;
        lc1 = rec1.left + rec1.width / 2;
        lc2 = rec2.left + rec2.width / 2;
        tc1 = rec1.top + rec1.height / 2 ;
        tc2 = rec2.top + rec2.height / 2 ;
        w1 = (rec1.width + rec2.width) / 2 ;
        h1 = (rec1.height + rec2.height) / 2;
        return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2)
= 0; i--) {
            if (arr[i]) {
                prec2 = self.getSubClient(arr[i]);
                if (self.intens(prec1, prec2)) {
                    callback(arr[i]);
    // 加载资源后，删除监测
                    delete arr[i];
                }
            }
        }
    },
    autocheck: function (){
        var prec1 = this.getClient();
        var arr = [$('#recommend').get(0)];
        this.detection(arr, prec1, function(obj){
            $('.lazy-loading img').each(function(){
                this.src = $(this).data('src');
                $(this).removeAttr('data-src');
            })
        })
    },

    init: function(){
        var self = this;
        self.autocheck();
        window.onscroll = function(){
            self.autocheck()
        };
        window.onresize = function(){
            self.autocheck()
        }
    }

}
$(function(){

    recommend.init();

    lazyLoad.init();
});
<|endoftext|>