<commit_before>import React, { useEffect, useRef } from "react";
import styled from "styled-components";

const Planets = () => {
  const canvas = useRef(null);

  useEffect(() => {
    // Get the canvas for resizing
    const cvs = canvas.current;

    // Size canvas to the parent
    cvs.width = cvs.offsetWidth;
    cvs.height = cvs.offsetHeight;

    // Add new event listener for resize the canvas on window resize
    const resizeCanvas = () => {
      cvs.width = cvs.offsetWidth;
      cvs.height = cvs.offsetHeight;
    };
    window.addEventListener("resize", resizeCanvas);

    // Clean up event listener when dismounting the component
    return () => {
      window.removeEventListener("resize", resizeCanvas);
    };
  }, []);

  useEffect(() => {
    // Get the canvas and context
    const cvs = canvas.current;
    const ctx = cvs.getContext("2d");

    // Get center of the canvas
    const ctr = [cvs.width / 2, cvs.height / 2];

    // Background
    const grd = ctx.createLinearGradient(0, 0, 0, cvs.height);
    grd.addColorStop(0, "#110f33");
    grd.addColorStop(1, "#040103");
    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, cvs.width, cvs.height);

    // Generate all stars
    let stars = [];
    let numStars = 0;
    const maxNumStars = 150;
    while (numStars < maxNumStars) {
      const randomPoint = [
        cvs.width * Math.random(),
        cvs.height * Math.random()
      ];
      stars.push(randomPoint);
      numStars++;
    }

    // Draw stars
    stars.forEach(star => {
      ctx.beginPath();
      ctx.arc(...star, 1, 0, 2 * Math.PI);
      ctx.fillStyle = `rgba(255, 255, 255, ${Math.random()})`;
      ctx.fill();
      ctx.closePath();
    });

    // Draw triangle
    ctx.beginPath();
    ctx.moveTo(ctr[0], ctr[1] - 100);
    ctx.lineTo(ctr[0] + 100, ctr[1] + 75);
    ctx.lineTo(ctr[0] - 100, ctr[1] + 75);
    ctx.closePath();
    ctx.fillStyle = "white";
    ctx.fill();

    // Draw triangle
    ctx.beginPath();
    ctx.moveTo(ctr[0], ctr[1] - 25);
    ctx.lineTo(ctr[0] + 50, ctr[1] + 75);
    ctx.lineTo(ctr[0] - 50, ctr[1] + 75);
    ctx.closePath();
    ctx.fillStyle = "black";
    ctx.fill();
  }, []);

  return <Canvas ref={canvas} />;
};

export default Planets;

const Canvas = styled.canvas`
  width: 100%;
  height: 100%;
`;
<commit_msg>Trying some synthwave stuff<commit_after>import React, { useEffect, useRef } from "react";
import styled from "styled-components";

const Planets = () => {
  const canvas = useRef(null);

  useEffect(() => {
    // Get the canvas for resizing
    const cvs = canvas.current;

    // Size canvas to the parent
    cvs.width = cvs.offsetWidth;
    cvs.height = cvs.offsetHeight;

    // Add new event listener for resize the canvas on window resize
    const resizeCanvas = () => {
      cvs.width = cvs.offsetWidth;
      cvs.height = cvs.offsetHeight;
    };
    window.addEventListener("resize", resizeCanvas);

    // Clean up event listener when dismounting the component
    return () => {
      window.removeEventListener("resize", resizeCanvas);
    };
  }, []);

  useEffect(() => {
    // Get the canvas and context
    const cvs = canvas.current;
    const ctx = cvs.getContext("2d");

    // Get center of the canvas
    const ctr = [cvs.width / 2, cvs.height / 2];

    // Background
    const grd = ctx.createLinearGradient(0, 0, 0, cvs.height);
    grd.addColorStop(0, "#110f33");
    grd.addColorStop(1, "#040103");
    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, cvs.width, cvs.height);

    // Generate all stars
    let stars = [];
    let numStars = 0;
    const maxNumStars = 150;
    while (numStars < maxNumStars) {
      const randomPoint = [
        cvs.width * Math.random(),
        cvs.height * Math.random()
      ];
      stars.push(randomPoint);
      numStars++;
    }

    // Draw stars
    stars.forEach(star => {
      ctx.beginPath();
      ctx.arc(...star, 1, 0, 2 * Math.PI);
      ctx.fillStyle = `rgba(255, 255, 255, ${Math.random()})`;
      ctx.fill();
      ctx.closePath();
    });

    // Draw horizontal lines
    let currentLine = 0;
    let maxLines = 15;
    let start = cvs.height;
    let offset = 30;
    let quotient = 0.9;
    ctx.strokeStyle = "#dd299c";
    while (currentLine < maxLines) {
      start = start - offset;
      ctx.beginPath();
      ctx.moveTo(0, start);
      ctx.lineTo(cvs.width, start);
      ctx.stroke();
      offset = offset * quotient;
      currentLine++;
    }
    currentLine = 0;
    start = cvs.height;
    offset = 30;
    ctx.filter = "blur(3px)";
    while (currentLine < maxLines) {
      start = start - offset;
      ctx.beginPath();
      ctx.moveTo(0, start);
      ctx.lineTo(cvs.width, start);
      ctx.stroke();
      offset = offset * quotient;
      currentLine++;
    }
    ctx.filter = "none";

    // Draw triangle
    ctx.beginPath();
    ctx.moveTo(ctr[0], ctr[1] - 100);
    ctx.lineTo(ctr[0] + 100, ctr[1] + 75);
    ctx.lineTo(ctr[0] - 100, ctr[1] + 75);
    ctx.closePath();
    ctx.fillStyle = "#f28b42";
    ctx.fill();

    // Draw triangle
    ctx.beginPath();
    ctx.moveTo(ctr[0], ctr[1] - 25);
    ctx.lineTo(ctr[0] + 50, ctr[1] + 75);
    ctx.lineTo(ctr[0] - 50, ctr[1] + 75);
    ctx.closePath();
    ctx.fillStyle = "#fdf84f";
    ctx.fill();
  }, []);

  return <Canvas ref={canvas} />;
};

export default Planets;

const Canvas = styled.canvas`
  width: 100%;
  height: 100%;
`;
<|endoftext|>


<commit_before>import Shogi from '../shogi';

export default class Piece {
  constructor(type, x, y) {
    this.type = type;
    this.x = x;
    this.y = y;
  }

  promote() {
    this.type = this.usiPromoteTypes[this.type] || this.type;
    return this.type;
  }

  unpromote() {
    this.type = this.usiUnPromoteTypes[this.type] || this.type;
    return this.type;
  }

  usiMoveDef() {
    switch (this.type) {
    case 'p':
      return { just: [[0, -1]] };
    case 'P':
      return { just: [[0, 1]] };
    case 'l':
      return { fly: [[0, -1]] };
    case 'L':
      return { fly: [[0, 1]] };
    case 'n':
      return { just: [[-1, -2], [1, -2]] };
    case 'N':
      return { just: [[-1, 2], [1, 2]] };
    case 's':
      return { just: [[-1, -1], [-1, 0], [-1, 1], [1, -1], [1, 1]] };
    case 'S':
      return { just: [[1, -1], [1, 0], [1, 1], [-1, -1], [-1, 1]] };
    case 'g':
    case 'p+':
    case 'l+':
    case 'n+':
    case 's+':
      return { just: [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, 0]] };
    case 'G':
    case 'P+':
    case 'L+':
    case 'N+':
    case 'S+':
      return { just: [[1, -1], [1, 0], [1, 1], [0, -1], [0, 1], [-1, 0]] };
    case 'r':
    case 'R':
      return { fly: [[0, -1], [0, 1], [1, 0], [-1, 0]] };
    case 'b':
    case 'B':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]] };
    case 'r+':
    case 'R+':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]], just: [[1, -1], [1, 1], [-1, 1], [-1, -1]] };
    case 'b+':
    case 'B+':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]], just: [[1, -1], [1, 1], [-1, 1], [-1, -1]] };
    case 'k':
    case 'K':
      return { just: [[1, 1], [1, 0], [1, -1], [0, 1], [0, -1], [-1, -1], [-1, 0], [-1, 1]] };
    default:
      return undefined;
    }
  }

  usiPromoteTypes() {
    return {
      p: 'p+',
      l: 'l+',
      n: 'n+',
      s: 's+',
      b: 'b+',
      r: 'r+',
      P: 'P+',
      L: 'L+',
      N: 'N+',
      S: 'S+',
      B: 'B+',
      R: 'R+'
    };
  }

  usiUnPromoteTypes() {
    return {
      'p+': 'p',
      'l+': 'l',
      'n+': 'n',
      's+': 's',
      'b+': 'b',
      'r+': 'r',
      'P+': 'P',
      'L+': 'L',
      'N+': 'N',
      'S+': 'S',
      'B+': 'B',
      'R+': 'R'
    };
  }
};
<commit_msg>Remove import `Shogi`<commit_after>export default class Piece {
  constructor(type, x, y) {
    this.type = type;
    this.x = x;
    this.y = y;
  }

  promote() {
    this.type = this.usiPromoteTypes[this.type] || this.type;
    return this.type;
  }

  unpromote() {
    this.type = this.usiUnPromoteTypes[this.type] || this.type;
    return this.type;
  }

  usiMoveDef() {
    switch (this.type) {
    case 'p':
      return { just: [[0, -1]] };
    case 'P':
      return { just: [[0, 1]] };
    case 'l':
      return { fly: [[0, -1]] };
    case 'L':
      return { fly: [[0, 1]] };
    case 'n':
      return { just: [[-1, -2], [1, -2]] };
    case 'N':
      return { just: [[-1, 2], [1, 2]] };
    case 's':
      return { just: [[-1, -1], [-1, 0], [-1, 1], [1, -1], [1, 1]] };
    case 'S':
      return { just: [[1, -1], [1, 0], [1, 1], [-1, -1], [-1, 1]] };
    case 'g':
    case 'p+':
    case 'l+':
    case 'n+':
    case 's+':
      return { just: [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, 0]] };
    case 'G':
    case 'P+':
    case 'L+':
    case 'N+':
    case 'S+':
      return { just: [[1, -1], [1, 0], [1, 1], [0, -1], [0, 1], [-1, 0]] };
    case 'r':
    case 'R':
      return { fly: [[0, -1], [0, 1], [1, 0], [-1, 0]] };
    case 'b':
    case 'B':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]] };
    case 'r+':
    case 'R+':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]], just: [[1, -1], [1, 1], [-1, 1], [-1, -1]] };
    case 'b+':
    case 'B+':
      return { fly: [[1, 1], [1, -1], [-1, 1], [-1, -1]], just: [[1, -1], [1, 1], [-1, 1], [-1, -1]] };
    case 'k':
    case 'K':
      return { just: [[1, 1], [1, 0], [1, -1], [0, 1], [0, -1], [-1, -1], [-1, 0], [-1, 1]] };
    default:
      return undefined;
    }
  }

  usiPromoteTypes() {
    return {
      p: 'p+',
      l: 'l+',
      n: 'n+',
      s: 's+',
      b: 'b+',
      r: 'r+',
      P: 'P+',
      L: 'L+',
      N: 'N+',
      S: 'S+',
      B: 'B+',
      R: 'R+'
    };
  }

  usiUnPromoteTypes() {
    return {
      'p+': 'p',
      'l+': 'l',
      'n+': 'n',
      's+': 's',
      'b+': 'b',
      'r+': 'r',
      'P+': 'P',
      'L+': 'L',
      'N+': 'N',
      'S+': 'S',
      'B+': 'B',
      'R+': 'R'
    };
  }
};
<|endoftext|>


<commit_before>
var Vault=(function(){var parse=function(value){if(value===null||value===undefined){return undefined;}
if(value==="true"){return true;}
if(value==="false"){return false;}
if(!isNaN(value)){return parseFloat(value);}
if(value.indexOf&&(value.indexOf("{")===0||value.indexOf("[")===0)&&window.JSON!==undefined){return JSON.parse(value);}
return value;};var prepare=function(value){if(typeof value==="object"&&window.JSON!==undefined){return JSON.stringify(value);}
return value;};var notSupported=function(){return undefined;};var prepareSqlValue=function(value){if(isNaN(value)&&value.indexOf('"')<0){value='"'+value+'"';}
return value;};var parseKeyValueList=function(pair){var key,fields=[],values=[];for(key in pair){if(!key.match(/^\_/)){fields.push(key);values.push(prepareSqlValue(pair[key]));}}
return{fields:fields,values:values};};var setup=function(type){var storage;try{storage=window[type];try{var test=storage["foo"];}catch(e){storage=undefined;}}catch(e){storage=undefined;}
if(storage===undefined){return{get:notSupported,set:notSupported,remove:notSupported,clear:notSupported,list:notSupported,isSupported:function(){return false;}};}
return{get:function(key){var value=storage[key];return parse(value);},getAndRemove:function(key){var value=this.get(key);this.remove(key);return value;},set:function(key,value){try{return storage.setItem(key,prepare(value));}catch(e){console.warn("Can't write to local stoarge. Perhaps you're using your browser in private mode? Here's the error: ",e);}},remove:function(key){return storage.removeItem(key);},clear:function(){return storage.clear();},list:function(){var i,il=storage.length;if(il===0){console.log("0 items in "+type);return undefined;}
for(i in storage){console.log(i,"=",parse(storage[i]));}},isSupported:function(){return true;}};};var __db__;var db=function(){if(window.openDatabase===undefined){return{info:notSupported,open:notSupported,createTable:notSupported,dropTable:notSupported,sql:notSupported,get:notSupported,set:notSupported,remove:notSupported,clear:notSupported,list:notSupported,isSupported:function(){return false;}};}
return{info:function(){return __db__;},open:function(name,version,display_name,size){__db__=window.openDatabase(name,version,display_name,size);return __db__;},create:function(tables){var table;for(table in tables){var fields=tables[table];var sql='CREATE TABLE IF NOT EXISTS '+table+' ('+fields+')';this.sql(sql);}},drop:function(tables){var i,il=tables.length;for(i=0;i<il;i++){var table=tables[i];var sql='DROP TABLE '+table;this.sql(sql);}},get:function(args,success){var sql=[];var table;for(table in args){var fields=args[table];sql.push('SELECT '+fields+' FROM '+table);}
sql=sql.join(",");this.sql(sql,success);},set:function(args){var table;for(table in args){var values=args[table];var i,il=values.length;for(i=0;i<il;i++){var set=values[i];var pairs=parseKeyValueList(set);var sql;if(set.where!==undefined){var where=parseKeyValueList(set.where);var j,jl=pairs.fields.length,updates=[];for(j=0;j<jl;j++){updates.push(pairs.fields[j]+'='+pairs.values[j]);}
sql='UPDATE '+table+' SET '+updates.join(",")+' WHERE '+where.fields+'='+where.values;this.sql(sql);}else if(set.remove!==undefined){var rm={};rm[table]=[set.remove];this.remove(rm);}else{sql='INSERT INTO '+table+' ('+pairs.fields+') VALUES ('+pairs.values+')';this.sql(sql);}}}},remove:function(args){var table;for(table in args){var pairs=args[table];var i,il=pairs.length;for(i=0;i<il;i++){var values=pairs[i];var remove=parseKeyValueList(values);var sql='DELETE FROM '+table+' WHERE '+remove.fields+'='+remove.values;this.sql(sql);}}},clear:function(tables){var i,il=tables.length;for(i=0;i<il;i++){var table=tables[i];var sql='DELETE FROM '+table;this.sql(sql);}},sql:function(query,success){if(__db__===undefined){console.warn("No DB open. Open with:\nVault.DB.open(name, version, display_name, size);\nQuery: "+query);return false;}
success=success||function(){};console.log(query);__db__.transaction(function(tx){return tx.executeSql(query,[],function(tx,results){if(results.rows!==undefined){var i,il=results.rows.length;var res=[];for(i=0;i<il;i++){var row=results.rows.item(i);res.push(row);}
success(res);}});});},isSupported:function(){return true;}};};var cookie={get:function(cookie){var cookies=document.cookie.split(";");var c,cl=cookies.length;for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");if(pair[0]===cookie){return parse(pair[1]);}}
return undefined;},getAndRemove:function(key){var value=this.get(key);this.remove(key);return value;},set:function(key,value,milliseconds,path){var expires="";if(milliseconds!==undefined){var date=new Date();date.setMilliseconds(date.getMilliseconds()+milliseconds);expires="; expires="+date.toUTCString();}
value=prepare(value)+expires+(path===undefined?"":"; path="+path);document.cookie=key+"="+value;},remove:function(key){document.cookie=key+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';},clear:function(){var cookies=document.cookie.split(";");var c,cl=cookies.length;for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");this.remove(pair[0]);}},list:function(){var cookies=document.cookie.split(";");var c,cl=cookies.length;if(cl===0){console.log("No cookies set");return undefined;}
for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");console.log(pair[0],"=",parse(pair[1]));}}};return{Local:setup("localStorage"),Session:setup("sessionStorage"),DB:db(),Cookie:cookie};}());<commit_msg>updating minified version<commit_after>
var Vault=(function(){var parse=function(value){if(value===null||value===undefined){return undefined;}
if(value==="true"){return true;}
if(value==="false"){return false;}
if(!isNaN(value)){return parseFloat(value);}
if(value.indexOf&&(value.indexOf("{")===0||value.indexOf("[")===0)&&window.JSON!==undefined){return JSON.parse(value);}
return value;};var prepare=function(value){if(typeof value==="object"&&window.JSON!==undefined){return JSON.stringify(value);}
return value;};var notSupported=function(){return undefined;};var prepareSqlValue=function(value){if(isNaN(value)&&value.indexOf('"')<0){value='"'+value+'"';}
return value;};var parseKeyValueList=function(pair){var key,fields=[],values=[];for(key in pair){if(!key.match(/^\_/)){fields.push(key);values.push(prepareSqlValue(pair[key]));}}
return{fields:fields,values:values};};var setup=function(type){var storage;try{storage=window[type];try{var test=storage["foo"];}catch(e){storage=undefined;}}catch(e){storage=undefined;}
if(storage===undefined){return{get:notSupported,set:notSupported,remove:notSupported,clear:notSupported,list:notSupported,isSupported:function(){return false;}};}
return{get:function(key,default_value){var value=parse(storage[key]);if(value===undefined&&default_value){return default_value;}
return value;},getAndRemove:function(key){var value=this.get(key);this.remove(key);return value;},getList:function(){var list=[];var i,il=storage.length;for(i in storage){var item={};item[i]=parse(storage[i]);list.push(item);}
return list;},set:function(key,value){try{return storage.setItem(key,prepare(value));}catch(e){console.warn("Can't write to local stoarge. Perhaps you're using your browser in private mode? Here's the error: ",e);}},remove:function(key){return storage.removeItem(key);},clear:function(){return storage.clear();},list:function(){var i,il=storage.length;if(il===0){console.log("0 items in "+type);return undefined;}
for(i in storage){console.log(i,"=",parse(storage[i]));}},isSupported:function(){return true;}};};var __db__;var db=function(){if(window.openDatabase===undefined){return{info:notSupported,open:notSupported,createTable:notSupported,dropTable:notSupported,sql:notSupported,get:notSupported,set:notSupported,remove:notSupported,clear:notSupported,list:notSupported,isSupported:function(){return false;}};}
return{info:function(){return __db__;},open:function(name,version,display_name,size){__db__=window.openDatabase(name,version,display_name,size);return __db__;},create:function(tables){var table;for(table in tables){var fields=tables[table];var sql='CREATE TABLE IF NOT EXISTS '+table+' ('+fields+')';this.sql(sql);}},drop:function(tables){var i,il=tables.length;for(i=0;i<il;i++){var table=tables[i];var sql='DROP TABLE '+table;this.sql(sql);}},get:function(args,success){var sql=[];var table;for(table in args){var fields=args[table];sql.push('SELECT '+fields+' FROM '+table);}
sql=sql.join(",");this.sql(sql,success);},set:function(args){var table;for(table in args){var values=args[table];var i,il=values.length;for(i=0;i<il;i++){var set=values[i];var pairs=parseKeyValueList(set);var sql;if(set.where!==undefined){var where=parseKeyValueList(set.where);var j,jl=pairs.fields.length,updates=[];for(j=0;j<jl;j++){updates.push(pairs.fields[j]+'='+pairs.values[j]);}
sql='UPDATE '+table+' SET '+updates.join(",")+' WHERE '+where.fields+'='+where.values;this.sql(sql);}else if(set.remove!==undefined){var rm={};rm[table]=[set.remove];this.remove(rm);}else{sql='INSERT INTO '+table+' ('+pairs.fields+') VALUES ('+pairs.values+')';this.sql(sql);}}}},remove:function(args){var table;for(table in args){var pairs=args[table];var i,il=pairs.length;for(i=0;i<il;i++){var values=pairs[i];var remove=parseKeyValueList(values);var sql='DELETE FROM '+table+' WHERE '+remove.fields+'='+remove.values;this.sql(sql);}}},clear:function(tables){var i,il=tables.length;for(i=0;i<il;i++){var table=tables[i];var sql='DELETE FROM '+table;this.sql(sql);}},sql:function(query,success){if(__db__===undefined){console.warn("No DB open. Open with:\nVault.DB.open(name, version, display_name, size);\nQuery: "+query);return false;}
success=success||function(){};console.log(query);__db__.transaction(function(tx){return tx.executeSql(query,[],function(tx,results){if(results.rows!==undefined){var i,il=results.rows.length;var res=[];for(i=0;i<il;i++){var row=results.rows.item(i);res.push(row);}
success(res);}});});},isSupported:function(){return true;}};};var cookie={get:function(cookie,default_value){var cookies=document.cookie.split(";");var c,cl=cookies.length;for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");if(pair[0]===cookie){return parse(pair[1]);}}
return default_value;},getAndRemove:function(key){var value=this.get(key);this.remove(key);return value;},getList:function(){var list=[];var cookies=document.cookie.split(";");var c,cl=cookies.length;for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");var item={};item[pair[0]]=parse(pair[1]);list.push(item);}
return list;},set:function(key,value,milliseconds,path){var expires="";if(milliseconds!==undefined){var date=new Date();date.setMilliseconds(date.getMilliseconds()+milliseconds);expires="; expires="+date.toUTCString();}
value=prepare(value)+expires+(path===undefined?"":"; path="+path);document.cookie=key+"="+value;},remove:function(key){document.cookie=key+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';},clear:function(){var cookies=document.cookie.split(";");var c,cl=cookies.length;for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");this.remove(pair[0]);}},list:function(){var cookies=document.cookie.split(";");var c,cl=cookies.length;if(cl===0){console.log("No cookies set");return undefined;}
for(c=0;c<cl;c++){var pair=cookies[c].split("=");pair[0]=pair[0].replace(/^[ ]/,"");console.log(pair[0],"=",parse(pair[1]));}}};return{Local:setup("localStorage"),Session:setup("sessionStorage"),DB:db(),Cookie:cookie};}());<|endoftext|>


<commit_before>var map = L.map('map').setView([45.762858, 4.855000], 13);
        mapLink =
            'OpenStreetMap';
        L.tileLayer('http://{s}.tiles.mapbox.com/v3/kevinlecocq.jfk00chc/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors, CC-BY-SA, Imagery &copy Mapbox',
            maxZoom: 20
        	}).addTo(map);

	/* Initialize the SVG layer */
	map._initPathRoot();

	/* We simply pick up the SVG from the map object */
	var svg = d3.select("#map").select("svg"),
	g = svg.append("g");

	d3.json("wherearethebikes?q=Lyon", function(stations) {
		/* Add a LatLng object to each item in the dataset */
		stations.forEach(function(d) {
			d.LatLng = new L.LatLng(d.position.lat, d.position.lng);
		})

		/*var vertices = d3.range(stations.length).map(function(d, i) {
			return [stations[i].LatLng.lat, stations[i].LatLng.lng];
		});*/

		var voronoi = d3.geom.voronoi()
			.x(function(d) {
					return d.LatLng[0];
				})
			.y(function(d) {
					return d.LatLng[1];
				});

		voronoi(stations).forEach(function(d) { d.point.cell = d; });

		//var voronoiGraph = d3.geom.voronoi(vertices);

		var stationCircles = g.selectAll("circle")
			.data(stations)
			.enter().append("circle")
			.style("stroke", "black")
			.style("opacity", .6)
			.style("fill", function(d, i) {
				if(d.available_bikes) return "green";
				else return "red";
				})
			.attr("r", 3);

		/*var stationPaths = g.selectAll("path")
			.data(voronoi)
			.enter().append("svg:path")
			.attr("class", function(d, i) {
					return i ? "q" + (i % 9) + "-9" : null;
				})
			.attr("d", function(d) {
					return "M" + d.join("L") + "Z";
					//return "M" + d.source.LatLng.lat
				});*/
		var stationPaths = g.selectAll("path")
			.data(stations)
			.enter().append("svg:path")
			.attr("class", function(d, i) {
					return i ? "q" + (i % 9) + "-9" : null;
				})
			.attr("d", function(d) {
					return "M" + d.join("L") + "Z";
				});

		map.on("viewreset", update);
		update();

		function update() {
			stationCircles.attr("transform",
			function(d) {
				return "translate("+
					map.latLngToLayerPoint(d.LatLng).x +","+
					map.latLngToLayerPoint(d.LatLng).y +")";
				}
			)

			stationPaths.attr("transform",
					function(d) {
						return "translate(" +
							map.latLngToLayerPoint(new L.LatLng(d[0], d[1])).x +","+
							map.latLngToLayerPoint(new L.LatLng(d[0], d[1])).y +")";
					}
				)
		}
	})<commit_msg>Update index.js<commit_after>var map = L.map('map').setView([45.762858, 4.855000], 13);
mapLink =
    'OpenStreetMap';
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors, CC-BY-SA',
	minZoom:1,
    maxZoom: 19
}).addTo(map);

// Initialize the SVG layer
	map._initPathRoot();

	// svg selection
var svg = d3.select("#map").select("svg"),
	stationAreaGroup = svg.append("g"),
	stationPointGroup = svg.append("g");

d3.json("wherearethebikes?q=Lyon", function(stations) {

	stations.forEach(function(d) {
		d.LatLng = new L.LatLng(d.position.lat, d.position.lng);
	})

	var stationPoints = stationPointGroup.selectAll("circle")
		.data(stations)
		.enter().append("circle")
		.style("stroke", "black")
		.style("opacity", .6)
		.style("fill", function(d, i) {
			if(d.available_bikes) return "green";
			else return "red";
			})
		.attr("r", 2);

	var colorScale = d3.scale.linear()
							.range(["red", "yellow", "green"])
							.domain([0, 0.5, 1]);

	var stationAreas = stationAreaGroup.selectAll("path")
		.data(stations)
		.enter().append("svg:polygon")
		.attr("id", function(d, i) {
				return "station-" + i;
			})
		.attr("stroke-width", "0px")
		.attr("fill-opacity", "0.5")
		.attr("fill", function(d, i) {
				var bikeAvailability = d.available_bikes / d.bike_stands;
				var standAvailability = d.available_bike_stands / d.bike_stands;
				return colorScale(standAvailability);
			});

	map.on("viewreset", update);
	update();

	function update() {
		// Data reprojection
		stations.forEach(function(d, i) {
				var stationPoint = map.latLngToLayerPoint(d.LatLng);
				d.x = stationPoint.x;
				d.y = stationPoint.y;
			});

		//var pixelBounds = map.getPixelBounds();

		// Voronoi computation, clipped by the new map frame
		var voronoi = d3.geom.voronoi()
		.x(function(d) {
				return d.x;
			})
		.y(function(d) {
				return d.y;
			});
		//.clipExtent([[pixelBounds.min.x, pixelBounds.min.y], [pixelBounds.max.x, pixelBounds.max.y]]);

		voronoi(stations).forEach(function(d) {
				d.point.cell = d;
			});

		stationPoints.attr("transform", function(d) {
			return "translate("+ d.x +","+ d.y +")";
			}
		);

		stationAreas.attr("points", function(d) {
			var polygon = "";
			var first = true;
			for(var i = 0; i < d.cell.length; i++) {
				if(isNaN(d.cell[i][0]) || isNaN(d.cell[i][1])) return "";

				//var latLngPoint = new L.LatLng(d.cell[i][0], d.cell[i][1]);
				//var screenPoint = map.latLngToLayerPoint(latLngPoint);
				if(first) {
					first = false;
				} else {
					polygon += " ";
				}
				//polygon += screenPoint.x + "," + screenPoint.y;

				polygon += d.cell[i][0] + "," + d.cell[i][1];
			}
			return polygon;
		});

	}
});
<|endoftext|>


<commit_before>var Express = require("express");
var news = new Express.Router();
var moment = require("moment");
var exec = require("child_process").exec;
var fs = require("fs-extra");
var marked = require("marked");
var helper = require("helper");
var parse = require("body-parser").urlencoded({ extended: false });
var uuid = require("uuid/v4");
var config = require("config");
var client = require("client");

var listKey = "newsletter:list";
var TTL = 60 * 60 * 24; // 1 day in seconds

news.get("/", loadDone, loadToDo, function(req, res) {
  res.render("news");
});

news.get("/archive", function(req, res) {
  res.render("news/archive");
});

news.get("/archive/:letter", function(req, res) {
  res.render("news/archive");
});

// The rest of these pages should not be cached
news.use(function(req, res, next) {
  res.header("Cache-Control", "no-cache");
  next();
});

news.get("/sign-up", function(req, res) {
  if (req.session && req.session.newsletter_email) {
    res.locals.email = req.session.newsletter_email;
    delete req.session.newsletter_email;
  }

  res.render("news/sign-up");
});

news.get("/cancel", function(req, res) {
  if (req.session && req.session.newsletter_email) {
    res.locals.email = req.session.newsletter_email;
    delete req.session.newsletter_email;
  }

  res.render("news/cancel");
});

function confirmationKey(guid) {
  return "newsletter:confirm:" + guid;
}

function cancellationKey(guid) {
  return "newsletter:cancel:" + guid;
}

function confirmationLink(guid) {
  return "https://" + config.host + "/news/confirm/" + guid;
}

function cancellationLink(guid) {
  return "https://" + config.host + "/news/cancel/" + guid;
}

news.post("/cancel", parse, function(req, res, next) {
  var cancel, email, locals;
  var guid = uuid();

  if (!req.body || !req.body.email) {
    return next(new Error("No email"));
  }

  email = req.body.email.trim().toLowerCase();
  guid = guid.split("-").join("");
  guid = encodeURIComponent(guid);
  cancel = cancellationLink(guid);
  locals = { email: email, cancel: cancel };

  client.sismember(listKey, email, function(err, stat) {
    if (err || !stat) return next(err || new Error("No subscription found"));

    client.setex(cancellationKey(guid), TTL, email, function(err) {
      if (err) return next(err);

      helper.email.NEWSLETTER_CANCELLATION_CONFIRMATION(null, locals, function(
        err
      ) {
        if (err) return next(err);

        req.session.newsletter_email = email;
        res.redirect("/news/cancel");
      });
    });
  });
});

news.get("/cancel/:guid", function(req, res, next) {
  var guid = decodeURIComponent(req.params.guid);

  client.get(cancellationKey(guid), function(err, email) {
    if (err || !email) return next(err || new Error("No email"));

    client.srem(listKey, email, function(err) {
      if (err) return next(err);

      var locals = { email: email };

      helper.email.NEWSLETTER_CANCELLATION_CONFIRMED(null, locals, function(
        err
      ) {
        if (err) return next(err);

        client.del(cancellationKey(guid), function(err) {
          if (err) return next(err);

          res.locals.email = email;
          res.render("news/cancelled");
        });
      });
    });
  });
});

news.get("/confirm/:guid", function(req, res, next) {
  var guid = decodeURIComponent(req.params.guid);

  client.get(confirmationKey(guid), function(err, email) {
    if (err || !email) return next(err || new Error("No email"));

    client.sadd(listKey, email, function(err) {
      if (err) return next(err);

      var locals = {
        email: email,
        cancel: "https://" + config.host + "/news/cancel",
      };

      helper.email.NEWSLETTER_SUBSCRIPTION_CONFIRMED(null, locals, function(
        err
      ) {
        if (err) return next(err);

        client.del(confirmationKey(guid), function(err) {
          if (err) return next(err);
          res.locals.email = email;
          res.render("news/confirmed");
        });
      });
    });
  });
});

news.post("/sign-up", parse, function(req, res, next) {
  var confirm, email, locals;
  var guid = uuid();

  if (!req.body || !req.body.email) {
    return next(new Error("No email"));
  }

  email = req.body.email.trim().toLowerCase();
  guid = guid.split("-").join("");
  guid = encodeURIComponent(guid);
  confirm = confirmationLink(guid);
  locals = { email: email, confirm: confirm };

  client.setex(confirmationKey(guid), TTL, email, function(err) {
    if (err) return next(err);

    helper.email.NEWSLETTER_SUBSCRIPTION_CONFIRMATION(null, locals, function(
      err
    ) {
      if (err) return next(err);

      req.session.newsletter_email = email;
      res.redirect("/news/sign-up");
    });
  });
});

function loadToDo(req, res, next) {
  fs.readFile(__dirname + "/../../../todo.txt", "utf-8", function(err, todo) {
    if (err) return next(err);
    res.locals.todo = marked(todo);

    var html = res.locals.todo;
    var $ = require("cheerio").load(html);

    $("ul").each(function() {
      var ul = $(this).html();
      var p = $(this)
        .prev()
        .html();

      $(this)
        .prev()
        .remove();
      $(this).replaceWith(
        "" + p + "
" + ul + "
"
      );
    });

    res.locals.todo = $.html();
    return next();
  });
}

function loadDone(req, res, next) {
  exec("git log -100", { cwd: helper.rootDir }, function(err, output) {
    if (err) return next(err);

    output = output.split("\n\n");

    var commits = [];

    output.forEach(function(item, i) {
      if (i % 2 === 0) {
        var message = output[i + 1].trim();

        message = message[0].toUpperCase() + message.slice(1);

        // Ignores merge commits since they're not useful to readers
        if (
          message
            .split(" ")
            .join("")
            .toLowerCase()
            .indexOf("merge") > -1
        )
          return;

        // Ignores commits mentioning 'commit' since they're not useful to readers
        if (
          message
            .split(" ")
            .join("")
            .toLowerCase()
            .indexOf("commit") > -1
        )
          return;

        // Ignores commits to todo file since there are so many of them
        if (
          message
            .split(" ")
            .join("")
            .toLowerCase()
            .indexOf("todo") > -1
        )
          return;

        // Ignores commits with links since they're ugly
        if (
          message
            .split(" ")
            .join("")
            .toLowerCase()
            .indexOf("://") > -1
        )
          return;

        commits.push({
          author: item
            .slice(
              item.indexOf("Author:") + "Author:".length,
              item.indexOf("<")
            )
            .trim(),
          date: moment(
            new Date(item.slice(item.indexOf("Date:") + "Date:".length).trim())
          ).fromNow(),
          hash: item
            .slice(
              item.indexOf("commit ") + "commit ".length,
              item.indexOf("Author")
            )
            .trim(),
          message: message,
        });
      }
    });

    res.locals.commits = commits;
    next();
  });
}

module.exports = news;
<commit_msg>Tune up newsletter subscription UX<commit_after>var Express = require("express");
var news = new Express.Router();
var moment = require("moment");
var exec = require("child_process").exec;
var fs = require("fs-extra");
var marked = require("marked");
var helper = require("helper");
var parse = require("body-parser").urlencoded({ extended: false });
var uuid = require("uuid/v4");
var config = require("config");
var client = require("client");

var listKey = "newsletter:list";
var TTL = 60 * 60 * 24; // 1 day in seconds

news.get("/", loadDone, loadToDo, function (req, res) {
  res.render("news");
});

news.get("/archive", function (req, res) {
  res.render("news/archive");
});

news.get("/archive/:letter", function (req, res) {
  res.render("news/archive");
});

// The rest of these pages should not be cached
news.use(function (req, res, next) {
  res.header("Cache-Control", "no-cache");
  next();
});

news.get("/sign-up", function (req, res) {
  if (req.session && req.session.newsletter_email) {
    res.locals.email = req.session.newsletter_email;
    delete req.session.newsletter_email;
  } else {
    return res.redirect(req.baseUrl);
  }

  res.render("news/sign-up");
});

news.get("/cancel", function (req, res) {
  if (req.session && req.session.newsletter_email) {
    res.locals.email = req.session.newsletter_email;
    delete req.session.newsletter_email;
  }

  res.render("news/cancel");
});

function confirmationKey(guid) {
  return "newsletter:confirm:" + guid;
}

function cancellationKey(guid) {
  return "newsletter:cancel:" + guid;
}

function confirmationLink(guid) {
  return "https://" + config.host + "/news/confirm/" + guid;
}

function cancellationLink(guid) {
  return "https://" + config.host + "/news/cancel/" + guid;
}

// Removes guid from visible breadcrumbs
news.param("guid", function (req, res, next) {
  res.locals.breadcrumbs = res.locals.breadcrumbs.slice(0, -1);
  next();
});

news.post("/cancel", parse, function (req, res, next) {
  var cancel, email, locals;
  var guid = uuid();

  if (!req.body || !req.body.email) {
    return next(new Error("No email"));
  }

  email = req.body.email.trim().toLowerCase();
  guid = guid.split("-").join("");
  guid = encodeURIComponent(guid);
  cancel = cancellationLink(guid);
  locals = { email: email, cancel: cancel };

  client.sismember(listKey, email, function (err, stat) {
    if (err || !stat) return next(err || new Error("No subscription found"));

    client.setex(cancellationKey(guid), TTL, email, function (err) {
      if (err) return next(err);

      helper.email.NEWSLETTER_CANCELLATION_CONFIRMATION(null, locals, function (
        err
      ) {
        if (err) return next(err);

        req.session.newsletter_email = email;
        res.redirect("/news/cancel");
      });
    });
  });
});

news.get("/cancel/:guid", function (req, res, next) {
  var guid = decodeURIComponent(req.params.guid);

  client.get(cancellationKey(guid), function (err, email) {
    if (err || !email) return next(err || new Error("No email"));

    client.srem(listKey, email, function (err, removed) {
      if (err) return next(err);

      var locals = { email: email };

      res.locals.title = "Cancelled";
      res.locals.email = email;
      res.render("news/cancelled");

      if (removed) {
        helper.email.NEWSLETTER_CANCELLATION_CONFIRMED(
          null,
          locals,
          function () {
            // Email confirmation sent
          }
        );
      }
    });
  });
});

news.get("/confirm/:guid", function (req, res, next) {
  var guid = decodeURIComponent(req.params.guid);

  client.get(confirmationKey(guid), function (err, email) {
    if (err || !email) return next(err || new Error("No email"));

    client.sadd(listKey, email, function (err, added) {
      if (err) return next(err);

      var locals = {
        email: email,
        cancel: "https://" + config.host + "/news/cancel",
      };

      res.locals.title = "Confirmed";
      res.locals.email = email;
      res.render("news/confirmed");

      // The first time the user clicks the confirmation
      // link we send out a confirmation email, subsequent
      // clicks they just see the confirmation page.
      if (added) {
        helper.email.NEWSLETTER_SUBSCRIPTION_CONFIRMED(
          null,
          locals,
          function () {
            // Email confirmation sent
          }
        );
      }
    });
  });
});

news.post("/sign-up", parse, function (req, res, next) {
  var confirm, email, locals;
  var guid = uuid();

  if (!req.body || !req.body.email) {
    return next(new Error("No email"));
  }

  email = req.body.email.trim().toLowerCase();
  guid = guid.split("-").join("");
  guid = encodeURIComponent(guid);
  confirm = confirmationLink(guid);
  locals = { email: email, confirm: confirm };

  client.setex(confirmationKey(guid), TTL, email, function (err) {
    if (err) return next(err);

    helper.email.NEWSLETTER_SUBSCRIPTION_CONFIRMATION(null, locals, function (
      err
    ) {
      if (err) return next(err);

      req.session.newsletter_email = email;
      res.redirect("/news/sign-up");
    });
  });
});

function loadToDo(req, res, next) {
  fs.readFile(__dirname + "/../../../todo.txt", "utf-8", function (err, todo) {
    if (err) return next(err);
    res.locals.todo = marked(todo);

    var html = res.locals.todo;
    var $ = require("cheerio").load(html);

    $("ul").each(function () {
      var ul = $(this).html();
      var p = $(this).prev().html();

      $(this).prev().remove();
      $(this).replaceWith(
        "" + p + "
" + ul + "
"
      );
    });

    res.locals.todo = $.html();
    return next();
  });
}

function loadDone(req, res, next) {
  exec("git log -100", { cwd: helper.rootDir }, function (err, output) {
    if (err) return next(err);

    output = output.split("\n\n");

    var commits = [];

    output.forEach(function (item, i) {
      if (i % 2 === 0) {
        var message = output[i + 1].trim();

        message = message[0].toUpperCase() + message.slice(1);

        // Ignores merge commits since they're not useful to readers
        if (message.split(" ").join("").toLowerCase().indexOf("merge") > -1)
          return;

        // Ignores commits mentioning 'commit' since they're not useful to readers
        if (message.split(" ").join("").toLowerCase().indexOf("commit") > -1)
          return;

        // Ignores commits to todo file since there are so many of them
        if (message.split(" ").join("").toLowerCase().indexOf("todo") > -1)
          return;

        // Ignores commits with links since they're ugly
        if (message.split(" ").join("").toLowerCase().indexOf("://") > -1)
          return;

        commits.push({
          author: item
            .slice(
              item.indexOf("Author:") + "Author:".length,
              item.indexOf("<")
            )
            .trim(),
          date: moment(
            new Date(item.slice(item.indexOf("Date:") + "Date:".length).trim())
          ).fromNow(),
          hash: item
            .slice(
              item.indexOf("commit ") + "commit ".length,
              item.indexOf("Author")
            )
            .trim(),
          message: message,
        });
      }
    });

    res.locals.commits = commits;
    next();
  });
}

module.exports = news;
<|endoftext|>


<commit_before>var map;

Map = {

  available: function() {
    if (!window.GBrowserIsCompatible || !GBrowserIsCompatible()) return false;
    if (!map) Map.establish();
    return true;
  },

  load_and_refocus: function(markers) {
    markers = markers.compact();
    Map.set_bounds_from_lat_lngs(markers);
    Map.Gmap.clearOverlays();
    $.each(markers, function(){ Map.Gmap.addOverlay(this); });
  },

  add: function(markers) {
    markers = markers.compact();
    $.each(markers, function(){ Map.Gmap.addOverlay(this); });
  },

  establish: function(){
    map = Map.Gmap = new GMap2(document.getElementById("map_div"), {
      mapTypes: [G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP, G_NORMAL_MAP]  //G_NORMAL_MAP
    });
    // Map.Gmap.enableContinuousZoom();
    Map.Gmap.enableScrollWheelZoom();
    new GKeyboardHandler(Map.Gmap);
    var bRight = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(29,5));
    var bRightSnug = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5,5));
    var bLeftFurther = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(160,5));
    Map.Gmap.addControl(new GSmallZoomControl(), bRightSnug);
    Map.Gmap.addControl(new GMenuMapTypeControl(), bRight);
  },

  set_bounds_from_lat_lngs: function(items) {
    if (!Map.Gmap) return;  // for disconnected testing
    var latlngs = items.map(function(x){
      if(x.lat && x.lng) return new GLatLng(x.lat, x.lng);
      if(x.getLatLng) return x.getLatLng();
    }).compact();
    if (latlngs.length == 0) { alert('problem'); return; }
    var bounds = new GLatLngBounds(latlngs[0], latlngs[0]);
    for (var i=1; i < latlngs.length; i++) bounds.extend(latlngs[i]);
    var zoom = Map.Gmap.getBoundsZoomLevel(bounds);
    if (Viewer.item == agent_tag) {
      // center just above "me"
      if (zoom < 16) zoom = 16;
      var map_height = Map.Gmap.getSize().height;
      var mp = new GMercatorProjection(23);
      var me_marker_lat_lng = MapMarkers.cache[agent_tag].getLatLng();
      var me_marker_pixel = mp.fromLatLngToPixel(me_marker_lat_lng, zoom);
      var new_center_pixel = new GPoint(me_marker_pixel.x, me_marker_pixel.y - Math.round(map_height / 4));
      var new_center_lat_lng = mp.fromPixelToLatLng(new_center_pixel, zoom);
      Map.Gmap.setCenter(new_center_lat_lng, zoom);
    } else {
      Map.Gmap.setCenter(bounds.getCenter(), zoom);
    }
    if (!Map.initted) {
      components.trigger('map_init', Map.Gmap);
      Map.initted = true;
    }
  },

  replace_marker: function(old_marker, new_marker) {
    if (!Map.Gmap) return;  // for disconnected testing
    if (old_marker) Map.Gmap.removeOverlay(old_marker);
    if (new_marker) Map.Gmap.addOverlay(new_marker);
  }

};
<commit_msg>Prevent 'sorry' msg in satellite imagery in viewer's default view.<commit_after>var map;

Map = {

  available: function() {
    if (!window.GBrowserIsCompatible || !GBrowserIsCompatible()) return false;
    if (!map) Map.establish();
    return true;
  },

  load_and_refocus: function(markers) {
    markers = markers.compact();
    Map.set_bounds_from_lat_lngs(markers);
    Map.Gmap.clearOverlays();
    $.each(markers, function(){ Map.Gmap.addOverlay(this); });
  },

  add: function(markers) {
    markers = markers.compact();
    $.each(markers, function(){ Map.Gmap.addOverlay(this); });
  },

  establish: function(){
    map = Map.Gmap = new GMap2(document.getElementById("map_div"), {
      mapTypes: [G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP, G_NORMAL_MAP]  //G_NORMAL_MAP
    });
    // Map.Gmap.enableContinuousZoom();
    Map.Gmap.enableScrollWheelZoom();
    new GKeyboardHandler(Map.Gmap);
    var bRight = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(29,5));
    var bRightSnug = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5,5));
    var bLeftFurther = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(160,5));
    Map.Gmap.addControl(new GSmallZoomControl(), bRightSnug);
    Map.Gmap.addControl(new GMenuMapTypeControl(), bRight);
  },

  set_bounds_from_lat_lngs: function(items) {
    if (!Map.Gmap) return;  // for disconnected testing
    var latlngs = items.map(function(x){
      if(x.lat && x.lng) return new GLatLng(x.lat, x.lng);
      if(x.getLatLng) return x.getLatLng();
    }).compact();
    if (latlngs.length == 0) { alert('problem'); return; }
    var bounds = new GLatLngBounds(latlngs[0], latlngs[0]);
    for (var i=1; i < latlngs.length; i++) bounds.extend(latlngs[i]);
    var zoom = Map.Gmap.getBoundsZoomLevel(bounds);
    if (zoom > 18) zoom = 18; // prevent 'sorry' msg in satellite imagery
    if (Viewer.item == agent_tag) {
      // center just above "me"
      if (zoom < 16) zoom = 16;
      var map_height = Map.Gmap.getSize().height;
      var mp = new GMercatorProjection(23);
      var me_marker_lat_lng = MapMarkers.cache[agent_tag].getLatLng();
      var me_marker_pixel = mp.fromLatLngToPixel(me_marker_lat_lng, zoom);
      var new_center_pixel = new GPoint(me_marker_pixel.x, me_marker_pixel.y - Math.round(map_height / 4));
      var new_center_lat_lng = mp.fromPixelToLatLng(new_center_pixel, zoom);
      Map.Gmap.setCenter(new_center_lat_lng, zoom);
    } else {
      Map.Gmap.setCenter(bounds.getCenter(), zoom);
    }
    if (!Map.initted) {
      components.trigger('map_init', Map.Gmap);
      Map.initted = true;
    }
  },

  replace_marker: function(old_marker, new_marker) {
    if (!Map.Gmap) return;  // for disconnected testing
    if (old_marker) Map.Gmap.removeOverlay(old_marker);
    if (new_marker) Map.Gmap.addOverlay(new_marker);
  }

};
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { asField } from 'informed'
import styled, { withTheme } from 'styled-components'
import Downshift from 'downshift'
import { Box, Flex } from 'rebass'
import system from '@rebass/components'
import { Input, Text } from 'components/UI'
import Check from 'components/Icon/Check'
import AngleUp from 'components/Icon/AngleUp'
import AngleDown from 'components/Icon/AngleDown'

const SelectOptionList = styled.ul`
  padding: 0;
  margin-top: 4px;
  position: absolute;
  z-index: 2;
  width: 100%;
  max-height: 20rem;
  overflow-y: auto;
  overflow-x: hidden;
  outline: 0;
  transition: opacity 0.1s ease;
  background-color: ${props => props.theme.colors.secondaryColor};
  border-radius: 5px;
  box-shadow: 0 3px 4px 0 rgba(30, 30, 30, 0.5);
`

const SelectOptionItem = styled(
  system(
    {
      extend: Box,
      as: 'li',
      p: 2
    },
    'space',
    'color'
  )
)`
  outline: none;
  cursor: pointer;
`

const getIconStyles = props => `
  margin-left: -${props.width + 16}px;
  width: ${props.width}px;
  pointer-events: none;
  color: ${props.color || props.theme.colors.gray};
`

const ArrowIconClosed = styled(AngleDown)`
  ${props => getIconStyles(props)}
`

const ArrowIconOpen = styled(AngleUp)`
  ${props => getIconStyles(props)}
`

const StyledInput = styled(Input)`
  input {
    cursor: pointer;
    color: transparent;
    text-shadow: 0 0 0 ${props => props.color || props.theme.colors.primaryText};
  }
`

const itemToString = item => (item ? item.value : '')

/**
 * @render react
 * @name Select
 */
class Select extends React.PureComponent {
  static displayName = 'Select'

  static propTypes = {
    color: PropTypes.string,
    iconSize: PropTypes.number,
    initialSelectedItem: PropTypes.string,
    items: PropTypes.array,
    theme: PropTypes.object.isRequired,
    fieldApi: PropTypes.object.isRequired,
    fieldState: PropTypes.object.isRequired,
    onValueSelected: PropTypes.func.isRequired
  }

  static defaultProps = {
    items: [],
    iconSize: 8
  }

  inputRef = React.createRef()

  blurInput = () => {
    if (this.inputRef.current) {
      this.inputRef.current.blur()
    }
  }

  renderSelectOptions = (highlightedIndex, selectedItem, getItemProps) => {
    let { items, theme } = this.props

    return items.map((item, index) => (
      <SelectOptionItem
        key={item.key}
        {...getItemProps({
          key: item.key,
          index,
          item
        })}
        bg={highlightedIndex === index ? theme.colors.primaryColor : null}
        p={2}
      >
        <Flex alignItems="center" pr={2}>
          <Text width="20px" textAlign="center" color="superGreen">
            {selectedItem.key === item.key && <Check height="0.95em" />}
          </Text>
          <Text>{item.value}</Text>
        </Flex>
      </SelectOptionItem>
    ))
  }

  render() {
    let {
      fieldApi,
      iconSize,
      items,
      theme,
      color,
      onValueSelected,
      initialSelectedItem,
      ...rest
    } = this.props
    const { setValue, setTouched } = fieldApi

    let initialInputValue
    if (initialSelectedItem) {
      initialSelectedItem = items.find(i => i.key === initialSelectedItem)
      initialInputValue = itemToString(initialSelectedItem)
    }

    return (
      <Downshift
        itemToString={itemToString}
        // When an item is selected, set the item in the Informed form state.
        onSelect={item => {
          setValue(item.value)
          setTouched(true)
          if (onValueSelected) {
            onValueSelected(item.key)
          }
          this.blurInput()
        }}
        // If an invalid value has been typed into the input, set it back to the currently slected item.
        onInputValueChange={(inputValue, stateAndHelpers) => {
          if (inputValue && inputValue !== itemToString(stateAndHelpers.selectedItem)) {
            fieldApi.setValue(itemToString(stateAndHelpers.selectedItem))
          }
        }}
        initialInputValue={initialInputValue}
        initialSelectedItem={initialSelectedItem}
      >
        {({
          getInputProps,
          getItemProps,
          getMenuProps,
          isOpen,
          highlightedIndex,
          selectedItem,
          closeMenu,
          openMenu,
          toggleMenu
        }) => (

            <Flex alignItems="center">


<commit_before>/* globals UI */

var C = UI.Connectors;

class EditForm extends React.Component {
  constructor (props) {
    super(props);
    if (!props.connector) {
      this.state = {
        mode: 'connect'
      };
    }
  }
  connect () {
    this.props.onConnect();
  }
  render () {
    return (
      <C.View>
        <C.View.Sidebar>
          <UI.FormElements.Button text="Save" onClick={this.connect} />
        </C.View.Sidebar>
        <C.View.Content>

Adding a MYOB AccountRight Connector

Register for MYOB developer access at http://developer.myob.com/contact/register-for-myobapi-access/

Log into your my.myob.com account and choose the correct country.

Select 'Developer' from the top menu on the page.

Click on 'Register App'.

In Redirect URL use https://bouncer.hoist.io/bounce, fill out the rest of the form and click Register App.

Copy the Key into here

        </C.View.Content>
      </C.View>
    );
  }
}

window.EditForm = EditForm;
<commit_msg>fix scoping<commit_after>/* globals UI */

var C = UI.Connectors;

class EditForm extends React.Component {
  constructor (props) {
    super(props);
    if (!props.connector) {
      this.state = {
        mode: 'connect'
      };
    }
  }
  connect () {
    console.log('calling on connect');
    this.props.onConnect();
  }
  render () {
    return (
      <C.View>
        <C.View.Sidebar>
          <UI.FormElements.Button text="Save" onClick={()=>{
              return this.connect();
            }} />
        </C.View.Sidebar>
        <C.View.Content>

Adding a MYOB AccountRight Connector

Register for MYOB developer access at http://developer.myob.com/contact/register-for-myobapi-access/

Log into your my.myob.com account and choose the correct country.

Select 'Developer' from the top menu on the page.

Click on 'Register App'.

In Redirect URL use https://bouncer.hoist.io/bounce, fill out the rest of the form and click Register App.

Copy the Key into here

        </C.View.Content>
      </C.View>
    );
  }
}

window.EditForm = EditForm;
<|endoftext|>


<commit_before>import React from 'react'
import Fluxxor from 'fluxxor'
var FluxMixin = Fluxxor.FluxMixin(React)

export default React.createClass({
  mixins: [FluxMixin],

  getInitialState: function(){
    return {
      value: ""
    }
  },

  handleChange: function(event) {
    this.setState({value: event.target.value});
    this.props.onChange(this.state.value);
  },

  handleKeyDown: function(event) {
    if (event.which == 13) {
      this.getFlux().actions.addKeyword(this.props.chartID, this.state.value)
    }
  },

  render: function() {
    // var keyword = this.props.keyword
    // var index = this.props.id
    return (
        <input type="text" value={this.state.value} onChange={this.handleChange} onKeyDown={this.handleKeyDown}></input>
    )
  }
})
<commit_msg>Text field now clears when new keyword is entered<commit_after>import React from 'react'
import Fluxxor from 'fluxxor'
var FluxMixin = Fluxxor.FluxMixin(React)

export default React.createClass({
  mixins: [FluxMixin],

  getInitialState: function(){
    return {
      value: ""
    }
  },

  handleChange: function(event) {
    this.setState({value: event.target.value});
    this.props.onChange(this.state.value);
  },

  handleKeyDown: function(event) {
    if (event.which == 13) {
      this.getFlux().actions.addKeyword(this.props.chartID, this.state.value)
      this.setState({value: ""})
    }
  },

  render: function() {
    // var keyword = this.props.keyword
    // var index = this.props.id
    return (
        <input type="text" value={this.state.value} onChange={this.handleChange} onKeyDown={this.handleKeyDown}></input>
    )
  }
})
<|endoftext|>


<commit_before>import React from 'react';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import PageHeader from '../shared/PageHeader';
import Button from '../shared/Button';
import Emojify from '../shared/Emojify';
import permissions from '../../lib/permissions';

import Pipelines from './Pipelines';
import Members from './Members';

import TeamDeleteMutation from '../../mutations/TeamDelete';
import RelayBridge from '../../lib/RelayBridge';

class Show extends React.Component {
  static propTypes = {
    slug: React.PropTypes.string.isRequired,
    organization: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired
    }).isRequired,
    team: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      description: React.PropTypes.string,
      slug: React.PropTypes.string.isRequired,
      permissions: React.PropTypes.shape({
        teamUpdate: React.PropTypes.object.isRequired,
        teamDelete: React.PropTypes.object.isRequired
      }).isRequired
    })
  };

  static contextTypes = {
    router: React.PropTypes.object.isRequired
  };

  state = {
    removing: false
  };

  render() {
    // If the team doesn't exist, that means that it's just been deleted. And
    // since we require all the team to render this component, we'll just
    // short-circut the re-render when it's gone. This isn't great, maybe
    // there's a beter way?
    if(!this.props.team) {
      return null;
    }

    return (
      <DocumentTitle title={`${this.props.team.name} · ${this.props.organization.name} Team`}>

          <PageHeader>
            <PageHeader.Title><Emojify text={this.props.team.name} /></PageHeader.Title>
            <PageHeader.Description><Emojify text={this.props.team.description || "No description"} /></PageHeader.Description>
            <PageHeader.Menu>{this.renderMenu()}</PageHeader.Menu>
          </PageHeader>

          <Members team={this.props.team} className="mb4" />
          <Pipelines team={this.props.team} />

      </DocumentTitle>
    );
  }

  renderMenu() {
    return permissions(this.props.team.permissions).collect(
      {
        allowed: "teamUpdate",
        render: (idx) => (
          <PageHeader.Button key={idx} link={`/organizations/${this.props.organization.slug}/teams/${this.props.team.slug}/edit`}>Edit</PageHeader.Button>
        )
      },
      {
        allowed: "teamDelete",
        render: (idx) => (
          <PageHeader.Button key={idx} loading={this.state.removing ? "Deleting…" : false} onClick={this.handleRemoveTeamClick}>Delete</PageHeader.Button>
        )
      }
    )
  }

  handleRemoveTeamClick = () => {
    if(confirm("Delete this team?")) {
      // Show the removing indicator
      this.setState({ removing: true });

      var mutation = new TeamDeleteMutation({
        team: this.props.team
      });

      // Run the mutation
      Relay.Store.commitUpdate(mutation, {
        onSuccess: this.handleDeleteTeamMutationSuccess,
        onFailure: this.handleDeleteTeamMutationFailure
      });
    }
  }

  handleDeleteTeamMutationSuccess = (response) => {
    // Relay at the moment seems to have a hard time updating the _rootCallMap
    // when a NODE_DELETE mutation is required. The net result being, that if
    // you create a team with name "foo", delete it, then create it again, Relay won't be
    // able to find it again using the `team` root query. That's because it's cached
    // the slug "org-name/this-slug-name" and it's old relay ID. So when we go
    // to request it again, Relay is like "oh, I know about this slug, but it
    // was deleted, so I'll just return nothing.
    delete Relay.Store._storeData._cachedStore._rootCallMap.team[this.props.slug];

    // Update our RelayBridge with the new organization data (in this case, the
    // teams count will be reduced by 1)
    RelayBridge.update(`organization/${this.props.organization.slug}`, response.teamDelete.organization);

    // Redirect back to the index page
    this.context.router.push(`/organizations/${this.props.organization.slug}/teams`);
  }

  handleDeleteTeamMutationFailure = (transaction) => {
    // Hide the removing indicator
    this.setState({ removing: false });

    alert(transaction.getError());
  }
}

export default Relay.createContainer(Show, {
  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
	name
	slug
      }
    `,
    team: () => Relay.QL`
      fragment on Team {
        ${Pipelines.getFragment('team')}
        ${Members.getFragment('team')}
        ${TeamDeleteMutation.getFragment('team')}
        name
        description
        slug
        permissions {
          teamUpdate {
            allowed
          }
          teamDelete {
            allowed
          }
        }
      }
    `
  }
});
<commit_msg>Show a message when showing the "Everyone" team<commit_after>import React from 'react';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import PageHeader from '../shared/PageHeader';
import Panel from '../shared/Panel';
import Button from '../shared/Button';
import Emojify from '../shared/Emojify';
import permissions from '../../lib/permissions';

import Pipelines from './Pipelines';
import Members from './Members';

import TeamDeleteMutation from '../../mutations/TeamDelete';
import RelayBridge from '../../lib/RelayBridge';

class Show extends React.Component {
  static propTypes = {
    slug: React.PropTypes.string.isRequired,
    organization: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired
    }).isRequired,
    team: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      description: React.PropTypes.string,
      slug: React.PropTypes.string.isRequired,
      permissions: React.PropTypes.shape({
        teamUpdate: React.PropTypes.object.isRequired,
        teamDelete: React.PropTypes.object.isRequired
      }).isRequired
    })
  };

  static contextTypes = {
    router: React.PropTypes.object.isRequired
  };

  state = {
    removing: false
  };

  render() {
    // If the team doesn't exist, that means that it's just been deleted. And
    // since we require all the team to render this component, we'll just
    // short-circut the re-render when it's gone. This isn't great, maybe
    // there's a beter way?
    if(!this.props.team) {
      return null;
    }

    return (
      <DocumentTitle title={`${this.props.team.name} · ${this.props.organization.name} Team`}>

          <PageHeader>
            <PageHeader.Title><Emojify text={this.props.team.name} /></PageHeader.Title>
            <PageHeader.Description><Emojify text={this.props.team.description || "No description"} /></PageHeader.Description>
            <PageHeader.Menu>{this.renderMenu()}</PageHeader.Menu>
          </PageHeader>

          {this.renderMembers()}
          <Pipelines team={this.props.team} />

      </DocumentTitle>
    );
  }

  renderMenu() {
    return permissions(this.props.team.permissions).collect(
      {
        allowed: "teamUpdate",
        render: (idx) => (
          <PageHeader.Button key={idx} link={`/organizations/${this.props.organization.slug}/teams/${this.props.team.slug}/edit`}>Edit</PageHeader.Button>
        )
      },
      {
        allowed: "teamDelete",
        render: (idx) => (
          <PageHeader.Button key={idx} loading={this.state.removing ? "Deleting…" : false} onClick={this.handleRemoveTeamClick}>Delete</PageHeader.Button>
        )
      }
    )
  }

  renderMembers() {
    if(this.props.team.everyone) {
      return (
	<Panel className="mb4">
	  <Panel.Header>Members</Panel.Header>
	  <Panel.Section>This team is automatically managed by Buildkite so as you invite and remove users from your organization they are added and removed from this team.</Panel.Section>
	</Panel>
      )
    } else {
      return (
        <Members team={this.props.team} className="mb4" />
      );
    }
  }

  handleRemoveTeamClick = () => {
    if(confirm("Delete this team?")) {
      // Show the removing indicator
      this.setState({ removing: true });

      var mutation = new TeamDeleteMutation({
        team: this.props.team
      });

      // Run the mutation
      Relay.Store.commitUpdate(mutation, {
        onSuccess: this.handleDeleteTeamMutationSuccess,
        onFailure: this.handleDeleteTeamMutationFailure
      });
    }
  }

  handleDeleteTeamMutationSuccess = (response) => {
    // Relay at the moment seems to have a hard time updating the _rootCallMap
    // when a NODE_DELETE mutation is required. The net result being, that if
    // you create a team with name "foo", delete it, then create it again, Relay won't be
    // able to find it again using the `team` root query. That's because it's cached
    // the slug "org-name/this-slug-name" and it's old relay ID. So when we go
    // to request it again, Relay is like "oh, I know about this slug, but it
    // was deleted, so I'll just return nothing.
    delete Relay.Store._storeData._cachedStore._rootCallMap.team[this.props.slug];

    // Update our RelayBridge with the new organization data (in this case, the
    // teams count will be reduced by 1)
    RelayBridge.update(`organization/${this.props.organization.slug}`, response.teamDelete.organization);

    // Redirect back to the index page
    this.context.router.push(`/organizations/${this.props.organization.slug}/teams`);
  }

  handleDeleteTeamMutationFailure = (transaction) => {
    // Hide the removing indicator
    this.setState({ removing: false });

    alert(transaction.getError());
  }
}

export default Relay.createContainer(Show, {
  fragments: {
    organization: () => Relay.QL`
      fragment on Organization {
	name
	slug
      }
    `,
    team: () => Relay.QL`
      fragment on Team {
        ${Pipelines.getFragment('team')}
        ${Members.getFragment('team')}
        ${TeamDeleteMutation.getFragment('team')}
        name
        description
        slug
        everyone
        permissions {
          teamUpdate {
            allowed
          }
          teamDelete {
            allowed
          }
        }
      }
    `
  }
});
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react'
import Helmet from 'react-helmet'
import styled from 'styled-components'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router-dom'

import Header from 'components/Header'
import Footer from 'components/Footer'
import withProgressBar from 'components/ProgressBar'

const AppWrapper = styled.div`
  max-width: calc(768px + 16px * 2);
  margin: 0 auto;
  display: flex;
  min-height: calc(100vh - 172px); // min height for App wrapper should account for nav and footer
  padding: 0 16px;
  flex-direction: column;
`

export class App extends PureComponent {
  static propTypes = {
    children: PropTypes.node.isRequired
  }

  render () {
    return (

        <Helmet
          titleTemplate='%s - React.js Boilerplate'
          defaultTitle='React.js Boilerplate'
          meta={[
            { name: 'description', content: 'A React.js Boierlplate application with Redux' }
          ]}
        />

        <AppWrapper>
          {React.Children.toArray(this.props.children)}
        </AppWrapper>

    )
  }
}

export default withRouter(withProgressBar(App))
<commit_msg>ProgressBar not working right now. Removing<commit_after>import React, { PureComponent } from 'react'
import Helmet from 'react-helmet'
import styled from 'styled-components'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router-dom'

import Header from 'components/Header'
import Footer from 'components/Footer'

const AppWrapper = styled.div`
  max-width: calc(768px + 16px * 2);
  margin: 0 auto;
  display: flex;
  min-height: calc(100vh - 172px); // min height for App wrapper should account for nav and footer
  padding: 0 16px;
  flex-direction: column;
`

export class App extends PureComponent {
  static propTypes = {
    children: PropTypes.node.isRequired
  }

  render () {
    return (

        <Helmet
          titleTemplate='%s - React.js Boilerplate'
          defaultTitle='React.js Boilerplate'
          meta={[
            { name: 'description', content: 'A React.js Boierlplate application with Redux' }
          ]}
        />

        <AppWrapper>
          {React.Children.toArray(this.props.children)}
        </AppWrapper>

    )
  }
}

export default withRouter(App)
<|endoftext|>


<commit_before>/**
 *
 * App.react.js
 *
 * This component is the skeleton around the actual pages, and should only
 * contain code that should be seen on all pages. (e.g. navigation bar)
 *
 * NOTE: while this component should technically be a stateless functional
 * component (SFC), hot reloading does not currently support SFCs. If hot
 * reloading is not a necessity for you then you can refactor it and remove
 * the linting exception.
 */

import React from 'react';
import { Navbar } from 'react-bootstrap';

export default class App extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
  static propTypes = {
    children: React.PropTypes.node,
  };
  render() {
    return (

        <Navbar>
          <Navbar.Header>
            <Navbar.Brand>
              DoctorNow
            </Navbar.Brand>
          </Navbar.Header>
        </Navbar>
        {React.Children.toArray(this.props.children)}

    );
  }
}
<commit_msg>Force redirect to https<commit_after>/**
 *
 * App.react.js
 *
 * This component is the skeleton around the actual pages, and should only
 * contain code that should be seen on all pages. (e.g. navigation bar)
 *
 * NOTE: while this component should technically be a stateless functional
 * component (SFC), hot reloading does not currently support SFCs. If hot
 * reloading is not a necessity for you then you can refactor it and remove
 * the linting exception.
 */

import React from 'react';
import { Navbar } from 'react-bootstrap';

export default class App extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
  static propTypes = {
    children: React.PropTypes.node,
  };
  componentWillMount() {
    if (process.env.NODE_ENV === 'production' && window.location.protocol === 'http:') {
      window.location.replace('https://www.doctornow.io');
    }
  }
  render() {
    return (

        <Navbar>
          <Navbar.Header>
            <Navbar.Brand>
              DoctorNow
            </Navbar.Brand>
          </Navbar.Header>
        </Navbar>
        {React.Children.toArray(this.props.children)}

    );
  }
}
<|endoftext|>


<commit_before>'use strict';
const Parse = require('../../lib/parse');
const moment = require('moment');
const _ = require('lodash');

// 核销员管理
// cate 'dzp','zjd'
module.exports = app => {
    class CheckController extends app.Controller {

        * list() {
            const {ctx, service} = this;
            const team = ctx.user.team;
            console.log(ctx.session);
            const ret = {
                code: 200,
                data: {},
                options: {team}
            };
            const Check = Parse.Object.extend('check');

            const query = new Parse.Query(Check);
            query.equalTo('team', team);
            query.limit(100);
            query.descending('createdAt');// 先进先出，正序排列

            yield query.find().then(function (items) {

                const temp = [];

                _.forEach(items, function (n, i) {
                    const item = n.toJSON();

                    item.createdAt = ctx.helper.dateAt(n.createdAt, 'YYYY/MM/DD');
                    temp.push(item);
                });

                ret.data.items = temp;
            }, function (error) {

            });

            ctx.body = ret;

        }

        * save() {
            const {ctx, service} = this;
            const body = ctx.request.body;
            const ret = {
                code: 200,
                data: {}
            };

            console.log(ctx.session.uid);
            const Activity = Parse.Object.extend('activity');
            const activity = new Activity();

            if (body.objectId) {
                activity.id = body.objectId;
                yield app.redis.hdel('activitys', activity.id, function (e, b) {
                    console.log([e, b]);
                });
            } else {

            }

            activity.set('uid', ctx.session.uid);
            activity.set('status', 'draft');
            activity.set(body);

            ret.data = yield activity.save();
            ctx.body = ret;
        }

        // * get() {
        //     const {ctx, service} = this;
        //     const activityId = ctx.params.id;
        //     const ret = {
        //         code: 200,
        //         data: yield service.activity.get(activityId)
        //     };
        //     ctx.body = ret;
        // }

        * delete() {
            const {ctx, service} = this;
            const checkid = ctx.params.id;
            const ret = {
                code: 200,
                message: '操作成功'
            };
            const query = new Parse.Query('check');
            query.equalTo('objectId', checkid);
            query.equalTo('team', ctx.session.team);
            yield query.first().then(function (item) {
                console.log(item)
                return item.destroy();

            }, function (err) {

                ret.code = 100002;
                ret.message = '没权限操作';
            });

            ctx.body = ret;
        }

    }

    return CheckController;
};
<commit_msg>add vue<commit_after>'use strict';
const Parse = require('../../lib/parse');
const moment = require('moment');
const _ = require('lodash');

// 核销员管理
// cate 'dzp','zjd'
module.exports = app => {
    class CheckController extends app.Controller {

        * list() {
            const {ctx, service} = this;
            const team = ctx.user.team;
            console.log(ctx.session);
            const ret = {
                code: 200,
                data: {},
                options: {team}
            };
            const Check = Parse.Object.extend('check');

            const query = new Parse.Query(Check);
            query.equalTo('team', team);
            query.limit(100);
            query.descending('createdAt');// 先进先出，正序排列

            yield query.find().then(function (items) {

                const temp = [];

                _.forEach(items, function (n, i) {
                    const item = n.toJSON();

                    item.createdAt = ctx.helper.dateAt(n.createdAt, 'YYYY/MM/DD');
                    temp.push(item);
                });

                ret.data.items = temp;
            }, function (error) {

            });

            ctx.body = ret;

        }

        * save() {
            const {ctx, service} = this;
            const body = ctx.request.body;
            const ret = {
                code: 200,
                data: {}
            };

            console.log(ctx.session.uid);
            const Activity = Parse.Object.extend('activity');
            const activity = new Activity();

            if (body.objectId) {
                activity.id = body.objectId;
                yield app.redis.hdel('activitys', activity.id, function (e, b) {
                    console.log([e, b]);
                });
            } else {

            }

            activity.set('uid', ctx.session.uid);
            activity.set('status', 'draft');
            activity.set(body);

            ret.data = yield activity.save();
            ctx.body = ret;
        }

        // * get() {
        //     const {ctx, service} = this;
        //     const activityId = ctx.params.id;
        //     const ret = {
        //         code: 200,
        //         data: yield service.activity.get(activityId)
        //     };
        //     ctx.body = ret;
        // }

        * delete() {
            const {ctx, service} = this;
            const checkid = ctx.params.id;
            const ret = {
                code: 200,
                message: '操作成功'
            };
            const query = new Parse.Query('check');
            query.equalTo('objectId', checkid);
            query.equalTo('team', ctx.session.team);

            console.log(checkid)
            console.log(ctx.session.team)
            yield query.first().then(function (item) {
                console.log(item)
                if(item){
                    return item.destroy();
                }else{
                    ret.code = 100002;
                    ret.message = '没权限操作'
                }

            }, function (err) {

                ret.code = 100002;
                ret.message = '没权限操作';
            });

            ctx.body = ret;
        }

    }

    return CheckController;
};
<|endoftext|>


<commit_before>
var mongoose = require('mongoose')
  , Article = mongoose.model('Article')

// New article
exports.new = function(req, res){
  res.render('articles/new', {
    title: 'New Article',
    article: new Article({})
  })
}

// Create an article
exports.create = function (req, res) {
  var article = new Article(req.body.article)
  article.user = req.user

  article.save(function(err){
    if (err) {
      res.render('articles/new', {
          title: 'New Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/article/'+article._id)
    }
  })
}

// Edit an article
exports.edit = function (req, res) {
  res.render('articles/edit', {
    title: 'Edit '+req.article.title,
    article: req.article
  })
}

// Update article
exports.update = function(req, res){
  var article = req.article

  article.save(function(err, doc) {
    if (err) {
      utils.mongooseErrorHandler(err, req)
      res.render('articles/edit', {
          title: 'Edit Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/article/'+article._id)
    }
  })
}

// View an article
exports.show = function(req, res){
  res.render('articles/show', {
    title: req.article.title,
    article: req.article,
    comments: req.comments
  })
}

// Delete an article
exports.destroy = function(req, res){
  var article = req.article
  article.remove(function(err){
    // req.flash('notice', 'Deleted successfully')
    res.redirect('/articles')
  })
}

// Listing of Articles
exports.index = function(req, res){
  Article
    .find({})
    .populate('user')
    .populate('comments')
    .sort({'created_at': -1}) // sort by date
    .exec(function(err, articles) {
      if (err) throw err
      res.render('articles/index', {
        title: 'List of Articles',
        articles: articles
      })
    })
}

<commit_msg>use REST format paths<commit_after>
var mongoose = require('mongoose')
  , Article = mongoose.model('Article')

// New article
exports.new = function(req, res){
  res.render('articles/new', {
      title: 'New Article'
    , article: new Article({})
  })
}

// Create an article
exports.create = function (req, res) {
  var article = new Article(req.body)
  article.user = req.user

  article.save(function(err){
    if (err) {
      res.render('articles/new', {
          title: 'New Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/articles/'+article._id)
    }
  })
}

// Edit an article
exports.edit = function (req, res) {
  res.render('articles/edit', {
    title: 'Edit '+req.article.title,
    article: req.article
  })
}

// Update article
exports.update = function(req, res){
  var article = req.article

  article.save(function(err, doc) {
    if (err) {
      res.render('articles/edit', {
          title: 'Edit Article'
        , article: article
        , errors: err.errors
      })
    }
    else {
      res.redirect('/articles/'+article._id)
    }
  })
}

// View an article
exports.show = function(req, res){
  res.render('articles/show', {
    title: req.article.title,
    article: req.article,
    comments: req.comments
  })
}

// Delete an article
exports.destroy = function(req, res){
  var article = req.article
  article.remove(function(err){
    // req.flash('notice', 'Deleted successfully')
    res.redirect('/articles')
  })
}

// Listing of Articles
exports.index = function(req, res){
  Article
    .find({})
    .populate('user')
    .populate('comments')
    .sort({'created_at': -1}) // sort by date
    .exec(function(err, articles) {
      if (err) throw err
      res.render('articles/index', {
        title: 'List of Articles',
        articles: articles
      })
    })
}

<|endoftext|>


<commit_before>'use strict';

var http = require('http');
var path = require('path');

var selenium = require('selenium-standalone');
var nodeStatic = require('node-static');
var assign = require('object-assign');

var grid, staticServer, capabilities;

if (process.env.CI === 'true') {

    capabilities = [{
        browserName: 'firefox',
        version: '41',
        platform: 'OS X 10.11'
    }, {
        browserName: 'firefox',
        version: '40',
        platform: 'OS X 10.11'
    }, {
        browserName: 'chrome',
        version: '46',
        platform: 'OS X 10.11'
    }, {
        browserName: 'chrome',
        version: '45',
        platform: 'OS X 10.11'
    }, {
        browserName: 'safari',
        version: '9',
        platform: 'OS X 10.11'
    }, {
        browserName: 'safari',
        version: '8',
        platform: 'OS X 10.10'
    }, {
        browserName: 'microsoftedge',
        version: '20.10240',
        platform: 'Windows 10'
    }, {
        browserName: 'internet explorer',
        version: '11.0',
        platform: 'Windows 10'
    }, {
        browserName: 'internet explorer',
        version: '10.0',
        platform: 'Windows 8'
    }, {
        browserName: 'internet explorer',
        version: '9.0',
        platform: 'Windows 7'
    }, {
        browserName: 'iphone',
        version: '9.0',
        platform: 'OS X 10.10',
        deviceName: 'iPhone 6 Plus',
        deviceOrientation: 'portrait'
    }, {
        browserName: 'iphone',
        version: '8.4',
        platform: 'OS X 10.10',
        deviceName: 'iPhone 6 Plus',
        deviceOrientation: 'portrait'
    }].map(function (capability) {
        return assign(capability, {
            'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
            name: 'integration',
            build: process.env.TRAVIS_BUILD_NUMBER,
            public: true
        });
    });

} else {
    capabilities = [{
        browserName: 'chrome'
    }];
}

function startStaticServer (cb) {
    return new Promise(function (resolve, reject) {
        var file = new nodeStatic.Server('./test/site');
        var server = http.createServer(function (request, response) {
            request.addListener('end', function () {
                file.serve(request, response);
            }).resume();
        }).listen(8080, function (err) {
            if (err) {
                return reject(err);
            }
            staticServer = server;
            resolve(server);
        });
    });
}

function startSelenium (cb) {
    return new Promise(function (resolve, reject) {
        selenium.start(function (err, sel) {
            if (err) {
                return reject(err);
            }
            grid = sel;
            resolve(sel);
        });
    });
}

var plugin = path.resolve(__dirname, 'index.js');

var config = {

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: [
        './test/spec/**/*.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilties at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude option in
    // order to group specific specs to a specific capability.
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: capabilities,
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity.
    logLevel: 'silent',
    //
    // Enables colors for log output.
    coloredLogs: true,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Set a base URL in order to shorten url command calls. If your url parameter starts
    // with "/", the base url gets prepended.
    baseUrl: 'http://localhost:8080',
    //
    // Default timeout for all waitForXXX commands.
    waitforTimeout: 10000,
    //
    // Initialize the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as property. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    plugins: {
    },
    //
    // Framework you want to run your specs with.
    // The following are supported: mocha, jasmine and cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the node package for the specific framework installed before running
    // any tests. If not please install the following package:
    // Mocha: `$ npm install mocha`
    // Jasmine: `$ npm install jasmine`
    // Cucumber: `$ npm install cucumber`
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The following are supported: dot (default), spec and xunit
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    reporter: process.env.CI ? 'dot' : 'spec',

    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd',
        timeout: process.env.CI ? 100000 : 10000
    },

    //
    // =====
    // Hooks
    // =====
    // Run functions before or after the test. If one of them returns with a promise, WebdriverIO
    // will wait until that promise got resolved to continue.
    // see also: http://webdriver.io/guide/testrunner/hooks.html
    //
    // Gets executed before all workers get launched.
    onPrepare: function() {
        return Promise.all([
            startSelenium(),
            startStaticServer()
        ]);
    },
    //
    // Gets executed before test execution begins. At this point you will have access to all global
    // variables like `browser`. It is the perfect place to define custom commands.
    before: function() {
        // do something
    },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    after: function(failures, pid) {
    },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    onComplete: function() {
        grid.kill();
        staticServer.close();
    }
};

config.plugins[plugin] = {};

exports.config = config;
<commit_msg>Remove ios9 testing<commit_after>'use strict';

var http = require('http');
var path = require('path');

var selenium = require('selenium-standalone');
var nodeStatic = require('node-static');
var assign = require('object-assign');

var grid, staticServer, capabilities;

if (process.env.CI === 'true') {

    capabilities = [{
        browserName: 'firefox',
        version: '41',
        platform: 'OS X 10.11'
    }, {
        browserName: 'firefox',
        version: '40',
        platform: 'OS X 10.11'
    }, {
        browserName: 'chrome',
        version: '46',
        platform: 'OS X 10.11'
    }, {
        browserName: 'chrome',
        version: '45',
        platform: 'OS X 10.11'
    }, {
        browserName: 'safari',
        version: '9',
        platform: 'OS X 10.11'
    }, {
        browserName: 'safari',
        version: '8',
        platform: 'OS X 10.10'
    }, {
        browserName: 'microsoftedge',
        version: '20.10240',
        platform: 'Windows 10'
    }, {
        browserName: 'internet explorer',
        version: '11.0',
        platform: 'Windows 10'
    }, {
        browserName: 'internet explorer',
        version: '10.0',
        platform: 'Windows 8'
    }, {
        browserName: 'internet explorer',
        version: '9.0',
        platform: 'Windows 7'
    }, {
        browserName: 'iphone',
        version: '8.4',
        platform: 'OS X 10.10',
        deviceName: 'iPhone 6 Plus',
        deviceOrientation: 'portrait'
    }].map(function (capability) {
        return assign(capability, {
            'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
            name: 'integration',
            build: process.env.TRAVIS_BUILD_NUMBER,
            public: true
        });
    });

} else {
    capabilities = [{
        browserName: 'chrome'
    }];
}

function startStaticServer (cb) {
    return new Promise(function (resolve, reject) {
        var file = new nodeStatic.Server('./test/site');
        var server = http.createServer(function (request, response) {
            request.addListener('end', function () {
                file.serve(request, response);
            }).resume();
        }).listen(8080, function (err) {
            if (err) {
                return reject(err);
            }
            staticServer = server;
            resolve(server);
        });
    });
}

function startSelenium (cb) {
    return new Promise(function (resolve, reject) {
        selenium.start(function (err, sel) {
            if (err) {
                return reject(err);
            }
            grid = sel;
            resolve(sel);
        });
    });
}

var plugin = path.resolve(__dirname, 'index.js');

var config = {

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: [
        './test/spec/**/*.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilties at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude option in
    // order to group specific specs to a specific capability.
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: capabilities,
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity.
    logLevel: 'silent',
    //
    // Enables colors for log output.
    coloredLogs: true,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Set a base URL in order to shorten url command calls. If your url parameter starts
    // with "/", the base url gets prepended.
    baseUrl: 'http://localhost:8080',
    //
    // Default timeout for all waitForXXX commands.
    waitforTimeout: 10000,
    //
    // Initialize the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as property. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    plugins: {
    },
    //
    // Framework you want to run your specs with.
    // The following are supported: mocha, jasmine and cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the node package for the specific framework installed before running
    // any tests. If not please install the following package:
    // Mocha: `$ npm install mocha`
    // Jasmine: `$ npm install jasmine`
    // Cucumber: `$ npm install cucumber`
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The following are supported: dot (default), spec and xunit
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    reporter: process.env.CI ? 'dot' : 'spec',

    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd',
        timeout: process.env.CI ? 100000 : 10000
    },

    //
    // =====
    // Hooks
    // =====
    // Run functions before or after the test. If one of them returns with a promise, WebdriverIO
    // will wait until that promise got resolved to continue.
    // see also: http://webdriver.io/guide/testrunner/hooks.html
    //
    // Gets executed before all workers get launched.
    onPrepare: function() {
        return Promise.all([
            startSelenium(),
            startStaticServer()
        ]);
    },
    //
    // Gets executed before test execution begins. At this point you will have access to all global
    // variables like `browser`. It is the perfect place to define custom commands.
    before: function() {
        // do something
    },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    after: function(failures, pid) {
    },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    onComplete: function() {
        grid.kill();
        staticServer.close();
    }
};

config.plugins[plugin] = {};

exports.config = config;
<|endoftext|>