<commit_before>// Skin locations are based on the work of Confuser
// https://github.com/confuser/serverless-mc-skin-viewer
// Permission to use & distribute https://github.com/confuser/serverless-mc-skin-viewer/blob/master/LICENSE

var helpers = require('./helpers');
var logging = require('./logging');
var fs = require('fs');

var exp = {};

var Canvas = require('canvas');
var Image = Canvas.Image;

exp.draw_helmet = function(skin_canvas, model_ctx, scale) {
  //Helmet - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 40*scale, 8*scale, 8*scale, 8*scale, 10*scale, 13/1.2*scale, 8*scale, 8*scale);
  //Helmet - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 32*scale, 8*scale, 8*scale, 8*scale, 2*scale, 3/1.2*scale, 8*scale, 8*scale);
  //Helmet - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 40*scale, 0, 8*scale, 8*scale, -3.4*scale, 5.14*scale, 8*scale, 8*scale);
};

exp.draw_head = function(skin_canvas, model_ctx, scale) {
  //Head - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 8*scale, 8*scale, 8*scale, 8*scale, 10*scale, 13/1.2*scale, 8*scale, 8*scale);
  //Head - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 0, 8*scale, 8*scale, 8*scale, 2*scale, 3/1.2*scale, 8*scale, 8*scale);
  //Head - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 8*scale, 0, 8*scale, 8*scale, -3.35*scale, 5.16*scale, 8.3*scale, 8*scale);
};

exp.draw_body = function(skin_canvas, model_ctx, scale) {
  //Left Leg
  //Left Leg - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 4*scale, 20*scale, 4*scale, 12*scale, -16*scale, 34.4/1.2*scale, 4*scale, 12*scale);

  //Right Leg
  //Right Leg - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 0*scale, 20*scale, 4*scale, 12*scale, 4*scale, 26.4/1.2*scale, 4*scale, 12*scale);
  //Right Leg - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 4*scale, 20*scale, 4*scale, 12*scale, 8*scale, 34.4/1.2*scale, 4*scale, 12*scale);

  //Arm Left
  //Arm Left - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 44*scale, 20*scale, 4*scale, 12*scale, -20*scale, 20/1.2*scale, 4*scale, 12*scale);
  //Arm Left - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.drawImage(skin_canvas, 44*scale, 16*scale, 4*scale, 4*scale, 0, 16*scale, 4*scale, 4*scale);

  //Body
  //Body - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 20*scale, 20*scale, 8*scale, 12*scale, 8*scale, 20/1.2*scale, 8*scale, 12*scale);

  //Arm Right
  //Arm Right - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 40*scale, 20*scale, 4*scale, 12*scale, 0, 16/1.2*scale, 4*scale, 12*scale);
  //Arm Right - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 44*scale, 20*scale, 4*scale, 12*scale, 4*scale, 20/1.2*scale, 4*scale, 12*scale);
  //Arm Right - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 44*scale, 16*scale, 4*scale, 4*scale, -16*scale, 16*scale, 4*scale, 4*scale);
};

exp.draw_model = function(uuid, img, scale, helm, body, callback) {
  var image = new Image();
  var width = 64 * scale;
  var height = 64 * scale;
  var model_canvas = new Canvas(20 * scale, (body ? 44.8 : 17.6) * scale);
  var skin_canvas = new Canvas(width, height);
  var model_ctx = model_canvas.getContext('2d');
  var skin_ctx = skin_canvas.getContext('2d');

  image.onerror = function(err) {
    logging.error("render error: " + err);
    callback(err, null);
  };

  image.onload = function() {
    skin_ctx.drawImage(image,0,0,64,64,0,0,64,64);
    //Scale it
    scale_image(skin_ctx.getImageData(0,0,64,64), skin_ctx, 0, 0, scale);
    if (body) {
      logging.log("drawing body");
      exp.draw_body(skin_canvas, model_ctx, scale);
    }
    logging.log("drawing head");
    exp.draw_head(skin_canvas, model_ctx, scale);
    if (helm) {
      logging.log("drawing helmet");
      exp.draw_helmet(skin_canvas, model_ctx, scale);
    }

    model_canvas.toBuffer(function(err, buf){
      if (err) {
        logging.log("error creating buffer: " + err);
      }
      callback(err, buf);
    });
  };

  image.src = img;
};

exp.open_render = function(renderpath, callback) {
  fs.readFile(renderpath, function (err, buf) {
    if (err) {
      logging.error("error while opening skin file: " + err);
    }
    callback(err, buf);
  });
};

function scale_image(imageData, context, d_x, d_y, scale) {
  var width = imageData.width;
  var height = imageData.height;
  context.clearRect(0,0,width,height); //Clear the spot where it originated from
  for(y=0; y<height; y++) { //height original
    for(x=0; x<width; x++) { //width original
      //Gets original colour, then makes a scaled square of the same colour
      var index = (x + y * width) * 4;
      context.fillStyle = "rgba(" + imageData.data[index+0] + "," + imageData.data[index+1] + "," + imageData.data[index+2] + "," + imageData.data[index+3] + ")";
      context.fillRect(d_x + x*scale, d_y + y*scale, scale, scale);
    }
  }
}

module.exports = exp;
<commit_msg>Fix shoulder rendering<commit_after>// Skin locations are based on the work of Confuser
// https://github.com/confuser/serverless-mc-skin-viewer
// Permission to use & distribute https://github.com/confuser/serverless-mc-skin-viewer/blob/master/LICENSE

var helpers = require('./helpers');
var logging = require('./logging');
var fs = require('fs');

var exp = {};

var Canvas = require('canvas');
var Image = Canvas.Image;

exp.draw_helmet = function(skin_canvas, model_ctx, scale) {
  //Helmet - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 40*scale, 8*scale, 8*scale, 8*scale, 10*scale, 13/1.2*scale, 8*scale, 8*scale);
  //Helmet - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 32*scale, 8*scale, 8*scale, 8*scale, 2*scale, 3/1.2*scale, 8*scale, 8*scale);
  //Helmet - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 40*scale, 0, 8*scale, 8*scale, -3.4*scale, 5.14*scale, 8*scale, 8*scale);
};

exp.draw_head = function(skin_canvas, model_ctx, scale) {
  //Head - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 8*scale, 8*scale, 8*scale, 8*scale, 10*scale, 13/1.2*scale, 8*scale, 8*scale);
  //Head - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 0, 8*scale, 8*scale, 8*scale, 2*scale, 3/1.2*scale, 8*scale, 8*scale);
  //Head - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 8*scale, 0, 8*scale, 8*scale, -3.35*scale, 5.16*scale, 8.3*scale, 8*scale);
};

exp.draw_body = function(skin_canvas, model_ctx, scale) {
  //Left Leg
  //Left Leg - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 4*scale, 20*scale, 4*scale, 12*scale, -16*scale, 34.4/1.2*scale, 4*scale, 12*scale);

  //Right Leg
  //Right Leg - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 0*scale, 20*scale, 4*scale, 12*scale, 4*scale, 26.4/1.2*scale, 4*scale, 12*scale);
  //Right Leg - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 4*scale, 20*scale, 4*scale, 12*scale, 8*scale, 34.4/1.2*scale, 4*scale, 12*scale);

  //Arm Left
  //Arm Left - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 44*scale, 20*scale, 4*scale, 12*scale, -20*scale, 20/1.2*scale, 4*scale, 12*scale);
  //Arm Left - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.drawImage(skin_canvas, 44*scale, 16*scale, 4*scale, 4*scale, 0, 16.4*scale, 4*scale, 4.3*scale);

  //Body
  //Body - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 20*scale, 20*scale, 8*scale, 12*scale, 8*scale, 20/1.2*scale, 8*scale, 12*scale);

  //Arm Right
  //Arm Right - Right
  model_ctx.setTransform(1,0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 40*scale, 20*scale, 4*scale, 12*scale, 0, 16/1.2*scale, 4*scale, 12*scale);
  //Arm Right - Front
  model_ctx.setTransform(1,-0.5,0,1.2,0,0);
  model_ctx.drawImage(skin_canvas, 44*scale, 20*scale, 4*scale, 12*scale, 4*scale, 20/1.2*scale, 4*scale, 12*scale);
  //Arm Right - Top
  model_ctx.setTransform(-1,0.5,1,0.5,0,0);
  model_ctx.scale(-1,1);
  model_ctx.drawImage(skin_canvas, 44*scale, 16*scale, 4*scale, 4*scale, -16.4*scale, 16*scale, 4*scale, 4.3*scale);
};

exp.draw_model = function(uuid, img, scale, helm, body, callback) {
  var image = new Image();
  var width = 64 * scale;
  var height = 64 * scale;
  var model_canvas = new Canvas(20 * scale, (body ? 44.8 : 17.6) * scale);
  var skin_canvas = new Canvas(width, height);
  var model_ctx = model_canvas.getContext('2d');
  var skin_ctx = skin_canvas.getContext('2d');

  image.onerror = function(err) {
    logging.error("render error: " + err);
    callback(err, null);
  };

  image.onload = function() {
    skin_ctx.drawImage(image,0,0,64,64,0,0,64,64);
    //Scale it
    scale_image(skin_ctx.getImageData(0,0,64,64), skin_ctx, 0, 0, scale);
    if (body) {
      logging.log("drawing body");
      exp.draw_body(skin_canvas, model_ctx, scale);
    }
    logging.log("drawing head");
    exp.draw_head(skin_canvas, model_ctx, scale);
    if (helm) {
      logging.log("drawing helmet");
      exp.draw_helmet(skin_canvas, model_ctx, scale);
    }

    model_canvas.toBuffer(function(err, buf){
      if (err) {
        logging.log("error creating buffer: " + err);
      }
      callback(err, buf);
    });
  };

  image.src = img;
};

exp.open_render = function(renderpath, callback) {
  fs.readFile(renderpath, function (err, buf) {
    if (err) {
      logging.error("error while opening skin file: " + err);
    }
    callback(err, buf);
  });
};

function scale_image(imageData, context, d_x, d_y, scale) {
  var width = imageData.width;
  var height = imageData.height;
  context.clearRect(0,0,width,height); //Clear the spot where it originated from
  for(y=0; y<height; y++) { //height original
    for(x=0; x<width; x++) { //width original
      //Gets original colour, then makes a scaled square of the same colour
      var index = (x + y * width) * 4;
      context.fillStyle = "rgba(" + imageData.data[index+0] + "," + imageData.data[index+1] + "," + imageData.data[index+2] + "," + imageData.data[index+3] + ")";
      context.fillRect(d_x + x*scale, d_y + y*scale, scale, scale);
    }
  }
}

module.exports = exp;
<|endoftext|>


<commit_before>var	express = require('express')
		app = express()
		path = require('path')
		MongoClient = require('mongodb').MongoClient
		bodyParser = require('body-parser')
		datejs = require('datejs')
		utils = require('./utils')
		config = require('./config')

var db

// Helper functions
var sendError = function(errorMsg, res) {
	res.setHeader('Content-Type', 'application/json');
	res.send(
		JSON.stringify({ 'success': 'true' , 'url': 'none', 'error': errorMsg}));
}

// App setup
app.set('views', './views')
app.set('view engine', 'pug')

app.use('./static', express.static(path.join(__dirname, 'public')))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

// Handlers
app.get('/', function(req, res) {
	res.render('index', {'title':'Title', 'message':'Hello'})
})

app.post('/url', function(req, res) {
	var	url			= req.body.url,
			days		=	req.body.days,
			hours		= req.body.hours,
			minutes	= req.body.minutes;

	if (!url || !url.length)
		sendError('Please provide a URL', res);

	if (!days || !hours || !minutes)
		sendError('Trying to hack the Gibson?', res);

	if (isNaN(days) || isNaN(hours) || isNaN(minutes))
		sendError('Days, hours and minutes must be numeric values', res);

	if (!utils.urlHasScheme(url)) {
		url = '//' + url;
	}

	var today = new Date();
	if (days == 0 && hours == 0 && minutes == 0) {
		var expirationDate = today.add(365 * 100).days();
	} else {
		var expirationDate = today.add(days).days();
		expirationDate = expirationDate.add(hours).hours();
		expirationDate = expirationDate.add(minutes).minutes();
	}

	db.collection(config.db.collection).insertOne(
		{'_id':/*FIXME*/Math.random().toString(),/*FIXME*/'link':url,'expiry_date_utc':expirationDate},
		function(err, result) {
			if (err) throw err
		}
	)
	res.sendStatus(200)
})

app.get('/:linkID([a-zA-Z0-9]+)', function(req, res) {
	  db.collection(config.db.collection).find({'_id':req.params.linkID}).toArray(function (err, result) {
	    if (err) throw err

			if (result.length != 0) {
				var link = result[0].link;
				res.redirect(301, link);
			} else {
				console.log('nop');
			}
	  })
	})

// Start server
var dbConnectURL = 'mongodb://localhost:'+config.db.port+'/'+config.db.name;

MongoClient.connect(dbConnectURL, function (err, database) {
	if (err) throw err
	db = database
	var server = app.listen(3020, function() {
		console.log('Running on port ' + server.address().port)
	})
})
<commit_msg>Add redirection expiry check<commit_after>var	express = require('express')
		app = express()
		path = require('path')
		MongoClient = require('mongodb').MongoClient
		bodyParser = require('body-parser')
		datejs = require('datejs')
		utils = require('./utils')
		config = require('./config')

var db

// Helper functions
var sendError = function(errorMsg, res) {
	res.setHeader('Content-Type', 'application/json');
	res.send(
		JSON.stringify({ 'success': 'false' , 'url': 'none', 'error': errorMsg}));
}

/*FIXME*/
function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

// App setup
app.set('views', './views')
app.set('view engine', 'pug')

app.use('./static', express.static(path.join(__dirname, 'public')))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

// Handlers
app.get('/', function(req, res) {
	res.render('index', {'title':'Title', 'message':'Hello'})
})

app.post('/url', function(req, res) {
	var	url			= req.body.url,
			days		=	req.body.days,
			hours		= req.body.hours,
			minutes	= req.body.minutes;

	if (!url || !url.length)
		sendError('Please provide a URL', res);

	if (!days || !hours || !minutes)
		sendError('Trying to hack the Gibson?', res);

	if (isNaN(days) || isNaN(hours) || isNaN(minutes))
		sendError('Days, hours and minutes must be numeric values', res);

	if (!utils.urlHasScheme(url)) {
		url = '//' + url;
	}

	days = parseInt(days);
	hours = parseInt(hours);
	minutes = parseInt(minutes);

	var today = new Date();
	if (days == 0 && hours == 0 && minutes == 0) {
		var expirationDate = today.add(365 * 100).days();
	} else {
		var expirationDate = today.add(days).days();
		expirationDate = expirationDate.add(hours).hours();
		expirationDate = expirationDate.add(minutes).minutes();
	}

	db.collection(config.db.collection).insertOne(
		{'_id':/*FIXME*/makeid(),/*FIXME*/'link':url,'expiry_date_utc':expirationDate},
		function(err, result) {
			if (err) throw err
		}
	)
	res.sendStatus(200)
})

app.get('/:linkID([a-zA-Z0-9]+)', function(req, res) {
	  db.collection(config.db.collection).find({'_id':req.params.linkID}).toArray(function (err, result) {
	    if (err) throw err

			if (result.length != 0) {
				var now = new Date();
				var urlExpiryDate = result[0].expiry_date_utc;/*FIXME*/
				if (now.getTime() > urlExpiryDate.getTime()) {
					sendError('The link has expired', res);
				} else {
					var link = result[0].link;
					res.redirect(301, link);
				}
			} else {
				console.log('nop');
			}
	  })
	})

// Start server
var dbConnectURL = 'mongodb://localhost:'+config.db.port+'/'+config.db.name;

MongoClient.connect(dbConnectURL, function (err, database) {
	if (err) throw err
	db = database
	var server = app.listen(3020, function() {
		console.log('Running on port ' + server.address().port)
	})
})
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const dts = require('rollup-plugin-dts').default
const sourceMapLoader = require('rollup-plugin-sourcemaps')
const postcss = require('rollup-plugin-postcss')
const { checkNoSymlinks, buildBanner } = require('./scripts/lib/new')
const { externalizeStylesheets, externalizeNonRelative, injectReleaseDate } = require('./scripts/lib/new-rollup')

/*
needs tsc to run first
but needs symlinks killed also

compiles from TSC files
*/

const { publicPackageStructs } = require('./scripts/lib/package-index')
checkNoSymlinks(publicPackageStructs)

module.exports = [

  // for JS
  ...publicPackageStructs.map((struct) => {
    return {
      input: path.join(struct.dir, struct.mainTscJs),
      output: {
        format: 'es',
        file: path.join(struct.dir, struct.mainDistJs),
        sourcemap: true,
        banner: buildBanner(struct.isPremium)
      },
      plugins: [
        externalizeVDom(),
        externalizeNonRelative(),
        sourceMapLoader(), // load from transpiled-via-tsc JS files
        postcss({ // will use postcss.config.js
          extract: true
        }),
        transplantCss(struct.mainName),
        injectReleaseDate()
      ]
    }
  }),

  // for DTS
  ...publicPackageStructs.map((struct) => {
    return {
      input: path.join(struct.dir, struct.mainTscDts),
      output: {
        format: 'es',
        file: path.join(struct.dir, struct.mainDistDts),
      },
      plugins: [
        fixDtsCodeIn(),
        ensurePremiumCommonAmbient(),
        externalizeVDom(),
        externalizeStylesheets(),
        externalizeNonRelative(),
        dts(),
        fixDtsCodeOut()
      ]
    }
  })

]

function transplantCss(fileName) { // fileName w/o extension
  let hasCss = false

  return         {
    resolveId(id, importer) {
      if (/^\./.test(id) && /\.css$/.test(id)) { // relative stylesheet
        hasCss = true
        let filePath = path.join(importer, '..', id)
        filePath = filePath.replace('/tsc/', '/src/') // not very robust!!!
        return filePath
      }
    },
    intro() {
      if (hasCss) {
        return `import './${fileName}.css';`
      } else {
        return ''
      }
    }
  }
}

function externalizeVDom() {
  return {
    resolveId(id, importer) {
      if (/\/vdom$/.test(id) || id.match(/^(preact|react|react-dom)$/)) {
        if (
          importer.match('packages/common') ||
          importer.match('packages/core')
        ) {
          return { id: './vdom', external: true, moduleSideEffects: true }
        } else {
          return { id: '@fullcalendar/common', external: true, moduleSideEffects: true }
        }
      }
    }
  }
}

function ensurePremiumCommonAmbient() {
  return {
    resolveId(id) {
      if (id === '@fullcalendar/premium-common') {
        return { id, external: true, moduleSideEffects: true }
      }
    }
  }
}

function fixDtsCodeIn() {
  return {
    /*
    fix problem with tsc outputting random imports like this:
      import("../../../packages/common/src/plugin-system-struct")
      import("../../../packages/common/src/main")
    */
    resolveId(id, importer) {
      if (importer && id.match('packages/common')) {
        return { id: '@fullcalendar/common', external: true }
      }
    }
  }
}

function fixDtsCodeOut() {
  return {
    renderChunk(code) {

      // remove sourcemap comments and ///<reference>
      code = code.replace(/\/\/.*/g, '')

      /*
      tsc, for classes that have superclasses with getter methods, sometimes reference the return type like this:
        import("@fullcalendar/common/tsc/whatever").Something
      and this is from WITHIN the @fullcalendar/common package
      */
      // BUG: playing weird with TS triple-slash references
      code = code.replace(/(['"]@fullcalendar\/[^'"]+)\/[^'"]+(['"])/g, function(m0, m1, m2) {
        return m1 + m2
      })

      // sometimes tsc fully resolved generic vdom declarations to preact, which makes the VNode<any> a thing (which it shouldn't be)
      code = code.replace(/VNode<any>/g, 'VNode')

      /*
      rollup-plugin-dts sometimes does not correctly reduce nested type declarations, leaving something like this:
        import("../toolbar-struct").ToolbarInput
      */
      code = code.replace(/import\(([^)]*)\)\./g, '')

      if (/\b(p?react)\b/.test(code)) {
        throw new Error('BAD reference to preact/react in DTS')
      }

      return code
    }
  }
}
<commit_msg>link to tickets that are relevant to dts hacks<commit_after>const fs = require('fs')
const path = require('path')
const dts = require('rollup-plugin-dts').default
const sourceMapLoader = require('rollup-plugin-sourcemaps')
const postcss = require('rollup-plugin-postcss')
const { checkNoSymlinks, buildBanner } = require('./scripts/lib/new')
const { externalizeStylesheets, externalizeNonRelative, injectReleaseDate } = require('./scripts/lib/new-rollup')

/*
needs tsc to run first
but needs symlinks killed also

compiles from TSC files
*/

const { publicPackageStructs } = require('./scripts/lib/package-index')
checkNoSymlinks(publicPackageStructs)

module.exports = [

  // for JS
  ...publicPackageStructs.map((struct) => {
    return {
      input: path.join(struct.dir, struct.mainTscJs),
      output: {
        format: 'es',
        file: path.join(struct.dir, struct.mainDistJs),
        sourcemap: true,
        banner: buildBanner(struct.isPremium)
      },
      plugins: [
        externalizeVDom(),
        externalizeNonRelative(),
        sourceMapLoader(), // load from transpiled-via-tsc JS files
        postcss({ // will use postcss.config.js
          extract: true
        }),
        transplantCss(struct.mainName),
        injectReleaseDate()
      ]
    }
  }),

  // for DTS
  ...publicPackageStructs.map((struct) => {
    return {
      input: path.join(struct.dir, struct.mainTscDts),
      output: {
        format: 'es',
        file: path.join(struct.dir, struct.mainDistDts),
      },
      plugins: [
        fixDtsCodeIn(),
        ensurePremiumCommonAmbient(),
        externalizeVDom(),
        externalizeStylesheets(),
        externalizeNonRelative(),
        dts(),
        fixDtsCodeOut()
      ]
    }
  })

]

function transplantCss(fileName) { // fileName w/o extension
  let hasCss = false

  return         {
    resolveId(id, importer) {
      if (/^\./.test(id) && /\.css$/.test(id)) { // relative stylesheet
        hasCss = true
        let filePath = path.join(importer, '..', id)
        filePath = filePath.replace('/tsc/', '/src/') // not very robust!!!
        return filePath
      }
    },
    intro() {
      if (hasCss) {
        return `import './${fileName}.css';`
      } else {
        return ''
      }
    }
  }
}

function externalizeVDom() {
  return {
    resolveId(id, importer) {
      if (/\/vdom$/.test(id) || id.match(/^(preact|react|react-dom)$/)) {
        if (
          importer.match('packages/common') ||
          importer.match('packages/core')
        ) {
          return { id: './vdom', external: true, moduleSideEffects: true }
        } else {
          return { id: '@fullcalendar/common', external: true, moduleSideEffects: true }
        }
      }
    }
  }
}

function ensurePremiumCommonAmbient() {
  return {
    resolveId(id) {
      if (id === '@fullcalendar/premium-common') {
        return { id, external: true, moduleSideEffects: true }
      }
    }
  }
}

function fixDtsCodeIn() {
  return {
    /*
    fix problem with tsc outputting random imports like this:
      import("../../../packages/common/src/plugin-system-struct")
      import("../../../packages/common/src/main")
    relevant tickets:
      https://github.com/microsoft/TypeScript/issues/38111 - "Declaration emit reveals paths within dependency that were not referred to in the source file"
    */
    resolveId(id, importer) {
      if (importer && id.match('packages/common')) {
        return { id: '@fullcalendar/common', external: true }
      }
    }
  }
}

function fixDtsCodeOut() {
  return {
    renderChunk(code) {

      // remove sourcemap comments and ///<reference>
      code = code.replace(/\/\/.*/g, '')

      /*
      tsc, for classes that have superclasses with getter methods, sometimes reference the return type like this:
        import("@fullcalendar/common/tsc/whatever").Something
      (and this is from WITHIN the @fullcalendar/common package)
      possible BUG with this hack: playing weird with TS triple-slash references
      relevant tickets:
        https://github.com/microsoft/TypeScript/issues/38111 - "Declaration emit reveals paths within dependency that were not referred to in the source file"
      */
      code = code.replace(/(['"]@fullcalendar\/[^'"]+)\/[^'"]+(['"])/g, function(m0, m1, m2) {
        return m1 + m2
      })

      /*
      sometimes tsc fully resolved generic vdom declarations to preact, which makes the VNode<any> a thing (which it shouldn't be)
      relevant tickets:
        https://github.com/microsoft/TypeScript/issues/37151 - "Declaration emit should not inline type definitions"
      */
      code = code.replace(/VNode<any>/g, 'VNode')

      /*
      rollup-plugin-dts sometimes does not correctly reduce nested type declarations, leaving something like this:
        import("../toolbar-struct").ToolbarInput
      relevant tickets:
        https://github.com/Swatinem/rollup-plugin-dts/issues/106 - "Imported type within imported generic is not reduced"
      */
      code = code.replace(/import\(([^)]*)\)\./g, '')

      if (/\b(p?react)\b/.test(code)) {
        throw new Error('BAD reference to preact/react in DTS')
      }

      return code
    }
  }
}
<|endoftext|>


<commit_before>const spotify = new require('./node-spotify-webhelper').SpotifyWebHelper()
const EventEmitter = require('events')

let loopId, lastSongId = []

module.exports = exports = new EventEmitter()

let getTrackId = track => ['track', 'artist', 'album'].map(x => track[x + '_resource'].uri)
let equals = (a, b) => a.length === b.length && a.every((x, i) => x === b[i])

exports.listen = function() {
    let loop = () => spotify.getStatus((err, result) => {
        if (err || result.error || !result.running) return

        clearTimeout(loopId)
        loopId = setTimeout(loop, Math.min(result.track.length - result.playing_position, 1) * 1000)

        if (equals(lastSongId, getTrackId(result.track)))
            return exports.emit('song-progress', result)

        lastSongId = getTrackId(result.track)
        exports.emit('song-update', result)
    })

    loop()
}

exports.stop = function() {
    clearTimeout(loopId)
}
<commit_msg>Lazily instantiate SpotifyWebHelper to boost startup speed<commit_after>const {SpotifyWebHelper} = new require('./node-spotify-webhelper')
const EventEmitter = require('events')

let spotify, loopId, lastSongId = []

module.exports = exports = new EventEmitter()

let getTrackId = track => ['track', 'artist', 'album'].map(x => track[x + '_resource'].uri)
let equals = (a, b) => a.length === b.length && a.every((x, i) => x === b[i])

exports.listen = function() {
    if (spotify == null) spotify = new SpotifyWebHelper()

    let loop = () => spotify.getStatus((err, result) => {
        if (err || result.error || !result.running) return

        clearTimeout(loopId)
        loopId = setTimeout(loop, Math.min(result.track.length - result.playing_position, 1) * 1000)

        if (equals(lastSongId, getTrackId(result.track)))
            return exports.emit('song-progress', result)

        lastSongId = getTrackId(result.track)
        exports.emit('song-update', result)
    })

    loop()
}

exports.stop = function() {
    clearTimeout(loopId)
}
<|endoftext|>


<commit_before>var columnify = require('columnify');
console.log("HELP PROCESS", process.argv);

var programInfo = {
    version: '0.0.0',
    usage_message: 'usage:',
};

var help = {
    description: 'display usage information',
    action: displayHelp
};

Object.defineProperty(help, "version", {
    enumerable: false,
    get: function() {
        return programInfo.version;
    },
    set: function(module) {
        programInfo.version = pkginfo.version;
    }
});

function displayHelp(err, value) {

    console.log("HELP CALLED");

    var display = [],
        flag;

    var prorogram = this;

    console.log('\n  ' + pjson.name + ' v' + pjson.version);
    console.log('  Usage: node example/example.js [options]\n');

    for (var flag_name in prorogram.options) {
        flag = prorogram.options[flag_name];
        display.push({
            ' ': ' ',
            flag: prorogram.renderFlagDetails(flag_name),
            description: flag.description
        });
    }

    console.log(columnify(display, {
        columnSplitter: '  '
    }), "\n");
}

function renderFlagDetails(flag_name) {

    var flag = this.options[flag_name],
        str = '';

    str += flag.shortcut ? '-' + flag.shortcut + ', ' : '    ';
    str += '--' + flag_name;
    str += ' ' + (flag.required ? '<' + flag.required + '> ' : (flag.optional ? '[' + flag.optional + '] ' : ' '));

    return str;
}

module.exports = exports = help;
<commit_msg>retrieve and set package info<commit_after>var columnify = require('columnify');
console.log("HELP PROCESS", process.argv);

var programInfo = {
    version: '0.0.0',
    module_name: 'no_name'
    usage_message: 'usage:',
};

var help = {
    description: 'display usage information',
    action: displayHelp
};

Object.defineProperty(help, "version", {
    enumerable: false,
    get: function() {
        return programInfo.version;
    },
    set: function(module) {
        programInfo.version = pkginfo.version;
    }
});

function displayHelp(err, value) {

    console.log("HELP CALLED");

    var display = [],
        flag;

    var prorogram = this;

    console.log('\n  ' + programInfo.name + ' v' + programInfo.version);
    console.log('  Usage: node example/example.js [options]\n');

    for (var flag_name in prorogram.options) {
        flag = prorogram.options[flag_name];
        display.push({
            ' ': ' ',
            flag: prorogram.renderFlagDetails(flag_name),
            description: flag.description
        });
    }

    console.log(columnify(display, {
        columnSplitter: '  '
    }), "\n");
}

function renderFlagDetails(flag_name) {

    var flag = this.options[flag_name],
        str = '';

    str += flag.shortcut ? '-' + flag.shortcut + ', ' : '    ';
    str += '--' + flag_name;
    str += ' ' + (flag.required ? '<' + flag.required + '> ' : (flag.optional ? '[' + flag.optional + '] ' : ' '));

    return str;
}

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


<commit_before>// for debugging
function MOVE_TO(x,y) {
  VIEWER1.MainView.Camera.SetFocalPoint(x,y);
  VIEWER1.MainView.Camera.ComputeMatrix();
  eventuallyRender();
}

// This file contains some global variables and misc procedures to
// initials shaders and some buffers we need and to render.

var ROOT_DIV;

var SLICE = 1;

// globals (for now)
var imageProgram;
var textProgram;
var polyProgram;
var mvMatrix = mat4.create();
var pMatrix = mat4.create();
var squareOutlinePositionBuffer;
var squarePositionBuffer;
var tileVertexPositionBuffer;
var tileVertexTextureCoordBuffer;
var tileCellBuffer;

var MOBILE_DEVICE = false;
// Hack to get rid of white lines.
var I_PAD_FLAG = false;

function detectMobile() {
  MOBILE_DEVICE = false;
  if ( navigator.userAgent.match(/Android/i)) {
   MOBILE_DEVICE = "Andriod";
  }
  if ( navigator.userAgent.match(/webOS/i)) {
   MOBILE_DEVICE = "webOS";
  }
  if ( navigator.userAgent.match(/iPhone/i)) {
   MOBILE_DEVICE = "iPhone";
  }
  if ( navigator.userAgent.match(/iPad/i)) {
   MOBILE_DEVICE = "iPad";
   I_PAD_FLAG = true;
  }
  if ( navigator.userAgent.match(/iPod/i)) {
   MOBILE_DEVICE = "iPod";
  }
  if ( navigator.userAgent.match(/BlackBerry/i)) {
   MOBILE_DEVICE = "BlackBerry";
  }
  if ( navigator.userAgent.match(/Windows Phone/i)) {
   MOBILE_DEVICE = "Windows Phone";
  }
  if (MOBILE_DEVICE) {
    MAXIMUM_NUMBER_OF_TILES = 5000;
  }
}

// This global is used in every class that renders something.
// I can not test multiple canvases until I modularize the canvas
// and get rid of these globals.
// WebGL context
var GL;

function GetUser() {
  if (typeof(USER) != "undefined") {
    return USER;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.User;
  }
  alert ("Could not find user");
  return "";
}

function GetViewId () {
  if (typeof(VIEW_ID) != "undefined") {
    return VIEW_ID;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.Viewer1.viewid;
  }
  if ( ! NOTES_WIDGET && ! NOTES_WIDGET.RootNote) {
    return NOTES_WIDGET.RootNote._id;
  }
  alert ("Could not find view id");
  return "";
}

function GetSessionDatabase() {
  if (typeof(SESSION_DATABASE) != "undefined") {
    return SESSION_DATABASE;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.Viewer1.db;
  }
  alert ("Could not find session database");
  return "";
}

// WebGL Initialization

function doesBrowserSupportWebGL(canvas) {
    try {
        //GL = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
        GL = canvas.getContext("webgl");
    } catch (e) {
    }
    if (!GL) {
        //alert("Could not initialise WebGL, sorry :-(");
        return false;
    }
   return true;
}

function initGL() {
  // Add a new canvas.
  CANVAS = $('<canvas>').appendTo('body').css({
      'position': 'absolute',
      'width': '100%',
      'height': '100%',
      'top' : '0px',
      'left' : '0px',
      'z-index': '1'
  }); // class='fillin nodoubleclick'
  //this.canvas.onselectstart = function() {return false;};
  //this.canvas.onmousedown = function() {return false;};
  GL = CANVAS[0].getContext("webgl") || CANVAS[0].getContext("experimental-webgl");

  // Defined in HTML
  initShaderPrograms();
  initOutlineBuffers();
  initImageTileBuffers();
  GL.clearColor(1.0, 1.0, 1.0, 1.0);
  GL.enable(GL.DEPTH_TEST);
}

function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
        return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
        if (k.nodeType == 3) {
            str += k.textContent;
        }
        k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
        return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}

function initShaderPrograms() {
    polyProgram = createProgram("shader-poly-fs", "shader-poly-vs");
    polyProgram.colorUniform = GL.getUniformLocation(polyProgram, "uColor");

    imageProgram = createProgram("shader-tile-fs", "shader-tile-vs");
    // Texture coordinate attribute and texture image uniform
    imageProgram.textureCoordAttribute
        = GL.getAttribLocation(imageProgram,"aTextureCoord");
    GL.enableVertexAttribArray(imageProgram.textureCoordAttribute);
    imageProgram.samplerUniform = GL.getUniformLocation(imageProgram, "uSampler");

    textProgram = createProgram("shader-text-fs", "shader-text-vs");
    textProgram.textureCoordAttribute
        = GL.getAttribLocation(textProgram, "aTextureCoord");
    GL.enableVertexAttribArray(textProgram.textureCoordAttribute);
    textProgram.samplerUniform
        = GL.getUniformLocation(textProgram, "uSampler");
    textProgram.colorUniform = GL.getUniformLocation(textProgram, "uColor");
}

function createProgram(fragmentShaderID, vertexShaderID) {
    var fragmentShader = getShader(GL, fragmentShaderID);
    var vertexShader = getShader(GL, vertexShaderID);

    var program = GL.createProgram();
    GL.attachShader(program, vertexShader);
    GL.attachShader(program, fragmentShader);
    GL.linkProgram(program);

    if (!GL.getProgramParameter(program, GL.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    program.vertexPositionAttribute = GL.getAttribLocation(program, "aVertexPosition");
    GL.enableVertexAttribArray(program.vertexPositionAttribute);

    // Camera matrix
    program.pMatrixUniform = GL.getUniformLocation(program, "uPMatrix");
    // Model matrix
    program.mvMatrixUniform = GL.getUniformLocation(program, "uMVMatrix");

    return program;
}

function initOutlineBuffers() {
    // Outline Square
    vertices = [
        0.0,  0.0,  0.0,
        0.0,  1.0,  0.0,
        1.0, 1.0,  0.0,
        1.0, 0.0,  0.0,
        0.0, 0.0,  0.0];
    squareOutlinePositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, squareOutlinePositionBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertices), GL.STATIC_DRAW);
    squareOutlinePositionBuffer.itemSize = 3;
    squareOutlinePositionBuffer.numItems = 5;

    // Filled square
    squarePositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, squarePositionBuffer);
    vertices = [
        1.0,  1.0,  0.0,
        0.0,  1.0,  0.0,
        1.0,  0.0,  0.0,
        0.0,  0.0,  0.0
    ];
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertices), GL.STATIC_DRAW);
    squarePositionBuffer.itemSize = 3;
    squarePositionBuffer.numItems = 4;
}

//==============================================================================

function initImageTileBuffers() {
    var vertexPositionData = [];
    var textureCoordData = [];

    // Make 4 points
    textureCoordData.push(0.0);
    textureCoordData.push(0.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(1.0);
    textureCoordData.push(0.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(0.0);
    textureCoordData.push(1.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(1.0);
    textureCoordData.push(1.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);

    // Now create the cell.
    var cellData = [];
    cellData.push(0);
    cellData.push(1);
    cellData.push(2);

    cellData.push(2);
    cellData.push(1);
    cellData.push(3);

    tileVertexTextureCoordBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, tileVertexTextureCoordBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(textureCoordData), GL.STATIC_DRAW);
    tileVertexTextureCoordBuffer.itemSize = 2;
    tileVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;

    tileVertexPositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, tileVertexPositionBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertexPositionData), GL.STATIC_DRAW);
    tileVertexPositionBuffer.itemSize = 3;
    tileVertexPositionBuffer.numItems = vertexPositionData.length / 3;

    tileCellBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, tileCellBuffer);
    GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Uint16Array(cellData), GL.STATIC_DRAW);
    tileCellBuffer.itemSize = 1;
    tileCellBuffer.numItems = cellData.length;
}

// Stuff for drawing
var RENDER_PENDING = false;
function eventuallyRender() {
    if (! RENDER_PENDING) {
      RENDER_PENDING = true;
      requestAnimFrame(tick);
    }
}

function tick() {
    RENDER_PENDING = false;
    draw();
}

// TODO:
// I still need to make the zoom buttons relative to the viewport
// Also the callback (zoom) cannot be hardcoded to VIEWER1!!!!!
function initView(viewport) {
  var viewer = new Viewer(viewport, null);
  EVENT_MANAGER.AddViewer(viewer);

  // Place the zoom in / out buttons.
  // Todo: Make the button become more opaque when pressed.
  // Associate with viewer (How???).
  // Place properly (div per viewer?) (viewer.SetViewport also places buttons).
  $('<img>').appendTo('body').css({
      'opacity': '0.4',
      'position': 'absolute',
      'height': '50px',
      'width': '50px',
      'bottom' : '55px',
      'right' : '5px',
      'z-index': '2'
  }).attr('class', 'viewer1').attr('type','image').attr('src',"/webgl-viewer/static/zoomin2.png").click(function(){
           VIEWER1.AnimateZoom(0.5);});
  $('<img>').appendTo('body').css({
      'opacity': '0.4',
      'position': 'absolute',
      'height': '50px',
      'width': '50px',
      'bottom' : '5px',
      'right' : '5px',
      'z-index': '2'
  }).attr('class', 'viewer1').attr('type','image').attr('src',"/webgl-viewer/static/zoomout2.png").click(function(){
           VIEWER1.AnimateZoom(2.0);});
  return viewer;
}

//==============================================================================
// Alternative to webgl, HTML5 2d canvas

function initGC() {

  detectMobile();

  // Add a new canvas.
  CANVAS = $('<div>').appendTo('body').css({
                'position': 'absolute',
                'width': '100%',
                'height': '100%',
                'top' : '0px',
                'left' : '0px',
                'z-index': '1'
            });
}

var GC_STACK = [];
var GCT = [1,0,0,1,0,0];
function GC_save() {
  var tmp = [GCT[0], GCT[1], GCT[2], GCT[3], GCT[4], GCT[5]];
  GC_STACK.push(tmp);
}
function GC_restore() {
  var tmp = GC_STACK.pop();
  GCT = tmp;
  GC.setTransform(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5]);
}
function GC_setTransform(m00,m10,m01,m11,m02,m12) {
  GCT = [m00,m10,m01,m11,m02,m12];
  GC.setTransform(m00,m10,m01,m11,m02,m12);
}
function GC_transform(m00,m10,m01,m11,m02,m12) {
  var n00 = m00*GCT[0] + m10*GCT[2];
  var n10 = m00*GCT[1] + m10*GCT[3];
  var n01 = m01*GCT[0] + m11*GCT[2];
  var n11 = m01*GCT[1] + m11*GCT[3];
  var n02 = m02*GCT[0] + m12*GCT[2] + GCT[4];
  var n12 = m02*GCT[1] + m12*GCT[3] + GCT[5];

  GCT = [n00,n10,n01,n11,n02,n12];
  GC.setTransform(n00,n10,n01,n11,n02,n12);
}

//----------------------------------------------------------
// Log to trackdown iPad bug.  Console does not log until
// debugger is running.  Bug does not occur when debugger
// is running.

LOGGING = false;
DEBUG_LOG = [];

function StartLogging (message) {
  if (LOGGING) return;
  LOGGING = true;
  //alert("Error: Check log");
}

function LogMessage (message) {
  if (LOGGING) {
    DEBUG_LOG.push(message);
  }
}

function FixJustification () {
  cache = VIEWER1.GetCache()

  $.ajax({
    type: "post",
    url: "/webgl-viewer/fixjustification",
    data: {"img": cache.Image._id,
           "db": cache.Image.database},
    success: function(data,status) {},
    error: function() { alert( "AJAX - error() : fixjustification" ); },
    });
}

<commit_msg>Use canvas by default (not webGL)<commit_after>// for debugging
function MOVE_TO(x,y) {
  VIEWER1.MainView.Camera.SetFocalPoint(x,y);
  VIEWER1.MainView.Camera.ComputeMatrix();
  eventuallyRender();
}

// This file contains some global variables and misc procedures to
// initials shaders and some buffers we need and to render.

var ROOT_DIV;

var SLICE = 1;

// globals (for now)
var imageProgram;
var textProgram;
var polyProgram;
var mvMatrix = mat4.create();
var pMatrix = mat4.create();
var squareOutlinePositionBuffer;
var squarePositionBuffer;
var tileVertexPositionBuffer;
var tileVertexTextureCoordBuffer;
var tileCellBuffer;

var MOBILE_DEVICE = false;
// Hack to get rid of white lines.
var I_PAD_FLAG = false;

function detectMobile() {
  MOBILE_DEVICE = false;
  if ( navigator.userAgent.match(/Android/i)) {
   MOBILE_DEVICE = "Andriod";
  }
  if ( navigator.userAgent.match(/webOS/i)) {
   MOBILE_DEVICE = "webOS";
  }
  if ( navigator.userAgent.match(/iPhone/i)) {
   MOBILE_DEVICE = "iPhone";
  }
  if ( navigator.userAgent.match(/iPad/i)) {
   MOBILE_DEVICE = "iPad";
   I_PAD_FLAG = true;
  }
  if ( navigator.userAgent.match(/iPod/i)) {
   MOBILE_DEVICE = "iPod";
  }
  if ( navigator.userAgent.match(/BlackBerry/i)) {
   MOBILE_DEVICE = "BlackBerry";
  }
  if ( navigator.userAgent.match(/Windows Phone/i)) {
   MOBILE_DEVICE = "Windows Phone";
  }
  if (MOBILE_DEVICE) {
    MAXIMUM_NUMBER_OF_TILES = 5000;
  }
}

// This global is used in every class that renders something.
// I can not test multiple canvases until I modularize the canvas
// and get rid of these globals.
// WebGL context
var GL;

function GetUser() {
  if (typeof(USER) != "undefined") {
    return USER;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.User;
  }
  alert ("Could not find user");
  return "";
}

function GetViewId () {
  if (typeof(VIEW_ID) != "undefined") {
    return VIEW_ID;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.Viewer1.viewid;
  }
  if ( ! NOTES_WIDGET && ! NOTES_WIDGET.RootNote) {
    return NOTES_WIDGET.RootNote._id;
  }
  alert ("Could not find view id");
  return "";
}

function GetSessionDatabase() {
  if (typeof(SESSION_DATABASE) != "undefined") {
    return SESSION_DATABASE;
  }
  if (typeof(ARGS) != "undefined") {
    return ARGS.Viewer1.db;
  }
  alert ("Could not find session database");
  return "";
}

// WebGL Initialization

function doesBrowserSupportWebGL(canvas) {
    return false;
    try {
        //GL = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
        GL = canvas.getContext("webgl");
    } catch (e) {
    }
    if (!GL) {
        //alert("Could not initialise WebGL, sorry :-(");
        return false;
    }
   return true;
}

function initGL() {
  // Add a new canvas.
  CANVAS = $('<canvas>').appendTo('body').css({
      'position': 'absolute',
      'width': '100%',
      'height': '100%',
      'top' : '0px',
      'left' : '0px',
      'z-index': '1'
  }); // class='fillin nodoubleclick'
  //this.canvas.onselectstart = function() {return false;};
  //this.canvas.onmousedown = function() {return false;};
  GL = CANVAS[0].getContext("webgl") || CANVAS[0].getContext("experimental-webgl");

  // Defined in HTML
  initShaderPrograms();
  initOutlineBuffers();
  initImageTileBuffers();
  GL.clearColor(1.0, 1.0, 1.0, 1.0);
  GL.enable(GL.DEPTH_TEST);
}

function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
        return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
        if (k.nodeType == 3) {
            str += k.textContent;
        }
        k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
        return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}

function initShaderPrograms() {
    polyProgram = createProgram("shader-poly-fs", "shader-poly-vs");
    polyProgram.colorUniform = GL.getUniformLocation(polyProgram, "uColor");

    imageProgram = createProgram("shader-tile-fs", "shader-tile-vs");
    // Texture coordinate attribute and texture image uniform
    imageProgram.textureCoordAttribute
        = GL.getAttribLocation(imageProgram,"aTextureCoord");
    GL.enableVertexAttribArray(imageProgram.textureCoordAttribute);
    imageProgram.samplerUniform = GL.getUniformLocation(imageProgram, "uSampler");

    textProgram = createProgram("shader-text-fs", "shader-text-vs");
    textProgram.textureCoordAttribute
        = GL.getAttribLocation(textProgram, "aTextureCoord");
    GL.enableVertexAttribArray(textProgram.textureCoordAttribute);
    textProgram.samplerUniform
        = GL.getUniformLocation(textProgram, "uSampler");
    textProgram.colorUniform = GL.getUniformLocation(textProgram, "uColor");
}

function createProgram(fragmentShaderID, vertexShaderID) {
    var fragmentShader = getShader(GL, fragmentShaderID);
    var vertexShader = getShader(GL, vertexShaderID);

    var program = GL.createProgram();
    GL.attachShader(program, vertexShader);
    GL.attachShader(program, fragmentShader);
    GL.linkProgram(program);

    if (!GL.getProgramParameter(program, GL.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    program.vertexPositionAttribute = GL.getAttribLocation(program, "aVertexPosition");
    GL.enableVertexAttribArray(program.vertexPositionAttribute);

    // Camera matrix
    program.pMatrixUniform = GL.getUniformLocation(program, "uPMatrix");
    // Model matrix
    program.mvMatrixUniform = GL.getUniformLocation(program, "uMVMatrix");

    return program;
}

function initOutlineBuffers() {
    // Outline Square
    vertices = [
        0.0,  0.0,  0.0,
        0.0,  1.0,  0.0,
        1.0, 1.0,  0.0,
        1.0, 0.0,  0.0,
        0.0, 0.0,  0.0];
    squareOutlinePositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, squareOutlinePositionBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertices), GL.STATIC_DRAW);
    squareOutlinePositionBuffer.itemSize = 3;
    squareOutlinePositionBuffer.numItems = 5;

    // Filled square
    squarePositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, squarePositionBuffer);
    vertices = [
        1.0,  1.0,  0.0,
        0.0,  1.0,  0.0,
        1.0,  0.0,  0.0,
        0.0,  0.0,  0.0
    ];
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertices), GL.STATIC_DRAW);
    squarePositionBuffer.itemSize = 3;
    squarePositionBuffer.numItems = 4;
}

//==============================================================================

function initImageTileBuffers() {
    var vertexPositionData = [];
    var textureCoordData = [];

    // Make 4 points
    textureCoordData.push(0.0);
    textureCoordData.push(0.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(1.0);
    textureCoordData.push(0.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(0.0);
    textureCoordData.push(1.0);
    vertexPositionData.push(0.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);

    textureCoordData.push(1.0);
    textureCoordData.push(1.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(1.0);
    vertexPositionData.push(0.0);

    // Now create the cell.
    var cellData = [];
    cellData.push(0);
    cellData.push(1);
    cellData.push(2);

    cellData.push(2);
    cellData.push(1);
    cellData.push(3);

    tileVertexTextureCoordBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, tileVertexTextureCoordBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(textureCoordData), GL.STATIC_DRAW);
    tileVertexTextureCoordBuffer.itemSize = 2;
    tileVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;

    tileVertexPositionBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ARRAY_BUFFER, tileVertexPositionBuffer);
    GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertexPositionData), GL.STATIC_DRAW);
    tileVertexPositionBuffer.itemSize = 3;
    tileVertexPositionBuffer.numItems = vertexPositionData.length / 3;

    tileCellBuffer = GL.createBuffer();
    GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, tileCellBuffer);
    GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Uint16Array(cellData), GL.STATIC_DRAW);
    tileCellBuffer.itemSize = 1;
    tileCellBuffer.numItems = cellData.length;
}

// Stuff for drawing
var RENDER_PENDING = false;
function eventuallyRender() {
    if (! RENDER_PENDING) {
      RENDER_PENDING = true;
      requestAnimFrame(tick);
    }
}

function tick() {
    RENDER_PENDING = false;
    draw();
}

// TODO:
// I still need to make the zoom buttons relative to the viewport
// Also the callback (zoom) cannot be hardcoded to VIEWER1!!!!!
function initView(viewport) {
  var viewer = new Viewer(viewport, null);
  EVENT_MANAGER.AddViewer(viewer);

  // Place the zoom in / out buttons.
  // Todo: Make the button become more opaque when pressed.
  // Associate with viewer (How???).
  // Place properly (div per viewer?) (viewer.SetViewport also places buttons).
  $('<img>').appendTo('body').css({
      'opacity': '0.4',
      'position': 'absolute',
      'height': '50px',
      'width': '50px',
      'bottom' : '55px',
      'right' : '5px',
      'z-index': '2'
  }).attr('class', 'viewer1').attr('type','image').attr('src',"/webgl-viewer/static/zoomin2.png").click(function(){
           VIEWER1.AnimateZoom(0.5);});
  $('<img>').appendTo('body').css({
      'opacity': '0.4',
      'position': 'absolute',
      'height': '50px',
      'width': '50px',
      'bottom' : '5px',
      'right' : '5px',
      'z-index': '2'
  }).attr('class', 'viewer1').attr('type','image').attr('src',"/webgl-viewer/static/zoomout2.png").click(function(){
           VIEWER1.AnimateZoom(2.0);});
  return viewer;
}

//==============================================================================
// Alternative to webgl, HTML5 2d canvas

function initGC() {

  detectMobile();

  // Add a new canvas.
  CANVAS = $('<div>').appendTo('body').css({
                'position': 'absolute',
                'width': '100%',
                'height': '100%',
                'top' : '0px',
                'left' : '0px',
                'z-index': '1'
            });
}

var GC_STACK = [];
var GCT = [1,0,0,1,0,0];
function GC_save() {
  var tmp = [GCT[0], GCT[1], GCT[2], GCT[3], GCT[4], GCT[5]];
  GC_STACK.push(tmp);
}
function GC_restore() {
  var tmp = GC_STACK.pop();
  GCT = tmp;
  GC.setTransform(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5]);
}
function GC_setTransform(m00,m10,m01,m11,m02,m12) {
  GCT = [m00,m10,m01,m11,m02,m12];
  GC.setTransform(m00,m10,m01,m11,m02,m12);
}
function GC_transform(m00,m10,m01,m11,m02,m12) {
  var n00 = m00*GCT[0] + m10*GCT[2];
  var n10 = m00*GCT[1] + m10*GCT[3];
  var n01 = m01*GCT[0] + m11*GCT[2];
  var n11 = m01*GCT[1] + m11*GCT[3];
  var n02 = m02*GCT[0] + m12*GCT[2] + GCT[4];
  var n12 = m02*GCT[1] + m12*GCT[3] + GCT[5];

  GCT = [n00,n10,n01,n11,n02,n12];
  GC.setTransform(n00,n10,n01,n11,n02,n12);
}

//----------------------------------------------------------
// Log to trackdown iPad bug.  Console does not log until
// debugger is running.  Bug does not occur when debugger
// is running.

LOGGING = false;
DEBUG_LOG = [];

function StartLogging (message) {
  if (LOGGING) return;
  LOGGING = true;
  //alert("Error: Check log");
}

function LogMessage (message) {
  if (LOGGING) {
    DEBUG_LOG.push(message);
  }
}

function FixJustification () {
  cache = VIEWER1.GetCache()

  $.ajax({
    type: "post",
    url: "/webgl-viewer/fixjustification",
    data: {"img": cache.Image._id,
           "db": cache.Image.database},
    success: function(data,status) {},
    error: function() { alert( "AJAX - error() : fixjustification" ); },
    });
}

<|endoftext|>


<commit_before>// Modules to control application life and create native browser window
const {app, BrowserWindow} = require('electron')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600})

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<commit_msg>fix: specify nodeIntegration=true for Electron 5 compat (#257)<commit_after>// Modules to control application life and create native browser window
const {app, BrowserWindow} = require('electron')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<|endoftext|>


<commit_before>(function(window, document, $, undefined){
  'use strict';

  var config = {
    images: ['jpg', 'jpeg', 'bmp', 'png', 'gif'],
    videos: ['avi', 'mp4', 'webm', 'flv', 'mkv'],
    html: ['html', 'erb', 'swig', 'jade', 'hbs'],
    css: ['css', 'less', 'sass', 'scss', 'styl'],
    javascript: ['js', 'coffee']
  };
  var dotfiles = false;

  /*
  Get the filename from url
   */
  function filename (str) {
    return str.replace(/^.*(\\|\/|\:)/, '');
  }

  /*
  Build the html fot the navigation
   */
  function init () {
    if ($('#filter-nav').length > 0) {
      return;
    }

    var nav = '
';
    nav += 'All';

    var items = $('.info .js-selectable-text')
                  .map(function () {
                    var name = filename($(this).attr('title'));
                    dotfiles = name[0] === '.';
                    return /[^.]+$/.exec(name);
                  })
                  .splice(0)
                  .filter(function (e, i, arr) {
                    return arr.lastIndexOf(e) === i;
                  });

    items.forEach(function (el) {
      nav += '' + el + '';
    });
    if (dotfiles) {
      nav += 'Dotfiles';
    }
    nav += '
';

    $('#toc').append(nav);

    events();

  }

  /**
   * Bind events on navigation
   * @return {void}
   */
  function events () {
    $('#toc').off('click.filter').on('click.filter', '.subnav-item', function (e) {
      e.preventDefault();
      var $this = $(this);

      if ($this.data('all')) {
        $this.siblings().removeClass('selected');
        $('[data-all]').addClass('selected');
      } else {
        $('[data-all]').removeClass('selected');
        $this.toggleClass('selected');
      }

      filter({
        dotfiles: $this.data('dotfiles')
      });
    });
  }

  /*
    Filter the items
   */
  function filter (settings) {
    $('.file').each(function () {
      var $this = $(this);

      $this.addClass('hidden');
    });
  }

  init();
  if ($('#js-repo-pjax-container').length) {
    new window.MutationObserver(init).observe(document.querySelector('#js-repo-pjax-container'), {childList: true});
  }

})(this, this.document, this.jQuery);
<commit_msg>group items<commit_after>(function(window, document, $, undefined){
  'use strict';

  var config = {
    images: ['jpg', 'jpeg', 'bmp', 'png', 'gif'],
    videos: ['avi', 'mp4', 'webm', 'flv', 'mkv'],
    html: ['html', 'erb', 'swig', 'jade', 'hbs'],
    css: ['css', 'less', 'sass', 'scss', 'styl'],
    javascript: ['js', 'coffee']
  };
  var dotfiles = false;

  /*
  Get the filename from url
   */
  function filename (str) {
    return str.replace(/^.*(\\|\/|\:)/, '');
  }

  /*
  Build the html fot the navigation
   */
  function init () {
    if ($('#filter-nav').length > 0) {
      return;
    }

    var nav = '
';
    nav += 'All';

    var items = $('.info .js-selectable-text')
                  .map(function () {
                    var name = filename($(this).attr('title'));
                    var ext = name.split('.').pop();
                    return (name[0] === '.') ? 'dotfiles' : getExt(ext);
                  })
                  .splice(0)
                  .filter(function (e, i, arr) {
                    return arr.lastIndexOf(e) === i;
                  });

    items.forEach(function (el) {
      nav += '' + el + '';
    });
    nav += '
';
    $('#toc').append(nav);

    events();
  }

  function getExt (ext) {
    var curretnExt = ext;
    $.each(config, function (el, key) {
      if (key.indexOf(ext) !== -1) {
        curretnExt = el;
      }
    });
    return curretnExt;
  }

  /**
   * Bind events on navigation
   * @return {void}
   */
  function events () {
    $('#toc').off('click.filter').on('click.filter', '.subnav-item', function (e) {
      e.preventDefault();
      var $this = $(this);

      if ($this.data('all')) {
        $this.siblings().removeClass('selected');
        $('[data-all]').addClass('selected');
      } else {
        $('[data-all]').removeClass('selected');
        $this.toggleClass('selected');
      }

      filter({
        dotfiles: $this.data('dotfiles')
      });
    });
  }

  /*
    Filter the items
   */
  function filter (settings) {
    $('.file').each(function () {
      var $this = $(this);

      $this.addClass('hidden');
    });
  }

  init();
  if ($('#js-repo-pjax-container').length) {
    new window.MutationObserver(init).observe(document.querySelector('#js-repo-pjax-container'), {childList: true});
  }

})(this, this.document, this.jQuery);
<|endoftext|>


<commit_before>// directions:
// (anticlockwise)
// ["E", "N", "W", "S"]
//
// polazrization:
// ["H", "V"]

// cordinates
//  >
// V

var SIZE_X = 8;
var SIZE_Y = 8;
var TILE_SIZE = 40;
var TIME_STEP = 1000;
var board = [];
var elements = [];
var stash = [];
var state = {}; // or some hashtable like-tking
// as of now
// {"9,12,2": {i: 9, j: 12, dir: 2, amp: 1.}}
// as of now, no polarizarion and only real amp
var history2 = [];

var i2x = function (i) { return TILE_SIZE/2 + TILE_SIZE * i; }
var j2y = function (j) { return TILE_SIZE/2 + TILE_SIZE * j; }

var x2i = function (x) { return Math.floor(x / TILE_SIZE); }
var y2j = function (y) { return Math.floor(y / TILE_SIZE); }

var acronym = {corner_cube: 'cc', beam_splitter_a: 'ba'};

var drawElement = function (d) {

  var g = d3.select(this);

  // we need to add rotation as a parameter
  switch (d.val) {
    case ("beam_splitter_a"):
      drawBeamSplitterA(g);
      break;
    case ("beam_splitter_d"):
      drawBeamSplitterD(g);
      break;
    case ("corner_cube"):
      drawCornerCube(g);
      break;
    default:
      g.append("rect")
        .attr("width", 0.5 * TILE_SIZE)
        .attr("height", 0.5 * TILE_SIZE)
        .attr("x", 0.25 * TILE_SIZE)
        .attr("y", 0.25 * TILE_SIZE)
        .style("fill", "#afa")
        .style("opacity", 0.5);

      g.append("text")
        .attr("x", 0.5 * TILE_SIZE)
        .attr("y", 0.5 * TILE_SIZE + 4)
        .style("text-anchor", "middle")
        .text(acronym[d.val]);
  }

}

function drawBeamSplitterD (g) {

  g.append("path")
    .attr("class", "glass")
    .attr("d", "M 8 12 L 12 8 L 32 28 L 28 32");

}

function drawBeamSplitterA (g) {

  g.append("path")
    .attr("class", "glass")
    .attr("d", "M 32 12 L 28 8 L 8 28 L 12 32");

}

function drawCornerCube (g) {

  g.append("path")
    .attr("class", "metal")
    .attr("d", ["M 5 5", "10 5", "20 15", "30 5", "35 5",
                "35 10", "25 20", "35 30", "35 35",
                "30 35", "20 25", "10 35", "5 35",
                "5 30", "15 20", "5 10"].join("L"));

}

var main = function () {

  var i;

  var svg = d3.select("body").append("svg")
    .attr("id", "game")
    .attr("height", 600)
    .attr("width", 900);

  for (i = 0; i < SIZE_X; i++) {
    board[i] = [];
    for (j = 0; j < SIZE_Y; j++)
      board[i][j] = "beam_splitter_a";
  }

  board[4][4] = "beam_splitter_a";
  board[4][5] = "corner_cube";

  v = {i: 6, j: 4, dir: 2, amp: 0.7};
  state[[v.i, v.j, v.dir]] = v;

  v = {i: 4, j: 2, dir: 3, amp: 0.5};
  state[[v.i, v.j, v.dir]] = v;

  history2 = [];

  visualizeBoard();

}

function visualizeBoard () {

  var i, j, v;
  var boardFlat = [];

  var drag = d3.behavior.drag()
    .origin(function(d) { return {x: i2x(d.i), y: j2y(d.j)}; })
    .on("drag", dragmove)
    .on("dragend", function (d) {
      // here I don't get d3.event.x);

      board[d.i][d.j] = "empty";

      d.i = x2i(d.x);
      d.j = y2j(d.y);
      d3.select(this)
        .attr("transform", ["translate(", i2x(d.i), ",", j2y(d.j), ")"].join(""));

      board[d.i][d.j] = d.val;

    });

  function dragmove(d) {
    d3.select(this)
      .attr("transform", ["translate(", d.x = d3.event.x, ",", d.y = d3.event.y, ")"].join(""));
      // .attr("x", d3.event.x)
      // .attr("y", d3.event.y);
  }

  for (i = 0; i < SIZE_X; i++) {
    for (j = 0; j < SIZE_Y; j++) {
      v = board[i][j];
      boardFlat.push({i: i, j: j, val: v});
      if (v !== "empty") {
        elements.push({i: i, j: j, val: v});
      }
    }
  }

  d3.select("svg").append("g")
    .attr("id", "board")
    .selectAll(".tile")
    .data(boardFlat)
    .enter()
      .append("rect")
        .attr("class", "tile")
        .attr("width", 0.95 * TILE_SIZE)
        .attr("height", 0.95 * TILE_SIZE)
        .attr("rx", 3)
        .attr("ry", 3)
        .attr("x", function (d) { return i2x(d.i); })
        .attr("y", function (d) { return j2y(d.j); })
        .style("fill", function (d) { return d.val === "empty" ? null : "#aaa"; });

  d3.select("svg").append("g")
    .attr("id", "elements")
    .selectAll(".element")
    .data(elements)
    .enter()
      .append('g')
        .attr("class", "element")
        .attr("transform", function (d) {
          return ["translate(", i2x(d.i), ",", j2y(d.j), ")"].join("");
        })
        .each(drawElement)
        .call(drag);

}

d3.select("#run").on("click", function () {
  simulate();
  vizStep(0);
})

function simulate () {
  for (i = 0; i < 8; i++) {

    console.log(state);
    history2.push([]);
    for (k in state) {
      v = state[k];
      history2[i].push({i: v.i, j: v.j, dir: v.dir, amp: v.amp});  // to copy
    }

    state = propagate(state, board);

  }
}

function vizStep (i) {

  var photons = d3.select("#board").selectAll(".photon");

  photons.remove();

  photons = d3.select("#board").selectAll(".photon")
    .data(history2[i]);

  photons.enter()
    .append("circle")
      .attr("class", "photon")
      .attr("r", 10)
      .attr("cx", function (d) { return i2x(d.i - dir2vx(d.dir)) + TILE_SIZE/2; })  // as d.i and d.j are for destination location
      .attr("cy", function (d) { return j2y(d.j - dir2vy(d.dir)) + TILE_SIZE/2; })
      .style("opacity", function (d) { return Math.sqrt(Math.abs(d.amp)); })
      .style("fill", function (d) { return d.amp < 0 ? "violet" : null; });

  photons.transition()
    .ease([0,1])
    .duration(TIME_STEP)
      .attr("cx", function (d) { return i2x(d.i) + TILE_SIZE/2; })
      .attr("cy", function (d) { return j2y(d.j) + TILE_SIZE/2; });

  if ( i + 1 < history2.length ) {
    setTimeout(vizStep, TIME_STEP, i + 1);
  }

}

function propagate (state0, board) {

  var k, v0, i, v1s, h, tile;
  var state1 = {};

  for (k in state0) {
    v0 = state0[k];

    if ( (v0.i < 0) || (v0.i >= SIZE_X) || (v0.j < 0) || (v0.j >= SIZE_Y) ) {
      console.log(v0);
      continue;
    }

    tile = board[v0.i][v0.j];

    // v1 - warning: in most cases there are plenty outputs

    switch ( tile ) {
      case "empty":
        // deserves a separate function as it is used in all other
        v1s = [{i: v0.i, j: v0.j, dir: v0.dir, amp: v0.amp}];
        v1s[0].i = v0.i + dir2vx(v0.dir);
        v1s[0].j = v0.j + dir2vy(v0.dir);
        break;
      case "corner_cube":  // simplest
        v1s = [{i: v0.i, j: v0.j, dir: v0.dir, amp: v0.amp}];
        v1s[0].i = v0.i - dir2vx(v0.dir);
        v1s[0].j = v0.j - dir2vy(v0.dir);
        v1s[0].dir = (v0.dir + 2) % 4;
        break;
      case "beam_splitter_a":
        // antidiagonal; hadamard; not to careful with the sing
        v1s = [];
        // going forward
        v1s.push({i:   v0.i + dir2vx(v0.dir),
                  j:   v0.j + dir2vy(v0.dir),
                  dir: v0.dir,
                  amp: v0.amp/Math.sqrt(2)})
        // bouncing
        var dir1 = v0.dir ^ 1;  // {0:1, 1:0, 2:3, 3:2}
        v1s.push({i:   v0.i + dir2vx(dir1),
                  j:   v0.j + dir2vy(dir1),
                  dir: dir1,
                  amp: (2 * (dir1 % 2) - 1) * v0.amp/Math.sqrt(2)})  // sign swap for one possibility
        break;
    }

    for (i = 0; i < v1s.length; i++) {

      v1 = v1s[i];

      h = [v1.i, v1.j, v1.dir].join(",");  // we can do numerical, if needed for a speedup

      if (h in state1) {
        state1[h].amp += v1.amp;
        if (state1[h].amp === 0) {
          delete state1[h];
        }
      } else {
        state1[h] = v1;
      }

    }

  }

  return state1;

}

function dir2vx (direction) {
  return ((direction + 1) % 2) * (1 - direction);
}

function dir2vy (direction) {
  return (direction % 2) * (direction - 2);
}

main();<commit_msg>adding laser<commit_after>// directions:
// (anticlockwise)
// ["E", "N", "W", "S"]
//
// polazrization:
// ["H", "V"]

// cordinates
//  >
// V

var SIZE_X = 8;
var SIZE_Y = 8;
var TILE_SIZE = 40;
var TIME_STEP = 1000;
var board = [];
var elements = [];
var stash = [];
var state = {}; // or some hashtable like-tking
// as of now
// {"9,12,2": {i: 9, j: 12, dir: 2, amp: 1.}}
// as of now, no polarizarion and only real amp
var history2 = [];

var i2x = function (i) { return TILE_SIZE/2 + TILE_SIZE * i; }
var j2y = function (j) { return TILE_SIZE/2 + TILE_SIZE * j; }

var x2i = function (x) { return Math.floor(x / TILE_SIZE); }
var y2j = function (y) { return Math.floor(y / TILE_SIZE); }

var acronym = {corner_cube: 'cc', beam_splitter_a: 'ba'};

var drawElement = function (d) {

  var g = d3.select(this);

  // we need to add rotation as a parameter
  switch (d.val) {
    case ("beam_splitter_a"):
      drawBeamSplitterA(g);
      break;
    case ("beam_splitter_d"):
      drawBeamSplitterD(g);
      break;
    case ("corner_cube"):
      drawCornerCube(g);
      break;
    case ("laser"):
      drawLaser(g);
      break;
    default:
      g.append("rect")
        .attr("width", 0.5 * TILE_SIZE)
        .attr("height", 0.5 * TILE_SIZE)
        .attr("x", 0.25 * TILE_SIZE)
        .attr("y", 0.25 * TILE_SIZE)
        .style("fill", "#afa")
        .style("opacity", 0.5);

      g.append("text")
        .attr("x", 0.5 * TILE_SIZE)
        .attr("y", 0.5 * TILE_SIZE + 4)
        .style("text-anchor", "middle")
        .text(acronym[d.val]);
  }

}

function drawBeamSplitterD (g) {

  g.append("path")
    .attr("class", "glass")
    .attr("d", "M 8 12 L 12 8 L 32 28 L 28 32");

}

function drawBeamSplitterA (g) {

  g.append("path")
    .attr("class", "glass")
    .attr("d", "M 32 12 L 28 8 L 8 28 L 12 32");

}

function drawCornerCube (g) {

  g.append("path")
    .attr("class", "metal")
    .attr("d", ["M 5 5", "10 5", "20 15", "30 5", "35 5",
                "35 10", "25 20", "35 30", "35 35",
                "30 35", "20 25", "10 35", "5 35",
                "5 30", "15 20", "5 10"].join("L"));

}

function drawLaser (g) {

  g.append("rect")
    .attr("x", 10)
    .attr("y", 10)
    .attr("width", 20)
    .attr("height", 20)
    .style("fill", "black");

  var angles = [0, 45, 90, 135];

  g.selectAll("line").data(angles).enter()
    .append("line")
      .attr("x1", function (d) { return 30 - 7 * Math.cos(Math.PI * d / 180); })
      .attr("y1", function (d) { return 20 - 7 * Math.sin(Math.PI * d / 180); })
      .attr("x2", function (d) { return 30 + 7 * Math.cos(Math.PI * d / 180); })
      .attr("y2", function (d) { return 20 + 7 * Math.sin(Math.PI * d / 180); })
      .style("stroke-width", 1.5)
      .style("stroke", "red");

}

var main = function () {

  var i;

  var svg = d3.select("body").append("svg")
    .attr("id", "game")
    .attr("height", 600)
    .attr("width", 900);

  for (i = 0; i < SIZE_X; i++) {
    board[i] = [];
    for (j = 0; j < SIZE_Y; j++)
      board[i][j] = "empty";
  }

  board[1][1] = "laser";
  board[4][4] = "beam_splitter_a";
  board[4][5] = "corner_cube";

  // v = {i: 6, j: 4, dir: 2, amp: 0.7};
  // state[[v.i, v.j, v.dir]] = v;

  // v = {i: 4, j: 2, dir: 3, amp: 0.5};
  // state[[v.i, v.j, v.dir]] = v;

  history2 = [];

  visualizeBoard();

}

function visualizeBoard () {

  var i, j, v, s;
  var boardFlat = [];

  var drag = d3.behavior.drag()
    .origin(function(d) { return {x: i2x(d.i), y: j2y(d.j)}; })
    .on("drag", dragmove)
    .on("dragend", function (d) {
      // here I don't get d3.event.x);

      board[d.i][d.j] = "empty";

      d.i = x2i(d.x);
      d.j = y2j(d.y);
      d3.select(this)
        .attr("transform", ["translate(", i2x(d.i), ",", j2y(d.j), ")"].join(""));

      board[d.i][d.j] = d.val;

    });

  function dragmove(d) {
    d3.select(this)
      .attr("transform", ["translate(", d.x = d3.event.x, ",", d.y = d3.event.y, ")"].join(""));
      // .attr("x", d3.event.x)
      // .attr("y", d3.event.y);
  }

  for (i = 0; i < SIZE_X; i++) {
    for (j = 0; j < SIZE_Y; j++) {
      v = board[i][j];
      boardFlat.push({i: i, j: j, val: v});
      if (v !== "empty") {
        elements.push({i: i, j: j, val: v});
      }
    }
  }

  d3.select("svg").append("g")
    .attr("id", "board")
    .selectAll(".tile")
    .data(boardFlat)
    .enter()
      .append("rect")
        .attr("class", "tile")
        .attr("width", 0.95 * TILE_SIZE)
        .attr("height", 0.95 * TILE_SIZE)
        .attr("rx", 3)
        .attr("ry", 3)
        .attr("x", function (d) { return i2x(d.i); })
        .attr("y", function (d) { return j2y(d.j); });
        // .style("fill", function (d) { return d.val === "empty" ? null : "#aaa"; });

  d3.select("svg").append("g")
    .attr("id", "elements")
    .selectAll(".element")
    .data(elements)
    .enter()
      .append('g')
        .attr("class", "element")
        .attr("transform", function (d) {
          return ["translate(", i2x(d.i), ",", j2y(d.j), ")"].join("");
        })
        .each(drawElement)
        .call(drag);

}

d3.select("#run").on("click", function () {
  simulate();
  vizStep(0);
})

function simulate () {

  var i, j, v, s;

  // generating state from laser
  for (i = 0; i < SIZE_X; i++) {
    for (j = 0; j < SIZE_Y; j++) {
      v = board[i][j];
      if (v === 'laser') {
        s = {i: i + 1, j: j, dir: 0, amp: 1};
        state[[s.i, s.j, s.dir]] = s;
      }
    }
  }

  for (i = 0; i < 8; i++) {

    console.log(state);
    history2.push([]);
    for (k in state) {
      v = state[k];
      history2[i].push({i: v.i, j: v.j, dir: v.dir, amp: v.amp});  // to copy
    }

    state = propagate(state, board);

  }
}

function vizStep (i) {

  var photons = d3.select("#board").selectAll(".photon");

  photons.remove();

  photons = d3.select("#board").selectAll(".photon")
    .data(history2[i]);

  photons.enter()
    .append("circle")
      .attr("class", "photon")
      .attr("r", 10)
      .attr("cx", function (d) { return i2x(d.i - dir2vx(d.dir)) + TILE_SIZE/2; })  // as d.i and d.j are for destination location
      .attr("cy", function (d) { return j2y(d.j - dir2vy(d.dir)) + TILE_SIZE/2; })
      .style("opacity", function (d) { return Math.sqrt(Math.abs(d.amp)); })
      .style("fill", function (d) { return d.amp < 0 ? "violet" : null; });

  photons.transition()
    .ease([0,1])
    .duration(TIME_STEP)
      .attr("cx", function (d) { return i2x(d.i) + TILE_SIZE/2; })
      .attr("cy", function (d) { return j2y(d.j) + TILE_SIZE/2; });

  if ( i + 1 < history2.length ) {
    setTimeout(vizStep, TIME_STEP, i + 1);
  }

}

function propagate (state0, board) {

  var k, v0, i, v1s, h, tile;
  var state1 = {};

  for (k in state0) {
    v0 = state0[k];

    if ( (v0.i < 0) || (v0.i >= SIZE_X) || (v0.j < 0) || (v0.j >= SIZE_Y) ) {
      console.log(v0);
      continue;
    }

    tile = board[v0.i][v0.j];

    // v1 - warning: in most cases there are plenty outputs

    switch ( tile ) {
      case "empty":
        // deserves a separate function as it is used in all other
        v1s = [{i: v0.i, j: v0.j, dir: v0.dir, amp: v0.amp}];
        v1s[0].i = v0.i + dir2vx(v0.dir);
        v1s[0].j = v0.j + dir2vy(v0.dir);
        break;
      case "corner_cube":  // simplest
        v1s = [{i: v0.i, j: v0.j, dir: v0.dir, amp: v0.amp}];
        v1s[0].i = v0.i - dir2vx(v0.dir);
        v1s[0].j = v0.j - dir2vy(v0.dir);
        v1s[0].dir = (v0.dir + 2) % 4;
        break;
      case "beam_splitter_a":
        // antidiagonal; hadamard; not to careful with the sing
        v1s = [];
        // going forward
        v1s.push({i:   v0.i + dir2vx(v0.dir),
                  j:   v0.j + dir2vy(v0.dir),
                  dir: v0.dir,
                  amp: v0.amp/Math.sqrt(2)})
        // bouncing
        var dir1 = v0.dir ^ 1;  // {0:1, 1:0, 2:3, 3:2}
        v1s.push({i:   v0.i + dir2vx(dir1),
                  j:   v0.j + dir2vy(dir1),
                  dir: dir1,
                  amp: (2 * (dir1 % 2) - 1) * v0.amp/Math.sqrt(2)})  // sign swap for one possibility
        break;
    }

    for (i = 0; i < v1s.length; i++) {

      v1 = v1s[i];

      h = [v1.i, v1.j, v1.dir].join(",");  // we can do numerical, if needed for a speedup

      if (h in state1) {
        state1[h].amp += v1.amp;
        if (state1[h].amp === 0) {
          delete state1[h];
        }
      } else {
        state1[h] = v1;
      }

    }

  }

  return state1;

}

function dir2vx (direction) {
  return ((direction + 1) % 2) * (1 - direction);
}

function dir2vy (direction) {
  return (direction % 2) * (direction - 2);
}

main();<|endoftext|>


<commit_before>var NAMESPACE = NAMESPACE || {};

NAMESPACE.MessageCenter = {

	// message: Message to be shown
	// status: 'success' or 'error'
	// dismiss: class or id of element to trigger closing when clicked, or string 'time' to close by itself

	messageCenter: '#messageCenter',
	timeToClose: 6000

	, toOpen: function(message, status, dismiss, callback, breaklines) {

		var messagesFromArray = '',
			spacer = breaklines === true ? '
' : ' ';

		if($(this.messageCenter).is(':visible')) {

			this.toClose(true, message, status, dismiss);

		} else {

			if(typeof dismiss !== 'undefined') {

				this.dismiss(dismiss);

			}

			if(message instanceof Array) {
				for (var i = message.length - 1; i >= 0; i--) {
					messagesFromArray += spacer + message[i];
				};

				message = messagesFromArray;
			}

			$(this.messageCenter).append('
' + message + '
').addClass(status).slideDown(function() {

				if(typeof callback !== 'undefined' && typeof callback === 'function') {
					callback();
				}
			});

		}

	}

	, toClose: function(open, message, status, dismiss) {

		var obj = this;

		$(this.messageCenter).slideUp(function() {
			$(this).find('p').remove();
			$(this).removeClass();

			if(open === true) {
				obj.toOpen(message, status, dismiss);
			}
		});

	}

	, dismiss: function(dismiss) {

		var obj = this;

		if(dismiss === 'time') {

			setTimeout(function() {
				obj.toClose();
			}, obj.timeToClose)

		} else if(dismiss instanceof Array) {

			for (var i = dismiss.length - 1; i >= 0; i--) {

				$(dismiss[i]).click(function() {
					obj.toClose();
				});

			};

		} else {

			$(dismiss).click(function() {
				obj.toClose();
			});

		}
	}

	, displayMessage: function(message, status, dismiss, callback, breaklines) {

		var obj = this;

		if(typeof message === 'undefined' || typeof status === 'undefined') {
			throw new Error('MessageCenter: You need to pass the message and status parameter');
		}

		obj.toOpen(message, status, dismiss, callback, breaklines);

		$(obj.messageCenter).find('.close').click(function() {
			obj.toClose();
		});

	}

};<commit_msg>Bug fix<commit_after>var NAMESPACE = NAMESPACE || {};

NAMESPACE.MessageCenter = {

	// message: Message to be shown
	// status: 'success' or 'error'
	// dismiss: class or id of element to trigger closing when clicked, or string 'time' to close by itself

	messageCenter: '#messageCenter',
	timeToClose: 6000

	, toOpen: function(message, status, dismiss, callback, breaklines) {

        var messagesFromArray = '',
            spacer = breaklines === true ? '
' : ' ';

        if($(this.messageCenter).is(':visible')) {

            this.toClose(true, message, status, dismiss, callback, breaklines);

        } else {

            if(typeof dismiss !== 'undefined') {

                this.dismiss(dismiss);

            }

            if(message instanceof Array) {
                for (var i = 0; i <= message.length - 1; i++) {
                    messagesFromArray += spacer + message[i];
                };

                message = messagesFromArray;
            }

            $(this.messageCenter).append('
' + message + '
').addClass(status).slideDown(function() {

                if(typeof callback !== 'undefined' && typeof callback === 'function') {
                    callback();
                }
            });

        }

    }

    , toClose: function(open, message, status, dismiss, callback, breaklines) {

        var obj = this;

        $(this.messageCenter).slideUp(function() {
            $(this).find('p').remove();
            $(this).removeClass();

            if(open === true) {
                obj.toOpen(message, status, dismiss, callback, breaklines);
            }
        });

    }

    , dismiss: function(dismiss) {

        var obj = this;

        if(dismiss === 'time') {

            setTimeout(function() {
                obj.toClose();
            }, obj.timeToClose)

        } else if(dismiss instanceof Array) {

            for (var i = dismiss.length - 1; i >= 0; i--) {

                $(dismiss[i]).click(function() {
                    obj.toClose();
                });

            };

        } else {

            $(dismiss).click(function() {
                obj.toClose();
            });

        }
    }

    , displayMessage: function(message, status, dismiss, callback, breaklines) {

        var obj = this;

        if(typeof message === 'undefined' || typeof status === 'undefined') {
            throw new Error('MessageCenter: You need to pass the message and status parameter');
        }

        obj.toOpen(message, status, dismiss, callback, breaklines);

        $(obj.messageCenter).find('.close').click(function() {
            obj.toClose();
        });

    }

};<|endoftext|>


<commit_before>var app = require('app')
var BrowserWindow = require('browser-window')
var Menu = require('menu')
var ipc = require('electron').ipcMain
var dialog = require('dialog')
var fs = require('fs')
var path = require('path')

var darwinTemplate = require('./menus/darwin-menu.js')
var otherTemplate = require('./menus/other-menu.js')

var emptyData = require('./empty-data.json')
var emptySavedDir = require('./empty-saved-dir.json')

var mainWindow = null
var menu = null

var iconPath = path.join(__dirname, '/assets/git-it.png')

app.on('window-all-closed', function appQuit () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('ready', function appReady () {
  mainWindow = new BrowserWindow({"minWidth": 800, "minHeight": 600, width: 980, height: 760, title: 'Git-it', icon: iconPath })

  var appPath = app.getPath('userData')
  var userDataPath = path.join(appPath, 'user-data.json')
  var userSavedDir = path.join(appPath, 'saved-dir.json')

  // tools for development to prefill challenge completion
  // usage: electron . --none
  //        electron . --some
  //        electron . --all
  if (process.argv[2] === '--none') { setAllChallengesUncomplete(userDataPath) }
  if (process.argv[2] === '--some') { setSomeChallengesComplete(userDataPath) }
  if (process.argv[2] === '--all')  { setAllChallengesComplete(userDataPath) }

  fs.exists(userDataPath, function (exists) {
    if (!exists) {
      fs.writeFile(userDataPath, JSON.stringify(emptyData, null, ' '), function (err) {
        if (err) return console.log(err)
      })
    }
  })

  fs.exists(userSavedDir, function (exists) {
    if (!exists) {
      fs.writeFile(userSavedDir, JSON.stringify(emptyData, null, ' '), function (err) {
        if (err) return console.log(err)
      })
    }
  })

  mainWindow.loadURL('file://' + __dirname + '/index.html')

  ipc.on('getUserDataPath', function (event) {
    event.returnValue = userDataPath
  })

  ipc.on('getUserSavedDir', function (event) {
    event.returnValue = userSavedDir
  })

  ipc.on('open-file-dialog', function (event) {
    var files = dialog.showOpenDialog(mainWindow, { properties: [ 'openFile', 'openDirectory' ]})
    if (files) {
      event.sender.send('selected-directory', files)
    }
  })

  ipc.on('confirm-clear', function (event) {
    var options = {
      type: 'info',
      buttons: ['Yes', 'No'],
      title: 'Confirm Clearing Statuses',
      message: 'Are you sure you want to clear the status for every challenge?'
    }
    dialog.showMessageBox(options, function cb (response) {
      event.sender.send('confirm-clear-response', response)
    })
  })

  if (process.platform === 'darwin') {
    menu = Menu.buildFromTemplate(darwinTemplate(app, mainWindow))
    Menu.setApplicationMenu(menu)
  } else {
    menu = Menu.buildFromTemplate(otherTemplate(mainWindow))
    mainWindow.setMenu(menu)
  }

  mainWindow.on('closed', function winClosed () {
    mainWindow = null
  })
})

function setAllChallengesComplete (path) {
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    challenges[key].completed = true
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}

function setAllChallengesUncomplete (path) {
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    challenges[key].completed = false
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}

function setSomeChallengesComplete (path) {
  var counter = 0
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    counter++
    if (counter < 6) challenges[key].completed = true
    else challenges[key].completed = false
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}
<commit_msg>Fix wrong copied arg<commit_after>var app = require('app')
var BrowserWindow = require('browser-window')
var Menu = require('menu')
var ipc = require('electron').ipcMain
var dialog = require('dialog')
var fs = require('fs')
var path = require('path')

var darwinTemplate = require('./menus/darwin-menu.js')
var otherTemplate = require('./menus/other-menu.js')

var emptyData = require('./empty-data.json')
var emptySavedDir = require('./empty-saved-dir.json')

var mainWindow = null
var menu = null

var iconPath = path.join(__dirname, '/assets/git-it.png')

app.on('window-all-closed', function appQuit () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('ready', function appReady () {
  mainWindow = new BrowserWindow({"minWidth": 800, "minHeight": 600, width: 980, height: 760, title: 'Git-it', icon: iconPath })

  var appPath = app.getPath('userData')
  var userDataPath = path.join(appPath, 'user-data.json')
  var userSavedDir = path.join(appPath, 'saved-dir.json')

  // tools for development to prefill challenge completion
  // usage: electron . --none
  //        electron . --some
  //        electron . --all
  if (process.argv[2] === '--none') { setAllChallengesUncomplete(userDataPath) }
  if (process.argv[2] === '--some') { setSomeChallengesComplete(userDataPath) }
  if (process.argv[2] === '--all')  { setAllChallengesComplete(userDataPath) }

  fs.exists(userDataPath, function (exists) {
    if (!exists) {
      fs.writeFile(userDataPath, JSON.stringify(emptyData, null, ' '), function (err) {
        if (err) return console.log(err)
      })
    }
  })

  fs.exists(userSavedDir, function (exists) {
    if (!exists) {
      fs.writeFile(userSavedDir, JSON.stringify(emptySavedDir, null, ' '), function (err) {
        if (err) return console.log(err)
      })
    }
  })

  mainWindow.loadURL('file://' + __dirname + '/index.html')

  ipc.on('getUserDataPath', function (event) {
    event.returnValue = userDataPath
  })

  ipc.on('getUserSavedDir', function (event) {
    event.returnValue = userSavedDir
  })

  ipc.on('open-file-dialog', function (event) {
    var files = dialog.showOpenDialog(mainWindow, { properties: [ 'openFile', 'openDirectory' ]})
    if (files) {
      event.sender.send('selected-directory', files)
    }
  })

  ipc.on('confirm-clear', function (event) {
    var options = {
      type: 'info',
      buttons: ['Yes', 'No'],
      title: 'Confirm Clearing Statuses',
      message: 'Are you sure you want to clear the status for every challenge?'
    }
    dialog.showMessageBox(options, function cb (response) {
      event.sender.send('confirm-clear-response', response)
    })
  })

  if (process.platform === 'darwin') {
    menu = Menu.buildFromTemplate(darwinTemplate(app, mainWindow))
    Menu.setApplicationMenu(menu)
  } else {
    menu = Menu.buildFromTemplate(otherTemplate(mainWindow))
    mainWindow.setMenu(menu)
  }

  mainWindow.on('closed', function winClosed () {
    mainWindow = null
  })
})

function setAllChallengesComplete (path) {
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    challenges[key].completed = true
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}

function setAllChallengesUncomplete (path) {
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    challenges[key].completed = false
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}

function setSomeChallengesComplete (path) {
  var counter = 0
  var challenges = JSON.parse(fs.readFileSync(path))
  for (var key in challenges) {
    counter++
    if (counter < 6) challenges[key].completed = true
    else challenges[key].completed = false
  }
  fs.writeFileSync(path, JSON.stringify(challenges), '', null)
}
<|endoftext|>