<commit_before>const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const { DATABASE_URL, PORT, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET } = require('./config')
const GoogleStrategy = require('passport-google-oauth20')
const passport = require('passport')
const BearerStrategy = require('passport-http-bearer')
const User = require('./models/user');

const HOST = process.env.HOST;

console.log(`Server running in ${process.env.NODE_ENV} mode` );

const app = express();
const jsonParser = bodyParser.json();

app.use(jsonParser);

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
  next();
});

mongoose.Promise = global.Promise;

//google auth
passport.use(new GoogleStrategy({
    clientID: GOOGLE_CLIENT_ID,
    clientSecret: GOOGLE_CLIENT_SECRET,
    callbackURL: '/auth/google/callback'
  },
  (accessToken, refreshToken, profile, cb) => {
    console.log("this is the profile photo", profile.photos[0].value)
    User.findOneAndUpdate({ googleId: profile.id },
          {
            $set: {
              googleId: profile.id,
              name: profile.name,
              userName: profile.displayName,
              email: profile.emails[0].value,
              picture: profile.photos[0].value,
              accessToken
            }
          },
          { upsert: true, new: true, setDefaultsOnInsert: true })
          .then(user => {
            console.log(user)
              cb(null, user);
          })
          .catch((err) => {
              console.log('catch error', err);
          });
    }
  ));

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile', 'email'] }));

app.get('/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/', session: false }),
  (req, res) => {
    res.cookie('accessToken', req.user.accessToken, { expires: 0, httpOnly: false });
    // Successful authentication, redirect home.
    res.redirect('/');
  });

// passport bearer Strategy
passport.use(new BearerStrategy(
  (accessToken, done) => {
    User.findOne({
      accessToken
    }).then(user => {
      done(null, user, { scope: 'read' });
    }).catch(err => {
      done(err, null);
    });
  }
));

// get users homepage with authenticated route
app.get('/', passport.authenticate('bearer', { session: false }),
  (req, res) => {
    res.status(200).json({message: 'Hello from the server this route was protected'})
})

let server;

function runServer(callback) {
  return new Promise((resolve, reject) => {
    mongoose.connect(DATABASE_URL, err => {
      if (err && callback) {
        console.log(err);
        return callback(err);
      }
    });
    server = app.listen(PORT, HOST, () => {
      console.log(`Your app is listening on port ${PORT}`);
      if (callback) {
        callback();
      }
      resolve(server);
    }).on('error', err => {
      reject(err);
    });
  });
}

function closeServer() {
  return new Promise((resolve, reject) => {
    console.log('Closing server');
    server.close(err => {
      if (err) {
        reject(err);
        return;
      }
      resolve();
    });
  });
}

if (require.main === module) {
  runServer();
}

module.exports = app;
<commit_msg>remove protected middleware<commit_after>const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const { DATABASE_URL, PORT, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET } = require('./config')
const GoogleStrategy = require('passport-google-oauth20')
const passport = require('passport')
const BearerStrategy = require('passport-http-bearer')
const User = require('./models/user');

const HOST = process.env.HOST;

console.log(`Server running in ${process.env.NODE_ENV} mode` );

const app = express();
const jsonParser = bodyParser.json();

app.use(jsonParser);

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

mongoose.Promise = global.Promise;

//google auth
passport.use(new GoogleStrategy({
    clientID: GOOGLE_CLIENT_ID,
    clientSecret: GOOGLE_CLIENT_SECRET,
    callbackURL: '/auth/google/callback'
  },
  (accessToken, refreshToken, profile, cb) => {
    console.log("this is the profile photo", profile.photos[0].value)
    User.findOneAndUpdate({ googleId: profile.id },
          {
            $set: {
              googleId: profile.id,
              name: profile.name,
              userName: profile.displayName,
              email: profile.emails[0].value,
              picture: profile.photos[0].value,
              accessToken
            }
          },
          { upsert: true, new: true, setDefaultsOnInsert: true })
          .then(user => {
            console.log(user)
              cb(null, user);
          })
          .catch((err) => {
              console.log('catch error', err);
          });
    }
  ));

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile', 'email'] }));

app.get('/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/', session: false }),
  (req, res) => {
    res.cookie('accessToken', req.user.accessToken, { expires: 0, httpOnly: false });
    // Successful authentication, redirect home.
    res.redirect('/');
  });

// passport bearer Strategy
passport.use(new BearerStrategy(
  (accessToken, done) => {
    User.findOne({
      accessToken
    }).then(user => {
      done(null, user, { scope: 'read' });
    }).catch(err => {
      done(err, null);
    });
  }
));

// get users homepage with authenticated route
// app.get('/', passport.authenticate('bearer', { session: false }),
//   (req, res) => {
//     res.status(200).json({message: 'Hello from the server this route was protected'})
// })

app.get('/', (req, res) => {
    res.status(200).json({message: 'Hello from the server this route was protected'})
})

let server;

function runServer(callback) {
  return new Promise((resolve, reject) => {
    mongoose.connect(DATABASE_URL, err => {
      if (err && callback) {
        console.log(err);
        return callback(err);
      }
    });
    server = app.listen(PORT, HOST, () => {
      console.log(`Your app is listening on port ${PORT}`);
      if (callback) {
        callback();
      }
      resolve(server);
    }).on('error', err => {
      reject(err);
    });
  });
}

function closeServer() {
  return new Promise((resolve, reject) => {
    console.log('Closing server');
    server.close(err => {
      if (err) {
        reject(err);
        return;
      }
      resolve();
    });
  });
}

if (require.main === module) {
  runServer();
}

module.exports = app;
<|endoftext|>


<commit_before>var express				= require('express');
var session  			= require('express-session');
var passport 			= require('passport');
var cookieParser 	= require('cookie-parser');
var bodyParser 		= require('body-parser');
var flash    			= require('connect-flash');
var Strategy 			= require('passport-local').Strategy;
var pam	 					= require('authenticate-pam');

// =====================================
// CREATE SERVICE ======================
// =====================================
var app     			= express();
var port 					= 8000;

app.use(cookieParser());
app.use(bodyParser.urlencoded({
	extended: true
}));
app.set('view engine', 'ejs');
app.use(session({
	secret: '!@#$%FooBarBazQuz%$#@!',
	resave: true,
	saveUninitialized: true
 } ));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static('public'));

// =====================================
// CUSTOM PASSPORT STRATEGY=============
// =====================================
passport.use('pam', new Strategy({
		// by default, local strategy uses username and password, we will override with email
		usernameField : 'username',
		passwordField : 'password',
		passReqToCallback : true // allows us to pass back the entire request to the callback
	},
  function(req, username, password, done) {
		pam.authenticate(username, password, function(err) {
	    if(err) {
				done(null, false, req.flash('loginMessage', 'Oops! Wrong usrename or password.'));
	    }else{
				done(null, username);
			}
		});
  })
);

// =====================================
// PASSPORT SERIALIZE ==================
// =====================================
passport.serializeUser(function(username, done) {
		done(null, username);
});

// used to deserialize the user
passport.deserializeUser(function(username, done) {
		done(null, username);
});

// =====================================
// LOGIN ===============================
// =====================================
app.get('/sge/login', function(req, res) {
	// render the page and pass in any flash data if it exists
	res.render('login.ejs', { message: req.flash('loginMessage') });
});

app.post('/sge/login',
  passport.authenticate('pam', {
		failureRedirect: '/sge/login',
		successRedirect: '/sge/home',
		failureFlash: true
	}),
  function(req, res) {
		if (req.body.remember){
			req.session.cookie.maxAge = 1000 * 60 * 3;
		} else {
			req.session.cookie.expires = false;
		}
    res.redirect('/sge');
  }
);

// =====================================
// LOGOUT ==============================
// =====================================
app.get('/sge/logout', function(req, res) {
	req.logout();
	res.redirect('/sge');
});

// =====================================
// INDEX PAGE ==========================
// =====================================
app.get('/sge', function(req, res) {
	res.render('index.ejs'); // load the index.ejs file
});

// =====================================
// HOME PAGE ===========================
// =====================================
app.get('/sge/home', isLoggedIn, function(req, res) {
	res.render('home.ejs', {
		user : req.username, // get the user out of session and pass to template
		page : 'home'
	});
});

// =====================================
// ROUTE MIDDLEWARE ====================
// =====================================
function isLoggedIn(req, res, next) {

	// if user is authenticated in the session, carry on
	if (req.isAuthenticated())
		return next();

	// if they aren't redirect them to the home page
	res.redirect('/sge');
}

// =====================================
// LAUNCH APP ====================
// =====================================
app.listen(port);
console.log('The magic happens on port ' + port);
<commit_msg>test child process with qconf<commit_after>var express				= require('express');
var session  			= require('express-session');
var passport 			= require('passport');
var cookieParser 	= require('cookie-parser');
var bodyParser 		= require('body-parser');
var flash    			= require('connect-flash');
var Strategy 			= require('passport-local').Strategy;
var pam	 					= require('authenticate-pam');
var cp 						= require('child_process');

// =====================================
// CREATE SERVICE ======================
// =====================================
var app     			= express();
var port 					= 8000;

app.use(cookieParser());
app.use(bodyParser.urlencoded({
	extended: true
}));
app.set('view engine', 'ejs');
app.use(session({
	secret: '!@#$%FooBarBazQuz%$#@!',
	resave: true,
	saveUninitialized: true
 } ));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static('public'));

// =====================================
// CUSTOM PASSPORT STRATEGY=============
// =====================================
passport.use('pam', new Strategy({
		// by default, local strategy uses username and password, we will override with email
		usernameField : 'username',
		passwordField : 'password',
		passReqToCallback : true // allows us to pass back the entire request to the callback
	},
  function(req, username, password, done) {
		pam.authenticate(username, password, function(err) {
	    if(err) {
				done(null, false, req.flash('loginMessage', 'Oops! Wrong usrename or password.'));
	    }else{
				done(null, username);
			}
		});
  })
);

// =====================================
// PASSPORT SERIALIZE ==================
// =====================================
passport.serializeUser(function(username, done) {
		done(null, username);
});

// used to deserialize the user
passport.deserializeUser(function(username, done) {
		done(null, username);
});

// =====================================
// LOGIN ===============================
// =====================================
app.get('/sge/login', function(req, res) {
	// render the page and pass in any flash data if it exists
	res.render('login.ejs', { message: req.flash('loginMessage') });
});

app.post('/sge/login',
  passport.authenticate('pam', {
		failureRedirect: '/sge/login',
		successRedirect: '/sge/home',
		failureFlash: true
	}),
  function(req, res) {
		if (req.body.remember){
			req.session.cookie.maxAge = 1000 * 60 * 3;
		} else {
			req.session.cookie.expires = false;
		}
    res.redirect('/sge');
  }
);

// =====================================
// LOGOUT ==============================
// =====================================
app.get('/sge/logout', function(req, res) {
	req.logout();
	res.redirect('/sge');
});

// =====================================
// INDEX PAGE ==========================
// =====================================
app.get('/sge', function(req, res) {
	res.render('index.ejs'); // load the index.ejs file
});

// =====================================
// HOME PAGE ===========================
// =====================================
app.get('/sge/home', isLoggedIn, function(req, res) {

	// Get list of users
	cp.execFile('/usr/bin/qconf', ['-sul'], function(err, result){
		console.log(result);
	});

	res.render('home.ejs', {
		user : req.username, // get the user out of session and pass to template
		page : 'home',
		users : result
	});
});

// =====================================
// ROUTE MIDDLEWARE ====================
// =====================================
function isLoggedIn(req, res, next) {

	// if user is authenticated in the session, carry on
	if (req.isAuthenticated())
		return next();

	// if they aren't redirect them to the home page
	res.redirect('/sge');
}

// =====================================
// LAUNCH APP ====================
// =====================================
app.listen(port);
console.log('The magic happens on port ' + port);
<|endoftext|>


<commit_before>'use strict';

class Schema_Alchemia {

  constructor(schema_rules) {
    this.current_source;
    this.current_target;
    this.current_data;
    this.functions = [];

    if (Object.getOwnPropertyNames(schema_rules).length >= 1) {
      for (var prop in schema_rules) {
        if (typeof schema_rules[prop].group_by === 'undefined') {
          this[prop] = { is_source: false, is_target: false, group_by: false, schema: schema_rules[prop], data: {}, translated: {} };
        }
        else {
          this[prop] = { is_source: false, is_target: false, group_by: schema_rules[prop].group_by, schema: schema_rules[prop].model, data: {}, translated: {} };
        }
      }
    }
    else {
      throw { "msg": "At least 1 schema must be parsed to initialize this class, Example: { shema1:{}, schema2:{}, schemaN... }" }
    }
  }

  set_local_functions(function_name, funct) {
    this.functions[function_name] = funct;
  }

  //define el origen de los datos a ser manipulados
  set_source_schema(schema_name, data) {
    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].is_source = true;
      this.current_source = schema_name;
      if (data) {
        this[schema_name].data = data;
      }
    }
  }

  set_target_schema(schema_name) {
    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].is_target = true;
      this.current_target = schema_name;
    }
  }

  //guarda los datos obtenidos desde la base de datos
  set_data(data, schema_name) {
    schema_name = !schema_name ? this.current_schema : schema_name;

    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].data = data;
    }
    else {
      throw { "msg": "Schema not initialized" }
    }
  }

  transform() {
    if (this[this.current_source].group_by) {
      //console.log('Multiple documents -> group_by');
      //es un arreglo de datos con con el mismo schema
      for (let data_indx in this[this.current_source].data) {
        this.current_data = this[this.current_source].data[data_indx];
        //console.log(this.current_data);
        for (let prop in this[this.current_source].schema) {
          //read source
          let value = this.__read_write(this.current_data, prop);
          //write translation
          //console.log('targeting:', this[this.current_target]);
          if (typeof this[this.current_target].translated[this.current_data[this[this.current_source].group_by]] === 'undefined') {
            this[this.current_target].translated[this.current_data[this[this.current_source].group_by]] = {};
          }
          //console.log(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]]);
          this.__read_write(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]], this[this.current_source].schema[prop], value);
        }

      }
      return this[this.current_target].translated;
    }
    else if (Array.isArray(this[this.current_source].data)) {
      //console.log('Multiple documents -> no group_by');
      //es un arreglo de datos con con el mismo schema
      var doc = 0;
      for (let data_indx in this[this.current_source].data) {
        this.current_data = this[this.current_source].data[data_indx];
        //console.log(this.current_data);
        for (let prop in this[this.current_source].schema) {
          //read source
          let value = this.__read_write(this.current_data, prop);
          //write translation
          //console.log('targeting:', this[this.current_target]);
          if (!Array.isArray(this[this.current_target].translated)) {
            this[this.current_target].translated = [];
          }
          if (typeof this[this.current_target].translated[doc] === 'undefined') {
            this[this.current_target].translated[doc] = {};
          }
          //console.log(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]]);
          this.__read_write(this[this.current_target].translated[doc], this[this.current_source].schema[prop], value);
        }
        doc++;
      }
      return this[this.current_target].translated;
    }
    else {
      //es solo un documento con el schema definido
      //console.log('Single document');
      this.current_data = this[this.current_source].data;
      for (var prop in this[this.current_source].schema) {
        //read source
        let value = this.__read_write(this[this.current_source].data, prop);

        //write translation
        //console.log('targeting:', this[this.current_target]);
        this.__read_write(this[this.current_target].translated, this[this.current_source].schema[prop], value);
      }
      return this[this.current_target].translated;
    }
  }

  __read_write(obj, field_addr, value) {
    if (typeof field_addr == 'string') {
      return this.__read_write(obj, field_addr.split('.'), value);
    }
    else if (!Array.isArray(field_addr) && field_addr.toString() === '[object Object]') {
      if (typeof field_addr.target == 'undefined') { throw { "msg": "Target not defined for this value: " + value } }
      if (typeof field_addr.script == 'undefined') { throw { "msg": "Script not defined for [" + field_addr.target + "]" } }
      var data_source = this.current_data;
      let script = eval(field_addr.script);
      var result = null;
      try {
        result = script(this.functions);
      }
      catch (e) {
        console.error('script_failed: target:', field_addr.target);
        console.error('script_failed: value:', value);
        console.error('script_failed: script:', field_addr.script);
        result = '';
        throw e;
      }
      this.__read_write(obj, field_addr.target, result);
    }
    else if (field_addr.length == 1 && value !== undefined) {
      //console.log(obj);
      obj[field_addr[0]] = value;
      return obj[field_addr[0]];
    }
    else if (field_addr.length == 0) {
      return obj;
    }
    else {
      if (obj == undefined && value == undefined) {
        console.log('field', field_addr[0]);
        console.log('obj', obj);
        console.log('value', value);
        return;
      }
      if (typeof obj[field_addr[0]] === 'undefined' && value !== undefined) {
        obj[field_addr[0]] = {};
      }
      return this.__read_write(obj[field_addr[0]], field_addr.slice(1), value);
    }
  }
}

module.exports = Schema_Alchemia;
<commit_msg>cambio unico<commit_after>'use strict';

class Schema_Alchemia {

  constructor(schema_rules) {
    this.current_source;
    this.current_target;
    this.current_data;
    this.functions = [];
    this.ignore_data_null = false;

    if (Object.getOwnPropertyNames(schema_rules).length >= 1) {
      for (var prop in schema_rules) {
        if (typeof schema_rules[prop].group_by === 'undefined') {
          this[prop] = { is_source: false, is_target: false, group_by: false, schema: schema_rules[prop], data: {}, translated: {} };
        }
        else {
          this[prop] = { is_source: false, is_target: false, group_by: schema_rules[prop].group_by, schema: schema_rules[prop].model, data: {}, translated: {} };
        }
      }
    }
    else {
      throw { "msg": "At least 1 schema must be parsed to initialize this class, Example: { shema1:{}, schema2:{}, schemaN... }" }
    }
  }

  set_local_functions(function_name, funct) {
    this.functions[function_name] = funct;
  }

  //define el origen de los datos a ser manipulados
  set_source_schema(schema_name, data) {
    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].is_source = true;
      this.current_source = schema_name;
      if (data) {
        this[schema_name].data = data;
      }
    }
  }

  set_target_schema(schema_name) {
    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].is_target = true;
      this.current_target = schema_name;
    }
  }

  //guarda los datos obtenidos desde la base de datos
  set_data(data, schema_name) {
    schema_name = !schema_name ? this.current_schema : schema_name;

    if (typeof this[schema_name] !== 'undefined') {
      this[schema_name].data = data;
    }
    else {
      throw { "msg": "Schema not initialized" }
    }
  }

  transform() {
    if (this[this.current_source].group_by) {
      //console.log('Multiple documents -> group_by');
      //es un arreglo de datos con con el mismo schema
      for (let data_indx in this[this.current_source].data) {
        this.current_data = this[this.current_source].data[data_indx];
        //console.log(this.current_data);
        for (let prop in this[this.current_source].schema) {
          //read source
          let value = this.__read_write(this.current_data, prop);
          //write translation
          //console.log('targeting:', this[this.current_target]);
          if (typeof this[this.current_target].translated[this.current_data[this[this.current_source].group_by]] === 'undefined') {
            this[this.current_target].translated[this.current_data[this[this.current_source].group_by]] = {};
          }
          //console.log(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]]);
          this.__read_write(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]], this[this.current_source].schema[prop], value);
        }

      }
      return this[this.current_target].translated;
    }
    else if (Array.isArray(this[this.current_source].data)) {
      //console.log('Multiple documents -> no group_by');
      //es un arreglo de datos con con el mismo schema
      var doc = 0;
      for (let data_indx in this[this.current_source].data) {
        this.current_data = this[this.current_source].data[data_indx];
        //console.log(this.current_data);
        for (let prop in this[this.current_source].schema) {
          //read source
          let value = this.__read_write(this.current_data, prop);
          //write translation
          //console.log('targeting:', this[this.current_target]);
          if (!Array.isArray(this[this.current_target].translated)) {
            this[this.current_target].translated = [];
          }
          if (typeof this[this.current_target].translated[doc] === 'undefined') {
            this[this.current_target].translated[doc] = {};
          }
          //console.log(this[this.current_target].translated[this.current_data[this[this.current_source].group_by]]);
          this.__read_write(this[this.current_target].translated[doc], this[this.current_source].schema[prop], value);
        }
        doc++;
      }
      return this[this.current_target].translated;
    }
    else {
      //es solo un documento con el schema definido
      //console.log('Single document');
      this.current_data = this[this.current_source].data;
      for (var prop in this[this.current_source].schema) {
        //read source
        let value = this.__read_write(this[this.current_source].data, prop);

        //write translation
        //console.log('targeting:', this[this.current_target]);
        this.__read_write(this[this.current_target].translated, this[this.current_source].schema[prop], value);
      }
      return this[this.current_target].translated;
    }
  }

  __read_write(obj, field_addr, value) {
    if (typeof field_addr == 'string') {
      return this.__read_write(obj, field_addr.split('.'), value);
    }
    else if (!Array.isArray(field_addr) && field_addr.toString() === '[object Object]') {
      if (typeof field_addr.target == 'undefined') { throw { "msg": "Target not defined for this value: " + value } }
      if (typeof field_addr.script == 'undefined') { throw { "msg": "Script not defined for [" + field_addr.target + "]" } }
      var data_source = this.current_data;
      let script = eval(field_addr.script);
      var result = null;
      try {
        result = script(this.functions);
      }
      catch (e) {
        console.error('script_failed: target:', field_addr.target);
        console.error('script_failed: value:', value);
        console.error('script_failed: script:', field_addr.script);
        result = '';
        throw e;
      }
      this.__read_write(obj, field_addr.target, result);
    }
    else if (field_addr.length == 1 && value !== undefined) {
      //console.log(obj);
      obj[field_addr[0]] = value;
      return obj[field_addr[0]];
    }
    else if (field_addr.length == 0) {
      return obj;
    }
    else {
      if (obj == undefined && value == undefined) {
        console.log('field', field_addr[0]);
        console.log('obj', obj);
        console.log('value', value);
        return;
      }
      if (typeof obj[field_addr[0]] === 'undefined' && value !== undefined) {
        obj[field_addr[0]] = {};
      }
      return this.__read_write(obj[field_addr[0]], field_addr.slice(1), value);
    }
  }
}

module.exports = Schema_Alchemia;
<|endoftext|>


<commit_before>// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module with d3 as a dependency.
    define(['d3'], factory)
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS
    module.exports = function(d3) {
      d3.tip = factory(d3)
      return d3.tip
    }
  } else {
    // Browser global.
    root.d3.tip = factory(root.d3)
  }
}(this, function (d3) {

  // Public - contructs a new tooltip
  //
  // Returns a tip
  return function() {
    var direction = d3_tip_direction,
        offset    = d3_tip_offset,
        html      = d3_tip_html,
        node      = initNode(),
        svg       = null,
        point     = null,
        target    = null

    function tip(vis) {
      svg = getSVGNode(vis)
      point = svg.createSVGPoint()
      document.body.appendChild(node)
    }

    // Public - show the tooltip on the screen
    //
    // Returns a tip
    tip.show = function() {
      var args = Array.prototype.slice.call(arguments)
      if(args[args.length - 1] instanceof SVGElement) target = args.pop()

      var content = html.apply(this, args),
          poffset = offset.apply(this, args),
          dir     = direction.apply(this, args),
          nodel   = getNodeEl(),
          i       = directions.length,
          coords,
          scrollTop  = document.documentElement.scrollTop || document.body.scrollTop,
          scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft

      nodel.html(content)
        .style('opacity', 1).style('pointer-events', 'all')

      while(i--) nodel.classed(directions[i], false)
      coords = direction_callbacks.get(dir).apply(this)
      nodel.classed(dir, true)
      	.style('top', (coords.top +  poffset[0]) + scrollTop + 'px')
      	.style('left', (coords.left + poffset[1]) + scrollLeft + 'px')

      return tip;
    };

    // Public - hide the tooltip
    //
    // Returns a tip
    tip.hide = function() {
      var nodel = getNodeEl()
      nodel.style('opacity', 0).style('pointer-events', 'none')
      return tip
    }

    // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
    //
    // n - name of the attribute
    // v - value of the attribute
    //
    // Returns tip or attribute value
    tip.attr = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return getNodeEl().attr(n)
      } else {
        var args =  Array.prototype.slice.call(arguments)
        d3.selection.prototype.attr.apply(getNodeEl(), args)
      }

      return tip
    }

    // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
    //
    // n - name of the property
    // v - value of the property
    //
    // Returns tip or style property value
    tip.style = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return getNodeEl().style(n)
      } else {
        var args = Array.prototype.slice.call(arguments)
        d3.selection.prototype.style.apply(getNodeEl(), args)
      }

      return tip
    }

    // Public: Set or get the direction of the tooltip
    //
    // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
    //     sw(southwest), ne(northeast) or se(southeast)
    //
    // Returns tip or direction
    tip.direction = function(v) {
      if (!arguments.length) return direction
      direction = v == null ? v : functor(v)

      return tip
    }

    // Public: Sets or gets the offset of the tip
    //
    // v - Array of [x, y] offset
    //
    // Returns offset or
    tip.offset = function(v) {
      if (!arguments.length) return offset
      offset = v == null ? v : functor(v)

      return tip
    }

    // Public: sets or gets the html value of the tooltip
    //
    // v - String value of the tip
    //
    // Returns html value or tip
    tip.html = function(v) {
      if (!arguments.length) return html
      html = v == null ? v : functor(v)

      return tip
    }

    // Public: destroys the tooltip and removes it from the DOM
    //
    // Returns a tip
    tip.destroy = function() {
      if(node) {
        getNodeEl().remove();
        node = null;
      }
      return tip;
    }

    function d3_tip_direction() { return 'n' }
    function d3_tip_offset() { return [0, 0] }
    function d3_tip_html() { return ' ' }

    var direction_callbacks = d3.map({
      n:  direction_n,
      s:  direction_s,
      e:  direction_e,
      w:  direction_w,
      nw: direction_nw,
      ne: direction_ne,
      sw: direction_sw,
      se: direction_se
    }),

    directions = direction_callbacks.keys()

    function direction_n() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.n.y - node.offsetHeight,
        left: bbox.n.x - node.offsetWidth / 2
      }
    }

    function direction_s() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.s.y,
        left: bbox.s.x - node.offsetWidth / 2
      }
    }

    function direction_e() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.e.y - node.offsetHeight / 2,
        left: bbox.e.x
      }
    }

    function direction_w() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.w.y - node.offsetHeight / 2,
        left: bbox.w.x - node.offsetWidth
      }
    }

    function direction_nw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.nw.y - node.offsetHeight,
        left: bbox.nw.x - node.offsetWidth
      }
    }

    function direction_ne() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.ne.y - node.offsetHeight,
        left: bbox.ne.x
      }
    }

    function direction_sw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.sw.y,
        left: bbox.sw.x - node.offsetWidth
      }
    }

    function direction_se() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.se.y,
        left: bbox.e.x
      }
    }

    function initNode() {
      var node = d3.select(document.createElement('div'));
      node.style('position', 'absolute').style('top', 0).style('opacity', 0)
      	.style('pointer-events', 'none').style('box-sizing', 'border-box')

      return node.node()
    }

    function getSVGNode(el) {
      el = el.node()
      if(el.tagName.toLowerCase() === 'svg')
        return el

      return el.ownerSVGElement
    }

    function getNodeEl() {
      if(node === null) {
        node = initNode();
        // re-add node to DOM
        document.body.appendChild(node);
      };
      return d3.select(node);
    }

    // Private - gets the screen coordinates of a shape
    //
    // Given a shape on the screen, will return an SVGPoint for the directions
    // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
    // sw(southwest).
    //
    //    +-+-+
    //    |   |
    //    +   +
    //    |   |
    //    +-+-+
    //
    // Returns an Object {n, s, e, w, nw, sw, ne, se}
    function getScreenBBox() {
      var targetel   = target || d3.event.target;

      while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) {
          targetel = targetel.parentNode;
      }

      var bbox       = {},
          matrix     = targetel.getScreenCTM(),
          tbbox      = targetel.getBBox(),
          width      = tbbox.width,
          height     = tbbox.height,
          x          = tbbox.x,
          y          = tbbox.y

      point.x = x
      point.y = y
      bbox.nw = point.matrixTransform(matrix)
      point.x += width
      bbox.ne = point.matrixTransform(matrix)
      point.y += height
      bbox.se = point.matrixTransform(matrix)
      point.x -= width
      bbox.sw = point.matrixTransform(matrix)
      point.y -= height / 2
      bbox.w  = point.matrixTransform(matrix)
      point.x += width
      bbox.e = point.matrixTransform(matrix)
      point.x -= width / 2
      point.y -= height / 2
      bbox.n = point.matrixTransform(matrix)
      point.y += height
      bbox.s = point.matrixTransform(matrix)

      return bbox
    }

    // Private - replace D3JS 3.X d3.functor() function
    function functor(v) {
    	return typeof v === "function" ? v : function() {
        return v
    	}
    }

    return tip
  };

}));
<commit_msg>Use require to load d3 in the CommonJS loader, and export d3-tip directly<commit_after>// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module with d3 as a dependency.
    define(['d3'], factory)
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS
    var d3 = require('d3')
    module.exports = factory(d3)
  } else {
    // Browser global.
    root.d3.tip = factory(root.d3)
  }
}(this, function (d3) {

  // Public - contructs a new tooltip
  //
  // Returns a tip
  return function() {
    var direction = d3_tip_direction,
        offset    = d3_tip_offset,
        html      = d3_tip_html,
        node      = initNode(),
        svg       = null,
        point     = null,
        target    = null

    function tip(vis) {
      svg = getSVGNode(vis)
      point = svg.createSVGPoint()
      document.body.appendChild(node)
    }

    // Public - show the tooltip on the screen
    //
    // Returns a tip
    tip.show = function() {
      var args = Array.prototype.slice.call(arguments)
      if(args[args.length - 1] instanceof SVGElement) target = args.pop()

      var content = html.apply(this, args),
          poffset = offset.apply(this, args),
          dir     = direction.apply(this, args),
          nodel   = getNodeEl(),
          i       = directions.length,
          coords,
          scrollTop  = document.documentElement.scrollTop || document.body.scrollTop,
          scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft

      nodel.html(content)
        .style('opacity', 1).style('pointer-events', 'all')

      while(i--) nodel.classed(directions[i], false)
      coords = direction_callbacks.get(dir).apply(this)
      nodel.classed(dir, true)
      	.style('top', (coords.top +  poffset[0]) + scrollTop + 'px')
      	.style('left', (coords.left + poffset[1]) + scrollLeft + 'px')

      return tip;
    };

    // Public - hide the tooltip
    //
    // Returns a tip
    tip.hide = function() {
      var nodel = getNodeEl()
      nodel.style('opacity', 0).style('pointer-events', 'none')
      return tip
    }

    // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
    //
    // n - name of the attribute
    // v - value of the attribute
    //
    // Returns tip or attribute value
    tip.attr = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return getNodeEl().attr(n)
      } else {
        var args =  Array.prototype.slice.call(arguments)
        d3.selection.prototype.attr.apply(getNodeEl(), args)
      }

      return tip
    }

    // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
    //
    // n - name of the property
    // v - value of the property
    //
    // Returns tip or style property value
    tip.style = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return getNodeEl().style(n)
      } else {
        var args = Array.prototype.slice.call(arguments)
        d3.selection.prototype.style.apply(getNodeEl(), args)
      }

      return tip
    }

    // Public: Set or get the direction of the tooltip
    //
    // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
    //     sw(southwest), ne(northeast) or se(southeast)
    //
    // Returns tip or direction
    tip.direction = function(v) {
      if (!arguments.length) return direction
      direction = v == null ? v : functor(v)

      return tip
    }

    // Public: Sets or gets the offset of the tip
    //
    // v - Array of [x, y] offset
    //
    // Returns offset or
    tip.offset = function(v) {
      if (!arguments.length) return offset
      offset = v == null ? v : functor(v)

      return tip
    }

    // Public: sets or gets the html value of the tooltip
    //
    // v - String value of the tip
    //
    // Returns html value or tip
    tip.html = function(v) {
      if (!arguments.length) return html
      html = v == null ? v : functor(v)

      return tip
    }

    // Public: destroys the tooltip and removes it from the DOM
    //
    // Returns a tip
    tip.destroy = function() {
      if(node) {
        getNodeEl().remove();
        node = null;
      }
      return tip;
    }

    function d3_tip_direction() { return 'n' }
    function d3_tip_offset() { return [0, 0] }
    function d3_tip_html() { return ' ' }

    var direction_callbacks = d3.map({
      n:  direction_n,
      s:  direction_s,
      e:  direction_e,
      w:  direction_w,
      nw: direction_nw,
      ne: direction_ne,
      sw: direction_sw,
      se: direction_se
    }),

    directions = direction_callbacks.keys()

    function direction_n() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.n.y - node.offsetHeight,
        left: bbox.n.x - node.offsetWidth / 2
      }
    }

    function direction_s() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.s.y,
        left: bbox.s.x - node.offsetWidth / 2
      }
    }

    function direction_e() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.e.y - node.offsetHeight / 2,
        left: bbox.e.x
      }
    }

    function direction_w() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.w.y - node.offsetHeight / 2,
        left: bbox.w.x - node.offsetWidth
      }
    }

    function direction_nw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.nw.y - node.offsetHeight,
        left: bbox.nw.x - node.offsetWidth
      }
    }

    function direction_ne() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.ne.y - node.offsetHeight,
        left: bbox.ne.x
      }
    }

    function direction_sw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.sw.y,
        left: bbox.sw.x - node.offsetWidth
      }
    }

    function direction_se() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.se.y,
        left: bbox.e.x
      }
    }

    function initNode() {
      var node = d3.select(document.createElement('div'));
      node.style('position', 'absolute').style('top', 0).style('opacity', 0)
      	.style('pointer-events', 'none').style('box-sizing', 'border-box')

      return node.node()
    }

    function getSVGNode(el) {
      el = el.node()
      if(el.tagName.toLowerCase() === 'svg')
        return el

      return el.ownerSVGElement
    }

    function getNodeEl() {
      if(node === null) {
        node = initNode();
        // re-add node to DOM
        document.body.appendChild(node);
      };
      return d3.select(node);
    }

    // Private - gets the screen coordinates of a shape
    //
    // Given a shape on the screen, will return an SVGPoint for the directions
    // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
    // sw(southwest).
    //
    //    +-+-+
    //    |   |
    //    +   +
    //    |   |
    //    +-+-+
    //
    // Returns an Object {n, s, e, w, nw, sw, ne, se}
    function getScreenBBox() {
      var targetel   = target || d3.event.target;

      while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) {
          targetel = targetel.parentNode;
      }

      var bbox       = {},
          matrix     = targetel.getScreenCTM(),
          tbbox      = targetel.getBBox(),
          width      = tbbox.width,
          height     = tbbox.height,
          x          = tbbox.x,
          y          = tbbox.y

      point.x = x
      point.y = y
      bbox.nw = point.matrixTransform(matrix)
      point.x += width
      bbox.ne = point.matrixTransform(matrix)
      point.y += height
      bbox.se = point.matrixTransform(matrix)
      point.x -= width
      bbox.sw = point.matrixTransform(matrix)
      point.y -= height / 2
      bbox.w  = point.matrixTransform(matrix)
      point.x += width
      bbox.e = point.matrixTransform(matrix)
      point.x -= width / 2
      point.y -= height / 2
      bbox.n = point.matrixTransform(matrix)
      point.y += height
      bbox.s = point.matrixTransform(matrix)

      return bbox
    }

    // Private - replace D3JS 3.X d3.functor() function
    function functor(v) {
    	return typeof v === "function" ? v : function() {
        return v
    	}
    }

    return tip
  };

}));
<|endoftext|>


<commit_before>! function (definition) {
    if (typeof window != "undefined") window.cadence = definition()
    else if (typeof define == "function") define(definition)
    else module.exports = definition()
} (function () {
    var __slice = [].slice, __push = [].push

    function consume (to, from) {
        to.push.apply(to, from.splice(0, from.length))
    }

    function cadence () {
        var steps = __slice.call(arguments)

        function enframe (self, consumer, steps, index, caller, callbacks, catcher) {
            return {
                self: self,
                consumer: consumer,
                steps: steps,
                index: index,
                nextIndex: index + 1,
                caller: caller,
                catcher: catcher,
                callbacks: callbacks,
                errors: [],
                finalizers: []
            }
        }

        function execute () {
            var vargs = __slice.call(arguments, 0),
                callback = function (error) { if (error) throw error }

            if (vargs.length) {
                callback = vargs.pop()
            }

            invoke(enframe(this, consumer, steps, -1, { root: true }, argue([ step ].concat(vargs))))

            function consumer (errors, finalizers, results) {
                var vargs = results.length ? [null].concat(results) : []
                finalize.call(this, finalizers, finalizers.length - 1, errors, function (errors) {
                    if (errors.length) {
                        callback(errors.uncaught || errors.shift())
                    } else {
                        callback.apply(null, vargs)
                    }
                })
            }
        }

        // To use the same `step` function throughout while supporting reentrancy,
        // we keep a stack of frame objects. The stack is reversed; top is 0. The
        // `step` function is synchronous and will return immediately.
        //
        // It is possible for the user to invoke `step` outside of a step in a
        // cadence, we can't prevent it, nor really even detect it. Imagine the user
        // invoking `setTimeout` with a callback that calls `step` five minutes
        // later, long after the cadence has ended. Mayhem, but what can you do?

        //
        var frames = []

        function step () { return createHandler(frames[0], false, __slice.call(arguments)) }

        function createHandler (frame, event, vargs) {
            var callback = { errors: [], results: [] }

            if (vargs.length) {
                if (vargs[0] === Error) {
                  return createHandler(frame, true, [ 0, [] ].concat(vargs.slice(1)))
                }

                if (vargs[0] && vargs[0].invoke === invoke) {
                    frame.callbacks[0].results[0].push(vargs.shift())
                }

                if (vargs[0] === null) {
                  var callback = createHandler(frame, true, vargs.slice(1))
                  return function () {
                      return callback.apply(null, [ null ].concat(__slice.call(arguments)))
                  }
                }

                if (callback.fixup = (vargs[0] === step)) {
                    vargs.shift()
                }

                if (typeof vargs[0] == 'string') {
                    callback.property = vargs.shift()
                }

                if (!isNaN(parseInt(vargs[0], 10))) {
                    callback.arity = +(vargs.shift())
                }

                if (Array.isArray(vargs[0]) && vargs[0].length == 0) {
                    callback.arrayed = !! vargs.shift()
                }

                if (vargs[0] && typeof vargs[0].then == 'function') {
                    var promise = vargs.shift(), handler = step.apply(frame.self, vargs)
                    return promise.then(function () {
                        handler.apply(null, [null].concat(__slice.call(arguments)))
                    }, handler)
                }
            }

            frame.callbacks.push(callback)

            callback.steps = vargs

            if (callback.steps.length) {
                if (!callback.fixup) return createCadence(frames[0], callback)
            }

            if (callback.arrayed) {
                if (event) return createCallback(frames[0], callback, -1)
                else return createArray(frames[0], callback)
            }

            return createCallback(frame, callback, 0)
        }

        function createCadence (frame, callback) {
            var index = 0

            if (!callback.arrayed) callback.starter = starter

            function starter () {
                var vargs = __slice.call(arguments)
                var count = 0
                var prefix, gather, counter
                var whilst, each, first

                if (callback.arrayed) {
                    return createCallback(frame, callback, index++).apply(null, [null].concat(vargs))
                } else if (vargs[0] === invoke) {
                    // A reminder; zero index because the result is not arrayed.
                    createCallback(frame, callback, 0).call(null)
                } else {
                    delete callback.starter

                    whilst = function () { return true }
                    if (vargs[0] == null) {
                        vargs.shift()
                    } else {
                        if (Array.isArray(vargs[0]) && vargs.length > 1) {
                            gather = []
                            callback.arrayed = true
                            vargs.shift()
                        }
                        counter = vargs.shift()
                        if (typeof counter == 'number') {
                            whilst = function () { return count != counter }
                        } else if (each = Array.isArray(counter)) {
                            whilst = function () { return count != counter.length }
                        } else {
                            throw new Error('invalid arguments')
                        }
                    }

                    callback.steps.unshift(function () {
                        var vargs = __slice.call(arguments)
                        if (whilst()) {
                            if (counter) {
                                step().apply(frame.self, [ null ].concat(each ? [ counter[count] ] : [], count, vargs))
                            } else {
                                step().apply(frame.self, [ null ].concat(vargs).concat(count))
                            }
                        } else if (gather) {
                            //var release = createHandler(frame, false, [0])
                            //return [ step ].concat(vargs)
                            //callback.results = gather
                            //release()
                            callback.results = [ null ].concat(gather)
                            return [ step ]
                        } else {
                            return [ step ].concat(vargs)
                        }
                    })

                    callback.steps.push(function () {
                        var vargs = __slice.call(arguments)
                        if (gather) gather.push(vargs)
                        frames[0].nextIndex = 0
                        step().apply(frame.self, [null].concat(vargs))
                        count++
                    })

                    callback.starter = function () {
                        createCallback(frame, callback, 0).apply(null, [null].concat(vargs))
                    }

                    var label = function () {
                        label.offset = 0
                        return label
                    }

                    label.invoke = invoke
                    label.step = callback.steps[0]
                    label.offset = callback.steps.length

                    return label
                }
            }

            starter.invoke = invoke
            starter.step = callback.steps[0]
            starter.offset = callback.steps.length

            return starter
        }

        function createArray (frame, callback) {
            var index = 0
            return function () {
                return createCallback(frame, callback, index++)
            }
        }

        function createCallback (frame, callback, index) {
            if (-1 < index) frame.count++
            return function () {
                var vargs = __slice.call(arguments, 0), error
                error = vargs.shift()
                if (error) {
                    frame.errors.push(error)
                } else {
                    if (index < 0) callback.results.push(vargs)
                    else callback.results[index] = vargs
                    if (callback.steps.length) {
                        frame.count++
                        invoke(enframe(frame.self, consumer, callback.steps, -1, frame, argue(callback.results[index])))
                        function consumer (errors, finalizers, results) {
                            callback.results[index] = results
                            __push.apply(frame.errors, errors)

                            if (callback.fixup) {
                                __push.apply(frame.finalizers, finalizers)
                                consumer()
                            } else {
                                finalize.call(frame.self, finalizers, finalizers.length - 1, frame.errors, consumer)
                            }

                            function consumer () {
                                if (-1 < index && ++frame.called == frame.count) {
                                    invoke(frame)
                            //        frame.join()
                                }
                            }
                        }
                    }
                }
                if (index < 0 ? frame.errors.length : ++frame.called == frame.count) {
                    frame.join()
                }
            }
        }

        function subClass (base, override) {
            var object = {}
            for (var key in base) {
                object[key] = base[key]
            }
            for (var key in override) {
                object[key] = override[key]
            }
            return object
        }

        function finalize (finalizers, index, errors, consumer) {
            if (index == -1) {
                consumer.call(this, errors)
            } else {
                var finalizer = finalizers[index]
                invoke(enframe(this, function (e) {
                    __push.apply(errors, e)
                    finalize.call(this, finalizers, index - 1, errors, consumer)
                }, [ finalizer.f ], -1, finalizer.caller, argue(finalizer.vargs)))
            }
        }

        // When we explicitly set we always set the vargs as an array.
        function argue (vargs) { return [{ results: [[vargs]] }] }

        function invoke (frame) {
            var f = _invoke(frame)
            while (f) f = f()
        }

        function _invoke (frame) {
            var callbacks = frame.callbacks, vargs = [], arg = 0
            var catcher, finalizers, callback, arity, i, j, k, result, hold, jump
            var steps = frame.steps

            if (frame.errors.length) {
                catcher = frame._catcher
                if (catcher) {
                    invoke(enframe(frame.self, _consumer, [ catcher ], -1, frame, argue([ frame.errors, frame.errors[0] ]), true))
                    function _consumer (errors, finalizers, results) {
                        frame.errors = []
                        __push.apply(frame.finalizers, finalizers)
                        if (errors.length) {
                            frame.consumer.call(frame.self, errors, frame.finalizers, results)
                        } else {
                            frame.callbacks = argue(results)
                            invoke(frame)
                        }
                    }
                } else {
                    frame.consumer.call(frame.self, frame.errors, frame.finalizers.splice(0, frame.finalizers.length), [])
                }
                return
            }

            var results = callbacks[0].results[0]
            if (results.length == 1 && Array.isArray(results[0])) {
                callbacks[0].results[0] = results = results[0]
            }

            if (results[0] === step && !frame.caller.root) {
                var iterator = frame.catcher ? frame.caller : frame
                results[0] = {
                    invoke: invoke,
                    step: iterator.steps[0],
                    offset: iterator.steps.length
                }
            }

            if (results[0] && results[0].invoke === invoke) {
                var iterator = frame
                var label = results.shift()
                var finalizers = []
                // fixme: what about finalizers? are they run? probably not.
                while (!iterator.root) {
                    if (iterator.steps[0] === label.step) {
                        iterator.nextIndex = label.offset
                        iterator.callbacks = callbacks
                        callbacks[0].results[0] = [ results ]
                        iterator.errors.length = 0
                        consume(iterator.finalizers, finalizers)
                        return function () { invoke(iterator) }
                    }
                    consume(finalizers, iterator.finalizers)
                    iterator = iterator.caller
                }
            }

            // One in callbacks means that there were no callbacks created, we're
            // going to use the return value.
            if (callbacks.length == 1) {
                i = 0, j = 0
            } else {
                i = 1, j = 0
            }

            for (; i < callbacks.length; i++) {
                callback = callbacks[i]
                if (callback.arrayed) {
                    callback.results = callback.results.filter(function (vargs) { return vargs.length })
                }
                if ('arity' in callback) {
                    arity = callback.arity
                } else {
                    arity = callback.arrayed ? 1 : 0
                    callback.results.forEach(function (result) {
                        arity = Math.max(arity, result.length - j)
                    })
                }
                for (k = 0; k < arity; k++) {
                    vargs.push({ values: [], arrayed: callback.arrayed })
                }
                callback.results.forEach(function (result) {
                    for (k = 0; k < arity; k++) {
                        vargs[arg + k].values.push(result[k + j])
                    }
                })
                if (callback.property) {
                    frame.self[callback.property] = vargs[0].arrayed ? vargs[0].values : vargs[0].values[0]
                }
                arg += arity
                j = 0
            }

            vargs = vargs.map(function (vargs) {
                return vargs.arrayed ? vargs.values : vargs.values.shift()
            })

            frame = subClass(frame, {
                callbacks: [],
                errors: [],
                count: 0,
                called: 0,
                index: frame.nextIndex,
                nextIndex: frame.nextIndex + 1,
                sync: false,
                join: function () { frame.sync = true }
            })

            if (steps.length == frame.index) {
                return function () {
                    frame.consumer.call(frame.self, [], frame.finalizers.splice(0, frame.finalizers.length), vargs)
                }
            }

            var s = frame.steps[frame.index], fn
            if (Array.isArray(s)) {
                if (s.length == 1) {
                    frame.finalizers.push({ f: s[0], vargs: vargs, caller: frame.caller })
                    fn = function () {}
                } else {
                    s = s.slice()
                    fn = s[0]
                    frame._catcher = function (errors, error) {
                        var uncaught = []
                        errors.forEach(function (error) {
                            var caught = true
                            if (s.length == 4) {
                                caught = s[2].test(error[s[1]])
                            } else if (s.length == 3) {
                                var value = error.code || error.message
                                caught = s[1].test(value)
                            }
                            if (!caught && !errors.uncaught) errors.uncaught = error
                            return caught
                        })
                        if (!errors.uncaught) {
                            return s[s.length - 1].call(this, errors, errors[0])
                        } else {
                            throw errors
                        }
                    }
                }
            } else if (typeof s == 'function') {
                fn = s
            } else {
                throw new Error('invalid arguments')
            }

            frames.unshift(frame)

            hold = step()
            var results = frames[0].callbacks[0].results[0] = [ null ]
            try {
                result = fn.apply(frame.self, vargs)
            } catch (errors) {
                if (errors === frame.caller.errors) {
                    frames[0].errors.uncaught = errors.uncaught
                } else {
                    errors = [ errors ]
                }
                __push.apply(frames[0].errors, errors)
                frames[0].called = frames[0].count - 1
            }
            frame = frames.shift()
            frame.callbacks.forEach(function (callback) {
                if (callback.starter) callback.starter(invoke)
            })
            hold.apply(frame.self, results.concat([ result === void(0) ? vargs : result ]))

            if (frame.sync) {
                return function () { invoke(frame) }
            } else {
                frame.join = function () { invoke(frame) }
            }
        }

        return execute
    }

    return cadence
})
<commit_msg>Rename `createHandler` to `_step`.<commit_after>! function (definition) {
    if (typeof window != "undefined") window.cadence = definition()
    else if (typeof define == "function") define(definition)
    else module.exports = definition()
} (function () {
    var __slice = [].slice, __push = [].push

    function consume (to, from) {
        to.push.apply(to, from.splice(0, from.length))
    }

    function cadence () {
        var steps = __slice.call(arguments)

        function enframe (self, consumer, steps, index, caller, callbacks, catcher) {
            return {
                self: self,
                consumer: consumer,
                steps: steps,
                index: index,
                nextIndex: index + 1,
                caller: caller,
                catcher: catcher,
                callbacks: callbacks,
                errors: [],
                finalizers: []
            }
        }

        function execute () {
            var vargs = __slice.call(arguments, 0),
                callback = function (error) { if (error) throw error }

            if (vargs.length) {
                callback = vargs.pop()
            }

            invoke(enframe(this, consumer, steps, -1, { root: true }, argue([ step ].concat(vargs))))

            function consumer (errors, finalizers, results) {
                var vargs = results.length ? [null].concat(results) : []
                finalize.call(this, finalizers, finalizers.length - 1, errors, function (errors) {
                    if (errors.length) {
                        callback(errors.uncaught || errors.shift())
                    } else {
                        callback.apply(null, vargs)
                    }
                })
            }
        }

        // To use the same `step` function throughout while supporting reentrancy,
        // we keep a stack of frame objects. The stack is reversed; top is 0. The
        // `step` function is synchronous and will return immediately.
        //
        // It is possible for the user to invoke `step` outside of a step in a
        // cadence, we can't prevent it, nor really even detect it. Imagine the user
        // invoking `setTimeout` with a callback that calls `step` five minutes
        // later, long after the cadence has ended. Mayhem, but what can you do?

        //
        var frames = []

        function step () { return _step(frames[0], false, __slice.call(arguments)) }

        function _step (frame, event, vargs) {
            var callback = { errors: [], results: [] }

            if (vargs.length) {
                if (vargs[0] === Error) {
                  return _step(frame, true, [ 0, [] ].concat(vargs.slice(1)))
                }

                if (vargs[0] && vargs[0].invoke === invoke) {
                    frame.callbacks[0].results[0].push(vargs.shift())
                }

                if (vargs[0] === null) {
                  var callback = _step(frame, true, vargs.slice(1))
                  return function () {
                      return callback.apply(null, [ null ].concat(__slice.call(arguments)))
                  }
                }

                if (callback.fixup = (vargs[0] === step)) {
                    vargs.shift()
                }

                if (typeof vargs[0] == 'string') {
                    callback.property = vargs.shift()
                }

                if (!isNaN(parseInt(vargs[0], 10))) {
                    callback.arity = +(vargs.shift())
                }

                if (Array.isArray(vargs[0]) && vargs[0].length == 0) {
                    callback.arrayed = !! vargs.shift()
                }

                if (vargs[0] && typeof vargs[0].then == 'function') {
                    var promise = vargs.shift(), handler = step.apply(frame.self, vargs)
                    return promise.then(function () {
                        handler.apply(null, [null].concat(__slice.call(arguments)))
                    }, handler)
                }
            }

            frame.callbacks.push(callback)

            callback.steps = vargs

            if (callback.steps.length) {
                if (!callback.fixup) return createCadence(frames[0], callback)
            }

            if (callback.arrayed) {
                if (event) return createCallback(frames[0], callback, -1)
                else return createArray(frames[0], callback)
            }

            return createCallback(frame, callback, 0)
        }

        function createCadence (frame, callback) {
            var index = 0

            if (!callback.arrayed) callback.starter = starter

            function starter () {
                var vargs = __slice.call(arguments)
                var count = 0
                var prefix, gather, counter
                var whilst, each, first

                if (callback.arrayed) {
                    return createCallback(frame, callback, index++).apply(null, [null].concat(vargs))
                } else if (vargs[0] === invoke) {
                    // A reminder; zero index because the result is not arrayed.
                    createCallback(frame, callback, 0).call(null)
                } else {
                    delete callback.starter

                    whilst = function () { return true }
                    if (vargs[0] == null) {
                        vargs.shift()
                    } else {
                        if (Array.isArray(vargs[0]) && vargs.length > 1) {
                            gather = []
                            callback.arrayed = true
                            vargs.shift()
                        }
                        counter = vargs.shift()
                        if (typeof counter == 'number') {
                            whilst = function () { return count != counter }
                        } else if (each = Array.isArray(counter)) {
                            whilst = function () { return count != counter.length }
                        } else {
                            throw new Error('invalid arguments')
                        }
                    }

                    callback.steps.unshift(function () {
                        var vargs = __slice.call(arguments)
                        if (whilst()) {
                            if (counter) {
                                step().apply(frame.self, [ null ].concat(each ? [ counter[count] ] : [], count, vargs))
                            } else {
                                step().apply(frame.self, [ null ].concat(vargs).concat(count))
                            }
                        } else if (gather) {
                            //var release = _step(frame, false, [0])
                            //return [ step ].concat(vargs)
                            //callback.results = gather
                            //release()
                            callback.results = [ null ].concat(gather)
                            return [ step ]
                        } else {
                            return [ step ].concat(vargs)
                        }
                    })

                    callback.steps.push(function () {
                        var vargs = __slice.call(arguments)
                        if (gather) gather.push(vargs)
                        frames[0].nextIndex = 0
                        step().apply(frame.self, [null].concat(vargs))
                        count++
                    })

                    callback.starter = function () {
                        createCallback(frame, callback, 0).apply(null, [null].concat(vargs))
                    }

                    var label = function () {
                        label.offset = 0
                        return label
                    }

                    label.invoke = invoke
                    label.step = callback.steps[0]
                    label.offset = callback.steps.length

                    return label
                }
            }

            starter.invoke = invoke
            starter.step = callback.steps[0]
            starter.offset = callback.steps.length

            return starter
        }

        function createArray (frame, callback) {
            var index = 0
            return function () {
                return createCallback(frame, callback, index++)
            }
        }

        function createCallback (frame, callback, index) {
            if (-1 < index) frame.count++
            return function () {
                var vargs = __slice.call(arguments, 0), error
                error = vargs.shift()
                if (error) {
                    frame.errors.push(error)
                } else {
                    if (index < 0) callback.results.push(vargs)
                    else callback.results[index] = vargs
                    if (callback.steps.length) {
                        frame.count++
                        invoke(enframe(frame.self, consumer, callback.steps, -1, frame, argue(callback.results[index])))
                        function consumer (errors, finalizers, results) {
                            callback.results[index] = results
                            __push.apply(frame.errors, errors)

                            if (callback.fixup) {
                                __push.apply(frame.finalizers, finalizers)
                                consumer()
                            } else {
                                finalize.call(frame.self, finalizers, finalizers.length - 1, frame.errors, consumer)
                            }

                            function consumer () {
                                if (-1 < index && ++frame.called == frame.count) {
                                    invoke(frame)
                            //        frame.join()
                                }
                            }
                        }
                    }
                }
                if (index < 0 ? frame.errors.length : ++frame.called == frame.count) {
                    frame.join()
                }
            }
        }

        function subClass (base, override) {
            var object = {}
            for (var key in base) {
                object[key] = base[key]
            }
            for (var key in override) {
                object[key] = override[key]
            }
            return object
        }

        function finalize (finalizers, index, errors, consumer) {
            if (index == -1) {
                consumer.call(this, errors)
            } else {
                var finalizer = finalizers[index]
                invoke(enframe(this, function (e) {
                    __push.apply(errors, e)
                    finalize.call(this, finalizers, index - 1, errors, consumer)
                }, [ finalizer.f ], -1, finalizer.caller, argue(finalizer.vargs)))
            }
        }

        // When we explicitly set we always set the vargs as an array.
        function argue (vargs) { return [{ results: [[vargs]] }] }

        function invoke (frame) {
            var f = _invoke(frame)
            while (f) f = f()
        }

        function _invoke (frame) {
            var callbacks = frame.callbacks, vargs = [], arg = 0
            var catcher, finalizers, callback, arity, i, j, k, result, hold, jump
            var steps = frame.steps

            if (frame.errors.length) {
                catcher = frame._catcher
                if (catcher) {
                    invoke(enframe(frame.self, _consumer, [ catcher ], -1, frame, argue([ frame.errors, frame.errors[0] ]), true))
                    function _consumer (errors, finalizers, results) {
                        frame.errors = []
                        __push.apply(frame.finalizers, finalizers)
                        if (errors.length) {
                            frame.consumer.call(frame.self, errors, frame.finalizers, results)
                        } else {
                            frame.callbacks = argue(results)
                            invoke(frame)
                        }
                    }
                } else {
                    frame.consumer.call(frame.self, frame.errors, frame.finalizers.splice(0, frame.finalizers.length), [])
                }
                return
            }

            var results = callbacks[0].results[0]
            if (results.length == 1 && Array.isArray(results[0])) {
                callbacks[0].results[0] = results = results[0]
            }

            if (results[0] === step && !frame.caller.root) {
                var iterator = frame.catcher ? frame.caller : frame
                results[0] = {
                    invoke: invoke,
                    step: iterator.steps[0],
                    offset: iterator.steps.length
                }
            }

            if (results[0] && results[0].invoke === invoke) {
                var iterator = frame
                var label = results.shift()
                var finalizers = []
                // fixme: what about finalizers? are they run? probably not.
                while (!iterator.root) {
                    if (iterator.steps[0] === label.step) {
                        iterator.nextIndex = label.offset
                        iterator.callbacks = callbacks
                        callbacks[0].results[0] = [ results ]
                        iterator.errors.length = 0
                        consume(iterator.finalizers, finalizers)
                        return function () { invoke(iterator) }
                    }
                    consume(finalizers, iterator.finalizers)
                    iterator = iterator.caller
                }
            }

            // One in callbacks means that there were no callbacks created, we're
            // going to use the return value.
            if (callbacks.length == 1) {
                i = 0, j = 0
            } else {
                i = 1, j = 0
            }

            for (; i < callbacks.length; i++) {
                callback = callbacks[i]
                if (callback.arrayed) {
                    callback.results = callback.results.filter(function (vargs) { return vargs.length })
                }
                if ('arity' in callback) {
                    arity = callback.arity
                } else {
                    arity = callback.arrayed ? 1 : 0
                    callback.results.forEach(function (result) {
                        arity = Math.max(arity, result.length - j)
                    })
                }
                for (k = 0; k < arity; k++) {
                    vargs.push({ values: [], arrayed: callback.arrayed })
                }
                callback.results.forEach(function (result) {
                    for (k = 0; k < arity; k++) {
                        vargs[arg + k].values.push(result[k + j])
                    }
                })
                if (callback.property) {
                    frame.self[callback.property] = vargs[0].arrayed ? vargs[0].values : vargs[0].values[0]
                }
                arg += arity
                j = 0
            }

            vargs = vargs.map(function (vargs) {
                return vargs.arrayed ? vargs.values : vargs.values.shift()
            })

            frame = subClass(frame, {
                callbacks: [],
                errors: [],
                count: 0,
                called: 0,
                index: frame.nextIndex,
                nextIndex: frame.nextIndex + 1,
                sync: false,
                join: function () { frame.sync = true }
            })

            if (steps.length == frame.index) {
                return function () {
                    frame.consumer.call(frame.self, [], frame.finalizers.splice(0, frame.finalizers.length), vargs)
                }
            }

            var s = frame.steps[frame.index], fn
            if (Array.isArray(s)) {
                if (s.length == 1) {
                    frame.finalizers.push({ f: s[0], vargs: vargs, caller: frame.caller })
                    fn = function () {}
                } else {
                    s = s.slice()
                    fn = s[0]
                    frame._catcher = function (errors, error) {
                        var uncaught = []
                        errors.forEach(function (error) {
                            var caught = true
                            if (s.length == 4) {
                                caught = s[2].test(error[s[1]])
                            } else if (s.length == 3) {
                                var value = error.code || error.message
                                caught = s[1].test(value)
                            }
                            if (!caught && !errors.uncaught) errors.uncaught = error
                            return caught
                        })
                        if (!errors.uncaught) {
                            return s[s.length - 1].call(this, errors, errors[0])
                        } else {
                            throw errors
                        }
                    }
                }
            } else if (typeof s == 'function') {
                fn = s
            } else {
                throw new Error('invalid arguments')
            }

            frames.unshift(frame)

            hold = step()
            var results = frames[0].callbacks[0].results[0] = [ null ]
            try {
                result = fn.apply(frame.self, vargs)
            } catch (errors) {
                if (errors === frame.caller.errors) {
                    frames[0].errors.uncaught = errors.uncaught
                } else {
                    errors = [ errors ]
                }
                __push.apply(frames[0].errors, errors)
                frames[0].called = frames[0].count - 1
            }
            frame = frames.shift()
            frame.callbacks.forEach(function (callback) {
                if (callback.starter) callback.starter(invoke)
            })
            hold.apply(frame.self, results.concat([ result === void(0) ? vargs : result ]))

            if (frame.sync) {
                return function () { invoke(frame) }
            } else {
                frame.join = function () { invoke(frame) }
            }
        }

        return execute
    }

    return cadence
})
<|endoftext|>


<commit_before>var buildTags = function(links) {
    var tags = "";
    for (var i in links) {
        var link = links[i];
        var platform = link.platform;
        // delete link.platform;
        tags += '\n<meta property="al:' + platform + '">\n';
        var keys = Object.keys(link);
        for (var j in keys) {
            var key = keys[j];
            if (key !== "platform") {
                tags += '<meta property="al:' + platform + ":" + key + '" content="' + link[key] + '">\n';
            }
        }
        return tags;
    }
};

var injectMetaOptions = function(str, options) {
    return str.replace(/((?:.|\n|\r)+?)<\/head>/i, "$1" + buildTags(options)+"");
};

var _ = require("underscore");

module.exports = function(platforms) {
    return function(req, res, next) {
        if (_.isFunction(platforms)) {
            platforms = platforms(req, res);
        }
        if (!_.isArray(platforms)) {
            platforms = [ platforms ];
        }
        var htmlMetaHeaders = req.headers["prefer-html-meta-tags"] || "";
        var preferAppLinks = _.some(htmlMetaHeaders.split(","), function(value) {
            return value.trim() === "al";
        });
        if (preferAppLinks) {
            // Always returns html
            res.set("Content-Type", "text/html");
        }
        // Only modify the render function once in case app links
        // is defined multiple times
        if (!res._appLinks) {
            var render = res.render;
            res.render = function(view, options, finishCallback) {
                options = options || {};
                // Support callback function as second arg
                if (_.isFunction(options)) {
                    finishCallback = options, options = {};
                }
                var self = this;
                var defaultCallback = function(err, str) {
                    if (err) {
                        return req.next(err);
                    }
                    self.send(str);
                };
                if (!_.isFunction(finishCallback)) {
                    finishCallback = defaultCallback;
                }
                if (res._appLinks.preferAppLinks) {
                    // If we prefer App Links, let's render simple HTML
                    str = "";
                    str = injectMetaOptions(str, res._appLinks.meta);
                    res.send(str);
                } else {
                    render.call(res, view, options, function(err, str) {
                        str = injectMetaOptions(str, res._appLinks.meta);
                        // remove _appLinks object from response
                        delete res._appLinks;
                        finishCallback(err, str);
                    });
                }
            };
        }
        // Inject app links meta to response object
        res._appLinks = res._appLinks || {};
        res._appLinks.meta = res._appLinks.meta || [];
        // Render more specific meta tag first
        res._appLinks.meta = platforms.concat(res._appLinks.meta);
        res._appLinks.preferAppLinks = preferAppLinks;
        next();
    };
};<commit_msg>Fixes bug with multiple links passed<commit_after>var buildTags = function(links) {
    var tags = "";
    for (var i in links) {
        var link = links[i];
        var platform = link.platform;
        tags += '\n<meta property="al:' + platform + '">\n';
        var keys = Object.keys(link);
        for (var j in keys) {
            var key = keys[j];
            if (key !== "platform") {
                tags += '<meta property="al:' + platform + ":" + key + '" content="' + link[key] + '">\n';
            }
        }

    }
    return tags;
};

var injectMetaOptions = function(str, options) {
    return str.replace(/((?:.|\n|\r)+?)<\/head>/i, "$1" + buildTags(options)+"");
};

var _ = require("underscore");

module.exports = function(platforms) {
    return function(req, res, next) {
        if (_.isFunction(platforms)) {
            platforms = platforms(req, res);
        }
        if (!_.isArray(platforms)) {
            platforms = [ platforms ];
        }
        var htmlMetaHeaders = req.headers["prefer-html-meta-tags"] || "";
        var preferAppLinks = _.some(htmlMetaHeaders.split(","), function(value) {
            return value.trim() === "al";
        });
        if (preferAppLinks) {
            // Always returns html
            res.set("Content-Type", "text/html");
        }
        // Only modify the render function once in case app links
        // is defined multiple times
        if (!res._appLinks) {
            var render = res.render;
            res.render = function(view, options, finishCallback) {
                options = options || {};
                // Support callback function as second arg
                if (_.isFunction(options)) {
                    finishCallback = options, options = {};
                }
                var self = this;
                var defaultCallback = function(err, str) {
                    if (err) {
                        return req.next(err);
                    }
                    self.send(str);
                };
                if (!_.isFunction(finishCallback)) {
                    finishCallback = defaultCallback;
                }
                if (res._appLinks.preferAppLinks) {
                    // If we prefer App Links, let's render simple HTML
                    str = "";
                    str = injectMetaOptions(str, res._appLinks.meta);
                    res.send(str);
                } else {
                    render.call(res, view, options, function(err, str) {
                        str = injectMetaOptions(str, res._appLinks.meta);
                        // remove _appLinks object from response
                        delete res._appLinks;
                        finishCallback(err, str);
                    });
                }
            };
        }
        // Inject app links meta to response object
        res._appLinks = res._appLinks || {};
        res._appLinks.meta = res._appLinks.meta || [];
        // Render more specific meta tag first
        res._appLinks.meta = platforms.concat(res._appLinks.meta);
        res._appLinks.preferAppLinks = preferAppLinks;
        next();
    };
};<|endoftext|>