<commit_before>var particles = [];
var arrows = [];
var numberOfParticles = 100;
var temp = "temp";
var wind;
var windAngle;
var windMag;

Number.prototype.map = function ( in_min , in_max , out_min , out_max ) {
    return ( this - in_min ) * ( out_max - out_min ) / ( in_max - in_min ) + out_min;
}

function calculateHSL(hsb){
    // determine the lightness in the range [0,100]
    var l = (2 - hsb.s / 100) * hsb.b / 2;
    // store the HSL components
    var hsl =
      {
        'h' : hsb.h,
        's' : hsb.s * hsb.b / (l < 50 ? l * 2 : 200 - l * 2),
        'l' : l
      };
    // correct a division-by-zero error
    if (isNaN(hsl.s)) hsl.s = 0;
    return hsl;
}

function getHsb(temp){
    var hsb =
      {
        'h' : 0,
        's' : 80,
        'b' : 96
      };

    if(temp>32){
       temp = 32;
      }
    else if(temp<-10){
       temp = -10;
    }

    hsb.h = 200 - temp.map(0, 40, 0, 250);

    return hsb;
}

function drawBackground(hsb){
    var hsl = calculateHSL(hsb);
    background(hsb.h, hsb.s, hsb.b);
    $('body').css('background', 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)'); // css HSL
}

function drawMainArrow(hsb, x, y){
    push();
    translate(x, y-48);
    // Rotate by the wind's angle
    //draw base
    rotate(wind.heading() + PI/2);
    noStroke();
    fill(255);
    ellipse(0, 0, 48, 48);

    //draw arrow
    scale(0.75);
    stroke(hsb.h, hsb.s, hsb.b);
    strokeWeight(2);
    line(0, -16, 0, 16);

    noStroke();
    fill(hsb.h, hsb.s, hsb.b);
    triangle(0, -18, -6, -10, 6, -10);
    pop();
}

//bound check
function boundCheck(position){
    if (position.x > width)  position.x = 0;
    if (position.x < 0)      position.x = width;
    if (position.y > height) position.y = 0;
    if (position.y < 0)      position.y = height;
}

// particle class
function Particle () {
    this.position = createVector(random(width), random(height));
    this.size = random(8);
    this.opacity = random(1);

    this.draw = function(speed, i, mouseX, mouseY){

      mouse = createVector(mouseX, mouseY);
      normalizedPosition = this.position.copy();
      distance = mouse.dist(normalizedPosition);

      repulsion = createVector(normalizedPosition.x - mouse.x - sin(i), normalizedPosition.y - mouse.y - cos(i));
      repulsion.normalize()

      if (distance<30){
        this.position.add(repulsion)
      }
      else if (distance<60){
        repulsion.div(2)
        this.position.add(repulsion)
      }
      else if (distance<90){
        repulsion.div(3)
        this.position.add(repulsion)
      }
      else if (distance<120){
        repulsion.div(4)
        this.position.add(repulsion)
      }

      this.position.add(speed)

      // add some randomness
      this.position.x = this.position.x + cos(i)/10;
      this.position.y = this.position.y + sin(i)/10;
      this.size = this.size;

      boundCheck(this.position);

      noStroke();
      fill(color(25, this.opacity));
      ellipse(this.position.x, this.position.y, this.size, this.size);
    }
}

// arrow class
function Arrow () {
    this.position = createVector(random(width), random(height));
    this.size = random(10);
    this.opacity = random(1);

    this.draw = function(speed, i, mouseX, mouseY){

      mouse = createVector(mouseX, mouseY);
      normalizedPosition = this.position.copy();
      distance = mouse.dist(normalizedPosition);

      repulsion = createVector(normalizedPosition.x - mouse.x - sin(i), normalizedPosition.y - mouse.y - cos(i));
      repulsion.normalize()

      if (distance<30){
        this.position.add(repulsion)
      }
      else if (distance<60){
        repulsion.div(2)
        this.position.add(repulsion)
      }
      else if (distance<90){
        repulsion.div(3)
        this.position.add(repulsion)
      }
      else if (distance<120){
        repulsion.div(4)
        this.position.add(repulsion)
      }

      this.position.add(speed);

      // add some randomness
      this.position.x = this.position.x + cos(i)/10;
      this.position.y = this.position.y + sin(i)/10;
      this.size = this.size;

      boundCheck(this.position);

      stroke(color(255, this.opacity));
      strokeWeight(1);
      push();
      translate(this.position.x, this.position.y);
      rotate(windAngle);
      line(0, 0, this.size*2 ,0);
      //arrow
      line(this.size*2, 0, this.size*1.4, -this.size/2);
      line(this.size*2, 0, this.size*1.4, this.size/2);
      pop();
    }
}

function getData() {
      jQuery.ajax( {
      url: 'http://ip-api.com/json',
      type: 'GET',
      dataType: 'jsonp',
      cache: false,
      headers: { "Content-type": "application/json" },
      success: function(location) {
      // get city - update to long & lat
      console.log(location.city);
      console.log("long: " + location.lon);
      console.log("lat: " + location.lat);
      jQuery.ajax( {
         url: 'http://api.wunderground.com/api/16edb6959424f26b/conditions/settings/q/'+ location.lat +',' + location.lon + '.json',
         type: 'GET',
          dataType: 'jsonp',
          cache: false,
          headers: { "Content-type": "application/json" },
          success: function(weather) {
              console.log('http://api.wunderground.com/api/16edb6959424f26b/conditions/settings/q/'+ location.lat +',' + location.lon + '.json')
              console.log(weather.current_observation.wind_kph)
              console.log(weather.current_observation.wind_gust_kph)
              //console.log((float(weather.current_observation.wind_kph) + float(weather.current_observation.wind_gust_kph))/2)

              console.log(weather.current_observation.temp_c)

              //wind = (float(weather.current_observation.wind_kph) + float(weather.current_observation.wind_gust_kph))/2
              wind = float(weather.current_observation.wind_gust_kph);
              gotWeather(weather.current_observation.temp_c, wind, weather.current_observation.wind_degrees);
            }
            } );
            }
  } );
}

function setup() {
    createCanvas($(window).width(), $(window).height());

    getData();

    wind = createVector();

    numberOfParticles = floor(width/14);

    for(i=0; i<numberOfParticles; i++){
      particle = new Particle();
      particles.push(particle);

      arrow = new Arrow();
      arrows.push(arrow);
    }

    colorMode(HSB, 360, 100, 100, 1);
}

function draw() {
  // if temperature was read
  if(temp!="temp"){
      hsb = getHsb(temp);
      drawBackground(hsb);

      // removed mobile for now
      for(i=0; i<numberOfParticles; i++){
          particles[i].draw(wind, i, mouseX, mouseY);
          arrows[i].draw(wind, i , mouseX, mouseY);
      }
      	//drawMainArrow(hsb, $(".message").offset().left + $(".message").width()/2, $(".message").offset().top);
        //console.log(status.length);
        if(windMag<10)
            $(".message").html("Barely windy");
        else if(10<windMag && windMag<20)
            $(".message").html("A bit windy");
        else if(20<windMag && windMag<30)
            $(".message").html("Quite windy");
        else if(windMag>30)
            $(".message").html("Very windy");

    }

    $('html, body').on('touchstart touchmove', function(e){
     //prevent native touch activity like scrolling
     e.preventDefault();
  	});

    // recheck weather data
    if (floor((millis()/10)%60000) == 0){
        getData();
    }
}

function gotWeather(temperature, windSpeed, windDirection) {
    // Get the angle (convert to radians)
    var angle = radians(180-windDirection);
    windAngle = angle;
    // Get the wind speed
    windMag = Number(windSpeed);
    temp = floor(temperature);

    // Make a vector
    wind = p5.Vector.fromAngle(angle);
    // multiply wind magnitude
    wind.mult(windMag/4);
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight);

    particles = [];
    arrows = [];

    numberOfParticles = floor(width/14);

    for(i=0; i<numberOfParticles; i++){
      particle = new Particle();
      particles.push(particle);

      arrow = new Arrow();
      arrows.push(arrow);
    }
}<commit_msg>wind min 1<commit_after>var particles = [];
var arrows = [];
var numberOfParticles = 100;
var temp = "temp";
var wind;
var windAngle;
var windMag;

Number.prototype.map = function ( in_min , in_max , out_min , out_max ) {
    return ( this - in_min ) * ( out_max - out_min ) / ( in_max - in_min ) + out_min;
}

function calculateHSL(hsb){
    // determine the lightness in the range [0,100]
    var l = (2 - hsb.s / 100) * hsb.b / 2;
    // store the HSL components
    var hsl =
      {
        'h' : hsb.h,
        's' : hsb.s * hsb.b / (l < 50 ? l * 2 : 200 - l * 2),
        'l' : l
      };
    // correct a division-by-zero error
    if (isNaN(hsl.s)) hsl.s = 0;
    return hsl;
}

function getHsb(temp){
    var hsb =
      {
        'h' : 0,
        's' : 80,
        'b' : 96
      };

    if(temp>32){
       temp = 32;
      }
    else if(temp<-10){
       temp = -10;
    }

    hsb.h = 200 - temp.map(0, 40, 0, 250);

    return hsb;
}

function drawBackground(hsb){
    var hsl = calculateHSL(hsb);
    background(hsb.h, hsb.s, hsb.b);
    $('body').css('background', 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)'); // css HSL
}

function drawMainArrow(hsb, x, y){
    push();
    translate(x, y-48);
    // Rotate by the wind's angle
    //draw base
    rotate(wind.heading() + PI/2);
    noStroke();
    fill(255);
    ellipse(0, 0, 48, 48);

    //draw arrow
    scale(0.75);
    stroke(hsb.h, hsb.s, hsb.b);
    strokeWeight(2);
    line(0, -16, 0, 16);

    noStroke();
    fill(hsb.h, hsb.s, hsb.b);
    triangle(0, -18, -6, -10, 6, -10);
    pop();
}

//bound check
function boundCheck(position){
    if (position.x > width)  position.x = 0;
    if (position.x < 0)      position.x = width;
    if (position.y > height) position.y = 0;
    if (position.y < 0)      position.y = height;
}

// particle class
function Particle () {
    this.position = createVector(random(width), random(height));
    this.size = random(8);
    this.opacity = random(1);

    this.draw = function(speed, i, mouseX, mouseY){

      mouse = createVector(mouseX, mouseY);
      normalizedPosition = this.position.copy();
      distance = mouse.dist(normalizedPosition);

      repulsion = createVector(normalizedPosition.x - mouse.x - sin(i), normalizedPosition.y - mouse.y - cos(i));
      repulsion.normalize()

      if (distance<30){
        this.position.add(repulsion)
      }
      else if (distance<60){
        repulsion.div(2)
        this.position.add(repulsion)
      }
      else if (distance<90){
        repulsion.div(3)
        this.position.add(repulsion)
      }
      else if (distance<120){
        repulsion.div(4)
        this.position.add(repulsion)
      }

      this.position.add(speed)

      // add some randomness
      this.position.x = this.position.x + cos(i)/10;
      this.position.y = this.position.y + sin(i)/10;
      this.size = this.size;

      boundCheck(this.position);

      noStroke();
      fill(color(25, this.opacity));
      ellipse(this.position.x, this.position.y, this.size, this.size);
    }
}

// arrow class
function Arrow () {
    this.position = createVector(random(width), random(height));
    this.size = random(10);
    this.opacity = random(1);

    this.draw = function(speed, i, mouseX, mouseY){

      mouse = createVector(mouseX, mouseY);
      normalizedPosition = this.position.copy();
      distance = mouse.dist(normalizedPosition);

      repulsion = createVector(normalizedPosition.x - mouse.x - sin(i), normalizedPosition.y - mouse.y - cos(i));
      repulsion.normalize()

      if (distance<30){
        this.position.add(repulsion)
      }
      else if (distance<60){
        repulsion.div(2)
        this.position.add(repulsion)
      }
      else if (distance<90){
        repulsion.div(3)
        this.position.add(repulsion)
      }
      else if (distance<120){
        repulsion.div(4)
        this.position.add(repulsion)
      }

      this.position.add(speed);

      // add some randomness
      this.position.x = this.position.x + cos(i)/10;
      this.position.y = this.position.y + sin(i)/10;
      this.size = this.size;

      boundCheck(this.position);

      stroke(color(255, this.opacity));
      strokeWeight(1);
      push();
      translate(this.position.x, this.position.y);
      rotate(windAngle);
      line(0, 0, this.size*2 ,0);
      //arrow
      line(this.size*2, 0, this.size*1.4, -this.size/2);
      line(this.size*2, 0, this.size*1.4, this.size/2);
      pop();
    }
}

function getData() {
      jQuery.ajax( {
      url: 'http://ip-api.com/json',
      type: 'GET',
      dataType: 'jsonp',
      cache: false,
      headers: { "Content-type": "application/json" },
      success: function(location) {
      // get city - update to long & lat
      console.log(location.city);
      console.log("long: " + location.lon);
      console.log("lat: " + location.lat);
      jQuery.ajax( {
         url: 'http://api.wunderground.com/api/16edb6959424f26b/conditions/settings/q/'+ location.lat +',' + location.lon + '.json',
         type: 'GET',
          dataType: 'jsonp',
          cache: false,
          headers: { "Content-type": "application/json" },
          success: function(weather) {
              console.log('http://api.wunderground.com/api/16edb6959424f26b/conditions/settings/q/'+ location.lat +',' + location.lon + '.json')
              console.log(weather.current_observation.wind_kph)
              console.log(weather.current_observation.wind_gust_kph)
              //console.log((float(weather.current_observation.wind_kph) + float(weather.current_observation.wind_gust_kph))/2)

              console.log(weather.current_observation.temp_c)

              //wind = (float(weather.current_observation.wind_kph) + float(weather.current_observation.wind_gust_kph))/2
              if(float(weather.current_observation.wind_gust_kph) < 1){
                wind = 1.0;
              } else {
                wind = float(weather.current_observation.wind_gust_kph);
              }
              gotWeather(weather.current_observation.temp_c, wind, weather.current_observation.wind_degrees);
            }
            } );
            }
  } );
}

function setup() {
    createCanvas($(window).width(), $(window).height());

    getData();

    wind = createVector();

    numberOfParticles = floor(width/14);

    for(i=0; i<numberOfParticles; i++){
      particle = new Particle();
      particles.push(particle);

      arrow = new Arrow();
      arrows.push(arrow);
    }

    colorMode(HSB, 360, 100, 100, 1);
}

function draw() {
  // if temperature was read
  if(temp!="temp"){
      hsb = getHsb(temp);
      drawBackground(hsb);

      // removed mobile for now
      for(i=0; i<numberOfParticles; i++){
          particles[i].draw(wind, i, mouseX, mouseY);
          arrows[i].draw(wind, i , mouseX, mouseY);
      }
      	//drawMainArrow(hsb, $(".message").offset().left + $(".message").width()/2, $(".message").offset().top);
        //console.log(status.length);
        if(windMag<10)
            $(".message").html("Barely windy");
        else if(10<windMag && windMag<20)
            $(".message").html("A bit windy");
        else if(20<windMag && windMag<30)
            $(".message").html("Quite windy");
        else if(windMag>30)
            $(".message").html("Very windy");

    }

    $('html, body').on('touchstart touchmove', function(e){
     //prevent native touch activity like scrolling
     e.preventDefault();
  	});

    // recheck weather data
    if (floor((millis()/10)%60000) == 0){
        getData();
    }
}

function gotWeather(temperature, windSpeed, windDirection) {
    // Get the angle (convert to radians)
    var angle = radians(180-windDirection);
    windAngle = angle;
    // Get the wind speed
    windMag = Number(windSpeed);
    temp = floor(temperature);

    // Make a vector
    wind = p5.Vector.fromAngle(angle);
    // multiply wind magnitude
    wind.mult(windMag/4);
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight);

    particles = [];
    arrows = [];

    numberOfParticles = floor(width/14);

    for(i=0; i<numberOfParticles; i++){
      particle = new Particle();
      particles.push(particle);

      arrow = new Arrow();
      arrows.push(arrow);
    }
}<|endoftext|>


<commit_before>import { ApolloProvider } from '@apollo/react-hooks'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { createUploadLink } from 'apollo-upload-client'
import React, { useContext } from 'react'
import { useHistory, useLocation } from 'react-router-dom'

import AppContext from 'src/AppContext'

const URI =
  process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''

const ALT_URI = 'http://localhost:4001'

const uploadLink = createUploadLink({
  credentials: 'include',
  uri: `${URI}/graphql`
})

const uploadLinkALT = createUploadLink({
  credentials: 'include',
  uri: `${ALT_URI}/graphql`
})

const getClient = (history, location, getUserData, setUserData, setRole) =>
  new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (graphQLErrors)
          graphQLErrors.forEach(({ message, locations, path, extensions }) => {
            if (extensions?.code === 'UNAUTHENTICATED') {
              setUserData(null)
              if (location.pathname !== '/login') history.push('/login')
            }
            console.log(
              `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
            )
          })
        if (networkError) console.log(`[Network error]: ${networkError}`)
      }),
      new ApolloLink((operation, forward) => {
        return forward(operation).map(response => {
          const context = operation.getContext()
          const {
            response: { headers }
          } = context

          if (headers) {
            const role = headers.get('lamassu_role')
            setRole(role)
          }

          return response
        })
      }),
      ApolloLink.split(
        operation => operation.getContext().clientName === 'pazuz',
        uploadLinkALT,
        uploadLink
      )
    ]),
    cache: new InMemoryCache(),
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'ignore'
      },
      query: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'all'
      },
      mutate: {
        errorPolicy: 'all'
      }
    }
  })

const Provider = ({ children }) => {
  const history = useHistory()
  const location = useLocation()
  const { userData, setUserData, setRole } = useContext(AppContext)
  const client = getClient(
    history,
    location,
    () => userData,
    setUserData,
    setRole
  )

  return <ApolloProvider client={client}>{children}</ApolloProvider>
}

export default Provider
export { URI }
<commit_msg>fix: graphql server path<commit_after>import { ApolloProvider } from '@apollo/react-hooks'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { createUploadLink } from 'apollo-upload-client'
import React, { useContext } from 'react'
import { useHistory, useLocation } from 'react-router-dom'

import AppContext from 'src/AppContext'

const URI =
  process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''

const ALT_URI =
  process.env.NODE_ENV === 'development'
    ? 'https://localhost:4001'
    : `https://${window.location.hostname}:4001`

const uploadLink = createUploadLink({
  credentials: 'include',
  uri: `${URI}/graphql`
})

const uploadLinkALT = createUploadLink({
  credentials: 'include',
  uri: `${ALT_URI}/graphql`
})

const getClient = (history, location, getUserData, setUserData, setRole) =>
  new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (graphQLErrors)
          graphQLErrors.forEach(({ message, locations, path, extensions }) => {
            if (extensions?.code === 'UNAUTHENTICATED') {
              setUserData(null)
              if (location.pathname !== '/login') history.push('/login')
            }
            console.log(
              `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
            )
          })
        if (networkError) console.log(`[Network error]: ${networkError}`)
      }),
      new ApolloLink((operation, forward) => {
        return forward(operation).map(response => {
          const context = operation.getContext()
          const {
            response: { headers }
          } = context

          if (headers) {
            const role = headers.get('lamassu_role')
            setRole(role)
          }

          return response
        })
      }),
      ApolloLink.split(
        operation => operation.getContext().clientName === 'pazuz',
        uploadLinkALT,
        uploadLink
      )
    ]),
    cache: new InMemoryCache(),
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'ignore'
      },
      query: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'all'
      },
      mutate: {
        errorPolicy: 'all'
      }
    }
  })

const Provider = ({ children }) => {
  const history = useHistory()
  const location = useLocation()
  const { userData, setUserData, setRole } = useContext(AppContext)
  const client = getClient(
    history,
    location,
    () => userData,
    setUserData,
    setRole
  )

  return <ApolloProvider client={client}>{children}</ApolloProvider>
}

export default Provider
export { URI }
<|endoftext|>


<commit_before>define({
    "postbox-text": "在此輸入留言（至少3個字元）",
    "postbox-author": "名稱 (非必填)",
    "postbox-email": "電子信箱 (非必填)",
    "postbox-website": "個人網站 (非必填)",
    "postbox-submit": "送出",

    "num-comments": "1則留言\n{{ n }}則留言",
    "no-comments": "尚無留言",

    "comment-reply": "回覆",
    "comment-edit": "編輯",
    "comment-save": "儲存",
    "comment-delete": "刪除",
    "comment-confirm": "確認",
    "comment-close": "關閉",
    "comment-cancel": "取消",
    "comment-deleted": "留言已刪",
    "comment-queued": "留言待審",
    "comment-anonymous": "匿名",
    "comment-hidden": "{{ n }}則隱藏留言",

    "date-now": "剛剛",
    "date-minute": "1分鐘前\n{{ n }}分鐘前",
    "date-hour": "1小時前\n{{ n }}小時前",
    "date-day": "昨天\n{{ n }}天前",
    "date-week": "上週\n{{ n }}週前",
    "date-month": "上個月\n{{ n }}個月前",
    "date-year": "去年\n{{ n }}年前"
});
<commit_msg>corrected punctuation<commit_after>define({
    "postbox-text": "在此輸入留言（至少3個字元）",
    "postbox-author": "名稱（非必填）",
    "postbox-email": "電子信箱（非必填）",
    "postbox-website": "個人網站（非必填）",
    "postbox-submit": "送出",

    "num-comments": "1則留言\n{{ n }}則留言",
    "no-comments": "尚無留言",

    "comment-reply": "回覆",
    "comment-edit": "編輯",
    "comment-save": "儲存",
    "comment-delete": "刪除",
    "comment-confirm": "確認",
    "comment-close": "關閉",
    "comment-cancel": "取消",
    "comment-deleted": "留言已刪",
    "comment-queued": "留言待審",
    "comment-anonymous": "匿名",
    "comment-hidden": "{{ n }}則隱藏留言",

    "date-now": "剛剛",
    "date-minute": "1分鐘前\n{{ n }}分鐘前",
    "date-hour": "1小時前\n{{ n }}小時前",
    "date-day": "昨天\n{{ n }}天前",
    "date-week": "上週\n{{ n }}週前",
    "date-month": "上個月\n{{ n }}個月前",
    "date-year": "去年\n{{ n }}年前"
});
<|endoftext|>


<commit_before>
define(['sugar-web/graphics/palette',"text!activity/palettes/incomes.html"], function(palette,template) {

	var incomepalette = {};

	incomepalette.IncomePalette = function(invoker, primaryText) {
		palette.Palette.call(this, invoker, primaryText);
		this.getPalette().id = "incomepalette";
		this.incomeEvent = document.createEvent('CustomEvent');
		this.incomeEvent.initCustomEvent('income', true, true, {'min': 0, 'max': 11000});

		var incomeElem = document.createElement('div');
		incomeElem.innerHTML = template;
		this.setContent([incomeElem]);

		var that = this;;
		let children = document.getElementById("slider-incomes").childNodes;
		let minrange = children[3];
		let maxrange = children[5];
		minrange.addEventListener('input', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			_computeMinRange(minrange);
			that.incomeEvent.detail.min = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
			that.incomeEvent.detail.max = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
			that.getPalette().dispatchEvent(that.incomeEvent);
		});
		maxrange.addEventListener('input', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			_computeMaxRange(maxrange);
			that.incomeEvent.detail.min = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
			that.incomeEvent.detail.max = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
			that.getPalette().dispatchEvent(that.incomeEvent);
		});

		let wrapper = this.getPalette().childNodes[1];
		wrapper.style.width = "450px";
		wrapper.style.maxWidth = "400px";
		wrapper.style.height = "110px";

		invoker.addEventListener('click', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			let currentmin = (app.currentMinIncome-settings.poor)/rangeincome;
			let currentmax = app.currentMaxIncome/rangeincome;
			_initSlider(currentmin, currentmax, app.$refs.SugarActivity.getEnvironment().user.colorvalue.stroke);
		});
	};

	var addEventListener = function(type, listener, useCapture) {
		return this.getPalette().addEventListener(type, listener, useCapture);
	};

	incomepalette.IncomePalette.prototype = Object.create(palette.Palette.prototype, {
		addEventListener: {
			value: addEventListener,
			enumerable: true,
			configurable: true,
			writable: true
		}
	});

	return incomepalette;
});

function _computeMinRange(minrange) {
	minrange.value=Math.min(minrange.value,minrange.parentNode.childNodes[5].value-1);
	var value=(100/(parseInt(minrange.max)-parseInt(minrange.min)))*parseInt(minrange.value)-(100/(parseInt(minrange.max)-parseInt(minrange.min)))*parseInt(minrange.min);
	var children = minrange.parentNode.childNodes[1].childNodes;
	children[1].style.width=value+'%';
	children[5].style.left=value+'%';
	children[7].style.left=value+'%';
	let settings = app.$refs.api.getStreetSettings();
	let rangeincome = (settings.rich - settings.poor)/100.0;
	let newvalue = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
	document.getElementById("slider-min").innerHTML = _formatIncome(newvalue);
}

function _computeMaxRange(maxrange) {
	maxrange.value=Math.max(maxrange.value,maxrange.parentNode.childNodes[3].value-(-1));
	var value=(100/(parseInt(maxrange.max)-parseInt(maxrange.min)))*parseInt(maxrange.value)-(100/(parseInt(maxrange.max)-parseInt(maxrange.min)))*parseInt(maxrange.min);
	var children = maxrange.parentNode.childNodes[1].childNodes;
	children[3].style.width=(100-value)+'%';
	children[5].style.right=(100-value)+'%';
	children[9].style.left=value+'%';
	let settings = app.$refs.api.getStreetSettings();
	let rangeincome = (settings.rich - settings.poor)/100.0;
	let newvalue = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
	document.getElementById("slider-max").innerHTML = _formatIncome(newvalue);
}

function _initSlider(mymin, mymax, color) {
	let children = document.getElementById("slider-incomes").childNodes;
	children[1].childNodes[7].style.left = mymin+"%";
	children[3].value = mymin;
	children[1].childNodes[9].style.left = mymax+"%";
	children[5].value = mymax;
	children[1].childNodes[5].style.backgroundColor = color;
	_computeMinRange(children[3]);
	_computeMaxRange(children[5]);
}

function _formatIncome(income) {
	return new Intl.NumberFormat(app.$refs.api.language,{style:'currency', currency:'USD', maximumFractionDigits: 0}).format(Math.floor(income)).replace("$US","$")
}
<commit_msg>Fix income palette incompatibility with Android<commit_after>
define(['sugar-web/graphics/palette',"text!activity/palettes/incomes.html"], function(palette,template) {

	var incomepalette = {};

	incomepalette.IncomePalette = function(invoker, primaryText) {
		palette.Palette.call(this, invoker, primaryText);
		this.getPalette().id = "incomepalette";
		this.incomeEvent = document.createEvent('CustomEvent');
		this.incomeEvent.initCustomEvent('income', true, true, {'min': 0, 'max': 11000});

		var incomeElem = document.createElement('div');
		incomeElem.innerHTML = template;
		this.setContent([incomeElem]);

		var that = this;;
		let children = document.getElementById("slider-incomes").childNodes;
		let minrange = children[3];
		let maxrange = children[5];
		minrange.addEventListener('input', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			_computeMinRange(minrange);
			that.incomeEvent.detail.min = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
			that.incomeEvent.detail.max = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
			that.getPalette().dispatchEvent(that.incomeEvent);
		});
		maxrange.addEventListener('input', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			_computeMaxRange(maxrange);
			that.incomeEvent.detail.min = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
			that.incomeEvent.detail.max = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
			that.getPalette().dispatchEvent(that.incomeEvent);
		});

		let wrapper = this.getPalette().childNodes[1];
		wrapper.style.width = "450px";
		wrapper.style.maxWidth = "400px";
		wrapper.style.height = "110px";

		invoker.addEventListener('click', function(e) {
			let settings = app.$refs.api.getStreetSettings();
			let rangeincome = (settings.rich - settings.poor)/100.0;
			let currentmin = (app.currentMinIncome-settings.poor)/rangeincome;
			let currentmax = app.currentMaxIncome/rangeincome;
			_initSlider(currentmin, currentmax, app.$refs.SugarActivity.getEnvironment().user.colorvalue.stroke);
		});
	};

	var addEventListener = function(type, listener, useCapture) {
		return this.getPalette().addEventListener(type, listener, useCapture);
	};

	incomepalette.IncomePalette.prototype = Object.create(palette.Palette.prototype, {
		addEventListener: {
			value: addEventListener,
			enumerable: true,
			configurable: true,
			writable: true
		}
	});

	return incomepalette;
});

function _computeMinRange(minrange) {
	minrange.value=Math.min(minrange.value,minrange.parentNode.childNodes[5].value-1);
	var value=(100/(parseInt(minrange.max)-parseInt(minrange.min)))*parseInt(minrange.value)-(100/(parseInt(minrange.max)-parseInt(minrange.min)))*parseInt(minrange.min);
	var children = minrange.parentNode.childNodes[1].childNodes;
	children[1].style.width=value+'%';
	children[5].style.left=value+'%';
	children[7].style.left=value+'%';
	let settings = app.$refs.api.getStreetSettings();
	let rangeincome = (settings.rich - settings.poor)/100.0;
	let newvalue = (minrange.value == 0 ? settings.poor : settings.poor+minrange.value*rangeincome);
	document.getElementById("slider-min").innerHTML = _formatIncome(newvalue);
}

function _computeMaxRange(maxrange) {
	maxrange.value=Math.max(maxrange.value,maxrange.parentNode.childNodes[3].value-(-1));
	var value=(100/(parseInt(maxrange.max)-parseInt(maxrange.min)))*parseInt(maxrange.value)-(100/(parseInt(maxrange.max)-parseInt(maxrange.min)))*parseInt(maxrange.min);
	var children = maxrange.parentNode.childNodes[1].childNodes;
	children[3].style.width=(100-value)+'%';
	children[5].style.right=(100-value)+'%';
	children[9].style.left=value+'%';
	let settings = app.$refs.api.getStreetSettings();
	let rangeincome = (settings.rich - settings.poor)/100.0;
	let newvalue = (maxrange.value == 100 ? settings.rich : maxrange.value*rangeincome);
	document.getElementById("slider-max").innerHTML = _formatIncome(newvalue);
}

function _initSlider(mymin, mymax, color) {
	let children = document.getElementById("slider-incomes").childNodes;
	children[1].childNodes[7].style.left = mymin+"%";
	children[3].value = mymin;
	children[1].childNodes[9].style.left = mymax+"%";
	children[5].value = mymax;
	children[1].childNodes[5].style.backgroundColor = color;
	_computeMinRange(children[3]);
	_computeMaxRange(children[5]);
}

function _formatIncome(income) {
	return new Intl.NumberFormat(app.$refs.api.language,{style:'currency', currency:'USD', maximumFractionDigits: 0, minimumFractionDigits: 0}).format(Math.floor(income)).replace("$US","$")
}
<|endoftext|>


<commit_before>game.resources = [

    /* Graphics.
     * @example
     * {name: "example", type:"image", src: "data/img/example.png"},
     */

    /* Atlases
     * @example
     * {name: "example_tps", type: "tps", src: "data/img/example_tps.json"},
     */

    /* Maps.
     * @example
     * {name: "example01", type: "tmx", src: "data/map/example01.tmx"},
     * {name: "example01", type: "tmx", src: "data/map/example01.json"},
      */

    /* Background music.
     * @example
     * {name: "example_bgm", type: "audio", src: "data/bgm/"},
     */

    /* Sound effects.
     * @example
     * {name: "example_sfx", type: "audio", src: "data/sfx/"}
     */
];
<commit_msg>fixed the file type for the texture atlas example<commit_after>game.resources = [

    /* Graphics.
     * @example
     * {name: "example", type:"image", src: "data/img/example.png"},
     */

    /* Texture Atlases
     * @example
     * {name: "texture", type: "json", src: "data/img/example_tps.json"},
     */

    /* Maps.
     * @example
     * {name: "example01", type: "tmx", src: "data/map/example01.tmx"},
     * {name: "example01", type: "tmx", src: "data/map/example01.json"},
      */

    /* Background music.
     * @example
     * {name: "example_bgm", type: "audio", src: "data/bgm/"},
     */

    /* Sound effects.
     * @example
     * {name: "example_sfx", type: "audio", src: "data/sfx/"}
     */
];
<|endoftext|>


<commit_before>/**
 * Make an input[type=file]
 * @class cowboy.InputFile
 * @implements {cowboy.Options}
 * @todo Support Multiple Files
 */
cowboy.InputFile = new Class({
	Implements: cowboy.Options,
	options: {
		minSize: 4000,
		minSizeMessage: "File size needs to be more than %d%",
		maxSize: 5000000,
		maxSizeMessage: "File size needs to be less than %d%",
		requiredType: null,
		requiredTypeMessage: "File type is not correct",
	},

	/**
	 * Constructor
	 * @constructor
	 * @param  {Element} input   Input file to use
	 * @param  {Object} options  Options
	 */
	initialize: function(input, options) {
		var _this = this;
		this.input = input;
		this.options = Object.merge(this.options, options);

		// Set Options and overload options by properties in the input element
		this.setElementOptions(this.options, input);

		// Set filesize error messages
		var minSizeStr = ((this.options.minSize > 1000000) ? String(Math.round(this.options.minSize / 1000000)) + "Mo" : String(Math.round(this.options.minSize / 1000)) + "Ko");
		var maxSizeStr = ((this.options.maxSize > 1000000) ? String(Math.round(this.options.maxSize / 1000000)) + "Mo" : String(Math.round(this.options.maxSize / 1000)) + "Ko");
		this.options.minSizeMessage = this.options.minSizeMessage.replace('%d%', minSizeStr);
		this.options.maxSizeMessage = this.options.maxSizeMessage.replace('%d%', maxSizeStr);

		// Rebuild the Element
		var inputFile = new Element('div', {"Class": "inputfile"});

		// Inject the original input file into the contener "inputFile"
		inputFile.inject(this.input, 'after');
		this.input.inject(inputFile);

		// Create the fake input file
		var fakeInputFileContener = new Element('div', {"Class": "fakeinputfile"});
		this.fakeInputFile = new Element('input', {"type": "text","readonly": "readonly"});
		var icon = new Element('span', {"Class": "directory"});
		fakeInputFileContener.inject(inputFile);
		this.fakeInputFile.inject(fakeInputFileContener);
		icon.inject(fakeInputFileContener);

		// Add Event to control the value
		this.input.addEvent('change', _this.check.bind(_this));

		// Add Events on fake input and icon to focus the input
		this.fakeInputFile.addEvent('focus', function (e) {
			e.stop();
			_this.input.focus();
			_this.input.click();
			$$('html')[0].focus();
		});
		icon.addEvent('click', function () { _this.input.click(); });
	},

	/**
	 * Check if file meets expectations
	 * @method check
	 */
	check: function() {
		// with FileAPI
		if (window.File && window.Blob) {
			var file = this.input.files[0];

			// Check Type
			if ((this.options.requiredType === null || file.type == this.options.requiredType || this.options.requiredType.contains(file.type)) && file.size >= this.options.minSize && file.size <= this.options.maxSize) {
				this.fakeInputFile.value = file.name; // Show filename
				this.fakeInputFile.removeClass('log-error').addClass('log-validated');
			}
			// Show Warnings
			else {
				if (this.options.requiredType !== null && (file.type != this.options.requiredType || !this.options.requiredType.contains(file.type))) {
					this.fakeInputFile.value = this.options.requiredTypeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size < this.options.minSize) {
					this.fakeInputFile.value = this.options.minSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size > this.options.maxSize) {
					this.fakeInputFile.value = this.options.maxSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
			}
		}

		// Fallback for old browsers
		else if (this.value) this.fakeInputFile.value = e.value;
	}
});
<commit_msg>Use substitute instead of replace<commit_after>/**
 * Make an input[type=file]
 * @class cowboy.InputFile
 * @implements {cowboy.Options}
 * @todo Support Multiple Files
 */
cowboy.InputFile = new Class({
	Implements: cowboy.Options,
	options: {
		minSize: 4000,
		minSizeMessage: "File size needs to be more than {size}",
		maxSize: 5000000,
		maxSizeMessage: "File size needs to be less than {size}",
		requiredType: null,
		requiredTypeMessage: "File type is not correct",
	},

	/**
	 * Constructor
	 * @constructor
	 * @param  {Element} input   Input file to use
	 * @param  {Object} options  Options
	 */
	initialize: function(input, options) {
		var _this = this;
		this.input = input;
		this.options = Object.merge(this.options, options);

		// Set Options and overload options by properties in the input element
		this.setElementOptions(this.options, input);

		// Set filesize error messages
		var minSizeStr = ((this.options.minSize > 1000000) ? String(Math.round(this.options.minSize / 1000000)) + "Mo" : String(Math.round(this.options.minSize / 1000)) + "Ko");
		var maxSizeStr = ((this.options.maxSize > 1000000) ? String(Math.round(this.options.maxSize / 1000000)) + "Mo" : String(Math.round(this.options.maxSize / 1000)) + "Ko");
		this.options.minSizeMessage = this.options.minSizeMessage.substitute({"size": minSizeStr});
		this.options.maxSizeMessage = this.options.maxSizeMessage.substitute({"size": maxSizeStr});

		// Rebuild the Element
		var inputFile = new Element('div', {"Class": "inputfile"});

		// Inject the original input file into the contener "inputFile"
		inputFile.inject(this.input, 'after');
		this.input.inject(inputFile);

		// Create the fake input file
		var fakeInputFileContener = new Element('div', {"Class": "fakeinputfile"});
		this.fakeInputFile = new Element('input', {"type": "text","readonly": "readonly"});
		var icon = new Element('span', {"Class": "directory"});
		fakeInputFileContener.inject(inputFile);
		this.fakeInputFile.inject(fakeInputFileContener);
		icon.inject(fakeInputFileContener);

		// Add Event to control the value
		this.input.addEvent('change', _this.check.bind(_this));

		// Add Events on fake input and icon to focus the input
		this.fakeInputFile.addEvent('focus', function (e) {
			e.stop();
			_this.input.focus();
			_this.input.click();
			$$('html')[0].focus();
		});
		icon.addEvent('click', function () { _this.input.click(); });
	},

	/**
	 * Check if file meets expectations
	 * @method check
	 */
	check: function() {
		// with FileAPI
		if (window.File && window.Blob) {
			var file = this.input.files[0];

			// Check Type
			if ((this.options.requiredType === null || file.type == this.options.requiredType || this.options.requiredType.contains(file.type)) && file.size >= this.options.minSize && file.size <= this.options.maxSize) {
				this.fakeInputFile.value = file.name; // Show filename
				this.fakeInputFile.removeClass('log-error').addClass('log-validated');
			}
			// Show Warnings
			else {
				if (this.options.requiredType !== null && (file.type != this.options.requiredType || !this.options.requiredType.contains(file.type))) {
					this.fakeInputFile.value = this.options.requiredTypeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size < this.options.minSize) {
					this.fakeInputFile.value = this.options.minSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size > this.options.maxSize) {
					this.fakeInputFile.value = this.options.maxSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
			}
		}

		// Fallback for old browsers
		else if (this.value) this.fakeInputFile.value = e.value;
	}
});
<|endoftext|>


<commit_before>/* File: keyboardSelectionService.js
 *
 * Copyright (c) 2014
 * Centre National d’Enseignement à Distance (Cned), Boulevard Nicephore Niepce, 86360 CHASSENEUIL-DU-POITOU, France
 * (direction-innovation@cned.fr)
 *
 * GNU Affero General Public License (AGPL) version 3.0 or later version
 *
 * This file is part of a program which is free software: you can
 * redistribute it and/or modify it under the terms of the
 * GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 *
 */

'use strict';
/* global spyOn:false */

describe(
        'Service: keyboardSelectionService',
        function() {
            var window;

            beforeEach(module('cnedApp'));

            beforeEach(function() {
                window = {
                        navigator : {
                            userAgent : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36'
                        }
                }

                module(function($provide) {
                    $provide.value('$window', window);
                });
            });

            it('keyboardSelectionService:isSelectionCombination', inject(function(keyboardSelectionService) {
                var keyupEvent = {
                        keyCode : 37,
                        shiftKey : true
                }
                keyboardSelectionService.startSelection = false;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(true);

                keyboardSelectionService.startSelection = false;
                keyupEvent.keyCode = 16;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(false);

                keyboardSelectionService.startSelection = true;
                keyupEvent.keyCode = 16;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(true);
                expect(keyboardSelectionService.startSelection).toBe(false);

                keyboardSelectionService.startSelection = true;
                keyupEvent.keyCode = 80;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(false);
            }));

            it('keyboardSelectionService:endSelection', inject(function(keyboardSelectionService) {
                var keyupEvent = {
                        keyCode : 16
                }
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 17;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 91;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 92;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 24;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(false);
            }));

            it('keyboardSelectionService:eachChangeCombination', inject(function(keyboardSelectionService) {
                // normal keys combination
                var keyupEvent = {
                        keyCode : 37,
                        shiftKey : true
                }
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 38;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 40;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 33;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 34;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                // test on pc
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 36;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 35;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 36;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 35;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 65;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                window.navigator.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A';
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = false;
                keyupEvent.altKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = false;
                keyupEvent.altKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 38;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 40;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 65;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                // mauvaise combinaison
                keyupEvent.keyCode = 80;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(false);

            }));
        });<commit_msg>Add tests<commit_after>/* File: keyboardSelectionService.js
 *
 * Copyright (c) 2014
 * Centre National d’Enseignement à Distance (Cned), Boulevard Nicephore Niepce, 86360 CHASSENEUIL-DU-POITOU, France
 * (direction-innovation@cned.fr)
 *
 * GNU Affero General Public License (AGPL) version 3.0 or later version
 *
 * This file is part of a program which is free software: you can
 * redistribute it and/or modify it under the terms of the
 * GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 *
 */

'use strict';

describe(
        'Service: keyboardSelectionService',
        function() {
            var window;

            beforeEach(module('cnedApp'));

            beforeEach(function() {
                window = {
                        navigator : {
                            userAgent : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36'
                        }
                };

                module(function($provide) {
                    $provide.value('$window', window);
                });
            });

            it('keyboardSelectionService:isSelectionCombination', inject(function(keyboardSelectionService) {
                var keyupEvent = {
                        keyCode : 37,
                        shiftKey : true
                };
                keyboardSelectionService.startSelection = false;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(true);

                keyboardSelectionService.startSelection = false;
                keyupEvent.keyCode = 16;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(false);

                keyboardSelectionService.startSelection = true;
                keyupEvent.keyCode = 16;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(true);
                expect(keyboardSelectionService.startSelection).toBe(false);

                keyboardSelectionService.startSelection = true;
                keyupEvent.keyCode = 80;
                expect(keyboardSelectionService.isSelectionCombination(keyupEvent)).toBe(false);
                expect(keyboardSelectionService.startSelection).toBe(false);
            }));

            it('keyboardSelectionService:endSelection', inject(function(keyboardSelectionService) {
                var keyupEvent = {
                        keyCode : 16
                };
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 17;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 91;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 92;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 24;
                expect(keyboardSelectionService.endSelection(keyupEvent)).toBe(false);
            }));

            it('keyboardSelectionService:eachChangeCombination', inject(function(keyboardSelectionService) {
                // normal keys combination
                var keyupEvent = {
                        keyCode : 37,
                        shiftKey : true
                };
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 38;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 40;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 33;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 34;
                keyupEvent.shiftKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                // test on pc
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 36;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 35;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 36;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 35;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 65;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                window.navigator.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A';
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = false;
                keyupEvent.altKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = false;
                keyupEvent.altKey = true;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 37;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 39;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 38;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 40;
                keyupEvent.shiftKey = true;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);
                keyupEvent.keyCode = 65;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(true);

                // mauvaise combinaison
                keyupEvent.keyCode = 80;
                keyupEvent.shiftKey = false;
                keyupEvent.ctrlKey = false;
                keyupEvent.metaKey = true;
                keyupEvent.altKey = false;
                expect(keyboardSelectionService.eachChangeCombination(keyupEvent)).toBe(false);

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


<commit_before>import { showSelector } from "discourse/lib/emoji/emoji-toolbar";

export default Ember.Component.extend({
  classNames: ['babble-post-composer'],

  _init: function() {
    this.set('placeholder', Discourse.SiteSettings.babble_placeholder || I18n.t('babble.placeholder'))
  }.on('init'),

  _didInsertElement: function() {
    this.$('textarea').autocomplete({
      template: this.container.lookup('template:emoji-selector-autocomplete.raw'),
      key: ":",

      transformComplete(v) {
        if (!v.code) { return }
        return `${v.code}:`
      },

      dataSource(term) {
        return new Ember.RSVP.Promise(resolve => {
          term = term.toLowerCase()
          var options = (term === "" && ['smile', 'smiley', 'wink', 'sunny', 'blush']) ||
                        Discourse.Emoji.translations[`:${term}`] ||
                        Discourse.Emoji.search(term, {maxResults: 5})
          return resolve(options)
        }).then(list => list.map(code => {
          return {code, src: Discourse.Emoji.urlFor(code)};
        }))
      }
    })
  }.on('didInsertElement'),

  keyDown: function(event) {
    this.set('showError', false)
    if (event.keyCode == 13 && !(event.ctrlKey || event.altKey || event.shiftKey)) {
      if (!this.get('submitDisabled')) { // ignore if submit is disabled
        this._actions.submit(this) // submit on enter
      }
      return false
    }
  },

  textValidation: function() {
    var validation = { ok: true }
    if (this.get('processing') || Ember.isEmpty(this.get('text'))) {
      var validation = { failed: true }
    }

    return Discourse.InputValidation.create(validation)
  }.property('text', 'processing'),

  submitDisabled: function() {
    if (this.get('textValidation.failed')) return true
  }.property('textValidation'),

  actions: {
    selectEmoji: function() {
      var self = this
      var closeMenuPanelHandler = _.find($._data($('html')[0], 'events')['click'], function(e) {
        return e.namespace == 'close-menu-panel'
      }) // sorry mom.

      $('html').off('click.close-menu-panel')
      $('.emoji-modal-wrapper').on('click', function() {
        $('html').on('click.close-menu-panel', closeMenuPanelHandler.handler)
      })

      showSelector({
        container: this.container,
        onSelect: function(emoji) {
          self.set('text', (self.get('text') || '').trimRight() + ' :' + emoji + ':')

          $('.emoji-modal, .emoji-modal-wrapper').remove()
          $('.babble-post-composer textarea').focus()
          $('html').on('click.close-menu-panel', closeMenuPanelHandler.handler)
          return false
        }
      })
    },

    submit: function(context) {
      var self = context || this;

      if (self.get('text').trim() === "") {
        self.set('showError', true)
        self.set('text', '')
        return
      }

      self.set('processing', true)
      Discourse.ajax("/babble/topics/" + self.get('topic.id') + "/post", {
        type: 'POST',
        data: { raw: self.get('text').trim() }
      })
      .then(Discourse.Babble.handleNewPost)
      .finally(function() {
        self.set('text', '')
        self.set('processing', false)
      });
    }
  }

});
<commit_msg>Allow for @mention autocomplete<commit_after>import { showSelector } from "discourse/lib/emoji/emoji-toolbar";
import userSearch from "discourse/lib/user-search";

export default Ember.Component.extend({
  userSearch: userSearch,
  classNames: ['babble-post-composer'],

  _init: function() {
    this.set('placeholder', Discourse.SiteSettings.babble_placeholder || I18n.t('babble.placeholder'))
  }.on('init'),

  _didInsertElement: function() {
    const self = this
    self.$('textarea').autocomplete({
      template: self.container.lookup('template:emoji-selector-autocomplete.raw'),
      key: ":",

      transformComplete(v) {
        if (!v.code) { return }
        return `${v.code}:`
      },

      dataSource(term) {
        return new Ember.RSVP.Promise(resolve => {
          term = term.toLowerCase()
          var options = (term === "" && ['smile', 'smiley', 'wink', 'sunny', 'blush']) ||
                        Discourse.Emoji.translations[`:${term}`] ||
                        Discourse.Emoji.search(term, {maxResults: 5})
          return resolve(options)
        }).then(list => list.map(code => {
          return {code, src: Discourse.Emoji.urlFor(code)};
        }))
      }
    })

    self.$('textarea').autocomplete({
      template: self.container.lookup('template:user-selector-autocomplete.raw'),
      key: '@',
      dataSource(term) {
        return self.userSearch({
          term: term,
          topicId: self.get('topic.id'),
          includeGroups: true,
          exclude: [Discourse.User.current().get('username')]
        })
      },
      transformComplete(v) {
        return v.username || v.name
      }
    })
  }.on('didInsertElement'),

  keyDown: function(event) {
    this.set('showError', false)
    if (event.keyCode == 13 && !(event.ctrlKey || event.altKey || event.shiftKey)) {
      if (!this.get('submitDisabled')) { // ignore if submit is disabled
        this._actions.submit(this) // submit on enter
      }
      return false
    }
  },

  textValidation: function() {
    var validation = { ok: true }
    if (this.get('processing') || Ember.isEmpty(this.get('text'))) {
      var validation = { failed: true }
    }

    return Discourse.InputValidation.create(validation)
  }.property('text', 'processing'),

  submitDisabled: function() {
    if (this.get('textValidation.failed')) return true
  }.property('textValidation'),

  actions: {
    selectEmoji: function() {
      var self = this
      var closeMenuPanelHandler = _.find($._data($('html')[0], 'events')['click'], function(e) {
        return e.namespace == 'close-menu-panel'
      }) // sorry mom.

      $('html').off('click.close-menu-panel')
      $('.emoji-modal-wrapper').on('click', function() {
        $('html').on('click.close-menu-panel', closeMenuPanelHandler.handler)
      })

      showSelector({
        container: this.container,
        onSelect: function(emoji) {
          self.set('text', (self.get('text') || '').trimRight() + ' :' + emoji + ':')

          $('.emoji-modal, .emoji-modal-wrapper').remove()
          $('.babble-post-composer textarea').focus()
          $('html').on('click.close-menu-panel', closeMenuPanelHandler.handler)
          return false
        }
      })
    },

    submit: function(context) {
      var self = context || this;

      if (self.get('text').trim() === "") {
        self.set('showError', true)
        self.set('text', '')
        return
      }

      self.set('processing', true)
      Discourse.ajax("/babble/topics/" + self.get('topic.id') + "/post", {
        type: 'POST',
        data: { raw: self.get('text').trim() }
      })
      .then(Discourse.Babble.handleNewPost)
      .finally(function() {
        self.set('text', '')
        self.set('processing', false)
      });
    }
  }

});
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var fs = require('fs');
var path = require('path');
var marked = require('marked');
var ejs = require('ejs');
var minify = require('html-minifier').minify;
var ghpages = require('gh-pages');
var loading =  require('loading-cli');
var mkdirp = require('mkdirp');
var renderer = new marked.Renderer();
var color = require('colors-cli/safe')
var error = color.red.bold;
var warn = color.yellow;
var notice = color.blue;
var success = color.green;

// console.log(error('Error!'));
// console.log(warn('Warning'));
// console.log(notice('Notice'));

renderer.heading = function (text, level) {
    if(/[\u4E00-\u9FA5]/i.test(text)){
        return '<h' + level + ' id="'+text.toLowerCase()+'">'+text+'</h' + level + '>';
    }else{
        var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
        return '<h' + level + ' id="'+escapedText+'">'+text+'</h' + level + '>';
    }
}

marked.setOptions({
  renderer: renderer,
  // gfm: true,
  // tables: true,
  // breaks: false,
  // pedantic: false,
  // sanitize: true,
  // smartLists: true,
  // smartypants: false
  // highlight: function (code, lang, callback) {
  //   console.log("tes")
  //   require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
  //     callback(err, result.toString());
  //   });
  // }
});

// 删除文件夹
exec('rm -rf .deploy');
exec('mkdir .deploy');

MarkedToHTMLSave('.deploy/index.html','README.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → '+"ok!"));
})

MarkedToHTMLSave('.deploy/index.zh.html','README-zh.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → README-zh.md - '+"ok!"));
})

MarkedToHTMLSave('.deploy/editor-plugin.html','editor-plugin.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → editor-plugin.md - '+"ok!"));

})

MarkedToHTMLSave('.deploy/editor-plugin-zh.html','editor-plugin-zh.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → editor-plugin-zh.md - '+"ok!"));
})

PushGhpage()

function PushGhpage(){
    //copy favicon.ico
    fs.createReadStream(path.join(__dirname, './favicon.ico'))
      .pipe(fs.createWriteStream(path.join(__dirname, '../.deploy/favicon.ico')));
    // upload gh-page！～～
    var load = loading('  Pushing code!!')
    // load.start()
    // ghpages.publish(path.join(__dirname, '../.deploy'),{
    //     repo: 'https://github.com/jaywcjlove/awesome-mac.git',
    //     branch: 'gh-pages',
    //     message: 'Compiler generation page ' + new Date()
    // }, function(err) {
    //     if(err) return console.log(error('  → '+"ok!"+err));
    //     load.stop()
    //     console.log(success('\n\n   '+"Push success!!"));
    //     // 删除文件夹
    //     exec('rm -rf .deploy');
    // });
}

function MarkedToHTMLSave(_path,form_file,callback){
    var dirname = path.dirname(_path)

    var README_str = fs.readFileSync(form_file);
    var basename = path.basename(_path)
    var md_basename = path.basename(form_file)
    // console.log("md_basename::",md_basename)
    console.log('\n  ☆ '+_path+'\n');

    marked(README_str.toString(),function(err,html){
        if (err) return callback(err);
        console.log(notice('  → ['+form_file+"]成功转换成HTML!"+ _path));
        html = MDhrefToPath(html);

        var title="",description="",keywords="";
        if (_path.indexOf('zh.html')>0){
          title = "精品Mac应用分享推荐 - Awesome Mac";
          description = "收集分享大量非常好用的Mac应用程序、软件以及工具，主要面向开发者和设计师。 - Awesome Mac";
          keywords = "mac,osx,app,mac软件,awesome mac,苹果软件下载,免费软件,mac免费软件下载,精品mac应用";
        }else{
          title = "Awesome Mac application sharing recommendation - Awesome Mac";
          description = "A curated list of awesome applications, softwares, tools and shiny things for Mac osx. - Awesome Mac";
          keywords = "mac,osx,app,softwares,applications,mac softwares,awesome mac,free softwares,Freeware";
        }
        var data =  {
          html: html,
          title: title,
          description:description,
          keywords:keywords
        };
        var options = {
            // delimiter: '$'
        };
        ejs.renderFile('./build/template.ejs',data,options,function(err, str){
            // str => Rendered HTML string
            // HTML 代码压缩
            var result = minify(str, {
              // removeAttributeQuotes: true
              // collapseInlineTagWhitespace:true
              minifyCSS:true,
              minifyJS:true,
              collapseWhitespace:true,
              conservativeCollapse:true
            });
            fs.writeFileSync(_path,result,{
                encoding:'utf8'
            },function(err){
                if (err) return callback(err);
                callback(err)
            })
        });
    })
}

function MDhrefToPath(html){
    var reg = new RegExp('<*href="(.*?)"*>','ig')
    return html.replace(reg,function(a,st){
        if(st.indexOf('README.md')>-1){
            return a.replace(st,'index.html')
        }
        if(st.indexOf('README-zh.md')>-1){
            return a.replace(st,'index.zh.html')
        }
        if(st.indexOf('editor-plugin.md')>-1 || st.indexOf('editor-plugin-zh.md')>-1){
            return a.replace(/.md#/,'.html#').replace(/.md\"\>$/,'.html">')
        }
        return a
    })
}<commit_msg>fixed push branch error.<commit_after>var exec = require('child_process').exec;
var fs = require('fs');
var path = require('path');
var marked = require('marked');
var ejs = require('ejs');
var minify = require('html-minifier').minify;
var ghpages = require('gh-pages');
var loading =  require('loading-cli');
var mkdirp = require('mkdirp');
var renderer = new marked.Renderer();
var color = require('colors-cli/safe')
var error = color.red.bold;
var warn = color.yellow;
var notice = color.blue;
var success = color.green;

// console.log(error('Error!'));
// console.log(warn('Warning'));
// console.log(notice('Notice'));

renderer.heading = function (text, level) {
    if(/[\u4E00-\u9FA5]/i.test(text)){
        return '<h' + level + ' id="'+text.toLowerCase()+'">'+text+'</h' + level + '>';
    }else{
        var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
        return '<h' + level + ' id="'+escapedText+'">'+text+'</h' + level + '>';
    }
}

marked.setOptions({
  renderer: renderer,
  // gfm: true,
  // tables: true,
  // breaks: false,
  // pedantic: false,
  // sanitize: true,
  // smartLists: true,
  // smartypants: false
  // highlight: function (code, lang, callback) {
  //   console.log("tes")
  //   require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
  //     callback(err, result.toString());
  //   });
  // }
});

// 删除文件夹
exec('rm -rf .deploy');
exec('mkdir .deploy');

MarkedToHTMLSave('.deploy/index.html','README.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → '+"ok!"));
})

MarkedToHTMLSave('.deploy/index.zh.html','README-zh.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → README-zh.md - '+"ok!"));
})

MarkedToHTMLSave('.deploy/editor-plugin.html','editor-plugin.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → editor-plugin.md - '+"ok!"));

})

MarkedToHTMLSave('.deploy/editor-plugin-zh.html','editor-plugin-zh.md'.toString(),function(err){
    if (err) return console.log(error(err));
    console.log(notice('  → editor-plugin-zh.md - '+"ok!"));
})

PushGhpage()

function PushGhpage(){
    //copy favicon.ico
    fs.createReadStream(path.join(__dirname, './favicon.ico'))
      .pipe(fs.createWriteStream(path.join(__dirname, '../.deploy/favicon.ico')));
    // upload gh-page！～～
    var load = loading('  Pushing code!!')
    load.start()
    ghpages.publish(path.join(__dirname, '../.deploy'),{
        repo: 'https://github.com/jaywcjlove/awesome-mac.git',
        branch: 'gh-pages',
        message: 'Compiler generation page ' + new Date()
    }, function(err) {
        if(err) return console.log(error('  → '+"ok!"+err));
        load.stop()
        console.log(success('\n\n   '+"Push success!!"));
        // 删除文件夹
        exec('rm -rf .deploy');
    });
}

function MarkedToHTMLSave(_path,form_file,callback){
    var dirname = path.dirname(_path)

    var README_str = fs.readFileSync(form_file);
    var basename = path.basename(_path)
    var md_basename = path.basename(form_file)
    // console.log("md_basename::",md_basename)
    console.log('\n  ☆ '+_path+'\n');

    marked(README_str.toString(),function(err,html){
        if (err) return callback(err);
        console.log(notice('  → ['+form_file+"]成功转换成HTML!"+ _path));
        html = MDhrefToPath(html);

        var title="",description="",keywords="";
        if (_path.indexOf('zh.html')>0){
          title = "精品Mac应用分享推荐 - Awesome Mac";
          description = "收集分享大量非常好用的Mac应用程序、软件以及工具，主要面向开发者和设计师。 - Awesome Mac";
          keywords = "mac,osx,app,mac软件,awesome mac,苹果软件下载,免费软件,mac免费软件下载,精品mac应用";
        }else{
          title = "Awesome Mac application sharing recommendation - Awesome Mac";
          description = "A curated list of awesome applications, softwares, tools and shiny things for Mac osx. - Awesome Mac";
          keywords = "mac,osx,app,softwares,applications,mac softwares,awesome mac,free softwares,Freeware";
        }
        var data =  {
          html: html,
          title: title,
          description:description,
          keywords:keywords
        };
        var options = {
            // delimiter: '$'
        };
        ejs.renderFile('./build/template.ejs',data,options,function(err, str){
            // str => Rendered HTML string
            // HTML 代码压缩
            var result = minify(str, {
              // removeAttributeQuotes: true
              // collapseInlineTagWhitespace:true
              minifyCSS:true,
              minifyJS:true,
              collapseWhitespace:true,
              conservativeCollapse:true
            });
            fs.writeFileSync(_path,result,{
                encoding:'utf8'
            },function(err){
                if (err) return callback(err);
                callback(err)
            })
        });
    })
}

function MDhrefToPath(html){
    var reg = new RegExp('<*href="(.*?)"*>','ig')
    return html.replace(reg,function(a,st){
        if(st.indexOf('README.md')>-1){
            return a.replace(st,'index.html')
        }
        if(st.indexOf('README-zh.md')>-1){
            return a.replace(st,'index.zh.html')
        }
        if(st.indexOf('editor-plugin.md')>-1 || st.indexOf('editor-plugin-zh.md')>-1){
            return a.replace(/.md#/,'.html#').replace(/.md\"\>$/,'.html">')
        }
        return a
    })
}<|endoftext|>


<commit_before>javascript:
(function() {

    var page = prompt("page");
    if (page == "" || page == null) return;
    page = page.replace(/_/g, " ");
    var pages = page.split("|");
    wpTextbox1.value = wpTextbox1.value.replace(/(==.+==) *\n\n?/, "$1\n{{saveto|" + page + "}}\n");
    wpSummary.value = wpSummary.value + " saveto [[" + pages.join("]]、[[") + "]]";
    wpMinoredit.click();
    if (confirm("Save?")) wpSave.click();

})();
<commit_msg>Update saveto.js<commit_after>javascript:
(function() {

    var page = prompt('page');
    if (page == '' || page == null) return;
    page = page.replace(/_/g, ' ');
    var pages = page.split('|');
    wpTextbox1.value = wpTextbox1.value.replace(/(==.+==) *\n\n?/, '$1\n{{存檔至|' + page + '}}\n');
    wpSummary.value = wpSummary.value + ' 存檔至[[' + pages.join(']]、[[') + ']]';
    wpMinoredit.click();
    if (confirm('Save?')) wpSave.click();

})();
<|endoftext|>