<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict'

const URL = require('url')
const TrackingProtection = require('tracking-protection').CTPParser
const DataFile = require('./dataFile')
const Filtering = require('./filtering')
const LRUCache = require('lru_cache/core').LRUCache
const getBaseDomain = require('../js/lib/baseDomain').getBaseDomain

module.exports.resourceName = 'trackingProtection'

let trackingProtection

let cachedFirstParty = new LRUCache(50)

// Temporary whitelist until we find a better solution
const whitelistHosts = ['connect.facebook.net', 'connect.facebook.com', 'staticxx.facebook.com', 'www.facebook.com']
const whitelistBaseDomains = ['fbcdn.net']

const startTrackingProtection = (wnd) => {
  Filtering.registerBeforeRequestFilteringCB((details) => {
    const firstPartyUrl = URL.parse(details.firstPartyUrl)
    let firstPartyUrlHost = firstPartyUrl.hostname || ''
    if (firstPartyUrlHost.startsWith('www.')) {
      firstPartyUrlHost = firstPartyUrlHost.substring(4)
    }
    if (firstPartyUrl.protocol && firstPartyUrl.protocol.startsWith('http')) {
      if (!cachedFirstParty.get(firstPartyUrlHost)) {
        let firstPartyHosts = trackingProtection.findFirstPartyHosts(firstPartyUrlHost)
        cachedFirstParty.put(firstPartyUrlHost, firstPartyHosts && firstPartyHosts.split(',') || [])
      }
    }
    const urlHost = URL.parse(details.url).hostname
    const cancel = firstPartyUrl.protocol &&
      details.resourceType !== 'mainFrame' &&
      firstPartyUrl.protocol.startsWith('http') &&
      !whitelistHosts.includes(urlHost) &&
      cachedFirstParty.get(firstPartyUrlHost) &&
      trackingProtection.matchesTracker(firstPartyUrlHost, urlHost) &&
      urlHost !== firstPartyUrlHost &&
      !whitelistBaseDomains.includes(getBaseDomain(urlHost)) &&
      !cachedFirstParty.get(firstPartyUrlHost).find((baseHost) =>
        !Filtering.isThirdPartyHost(baseHost, urlHost))

    DataFile.debug(module.exports.resourceName, details, cancel)
    return {
      cancel,
      resourceName: module.exports.resourceName
    }
  })
}

module.exports.init = () => {
  trackingProtection = new TrackingProtection()
  DataFile.init(module.exports.resourceName, startTrackingProtection,
                (data) => trackingProtection.deserialize(data))
}
<commit_msg>Revert "Fix images sometimes blocked on Instagram"<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict'

const URL = require('url')
const TrackingProtection = require('tracking-protection').CTPParser
const DataFile = require('./dataFile')
const Filtering = require('./filtering')
const LRUCache = require('lru_cache/core').LRUCache

module.exports.resourceName = 'trackingProtection'

let trackingProtection

let cachedFirstParty = new LRUCache(50)

// Temporary whitelist until we find a better solution
const whitelistHosts = ['connect.facebook.net', 'connect.facebook.com', 'staticxx.facebook.com', 'www.facebook.com']

const startTrackingProtection = (wnd) => {
  Filtering.registerBeforeRequestFilteringCB((details) => {
    const firstPartyUrl = URL.parse(details.firstPartyUrl)
    let firstPartyUrlHost = firstPartyUrl.hostname || ''
    if (firstPartyUrlHost.startsWith('www.')) {
      firstPartyUrlHost = firstPartyUrlHost.substring(4)
    }
    if (firstPartyUrl.protocol && firstPartyUrl.protocol.startsWith('http')) {
      if (!cachedFirstParty.get(firstPartyUrlHost)) {
        let firstPartyHosts = trackingProtection.findFirstPartyHosts(firstPartyUrlHost)
        cachedFirstParty.put(firstPartyUrlHost, firstPartyHosts && firstPartyHosts.split(',') || [])
      }
    }
    const urlHost = URL.parse(details.url).hostname
    const cancel = firstPartyUrl.protocol &&
      details.resourceType !== 'mainFrame' &&
      firstPartyUrl.protocol.startsWith('http') &&
      !whitelistHosts.includes(urlHost) &&
      cachedFirstParty.get(firstPartyUrlHost) &&
      trackingProtection.matchesTracker(firstPartyUrlHost, urlHost) &&
      urlHost !== firstPartyUrlHost &&
      !cachedFirstParty.get(firstPartyUrlHost).find((baseHost) =>
        !Filtering.isThirdPartyHost(baseHost, urlHost))

    DataFile.debug(module.exports.resourceName, details, cancel)
    return {
      cancel,
      resourceName: module.exports.resourceName
    }
  })
}

module.exports.init = () => {
  trackingProtection = new TrackingProtection()
  DataFile.init(module.exports.resourceName, startTrackingProtection,
                (data) => trackingProtection.deserialize(data))
}
<|endoftext|>


<commit_before>var fifooter = "
 \
 \
FusionInventory 9.1+1.0 - Copyleft \
© \
2010-2016 by FusionInventory Team \
";

$(window).bind("load", function() {
   $('#footer').css('height', 'auto');
   $("#footer td.right").append(fifooter);
});
<commit_msg>Update version in footer; fixes #2281<commit_after>var fifooter = "
 \
 \
FusionInventory 9.2+1.1 - Copyleft \
© \
2010-2017 by FusionInventory Team \
";

$(window).bind("load", function() {
   $('#footer').css('height', 'auto');
   $("#footer td.right").append(fifooter);
});
<|endoftext|>


<commit_before>import React from 'react';
import _reduce from 'lodash/reduce';
import _find from 'lodash/find';
import { statusValues } from 'appConstants';
import styles from 'modules/common/styles';

export const formatAddress = ({ country = '', province = '', city = '', district = '' }) =>
  `${country === '中国' ? '' : country}${province}${city}${district}`;

export const formatPrices = (specs) => {
  const formattedPrice = _reduce(specs, (result, spec) => ({
    min: Math.min(result.min, spec.price),
    max: Math.max(result.max, spec.price),
  }), { min: 999999999, max: 0 });
  const { min, max } = formattedPrice;
  return min === max ? `${min}元` : `${min} ~ ${max}元`;
};

export const formatPrice = (spec) => {
  const result = `${spec.price}元每${spec.unit}`;
  if (spec.minimum > 1) {
    return `${result}，${spec.minimum}${spec.unit}起售`;
  }
  return result;
};

export const formatStatus = (statusValue) => {
  const status = _find(statusValues, (s) => s.value === statusValue) || {};
  const { title, value } = status;
  let className;
  switch (value) {
    case statusValues.unverified:
      className = styles.colorUnverified;
      break;
    case statusValues.rejected:
      className = styles.colorRejected;
      break;
    case statusValues.verified:
      className = styles.colorVerified;
      break;
    default:
      className = styles.colorAccent;
  }
  return ({title});
};

const miniSecsInHour = 3600 * 1000;
const miniSecsInDay = miniSecsInHour * 24;
const miniSecsInWeek = miniSecsInDay * 7;
const miniSecsInMonth = miniSecsInDay * 30;
const miniSecsInYear = miniSecsInDay * 365;
export const humanizeTime = (time) => {
  const now = new Date().getTime();
  const period = now - time;
  if (period < miniSecsInDay) {
    const hours = Math.floor((period) / miniSecsInHour);
    if (hours <= 0) {
      return '刚刚';
    }
    return `${hours}小时前`;
  } else if (period < miniSecsInWeek) {
    const days = Math.floor((now - time) / miniSecsInDay);
    if (days <= 0) {
      return '今天';
    }
    return `${days}天前`;
  } else if (period < miniSecsInMonth) {
    const weeks = Math.floor((now - time) / miniSecsInWeek);
    if (weeks <= 0) {
      return '本周';
    }
    return `${weeks}周前`;
  } else if (period < miniSecsInYear) {
    const months = Math.floor((now - time) / miniSecsInMonth);
    if (months <= 0) {
      return '本月';
    }
    return `${months}月前`;
  }
  const years = Math.floor((now - time) / miniSecsInYear);
  if (years <= 0) {
    return '今年';
  }
  return `${years}年前`;
};

function Rad(d) {
  return (d * Math.PI) / 180.0; // 经纬度转换成三角函数中度分表形式。
}
// 计算距离，参数分别为第一点的纬度，经度；第二点的纬度，经度
export function humanizeLnglat(lat1, lng1, lat2, lng2) {
  const radLat1 = Rad(lat1);
  const radLat2 = Rad(lat2);
  const a = radLat1 - radLat2;
  const b = Rad(lng1) - Rad(lng2);
  let s = 2 * Math.asin(
    Math.sqrt(Math.sin(a / 2) ** 2) + (Math.cos(radLat1) * Math.cos(radLat2) * (Math.sin(b / 2) ** 2)));
  s *= 6378.137;// EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000; // 输出为公里
  s = Math.floor(s);
  return s === 0 ? '小于1公里' : `约${s}公里`;
}

<commit_msg>certs<commit_after>import React from 'react';
import _reduce from 'lodash/reduce';
import _find from 'lodash/find';
import { statusValues } from 'appConstants';
import styles from 'modules/common/styles';

export const formatAddress = ({ country = '', province = '', city = '', district = '' }) =>
  `${country === '中国' ? '' : country}${province}${city}${district}`;

export const formatPrices = (specs) => {
  const formattedPrice = _reduce(specs, (result, spec) => ({
    min: Math.min(result.min, spec.price),
    max: Math.max(result.max, spec.price),
  }), { min: 999999999, max: 0 });
  const { min, max } = formattedPrice;
  return min === max ? `${min}元` : `${min} ~ ${max}元`;
};

export const formatPrice = (spec) => {
  const result = `${spec.price}元每${spec.unit}`;
  if (spec.minimum > 1) {
    return `${result}，${spec.minimum}${spec.unit}起售`;
  }
  return result;
};

export const formatStatus = (statusValue) => {
  const status = _find(statusValues, (s) => s.value === statusValue) || {};
  const { title, value } = status;
  let className;
  switch (value) {
    case statusValues.unverified.value:
      className = styles.colorUnverified;
      break;
    case statusValues.rejected.value:
      className = styles.colorRejected;
      break;
    case statusValues.verified.value:
      className = styles.colorVerified;
      break;
    default:
      className = styles.colorAccent;
  }
  return ({title});
};

const miniSecsInHour = 3600 * 1000;
const miniSecsInDay = miniSecsInHour * 24;
const miniSecsInWeek = miniSecsInDay * 7;
const miniSecsInMonth = miniSecsInDay * 30;
const miniSecsInYear = miniSecsInDay * 365;
export const humanizeTime = (time) => {
  const now = new Date().getTime();
  const period = now - time;
  if (period < miniSecsInDay) {
    const hours = Math.floor((period) / miniSecsInHour);
    if (hours <= 0) {
      return '刚刚';
    }
    return `${hours}小时前`;
  } else if (period < miniSecsInWeek) {
    const days = Math.floor((now - time) / miniSecsInDay);
    if (days <= 0) {
      return '今天';
    }
    return `${days}天前`;
  } else if (period < miniSecsInMonth) {
    const weeks = Math.floor((now - time) / miniSecsInWeek);
    if (weeks <= 0) {
      return '本周';
    }
    return `${weeks}周前`;
  } else if (period < miniSecsInYear) {
    const months = Math.floor((now - time) / miniSecsInMonth);
    if (months <= 0) {
      return '本月';
    }
    return `${months}月前`;
  }
  const years = Math.floor((now - time) / miniSecsInYear);
  if (years <= 0) {
    return '今年';
  }
  return `${years}年前`;
};

function Rad(d) {
  return (d * Math.PI) / 180.0; // 经纬度转换成三角函数中度分表形式。
}
// 计算距离，参数分别为第一点的纬度，经度；第二点的纬度，经度
export function humanizeLnglat(lat1, lng1, lat2, lng2) {
  const radLat1 = Rad(lat1);
  const radLat2 = Rad(lat2);
  const a = radLat1 - radLat2;
  const b = Rad(lng1) - Rad(lng2);
  let s = 2 * Math.asin(
    Math.sqrt(Math.sin(a / 2) ** 2) + (Math.cos(radLat1) * Math.cos(radLat2) * (Math.sin(b / 2) ** 2)));
  s *= 6378.137;// EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000; // 输出为公里
  s = Math.floor(s);
  return s === 0 ? '小于1公里' : `约${s}公里`;
}

<|endoftext|>


<commit_before>const createFilters = require('./facets/create-filters');
const createFiltersAll = require('./facets/create-filter-all');
const aggregationTotalCategories = require('./facets/aggs-total-categories');
const createAggregations = require('./facets/create-aggregations');
const createPostFilter = require('./facets/create-post-filter');
const searchWeights = require('./search-weights');
/**
* Search with aggregations
* The total aggregation is a filter bucket. It excludes data which are not agents archives or objects
* @param {Object} elastic - the elasticsearch client
* @param {Object} queryParams - the queryParams Object
* @param {Function} next - the callback with error and response as parameters
*/
module.exports = (elastic, queryParams, next) => {
  const pageNumber = queryParams.pageNumber <= 150 ? queryParams.pageNumber : 150;
  const pageSize = queryParams.pageSize;
  var body = {
    size: pageSize,
    query: {
      function_score: {
        query: {
          bool: {
            filter: {
              terms: {
                'type.base': ['agent', 'archive', 'object']
              }
            },
            should: [{
              multi_match: {
                query: queryParams.q,
                type: 'best_fields',
                fields: [
                  'name.value_text',
                  'name.value_lower',
                  'title.value_text',
                  'summary_title_stem',
                  'summary_title_lower',
                  // 'note.value',
                  'description.value',
                  'identifier.value'
                ]
              }
            }, {
              match: {
                'identifier.value': {
                  query: queryParams.q,
                  boost: 200
                }
              }
            }, {
              prefix: {
                'identifier.value': {
                  value: queryParams.q,
                  boost: 200
                }
              }
            }, {
              match_phrase: {
                'title.value_text': {
                  query: queryParams.q,
                  slop: 50,
                  boost: 5
                }
              }
            }, {
              match_phrase: {
                'name.value_text': {
                  query: queryParams.q,
                  slop: 50
                }
              }
            }, {
              match_phrase: {
                'summary_title_stem': {
                  query: queryParams.q,
                  slop: 50
                }
              }
            }, {
              match_phrase: {
                'description.value': {
                  query: queryParams.q,
                  slop: 50
                }
              }
            }]
          }
        },
        functions: searchWeights
      }
    },
    min_score: 0.01
  };

  const searchOpts = {
    index: 'smg',
    from: pageNumber * pageSize,
    body: body
  };

  if (!queryParams.q) {
    searchOpts.body.query.function_score.query = {match_all: {}};
  }

  if (queryParams.random) {
    /* See https://github.com/TheScienceMuseum/collectionsonline/issues/780
      Allows users to request a number (n) of random items using query '?random=n'
      Where 'n' is a number between 1 and 50
    */
    searchOpts.body = {
      size: queryParams.random,
      query: {
        function_score: {
          query: {match_all: {}},
          functions: [{
            random_score: {
              seed: Date.now()
            }
          }]
        }
      },
      min_score: 0.01
    };
  }

  const filtersType = [{terms: {'type.base': ['agent', 'archive', 'object']}}];
  const filtersPeople = createFilters(queryParams, 'agent');
  const filtersObjects = createFilters(queryParams, 'object');
  const filterDocuments = createFilters(queryParams, 'archive');
  const filters = {
    type: filtersType,
    people: filtersPeople,
    objects: filtersObjects,
    documents: filterDocuments
  };
  filters.all = createFiltersAll(queryParams, filters);
  /**
  * Build filters for aggregations based on queryParams object
  * queryParams contains a representation of the selected filters by the user
  */
  searchOpts.body.aggs = {};

  /**
  * Total per category aggregations
  */
  Object.assign(searchOpts.body.aggs, aggregationTotalCategories(filters));

 /**
 * Create aggregations
 */
  Object.assign(searchOpts.body.aggs, createAggregations(queryParams));

  /**
  * Create post filter query. This query is going to filter the list of results depending on the category and the filters selected by the user
  */
  searchOpts.body.post_filter = {};
  Object.assign(searchOpts.body.post_filter, createPostFilter(queryParams, filters));

  elastic.search(searchOpts, (err, result) => {
    return next(err, result);
  });
};
<commit_msg>adjust slop values on description field<commit_after>const createFilters = require('./facets/create-filters');
const createFiltersAll = require('./facets/create-filter-all');
const aggregationTotalCategories = require('./facets/aggs-total-categories');
const createAggregations = require('./facets/create-aggregations');
const createPostFilter = require('./facets/create-post-filter');
const searchWeights = require('./search-weights');
/**
* Search with aggregations
* The total aggregation is a filter bucket. It excludes data which are not agents archives or objects
* @param {Object} elastic - the elasticsearch client
* @param {Object} queryParams - the queryParams Object
* @param {Function} next - the callback with error and response as parameters
*/
module.exports = (elastic, queryParams, next) => {
  const pageNumber = queryParams.pageNumber <= 150 ? queryParams.pageNumber : 150;
  const pageSize = queryParams.pageSize;
  var body = {
    size: pageSize,
    query: {
      function_score: {
        query: {
          bool: {
            filter: {
              terms: {
                'type.base': ['agent', 'archive', 'object']
              }
            },
            should: [{
              multi_match: {
                query: queryParams.q,
                type: 'best_fields',
                fields: [
                  'name.value_text',
                  'name.value_lower',
                  'title.value_text',
                  'summary_title_stem',
                  'summary_title_lower',
                  // 'note.value',
                  // 'description.value',
                  'identifier.value'
                ]
              }
            }, {
              match: {
                'identifier.value': {
                  query: queryParams.q,
                  boost: 200
                }
              }
            }, {
              prefix: {
                'identifier.value': {
                  value: queryParams.q,
                  boost: 200
                }
              }
            }, {
              match_phrase: {
                'title.value_text': {
                  query: queryParams.q,
                  slop: 50,
                  boost: 5
                }
              }
            }, {
              match_phrase: {
                'name.value_text': {
                  query: queryParams.q,
                  slop: 50
                }
              }
            }, {
              match_phrase: {
                'summary_title_stem': {
                  query: queryParams.q,
                  slop: 50
                }
              }
            }, {
              match_phrase: {
                'description.value': {
                  query: queryParams.q,
                  slop: 150,
                  boost: 2
                }
              }
            }]
          }
        },
        functions: searchWeights
      }
    },
    min_score: 0.01
  };

  const searchOpts = {
    index: 'smg',
    from: pageNumber * pageSize,
    body: body
  };

  if (!queryParams.q) {
    searchOpts.body.query.function_score.query = {match_all: {}};
  }

  if (queryParams.random) {
    /* See https://github.com/TheScienceMuseum/collectionsonline/issues/780
      Allows users to request a number (n) of random items using query '?random=n'
      Where 'n' is a number between 1 and 50
    */
    searchOpts.body = {
      size: queryParams.random,
      query: {
        function_score: {
          query: {match_all: {}},
          functions: [{
            random_score: {
              seed: Date.now()
            }
          }]
        }
      },
      min_score: 0.01
    };
  }

  const filtersType = [{terms: {'type.base': ['agent', 'archive', 'object']}}];
  const filtersPeople = createFilters(queryParams, 'agent');
  const filtersObjects = createFilters(queryParams, 'object');
  const filterDocuments = createFilters(queryParams, 'archive');
  const filters = {
    type: filtersType,
    people: filtersPeople,
    objects: filtersObjects,
    documents: filterDocuments
  };
  filters.all = createFiltersAll(queryParams, filters);
  /**
  * Build filters for aggregations based on queryParams object
  * queryParams contains a representation of the selected filters by the user
  */
  searchOpts.body.aggs = {};

  /**
  * Total per category aggregations
  */
  Object.assign(searchOpts.body.aggs, aggregationTotalCategories(filters));

 /**
 * Create aggregations
 */
  Object.assign(searchOpts.body.aggs, createAggregations(queryParams));

  /**
  * Create post filter query. This query is going to filter the list of results depending on the category and the filters selected by the user
  */
  searchOpts.body.post_filter = {};
  Object.assign(searchOpts.body.post_filter, createPostFilter(queryParams, filters));

  elastic.search(searchOpts, (err, result) => {
    return next(err, result);
  });
};
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name dashboardJsApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the dashboardJsApp
 */

app.directive('visPie', function ($window) {
	return {
		restrict: 'EA',

		scope: {
			data: '=data',
			width: '=width',
			height: '=height',
			option: '=?'
		},

		templateUrl: 'scripts/directives/pie/pie.html',

		controller: function($scope) {
			$scope.option = $scope.option || false;
		},

		link: function (scope, element) {

            d3.selection.prototype.moveToFront = function() {
                return this.each(function(){
                    this.parentNode.appendChild(this);
                });
            };

			scope.$watch('data', function(data) {

                var drawChart = function() {

                    var thewidth = scope.width;
                    if (!thewidth) {

                        thewidth = element.parent().width();
                        if(thewidth < 0) {
                            thewidth = 100;
                        }
                        console.log(thewidth);
                    }

                    if ((data !== undefined) && (data !== null) && (data !== [])) {
                        var pie = d3.layout.pie()
                            .sort(null)
                            .value(function (d) {
                                return d.value;
                            });

                        var margin = { top: 20, right: 150, bottom: 20, left: 20 };
                        var colors = d3.scale.category20();
                        var tipOn = true;

                        var width = thewidth - margin.right - margin.left,
                            height = scope.height - margin.top - margin.bottom;

                        var radius = d3.min([width, height]) / 2;

                        var arc = d3.svg.arc()
                            .outerRadius(radius)
                            .innerRadius(0);

                        $(element.find('.pie-chart')[0]).html("");

                        var svg = d3.select(element.find('.pie-chart')[0])
                            .attr('width', thewidth)
                            .attr('height', scope.height)
                            .append('g')
                            .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

                        var tip = d3.tip()
                            .attr('class', 'd3-tip')
                            .html(function (d) {
                                var tipStr = '';
                                if (d.data.comment) {
                                    tipStr = d.data.comment;
                                }
                                else {
                                    tipStr = '<strong>' + d.data.label + ': </strong> ' + d.value + ' (' + (d.value / sum * 100).toFixed(1) + '%)';
                                }
                                return tipStr;
                            })
                            .offset(function (d) {
                                return [-10, 0];
                            });

                        var texton = function (d) {
                            var textElemnt = d3.select(this).node();
                            tip.show(d, textElemnt);
                        };

                        var textoff = function (d) {
                            tip.hide();
                        };

                        var contrastingColor = function (d3Color) {
                            var yiq = ((d3Color.r * 299) + (d3Color.g * 587) + (d3Color.b * 114)) / 1000;
                            return (yiq >= 128) ? '#111111' : '#fafafa';
                        }

                        var arcs = svg.selectAll('g.arc')
                            .data(pie(data))
                            .enter()
                            .append('g')
                            .attr('class', 'arc')
                            .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

                        var sum = d3.sum(data, function (d) {
                            return d.value;
                        });

                        arcs.call(tip);

                        arcs.append('path')
                            .attr('fill', function (d, i) {
                                return colors(i);
                            })
                            .attr('d', arc)
                            .on('mouseover', function (d, i) {
                                //d3.select(this).remove();
                                //var savedSlice = d3.select(this);
                                //savedSlice.remove();
                                d3.select(this).style('stroke-width', 6);
                                d3.select(this).style('stroke', d3.rgb(colors(i)).brighter(0.7));
                                d3.select(this.parentNode).select('.arctext').each(texton);
                                d3.select(this.parentNode).moveToFront();

                            })
                            .on('mouseout', function (d) {
                                d3.select(this).style('stroke-width', 0);
                                if (tipOn) {
                                    tip.hide();
                                }
                            });

                        arcs.append('text')
                            .attr('transform', function (d, i) {
                                var centroid = arc.centroid(d);
                                var xc = centroid[0] * 1.5;
                                var yc = centroid[1] * 1.5 + 5;
                                return 'translate(' + xc + ',' + yc + ')';
                            })
                            .attr('class', 'arctext')
                            .attr('text-anchor', 'middle')
                            .text(function (d) {
                                // Only show text when the arc is large enough
                                if ((d.endAngle - d.startAngle) > 0.2) {
                                    return d.value;
                                }
                                else {
                                    return ' ';
                                }
                            })
                            .attr('fill', function (d, i) {
                                var gColor = d3.rgb(colors(i));
                                return contrastingColor(gColor);
                            })
                            .on('mouseover', texton)
                            .on('mouseout', textoff);

                        d3.selectAll('.arctext').call(tip);

                        // Add legend
                        var legend = svg.selectAll('g.legend')
                            .data(data)
                            .enter()
                            .append('g')
                            .attr('class', 'legends')
                            .attr('transform', function (d, i) {
                                return 'translate(' + ( width + margin.left ) + ',' + i * 20 + ')';
                            })
                            .style('fill', function (d, i) {
                                return colors(i);
                            });

                        legend.append('rect')
                            .attr('width', 18)
                            .attr('height', 18);

                        legend.append('text')
                            .attr('x', 20)
                            .attr('y', 9)
                            .attr('dy', '.35em')
                            .style('text-anchor', 'start')
                            .text(function (d) {
                                return d.label;
                            });
                    }
                }

                drawChart();

                scope.resize = function() {
					d3.select(element.find('.tip')[0]).selectAll().remove();
					d3.select(element.find('.pie-chart')[0]).selectAll('g').remove();
					drawChart();
                }

				window.addEventListener('resize', function(event){
                    clearTimeout(scope.resizetimeout);
                    scope.resizetimeout = setTimeout(scope.resize,100);
				});

                setTimeout(scope.resize,100);

			});
		}
	};
});<commit_msg>Changed timeout<commit_after>'use strict';

/**
 * @ngdoc function
 * @name dashboardJsApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the dashboardJsApp
 */

app.directive('visPie', function ($window) {
	return {
		restrict: 'EA',

		scope: {
			data: '=data',
			width: '=width',
			height: '=height',
			option: '=?'
		},

		templateUrl: 'scripts/directives/pie/pie.html',

		controller: function($scope) {
			$scope.option = $scope.option || false;
		},

		link: function (scope, element) {

            d3.selection.prototype.moveToFront = function() {
                return this.each(function(){
                    this.parentNode.appendChild(this);
                });
            };

			scope.$watch('data', function(data) {

                var drawChart = function() {

                    var thewidth = scope.width;
                    if (!thewidth) {

                        thewidth = element.parent().width();
                        if(thewidth < 0) {
                            thewidth = 100;
                        }
                        console.log(thewidth);
                    }

                    if ((data !== undefined) && (data !== null) && (data !== [])) {
                        var pie = d3.layout.pie()
                            .sort(null)
                            .value(function (d) {
                                return d.value;
                            });

                        var margin = { top: 20, right: 150, bottom: 20, left: 20 };
                        var colors = d3.scale.category20();
                        var tipOn = true;

                        var width = thewidth - margin.right - margin.left,
                            height = scope.height - margin.top - margin.bottom;

                        var radius = d3.min([width, height]) / 2;

                        var arc = d3.svg.arc()
                            .outerRadius(radius)
                            .innerRadius(0);

                        $(element.find('.pie-chart')[0]).html("");

                        var svg = d3.select(element.find('.pie-chart')[0])
                            .attr('width', thewidth)
                            .attr('height', scope.height)
                            .append('g')
                            .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

                        var tip = d3.tip()
                            .attr('class', 'd3-tip')
                            .html(function (d) {
                                var tipStr = '';
                                if (d.data.comment) {
                                    tipStr = d.data.comment;
                                }
                                else {
                                    tipStr = '<strong>' + d.data.label + ': </strong> ' + d.value + ' (' + (d.value / sum * 100).toFixed(1) + '%)';
                                }
                                return tipStr;
                            })
                            .offset(function (d) {
                                return [-10, 0];
                            });

                        var texton = function (d) {
                            var textElemnt = d3.select(this).node();
                            tip.show(d, textElemnt);
                        };

                        var textoff = function (d) {
                            tip.hide();
                        };

                        var contrastingColor = function (d3Color) {
                            var yiq = ((d3Color.r * 299) + (d3Color.g * 587) + (d3Color.b * 114)) / 1000;
                            return (yiq >= 128) ? '#111111' : '#fafafa';
                        }

                        var arcs = svg.selectAll('g.arc')
                            .data(pie(data))
                            .enter()
                            .append('g')
                            .attr('class', 'arc')
                            .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

                        var sum = d3.sum(data, function (d) {
                            return d.value;
                        });

                        arcs.call(tip);

                        arcs.append('path')
                            .attr('fill', function (d, i) {
                                return colors(i);
                            })
                            .attr('d', arc)
                            .on('mouseover', function (d, i) {
                                //d3.select(this).remove();
                                //var savedSlice = d3.select(this);
                                //savedSlice.remove();
                                d3.select(this).style('stroke-width', 6);
                                d3.select(this).style('stroke', d3.rgb(colors(i)).brighter(0.7));
                                d3.select(this.parentNode).select('.arctext').each(texton);
                                d3.select(this.parentNode).moveToFront();

                            })
                            .on('mouseout', function (d) {
                                d3.select(this).style('stroke-width', 0);
                                if (tipOn) {
                                    tip.hide();
                                }
                            });

                        arcs.append('text')
                            .attr('transform', function (d, i) {
                                var centroid = arc.centroid(d);
                                var xc = centroid[0] * 1.5;
                                var yc = centroid[1] * 1.5 + 5;
                                return 'translate(' + xc + ',' + yc + ')';
                            })
                            .attr('class', 'arctext')
                            .attr('text-anchor', 'middle')
                            .text(function (d) {
                                // Only show text when the arc is large enough
                                if ((d.endAngle - d.startAngle) > 0.2) {
                                    return d.value;
                                }
                                else {
                                    return ' ';
                                }
                            })
                            .attr('fill', function (d, i) {
                                var gColor = d3.rgb(colors(i));
                                return contrastingColor(gColor);
                            })
                            .on('mouseover', texton)
                            .on('mouseout', textoff);

                        d3.selectAll('.arctext').call(tip);

                        // Add legend
                        var legend = svg.selectAll('g.legend')
                            .data(data)
                            .enter()
                            .append('g')
                            .attr('class', 'legends')
                            .attr('transform', function (d, i) {
                                return 'translate(' + ( width + margin.left ) + ',' + i * 20 + ')';
                            })
                            .style('fill', function (d, i) {
                                return colors(i);
                            });

                        legend.append('rect')
                            .attr('width', 18)
                            .attr('height', 18);

                        legend.append('text')
                            .attr('x', 20)
                            .attr('y', 9)
                            .attr('dy', '.35em')
                            .style('text-anchor', 'start')
                            .text(function (d) {
                                return d.label;
                            });
                    }
                }

                drawChart();

                scope.resize = function() {
					d3.select(element.find('.tip')[0]).selectAll().remove();
					d3.select(element.find('.pie-chart')[0]).selectAll('g').remove();
					drawChart();
                }

				window.addEventListener('resize', function(event){
                    clearTimeout(scope.resizetimeout);
                    scope.resizetimeout = setTimeout(scope.resize,100);
				});

                setTimeout(scope.resize,500);

			});
		}
	};
});<|endoftext|>


<commit_before>var t;
var isDocked;
var mainSettings;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// setting's block
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function loadSettings()
{
    mainSettings = new GetMainSettings();
    System.Gadget.onSettingsClosing = SettingsClosing;
    if(mainSettings.tamrielDays == "checked")
    {
        tamrielDays.checked = true;
    }
    if(mainSettings.whiteTheme == "checked")
    {
        whiteTheme.checked = true;
    }
    if(mainSettings.eng == "checked")
    {
        eng.checked = true;
    }
}

function SettingsClosing(event)
{
    if (event.closeAction == event.Action.commit)
    {
        System.Gadget.Settings.write("GadgetViewed","yes");
        SaveSettings();
    }
    else if(event.closeAction == event.Action.cancel)
    {
    }
    event.cancel = false;
}

////////////////////////////////////////////////////////////////////////////////
//
// save the new settings
//
////////////////////////////////////////////////////////////////////////////////
function SaveSettings()
{
    if(tamrielDays.checked)
    {
        mainSettings.tamrielDays = "checked";
    }
    else
    {
        mainSettings.tamrielDays = "unchecked";
    }
    if(whiteTheme.checked)
    {
        mainSettings.whiteTheme = "checked";
    }
    else
    {
        mainSettings.whiteTheme = "unchecked";
    }
    if(eng.checked)
    {
        mainSettings.eng = "checked";
    }
    else
    {
        mainSettings.eng = "unchecked";
    }
    SetMainSettings(mainSettings);
}

////////////////////////////////////////////////////////////////////////////////
//
// settings getter
//
////////////////////////////////////////////////////////////////////////////////
function GetMainSettings()
{
    this.tamrielDays = System.Gadget.Settings.read("tamriel's Days");
    this.whiteTheme  = System.Gadget.Settings.read("white Theme");
    this.eng  = System.Gadget.Settings.read("eng");
    this.gadgetViewed   = System.Gadget.Settings.read("GadgetViewed");

    // if(this.tamrielDays == "")
    // {
    //     this.tamrielDays="checked";
    // }
}

////////////////////////////////////////////////////////////////////////////////
//
// settings setter
//
////////////////////////////////////////////////////////////////////////////////
function SetMainSettings(settings)
{
    System.Gadget.Settings.write("tamriel's Days", settings.tamrielDays);
    System.Gadget.Settings.write("white Theme", settings.whiteTheme);
    System.Gadget.Settings.write("eng", settings.eng);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function loadmain() {
    System.Gadget.settingsUI = "settings.html";
    System.Gadget.onSettingsClosed = SettingsClosed;
    System.Gadget.onUndock = checkState;
    System.Gadget.onDock = checkState;
    checkState();
}

function checkState() {
    if (!System.Gadget.docked) undockedState();
    else dockedState();
}
function undockedState() {
    with(document.body.style) {
        width = "650px";
        height = "120px";
    }
    background.style.width = "650px";
    background.style.height = "120px";
    background.src = "url(images/background.png)";
    isDocked = false;
    setDate();
}
function dockedState() {
    with(document.body.style) {
        width = "200px";
        height = "120px";
    }
    background.style.width = "200px";
    background.style.height = "120px";
    background.src = "url(images/background.png)";
    isDocked = true;
    setDate();
}

function setDate() {
    var dayD = 15;
    var mjD = 16;
    function custom(arg) {
        // 1 - output of day(+options);
        // 2 - output of month(+options);
        // 3 - color;
        var output;
        switch(arg){
            case 1:
            if (System.Gadget.Settings.read("tamriel's Days") == 'checked') {
                dayD = 16;
                if (System.Gadget.Settings.read("eng") == 'checked') {
                    output = dayTmrlEn;
                } else {
                    output = dayTmrlRu;
                }
            } else {
                if (System.Gadget.Settings.read("eng") == 'checked') {
                    output = dayGregEn;
                    dayD = 16;
                } else {
                    output = dayGregRu;
                }
            }
            break;
            case 2:
            output = monthRu;
            if (System.Gadget.Settings.read("eng") == 'checked') {
                output = monthEn;
                mjD = 17;
            }
            break;
            case 3:
            output = 'Black';
            if (System.Gadget.Settings.read("white Theme") == 'checked') {
                output = 'White';
            }
            break;
        }
        return output;
    }
    function flmin() {
        var fullmin = mintxt;
        if (String(mintxt).length == 1) {
            fullmin = '0' + fullmin;
        }
        return fullmin;
    }
    System.Gadget.beginTransition();
    background.removeObjects();
    var dayGregRu = new Array("воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота");
    var dayGregEn = new Array("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday");
    var dayTmrlRu = new Array("Сандас", "Морндас", "Тирдас", "Миддас", "Турдас", "Фредас", "Лордас");
    var dayTmrlEn = new Array("Sundas", "Morndas", "Tirdas", "Middas", "Turdas", "Fredas", "Loredas");
    var monthRu = new Array("Утренней звезды", "Восхода солнца", "Первого зерна", "Руки дождя", "Второго зерна", "Середины года", "Высокого солнца", "Последнего зерна", "Огня очага", "Начала морозов", "Заката солнца", "Вечерней звезды");
    var monthEn = new Array("Morning Star", "Sun's Dawn", "First Seed", "Rain's Hand", "Second Seed", "Mid Year", "Sun's Height", "Last Seed", "Hearthfire", "Frostfall", "Sun's Dusk", "Evening Star");
    var nd = new Date;
    var hourtxt = (nd.getHours());
    var mintxt = (nd.getMinutes());
    var timetxt = (hourtxt + ':' + flmin());
    var daytxt = (custom(1)[nd.getDay()]);
    var datumtxt = (nd.getDate());
    var maandtxt = (custom(2)[nd.getMonth()]);
    var jaartxt = (nd.getYear());
    var color = custom(3);
    if (!isDocked) {
        var timeDisplay = background.addTextObject(timetxt, "Segoe UI", 110, color, 300, -40);
        timeDisplay.align = 2;
        var datumDisplay = background.addTextObject(datumtxt, "Segoe UI", 80, color, 365, -29);
        datumDisplay.align = 1;
        var dayDisplay = background.addTextObject(daytxt, "Segoe UI", 17, color, 365, 64);
        dayDisplay.align = 1;
        var maandjaarDisplay = background.addTextObject(maandtxt + ", " + jaartxt, "Segoe UI", 17, color, 411, 92);
        maandjaarDisplay.align = 2;
        t = setTimeout(setDate, 3000);
    } else {
        var dayDisplay = background.addTextObject(daytxt, "Segoe UI", dayD, color, 100, -3);
        dayDisplay.align = 1;
        var datumDisplay = background.addTextObject(datumtxt, "Segoe UI", 80, color, 100, -1);
        datumDisplay.align = 1;
        var maandjaarDisplay = background.addTextObject(maandtxt + ", " + jaartxt, "Segoe UI", mjD, color, 100, 95);
        maandjaarDisplay.align = 1;
        t = setTimeout(setDate, 3000);
    }
}<commit_msg>Update gadget.js<commit_after>var t;
var isDocked;
var mainSettings;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// setting's block
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function loadSettings()
{
    mainSettings = new GetMainSettings();
    System.Gadget.onSettingsClosing = SettingsClosing;
    if(mainSettings.tamrielDays == "checked")
    {
        tamrielDays.checked = true;
    }
    if(mainSettings.whiteTheme == "checked")
    {
        whiteTheme.checked = true;
    }
    if(mainSettings.eng == "checked")
    {
        eng.checked = true;
    }
}

function SettingsClosing(event)
{
    if (event.closeAction == event.Action.commit)
    {
        System.Gadget.Settings.write("GadgetViewed","yes");
        SaveSettings();
    }
    else if(event.closeAction == event.Action.cancel)
    {
    }
    event.cancel = false;
}

////////////////////////////////////////////////////////////////////////////////
//
// save the new settings
//
////////////////////////////////////////////////////////////////////////////////
function SaveSettings()
{
    if(tamrielDays.checked)
    {
        mainSettings.tamrielDays = "checked";
    }
    else
    {
        mainSettings.tamrielDays = "unchecked";
    }
    if(whiteTheme.checked)
    {
        mainSettings.whiteTheme = "checked";
    }
    else
    {
        mainSettings.whiteTheme = "unchecked";
    }
    if(eng.checked)
    {
        mainSettings.eng = "checked";
    }
    else
    {
        mainSettings.eng = "unchecked";
    }
    SetMainSettings(mainSettings);
}

////////////////////////////////////////////////////////////////////////////////
//
// settings getter
//
////////////////////////////////////////////////////////////////////////////////
function GetMainSettings()
{
    this.tamrielDays = System.Gadget.Settings.read("tamriel's Days");
    this.whiteTheme  = System.Gadget.Settings.read("white Theme");
    this.eng  = System.Gadget.Settings.read("eng");
    this.gadgetViewed   = System.Gadget.Settings.read("GadgetViewed");

    // if(this.tamrielDays == "")
    // {
    //     this.tamrielDays="checked";
    // }
}

////////////////////////////////////////////////////////////////////////////////
//
// settings setter
//
////////////////////////////////////////////////////////////////////////////////
function SetMainSettings(settings)
{
    System.Gadget.Settings.write("tamriel's Days", settings.tamrielDays);
    System.Gadget.Settings.write("white Theme", settings.whiteTheme);
    System.Gadget.Settings.write("eng", settings.eng);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function loadmain() {
    System.Gadget.settingsUI = "settings.html";
    System.Gadget.onSettingsClosed = SettingsClosed;
    System.Gadget.onUndock = checkState;
    System.Gadget.onDock = checkState;
    checkState();
}

function checkState() {
    if (!System.Gadget.docked) undockedState();
    else dockedState();
}
function undockedState() {
    with(document.body.style) {
        width = "650px";
        height = "120px";
    }
    background.style.width = "650px";
    background.style.height = "120px";
    background.src = "url(images/background.png)";
    isDocked = false;
    setDate();
}
function dockedState() {
    with(document.body.style) {
        width = "200px";
        height = "120px";
    }
    background.style.width = "200px";
    background.style.height = "120px";
    background.src = "url(images/background.png)";
    isDocked = true;
    setDate();
}

function setDate() {
    var dayD = 15;
    var mjD = 16;
    function custom(arg) {
        // 1 - output of day(+options);
        // 2 - output of month(+options);
        // 3 - color;
        var output;
        switch(arg){
            case 1:
            if (System.Gadget.Settings.read("tamriel's Days") == 'checked') {
                dayD = 16;
                if (System.Gadget.Settings.read("eng") == 'checked') {
                    output = dayTmrlEn;
                } else {
                    output = dayTmrlRu;
                }
            } else {
                if (System.Gadget.Settings.read("eng") == 'checked') {
                    output = dayGregEn;
                    dayD = 16;
                } else {
                    output = dayGregRu;
                }
            }
            break;
            case 2:
            output = monthRu;
            if (System.Gadget.Settings.read("eng") == 'checked') {
                output = monthEn;
                mjD = 17;
            }
            break;
            case 3:
            output = 'Black';
            if (System.Gadget.Settings.read("white Theme") == 'checked') {
                output = 'White';
            }
            break;
        }
        return output;
    }
    function flmin() {
        var fullmin = mintxt;
        if (String(mintxt).length == 1) {
            fullmin = '0' + fullmin;
        }
        return fullmin;
    }
    System.Gadget.beginTransition();
    background.removeObjects();
    var dayGregRu = new Array("воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота");
    var dayGregEn = new Array("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday");
    var dayTmrlRu = new Array("Сандас", "Морндас", "Тирдас", "Миддас", "Турдас", "Фредас", "Лордас");
    var dayTmrlEn = new Array("Sundas", "Morndas", "Tirdas", "Middas", "Turdas", "Fredas", "Loredas");
    var monthRu = new Array("Утренней звезды", "Восхода солнца", "Первого зерна", "Руки дождя", "Второго зерна", "Середины года", "Высокого солнца", "Последнего зерна", "Огня очага", "Начала морозов", "Заката солнца", "Вечерней звезды");
    var monthEn = new Array("Morning Star", "Sun's Dawn", "First Seed", "Rain's Hand", "Second Seed", "Mid Year", "Sun's Height", "Last Seed", "Hearthfire", "Frostfall", "Sun's Dusk", "Evening Star");
    var nd = new Date;
    var hourtxt = (nd.getHours());
    var mintxt = (nd.getMinutes());
    var timetxt = (hourtxt + ':' + flmin());
    var daytxt = (custom(1)[nd.getDay()]);
    var datumtxt = (nd.getDate());
    var maandtxt = (custom(2)[nd.getMonth()]);
    var jaartxt = (nd.getYear());
    var color = custom(3);
    if (!isDocked) {
        var timeDisplay = background.addTextObject(timetxt, "Segoe UI", 110, color, 500, -40);
        timeDisplay.align = 2;
        var datumDisplay = background.addTextObject(datumtxt, "Segoe UI", 80, color, 565, -29);
        datumDisplay.align = 1;
        var dayDisplay = background.addTextObject(daytxt, "Segoe UI", 17, color, 565, 64);
        dayDisplay.align = 1;
        var maandjaarDisplay = background.addTextObject(maandtxt + ", " + jaartxt, "Segoe UI", 17, color, 611, 92);
        maandjaarDisplay.align = 2;
        t = setTimeout(setDate, 3000);
    } else {
        var dayDisplay = background.addTextObject(daytxt, "Segoe UI", dayD, color, 100, -3);
        dayDisplay.align = 1;
        var datumDisplay = background.addTextObject(datumtxt, "Segoe UI", 80, color, 100, -1);
        datumDisplay.align = 1;
        var maandjaarDisplay = background.addTextObject(maandtxt + ", " + jaartxt, "Segoe UI", mjD, color, 100, 95);
        maandjaarDisplay.align = 1;
        t = setTimeout(setDate, 3000);
    }
}<|endoftext|>


<commit_before>(function() {
    'use strict';

    /**
     * Component for the home page.
     * @returns {directive}
     */
    var homeDirective = function() {
        return {
            restrict: 'E',
            scope: {},
            controller: 'vgHomeCtrl',
            controllerAs: 'homeVm',
            bindToController: true,
            templateUrl: '/veganaut/home/home.tpl.html'
        };
    };

    var homeCtrl = [
        '$scope', '$location', '$translate', 'backendService', 'angularPiwik',
        'mainMapService', 'geocodeService', 'alertService', 'localeService',
        function($scope, $location, $translate, backendService, angularPiwik,
            mainMapService, geocodeService, alertService, localeService)
        {
            var vm = this;

            /**
             * Zoom on the map used when we show the place returned
             * by the browser's geo location API.
             * @type {number}
             */
            var GEO_LOCATION_ZOOM = 15;

            // Expose the global methods we still need
            // TODO: find a better way to do this
            vm.legacyGlobals = {
                goToView: $scope.$parent.goToView,
                isLoggedIn: $scope.$parent.isLoggedIn
            };

            /**
             * Cta form input model
             * @type {string}
             */
            vm.ctaFormInput = '';

            /**
             * Whether we are currently running geo locating
             * @type {boolean}
             */
            vm.geolocating = false;

            /**
             * The target place to show on the map when submitting the cta form.
             * @type {{}}
             */
            var targetPlace;

            /**
             * Whether to clear the cta input field on the next focus event
             * @type {boolean}
             */
            var clearCtaInputOnFocus = true;

            /**
             * Uses the geocodeService to search for places with the given name
             * @param {string} searchInput
             * @returns {GeocodeResult[]}
             */
            vm.getSearchResults = function(searchInput) {
                // TODO: should use piwik's search tracking
                angularPiwik.track('home.cta', 'home.cta.searchStart');

                return geocodeService.search(searchInput).then(function(response) {
                    return response;
                });
            };

            /**
             * Whether the cta form can currently be submitted
             * @returns {boolean}
             */
            vm.canSubmitCta = function() {
                // Can only submit when we have a target and it's currently shown in the input field
                return (angular.isObject(targetPlace) && targetPlace.displayName === vm.ctaFormInput);
            };

            /**
             * Handler for when the user selects a result from the auto-complete.
             * @param {GeocodeResult} selected
             */
            vm.onResultSelected = function(selected) {
                // Set the target place
                targetPlace = {
                    lat: selected.lat,
                    lng: selected.lng,
                    boundingBox: selected.bounds,
                    displayName: selected.getDisplayName()
                };

                // We no longer want to clear the input field on focus
                clearCtaInputOnFocus = false;

                angularPiwik.track('home.cta', 'home.cta.selectResult');
            };

            /**
             * Handler for the focus event of the cta input.
             */
            vm.onCtaInputFocus = function() {
                if (clearCtaInputOnFocus) {
                    vm.ctaFormInput = '';
                }
            };

            /**
             * Handler for the blur event of the cta input.
             */
            vm.onCtaInputBlur = function() {
                // If the user leaves the input and we cannot submit the form
                // but we have a target place, set that place again
                if (!vm.canSubmitCta() && angular.isObject(targetPlace)) {
                    vm.ctaFormInput = targetPlace.displayName;
                }
            };

            /**
             * Handler for submission of the cta form.
             * Will go to the selected place on the map.
             */
            vm.onCtaSubmit = function() {
                mainMapService.setTargetPlace(targetPlace);
                $location.path('map');

                angularPiwik.track('home.cta', 'home.cta.submit');
            };

            /**
             * Gets the location from the browser's geolocation API
             * and sets the target place based on that.
             */
            vm.getUserLocation = function() {
                vm.geolocating = true;
                navigator.geolocation.getCurrentPosition(function(position) {
                    $scope.$apply(function() {
                        vm.geolocating = false;

                        // Extract the lat and lng
                        var lat = position.coords.latitude;
                        var lng = position.coords.longitude;

                        // Set the display name to some value that the user recognises it worked
                        vm.ctaFormInput = $translate.instant('home.callToAction.geolocate') +
                            ': ' + lat.toFixed(3) + ', ' + lng.toFixed(3)
                        ;

                        // Set the target place
                        targetPlace = {
                            lat: lat,
                            lng: lng,
                            zoom: GEO_LOCATION_ZOOM,
                            displayName: vm.ctaFormInput
                        };

                        // When the user focuses the input field, clear it
                        clearCtaInputOnFocus = true;

                        angularPiwik.track('home.geolocation', 'home.geolocation.found');
                    });
                }, function() {
                    $scope.$apply(function() {
                        vm.geolocating = false;
                        alertService.addAlert($translate.instant('message.geolocate.error'), 'danger');

                        angularPiwik.track('home.geolocation', 'home.geolocation.error');
                    });
                }, {
                    enableHighAccuracy: true,
                    timeout: 30000,
                    maximumAge: 0
                });

                angularPiwik.track('home.geolocation', 'home.geolocation.start');
            };

            // Get the location (country) from the backend
            // TODO: only do that if not already located (local storage?)
            backendService.getGeoIP(localeService.getLocale()).then(function(res) {
                var data = res.data;
                if (_.isObject(data)) {
                    vm.ctaFormInput = data.countryName;

                    targetPlace = {
                        lat: data.lat,
                        lng: data.lng,
                        boundingBox: data.boundingBox,
                        displayName: vm.ctaFormInput
                    };
                }
                // If nothing valid found, we can't do anything
            });
        }
    ];

    // Expose as directive
    angular.module('veganaut.app.home')
        .controller('vgHomeCtrl', homeCtrl)
        .directive('vgHome', [homeDirective])
    ;
})();
<commit_msg>Correctly handling when backend doesn't find the user's location based on the IP. Refs #186<commit_after>(function() {
    'use strict';

    /**
     * Component for the home page.
     * @returns {directive}
     */
    var homeDirective = function() {
        return {
            restrict: 'E',
            scope: {},
            controller: 'vgHomeCtrl',
            controllerAs: 'homeVm',
            bindToController: true,
            templateUrl: '/veganaut/home/home.tpl.html'
        };
    };

    var homeCtrl = [
        '$scope', '$location', '$translate', 'backendService', 'angularPiwik',
        'mainMapService', 'geocodeService', 'alertService', 'localeService',
        function($scope, $location, $translate, backendService, angularPiwik,
            mainMapService, geocodeService, alertService, localeService)
        {
            var vm = this;

            /**
             * Zoom on the map used when we show the place returned
             * by the browser's geo location API.
             * @type {number}
             */
            var GEO_LOCATION_ZOOM = 15;

            // Expose the global methods we still need
            // TODO: find a better way to do this
            vm.legacyGlobals = {
                goToView: $scope.$parent.goToView,
                isLoggedIn: $scope.$parent.isLoggedIn
            };

            /**
             * Cta form input model
             * @type {string}
             */
            vm.ctaFormInput = '';

            /**
             * Whether we are currently running geo locating
             * @type {boolean}
             */
            vm.geolocating = false;

            /**
             * The target place to show on the map when submitting the cta form.
             * @type {{}}
             */
            var targetPlace;

            /**
             * Whether to clear the cta input field on the next focus event
             * @type {boolean}
             */
            var clearCtaInputOnFocus = true;

            /**
             * Uses the geocodeService to search for places with the given name
             * @param {string} searchInput
             * @returns {GeocodeResult[]}
             */
            vm.getSearchResults = function(searchInput) {
                // TODO: should use piwik's search tracking
                angularPiwik.track('home.cta', 'home.cta.searchStart');

                return geocodeService.search(searchInput).then(function(response) {
                    return response;
                });
            };

            /**
             * Whether the cta form can currently be submitted
             * @returns {boolean}
             */
            vm.canSubmitCta = function() {
                // Can only submit when we have a target and it's currently shown in the input field
                return (angular.isObject(targetPlace) && targetPlace.displayName === vm.ctaFormInput);
            };

            /**
             * Handler for when the user selects a result from the auto-complete.
             * @param {GeocodeResult} selected
             */
            vm.onResultSelected = function(selected) {
                // Set the target place
                targetPlace = {
                    lat: selected.lat,
                    lng: selected.lng,
                    boundingBox: selected.bounds,
                    displayName: selected.getDisplayName()
                };

                // We no longer want to clear the input field on focus
                clearCtaInputOnFocus = false;

                angularPiwik.track('home.cta', 'home.cta.selectResult');
            };

            /**
             * Handler for the focus event of the cta input.
             */
            vm.onCtaInputFocus = function() {
                if (clearCtaInputOnFocus) {
                    vm.ctaFormInput = '';
                }
            };

            /**
             * Handler for the blur event of the cta input.
             */
            vm.onCtaInputBlur = function() {
                // If the user leaves the input and we cannot submit the form
                // but we have a target place, set that place again
                if (!vm.canSubmitCta() && angular.isObject(targetPlace)) {
                    vm.ctaFormInput = targetPlace.displayName;
                }
            };

            /**
             * Handler for submission of the cta form.
             * Will go to the selected place on the map.
             */
            vm.onCtaSubmit = function() {
                mainMapService.setTargetPlace(targetPlace);
                $location.path('map');

                angularPiwik.track('home.cta', 'home.cta.submit');
            };

            /**
             * Gets the location from the browser's geolocation API
             * and sets the target place based on that.
             */
            vm.getUserLocation = function() {
                vm.geolocating = true;
                navigator.geolocation.getCurrentPosition(function(position) {
                    $scope.$apply(function() {
                        vm.geolocating = false;

                        // Extract the lat and lng
                        var lat = position.coords.latitude;
                        var lng = position.coords.longitude;

                        // Set the display name to some value that the user recognises it worked
                        vm.ctaFormInput = $translate.instant('home.callToAction.geolocate') +
                            ': ' + lat.toFixed(3) + ', ' + lng.toFixed(3)
                        ;

                        // Set the target place
                        targetPlace = {
                            lat: lat,
                            lng: lng,
                            zoom: GEO_LOCATION_ZOOM,
                            displayName: vm.ctaFormInput
                        };

                        // When the user focuses the input field, clear it
                        clearCtaInputOnFocus = true;

                        angularPiwik.track('home.geolocation', 'home.geolocation.found');
                    });
                }, function() {
                    $scope.$apply(function() {
                        vm.geolocating = false;
                        alertService.addAlert($translate.instant('message.geolocate.error'), 'danger');

                        angularPiwik.track('home.geolocation', 'home.geolocation.error');
                    });
                }, {
                    enableHighAccuracy: true,
                    timeout: 30000,
                    maximumAge: 0
                });

                angularPiwik.track('home.geolocation', 'home.geolocation.start');
            };

            // Get the location (country) from the backend
            // TODO: only do that if not already located (local storage?)
            backendService.getGeoIP(localeService.getLocale()).then(function(res) {
                var data = res.data;
                if (_.isObject(data) && Object.keys(data) > 0) {
                    vm.ctaFormInput = data.countryName;

                    targetPlace = {
                        lat: data.lat,
                        lng: data.lng,
                        boundingBox: data.boundingBox,
                        displayName: vm.ctaFormInput
                    };
                }
                // If nothing valid found, we can't do anything
            });
        }
    ];

    // Expose as directive
    angular.module('veganaut.app.home')
        .controller('vgHomeCtrl', homeCtrl)
        .directive('vgHome', [homeDirective])
    ;
})();
<|endoftext|>


<commit_before> (function() {
     function seekBar($document) {
        var calculatePercent = function(seekBar, event) {
        var offsetX = event.pageX - seekBar.offset().left;
        var seekBarWidth = seekBar.width();
        var offsetXPercent = offsetX / seekBarWidth;
        offsetXPercent = Math.max(0, offsetXPercent);
        offsetXPercent = Math.min(1, offsetXPercent);
        return offsetXPercent;
    };
        return {
         templateUrl: '/templates/directives/seek_bar.html',
         replace: true,
         restrict: 'E',
         scope: {
            onChange: '&'
         },

         link: function(scope, element, attributes) {
             scope.value = 0;
             scope.max = 100;

             var seekBar = $(element);

             attributes.$observe('value', function(newValue) {
             scope.value = newValue;
            });

             attributes.$observe('max', function(newValue) {
             scope.max = newValue;
            });

             var percentString = function () {
                 var value = scope.value;
                 var max = scope.max;
                 var percent = value / max * 100;
                 return percent + "%";
             };

             scope.fillStyle = function() {
                 return {width: percentString()

                };
             };

             var notifyOnChange = function(newValue) {
                    if (typeof scope.onChange === 'function') {
                    scope.onChange({value: newValue});
                    }
                };

             scope.onClickSeekBar = function(event) {
                var percent = calculatePercent(seekBar, event);
                scope.value = percent * scope.max;
                notifyOnChange(scope.value);
            };

             scope.trackThumb = function() {
                $document.bind('mousemove.thumb', function(event) {
                    var percent = calculatePercent(seekBar, event);
                    scope.$apply(function() {
                        scope.value = percent * scope.max;
                        notifyOnChange(scope.value);
                    });
                });

                $document.bind('mouseup.thumb', function() {
                    $document.unbind('mousemove.thumb');
                    $document.unbind('mouseup.thumb');
                });
            };
         }
     };
 }

     angular
         .module('blocJams')
         .directive('seekBar', ['$document', seekBar]);
 })();<commit_msg>change to seekBar on 6/17<commit_after> (function() {
     function seekBar($document) {
        var calculatePercent = function(seekBar, event) {
        var offsetX = event.pageX - seekBar.offset().left;
        var seekBarWidth = seekBar.width();
        var offsetXPercent = offsetX / seekBarWidth;
        offsetXPercent = Math.max(0, offsetXPercent);
        offsetXPercent = Math.min(1, offsetXPercent);
        return offsetXPercent;
    };
        return {
         templateUrl: '/templates/directives/seek_bar.html',
         replace: true,
         restrict: 'E',
         scope: {
            onChange: '&'
         },

         link: function(scope, element, attributes) {
             scope.value = 0;
             scope.max = 100;

             var seekBar = $(element);

             attributes.$observe('value', function(newValue) {
             scope.value = newValue;
            });

             attributes.$observe('max', function(newValue) {
             scope.max = newValue;
            });

             var percentString = function () {
                 var value = scope.value;
                 var max = scope.max;
                 var percent = value / max * 100;
                 return percent + "%";
             };

             scope.fillStyle = function() {
                 return {width: percentString()};
             };

             scope.onClickSeekBar = function(event) {
                var percent = calculatePercent(seekBar, event);
                scope.value = percent * scope.max;
                notifyOnChange(scope.value);
            };

             scope.trackThumb = function() {
                $document.bind('mousemove.thumb', function(event) {
                    var percent = calculatePercent(seekBar, event);
                    scope.$apply(function() {
                        scope.value = percent * scope.max;
                        notifyOnChange(scope.value);
                    });
                });

                $document.bind('mouseup.thumb', function() {
                    $document.unbind('mousemove.thumb');
                    $document.unbind('mouseup.thumb');
                });
            };

             var notifyOnChange = function(newValue) {
                    if (typeof scope.onChange === 'function') {
                    scope.onChange({value: newValue});
                    }
                };
            }
        };
    }

     angular
         .module('blocJams')
         .directive('seekBar', ['$document', seekBar]);
 })();<|endoftext|>


<commit_before>var Seed = require('./seed');
var log = require('./log');
var dbmUtil = require('./util');
var Promise = require('bluebird');
var SeederInterface = require( './interface/seederInterface.js');

var internals = {};

Seeder = function (driver, seedsDir, versionControlled, intern) {
  this.driver = dbmUtil.reduceToInterface( driver, SeederInterface );
  this._driver = driver;
  this.seedDir = seedsDir;
  this.isVC = versionControlled;
  internals = intern;
};

Seeder.prototype = {

  seed: function (argv, callback) {

    if (this.isVC)
      this.up(argv, callback);
    else
      this._staticSeed(argv.destination, callback);
  },

  up: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, false, callback);
    } else {
      this.upToBy(funcOrOpts.destination, funcOrOpts.count, callback);
    }
  },

  down: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.downToBy(funcOrOpts.count, callback);
    }
  },

  /**
    * Statically call two methods from a static seeder.
    *
    * First: cleanSeeds
    * Second: seed
    *
    * It's highly recommended to not use version controlled seeders at the same
    * time as statics. While the cleanSeeds most of the time, the user executes
    * truncates or deletes on his database. A VC-Seeder can't detect this
    * and thus the state keeps the same, even if all changes of the VC-Seeder
    * are gone.
    *
    * Nevertheless, there is a possiblity to use static seeders together with
    * VC-Seeder, if you keep everything organized well at least.
    *
    * If a single seed is linked with it's tables and databases which it got
    * applied to, the state table of the seeds will automatically cleaned up.
    *
    */
  _staticSeed: function (partialName, callback) {

    var self = this;

    return Seed.loadFromFilesystem(self.seedDir, function(err, allSeeds) {

      if (err) {

        callback(err);
        return;
      }

      var toRun = dbmUtil.filterUp(allSeeds, [], partialName);

      if (toRun.length === 0) {
        log.info('No seeds to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(seeder) {
        log.verbose('preparing to run up seeder:', seeder.name);

        return self.driver.startMigration()
          .catch(callback)
          .then(function() {

            return (Promise.promisify(seeder.up.bind(seeder)))(self.driver, true);
          });
      })
      .catch(callback)
      .then(self.driver.endMigration.bind(self.driver))
      .catch(callback)
      .nodeify(callback);
    });
  },

  upToBy: function(partialName, count, callback) {

    var self = this;

    return Seed.loadFromFilesystem(self.seedDir, function(err, allMigrations) {

      if (err) { callback(err); return; }

      return Migration.loadFromDatabase(self.seedDir, self._driver, function(err, completedMigrations) {

        if (err) { callback(err); return; }
        var toRun = dbmUtil.filterUp(allMigrations, completedMigrations, partialName, count);

        if (toRun.length === 0) {
          log.info('No seeds to run');
          callback(null);
          return;
        }

        return Promise.resolve(toRun).each(function(seeder) {

          log.verbose('preparing to run up seeder:', seeder.name);

          return self.driver.startMigration()
          .then(function() {
            var setup = seeder.setup();

            if(typeof(setup) === 'function')
              setup(internals.seederOptions);

            return (Promise.promisify(self.up.bind(self)))(seeder.up.bind(seeder));
          })
          .then(self.driver.endMigration.bind(self.driver));
        })
        .catch(function(e) {

          throw e;
        })
        .nodeify(callback);

      });
    });
  },

  downToBy: function(count, callback) {
    var self = this;
    Seed.loadFromDatabase(self.seedDir, self._driver, function(err, completedMigrations) {
      if (err) { return callback(err); }

      var toRun = dbmUtil.filterDown(completedMigrations, count);

      if (toRun.length === 0) {
        log.info('No migrations to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(seeder) {

        log.verbose('preparing to run down seeder:', seeder.name);

        return self.driver.startMigration()
          .then(function() {

            var setup = seeder.setup();

            if(typeof(setup) === 'function')
              setup(internals.seederOptions);

            return (Promise.promisify(self.down.bind(self)))(seeder.down.bind(seeder));
          })
          .then(self.driver.endMigration.bind(self.driver));

      })
      .catch(function(e) {
        throw e;
      })
      .nodeify(callback);
    });
  }
};

module.exports = Seeder;
<commit_msg>add component for controlling vc seeder<commit_after>var Seed = require('./seed');
var log = require('./log');
var dbmUtil = require('./util');
var Promise = require('bluebird');
var SeederInterface = require( './interface/seederInterface.js');

var internals = {};

Seeder = function (driver, seedsDir, versionControlled, intern) {
  this.driver = dbmUtil.reduceToInterface( driver, SeederInterface );
  this._driver = driver;
  this.seedDir = seedsDir;
  this.isVC = versionControlled;
  internals = intern;
};

Seeder.prototype = {

  seed: function (argv, callback) {

    if (this.isVC)
      this.up(argv, callback);
    else
      this._staticSeed(argv.destination, callback);
  },

  up: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, false, callback);
    } else {
      this.upToBy(funcOrOpts.destination, funcOrOpts.count, callback);
    }
  },

  down: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.downToBy(funcOrOpts.count, callback);
    }
  },

  /**
    * Statically call two methods from a static seeder.
    *
    * First: cleanSeeds
    * Second: seed
    *
    * It's highly recommended to not use version controlled seeders at the same
    * time as statics. While the cleanSeeds most of the time, the user executes
    * truncates or deletes on his database. A VC-Seeder can't detect this
    * and thus the state keeps the same, even if all changes of the VC-Seeder
    * are gone.
    *
    * Nevertheless, there is a possiblity to use static seeders together with
    * VC-Seeder, if you keep everything organized well at least.
    *
    * If a single seed is linked with it's tables and databases which it got
    * applied to, the state table of the seeds will automatically cleaned up.
    *
    */
  _staticSeed: function (partialName, callback) {

    var self = this;

    return Seed.loadFromFilesystem(self.seedDir, function(err, allSeeds) {

      if (err) {

        callback(err);
        return;
      }

      var toRun = dbmUtil.filterUp(allSeeds, [], partialName);

      if (toRun.length === 0) {
        log.info('No seeds to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(seeder) {
        log.verbose('preparing to run up seeder:', seeder.name);

        return self.driver.startMigration()
          .catch(callback)
          .then(function() {

            return (Promise.promisify(seeder.up.bind(seeder)))(self.driver, true);
          });
      })
      .catch(callback)
      .then(self.driver.endMigration.bind(self.driver))
      .catch(callback)
      .nodeify(callback);
    });
  },

  deleteMigrationRecord: function(seed, callback) {
    function onComplete(err) {
      if (err) {
        log.error(seed.name, err);
      } else {
        log.info('Processed seed', seed.name);
      }
      callback(err);
    }
    this._driver.deleteSeed(this.internals.matching + '/' + seed.name, function(err) {

      if(!this.internals.matching) {

        this._driver.deleteSeed(seed.name, onComplete);
      }
      else {

        onComplete.apply(err);
      }
    }.bind(this));
  },

  upToBy: function(partialName, count, callback) {

    var self = this;

    return Seed.loadFromFilesystem(self.seedDir, function(err, allMigrations) {

      if (err) { callback(err); return; }

      return Seed.loadFromDatabase(self.seedDir, self._driver, function(err, completedSeeds) {

        if (err) { callback(err); return; }
        var toRun = dbmUtil.filterUp(allMigrations, completedSeeds, partialName, count);

        if (toRun.length === 0) {
          log.info('No seeds to run');
          callback(null);
          return;
        }

        return Promise.resolve(toRun).each(function(seeder) {

          log.verbose('preparing to run up seeder:', seeder.name);

          return self.driver.startMigration()
          .then(function() {
            var setup = seeder.setup();

            if(typeof(setup) === 'function')
              setup(internals.seederOptions);

            return (Promise.promisify(self.up.bind(self)))(seeder.up.bind(seeder));
          })
          .then(self.driver.endMigration.bind(self.driver));
        })
        .catch(function(e) {

          throw e;
        })
        .nodeify(callback);

      });
    });
  },

  downToBy: function(count, callback) {
    var self = this;
    Seed.loadFromDatabase(self.seedDir, self._driver, function(err, completedSeeds) {
      if (err) { return callback(err); }

      var toRun = dbmUtil.filterDown(completedSeeds, count);

      if (toRun.length === 0) {
        log.info('No migrations to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(seeder) {

        log.verbose('preparing to run down seeder:', seeder.name);

        return self.driver.startMigration()
          .then(function() {

            var setup = seeder.setup();

            if(typeof(setup) === 'function')
              setup(internals.seederOptions);

            return (Promise.promisify(self.down.bind(self)))(seeder.down.bind(seeder));
          })
          .then(self.driver.endMigration.bind(self.driver));

      })
      .catch(function(e) {
        throw e;
      })
      .nodeify(callback);
    });
  }
};

module.exports = Seeder;
<|endoftext|>


<commit_before>
/*!
 * Module dependencies.
 */

// Note: We can require users, articles and other cotrollers because we have
// set the NODE_PATH to be ./app/controllers (package.json # scripts # start)

var verts = require('../controllers/verts');
var express = require('express');
var config = require('../../../config/config');

var mongoose = require('mongoose')
var crudUtils = require('../../../lib/crudUtils');
var verts = mongoose.model('Verts');

// var comments = require('../app/controllers/comments');
// var tags = require('../app/controllers/tags');
var auth = require('../../../config/middlewares/authorization');

/**
 * Expose routes
 */

module.exports = function (app, passport, auth) {

  /**
   * Route middlewares
   */

  crudUtils.initRoutesForModel(app, verts, auth, '/verts')

}
<commit_msg>routes to push state.<commit_after>
/*!
 * Module dependencies.
 */

// Note: We can require users, articles and other cotrollers because we have
// set the NODE_PATH to be ./app/controllers (package.json # scripts # start)

var verts = require('../controllers/verts');

var mongoose = require('mongoose')
var crudUtils = require('../../../lib/crudUtils');
var VertsModel = mongoose.model('Verts');

var main = require('../../main/controllers/index');
var auth = require('../../../config/middlewares/authorization');

/**
 * Expose routes
 */

module.exports = function (app, passport, auth) {

  /**
   * Route middlewares
   */
  app.get('/verts', main.index);

  // Holder logic for working with uniqu links per route
  // app.param('id', articles.load);
  // app.get('/vert/:id', articles.show);
  // app.param('id', articles.load);
  // app.get('/vert/:id', articles.show);

  /**
   * Crud Operations With User Auth
   */
  crudUtils.initRoutesForModel(app, VertsModel, auth, '/verts/api')

}
<|endoftext|>